【问题标题】:File Upload using Rest API in Java在 Java 中使用 Rest API 上传文件
【发布时间】:2014-07-22 14:51:40
【问题描述】:

我是 REST API 的新手。我想使用 REST API 将用户选择的文件上传到用户提供的路径(远程或本地路径)。我的 html 文件有 1 个文本框和 1 个文件选择器。用户将在文本框中输入 FilePath(本地或远程计算机文件夹位置)。 请建议如何解决此问题。

这是我的代码:

文件上传.html:

<body>
    <form action="rest/file/upload" method="post" enctype="multipart/form-data">
        <p>
            Select a file : <input type="file" name="file" size="45" />
        </p>
        <p>Target Upload Path : <input type="text" name="path" /></p>
        <input type="submit" value="Upload It" />
   </form>
</body>

UploadFileService.java

@Path("/file")
public class UploadFileService {

    @POST
    @Path("/upload")
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    public Response uploadFile(
            @FormDataParam("file") InputStream uploadedInputStream,
            @FormDataParam("file") FormDataContentDisposition fileDetail,
            @FormParam("path") String path) {

        /*String uploadedFileLocation = "d://uploaded/"                                                                 + fileDetail.getFileName();*/

        /*String uploadedFileLocation = //10.217.14.88/Installables/uploaded/"                                                                  + fileDetail.getFileName();*/
        String uploadedFileLocation = path
                + fileDetail.getFileName();

        // save it
        writeToFile(uploadedInputStream, uploadedFileLocation);

        String output = "File uploaded to : " + uploadedFileLocation;

        return Response.status(200).entity(output).build();

    }

    // save uploaded file to new location
    private void writeToFile(InputStream uploadedInputStream,
            String uploadedFileLocation) {

        try {
            OutputStream out = new FileOutputStream(new File(
                    uploadedFileLocation));
            int read = 0;
            byte[] bytes = new byte[1024];

            out = new FileOutputStream(new File(uploadedFileLocation));
            while ((read = uploadedInputStream.read(bytes)) != -1) {
                out.write(bytes, 0, read);
            }
            out.flush();
            out.close();
        } catch (IOException e) {

            e.printStackTrace();
        }

    }

}

Web.xml

<display-name>JAXRSFileUploadJerseyExample</display-name>
<servlet>
    <servlet-name>jersey-serlvet</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <init-param>
        <param-name>com.sun.jersey.config.property.packages</param-name>
        <param-value>com.mkyong.rest</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>jersey-serlvet</servlet-name>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>

例外:

HTTP Status 500 - com.sun.jersey.api.container.ContainerException: Exception obtaining parameters
type Exception report
message com.sun.jersey.api.container.ContainerException: Exception obtaining parameters
description The server encountered an internal error that prevented it from fulfilling this request.
exception
javax.servlet.ServletException: com.sun.jersey.api.container.ContainerException: Exception obtaining parameters
        com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:425)
        com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537)
        com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:699)
        javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
root cause
com.sun.jersey.api.container.ContainerException: Exception obtaining parameters
        com.sun.jersey.server.impl.inject.InjectableValuesProvider.getInjectableValues(InjectableValuesProvider.java:54)
        com.sun.jersey.multipart.impl.FormDataMultiPartDispatchProvider$FormDataInjectableValuesProvider.getInjectableValues(FormDataMultiPartDispatchProvider.java:125)
        com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$EntityParamInInvoker.getParams(AbstractResourceMethodDispatchProvider.java:153)
        com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$ResponseOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:203)
        com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75)
        com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:288)
        com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
        com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108)
        com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
        com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84)
        com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1469)
        com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1400)
        com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1349)
        com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1339)
        com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416)
        com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537)
        com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:699)
        javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
root cause
java.lang.IllegalStateException: The @FormParam is utilized when the content type of the request entity is not application/x-www-form-urlencoded
        com.sun.jersey.server.impl.model.parameter.FormParamInjectableProvider$FormParamInjectable.getValue(FormParamInjectableProvider.java:81)
        com.sun.jersey.server.impl.inject.InjectableValuesProvider.getInjectableValues(InjectableValuesProvider.java:46)
        com.sun.jersey.multipart.impl.FormDataMultiPartDispatchProvider$FormDataInjectableValuesProvider.getInjectableValues(FormDataMultiPartDispatchProvider.java:125)
        com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$EntityParamInInvoker.getParams(AbstractResourceMethodDispatchProvider.java:153)
        com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$ResponseOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:203)
        com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75)
        com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:288)
        com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
        com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108)
        com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
        com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84)
        com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1469)
        com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1400)
        com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1349)
        com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1339)
        com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416)
        com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537)
        com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:699)
        javax.servlet.http.HttpServlet.service(HttpServlet.java:728)

【问题讨论】:

    标签: java web-services rest file-upload jersey


    【解决方案1】:

    我已经更新了下面类中的方法签名并且它工作正常。 而不是@FormParam,使用@FormDataParam("path")字符串路径,它解决了我的问题。 以下是更新后的代码:

    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    
    import javax.ws.rs.Consumes;
    import javax.ws.rs.FormParam;
    import javax.ws.rs.POST;
    import javax.ws.rs.Path;
    import javax.ws.rs.core.MediaType;
    import javax.ws.rs.core.Response;
    
    import com.sun.jersey.core.header.FormDataContentDisposition;
    import com.sun.jersey.multipart.FormDataParam;
    
    @Path("/file")
    public class UploadFileService {
    
    @POST
    @Path("/upload")
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    public Response uploadFile(
            @FormDataParam("file") InputStream uploadedInputStream,
            @FormDataParam("file") FormDataContentDisposition fileDetail,
            @FormDataParam("path") String path) {
    
    
        // Path format //10.217.14.97/Installables/uploaded/
        System.out.println("path::"+path);
        String uploadedFileLocation = path
                + fileDetail.getFileName();
    
        // save it
        writeToFile(uploadedInputStream, uploadedFileLocation);
    
        String output = "File uploaded to : " + uploadedFileLocation;
    
        return Response.status(200).entity(output).build();
    
    }
    
    // save uploaded file to new location
    private void writeToFile(InputStream uploadedInputStream,
            String uploadedFileLocation) {
    
        try {
            OutputStream out = new FileOutputStream(new File(
                    uploadedFileLocation));
            int read = 0;
            byte[] bytes = new byte[1024];
    
            out = new FileOutputStream(new File(uploadedFileLocation));
            while ((read = uploadedInputStream.read(bytes)) != -1) {
                out.write(bytes, 0, read);
            }
            out.flush();
            out.close();
        } catch (IOException e) {
    
            e.printStackTrace();
        }
    
       }
    
       }
    

    【讨论】:

    • java 代码会接受任何类型的文件并将其保存在定义的位置吗?我想保存 .pdf、.doc、.jpg 等文件类型
    • 如果上面的代码对 jars 有问题,请使用这个 maven 导入:com.sun.jerseyjersey-server1.8 com.sun.jersey.contribsjersey-multipart1.8
    【解决方案2】:

    另一种可能的解决方案

    @Consumes 注释并将其设置为应用程序八位字节流。使用 PUT http 方法。然后在客户端,从文件中读取字节并上传。

    我的 REST 服务压缩文件的示例代码在这里 - https://stackoverflow.com/a/32253028/15789

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-06
      相关资源
      最近更新 更多