2014-07-22 130 views
6

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

这里是我的代码:

FileUpload.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) 

回答

8

我已经更新了以下类的方法和它的做工精细的签名。 而不是@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(); 
    } 

    } 

    } 
+0

将java代码接受任何类型的文件,并将其保存在定义的位置? 我要保存的文件类型,如.PDF,.DOC,.JPG –

+0

如果上面的代码有问题,罐子使用Maven的进口: com.sun.jersey 球衣服务器 1.8 com.sun.jersey.contribs 球衣,多 1.8

1

另一种可能的解决方案

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

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

希望这有助于。