java - 如何在HttpRequest中获取源文件以上传文件

标签 java web-services rest file-upload httprequest

我在使用 Java 在 REST Web 服务中上传文件时遇到问题。我不知道如何获取源文件。 curl命令就是这样

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

我的问题是有人知道如何在 REST Web 服务 @PUT 方法中获取源文件 url“/home/student1/text1.txt”吗?或者任何其他方式来获取它?

谢谢

最佳答案

我对 JAX-RS 不是很熟悉,但我认为以下代码可以满足您的需求:

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();
    }

}

我还没有验证为 userdirectory 尝试放置 .. 是否安全,因此它可能需要输入卫生.此外,还需要更好地处理错误和异常。

我用 curl 对此进行了测试,它在服务器文件系统上创建了一个文件,其中包含通过 --upload-file 传递的文件的内容,然后可以通过向相同的资源。我确实必须将 Content-Type header 添加到 curl 请求才能使其正常工作:

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

我使用 Restlet's 对此进行了测试实现JAX-RS .

这个新版本处理了支持您在其他评论中提到的查询参数的额外要求。我将其重构为使用属性而不是方法参数,因为参数列表变得越来越笨重。我从 JAX-RS 规范中了解到这样做是线程安全的。此外,我修改了代码以支持纯文本和二进制文件,但我还没有尝试使用不同的文件编码。由于该方法需要一个字节数组输入,我希望 JAX-RS 框架做正确的事情,并且如果在请求的 Content-Type header 中提供了一种编码,则可以判断要使用哪种编码。

关于java - 如何在HttpRequest中获取源文件以上传文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5738665/

相关文章:

Java 数组与类名同名

java - 速度打印值及其键

java - 如何在没有 if 构造的情况下引发异常

java - 如何在 Controller 中仅调用一次方法

javascript - Express/Node中3个相关类别的RESTful路由结构

rest - 'Query String Parameters' 是 header 的一部分吗?

java - 如何从通用 ArrayList 中保留单个子类的所有实例

java - 如何将php客户端连接到java webservice?

asp.net - 超出 JavaScriptSerializer.MaxJsonLength。处理这个问题的最佳做法是什么?

java - WSDL 操作中的soapAction 属性为空