开发者

how to get source file in HttpRequest for uploading file

I have a problem with upload file in REST web service using java. I开发者_运维百科 don't know how to get the source file. The curl command is like that

curl --upload-file /home/student1/text1.txt http://localhost:20260/project/resources/user1/sub-folder/text1.txt

My question is anyone know how to get the source file url "/home/student1/text1.txt" in REST web service @PUT method?Or any other way to get it?

thanks


I'm not terribly familiar with JAX-RS but I think the following code does what you are looking for:

package org.restlet.example;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;

@Path("project/resources/{user}/{directory}/{filename}")
public class JaxRsResource {
    private static final int BLOCK_SIZE = 8192;
    private static final Map<String, MediaType> MEDIA_TYPE_MAP = new HashMap<String, MediaType>();

    @Context
    private UriInfo uriInfo;

    @Context
    private HttpHeaders httpHeaders;

    @PathParam("user")
    private String user;

    @PathParam("directory")
    private String directory;

    @PathParam("filename")
    private String filename;

    @QueryParam("name")
    private String name;

    @QueryParam("type")
    private String type;

    static {
        MEDIA_TYPE_MAP.put("txt", MediaType.TEXT_PLAIN_TYPE);
        MEDIA_TYPE_MAP.put("gif", MediaType.valueOf("image/gif"));
        MEDIA_TYPE_MAP.put("jpg", MediaType.valueOf("image/jpeg"));
        MEDIA_TYPE_MAP.put("png", MediaType.valueOf("image/png"));
        MEDIA_TYPE_MAP.put("zip", MediaType.valueOf("application/zip"));
    }

    public JaxRsResource() {
    }

    @PUT
    @Consumes({"text/plain", "image/jpeg", "image/png", "image/gif", "application/zip"})
    public Response upload(final byte[] contents) throws IOException, URISyntaxException {
        FileOutputStream output = null;
        try {
            final File directories = new File(user, directory);
            directories.mkdirs();
            final File file = new File(directories, filename);
            output = new FileOutputStream(file);
            output.write(contents);
        } finally {
            if (output != null) {
                output.flush();
                output.close();
            }
        }
        return Response.created(uriInfo.getAbsolutePath()).build();
    }

    @GET
    @Produces({"text/plain", "image/jpeg", "image/png", "image/gif", "application/zip"})
    public Response output() throws IOException {
        final String extension = filename.substring(filename.lastIndexOf('.') + 1);
        final ByteArrayOutputStream output = new ByteArrayOutputStream();
        InputStream input = null;
        try {
            input = new FileInputStream(new File(new File(user, directory), filename));
            final byte[] buffer = new byte[BLOCK_SIZE];
            int read = 0;
            while ((read = input.read(buffer)) > -1) {
                output.write(buffer, 0, read);
            }
        } finally {
            if (input != null) {
                input.close();
            }
        }
        final byte[] byteArray = output.toByteArray();
        output.flush();
        output.close();
        return Response.ok(byteArray, MEDIA_TYPE_MAP.get(extension)).build();
    }

}

I haven't verified that it is safe against trying to put .. for either user or directory so it might require input sanitation. Also, the errors and exceptions needs to be handled better.

I tested this out with curl and it creates the file on the server file system containing the contents of the file passed via --upload-file which can then be retrieved by issuing a GET to the same resource. I did have to add the Content-Type header to the curl request to get it working though:

curl -v -T test.txt -H "Content-Type: text/plain" http://localhost:8182/project/resources/user1/sub-folder/test.txt

I tested this out using Restlet's implementation of JAX-RS.

This new version handles your additional requirement of supporting the query parameters you mentioned in the other comment. I refactored it to use properties instead of method arguments, since the argument lists were growing unwieldy. I learned that it is thread safe to do so from the JAX-RS spec. Also, I modified the code to support plain text and binary files, though I haven't tried it with different file encodings. Since the method is expecting a byte array input I'm hoping that the JAX-RS framework does the right thing and can tell which encoding to use if one is provided in the request's Content-Type header.


I'm assuming that curl uses mltipart/form-data as content type for the upload. The filename would be part of the Content-Disposition header of the first MIME part.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜