web-dev-qa-db-ja.com

JavaのRest APIを使用したファイルのアップロード

REST APIは初めてです。 REST APIを使用して、ユーザーが指定したパス(リモートまたはローカルパス)にユーザーが選択したファイルをアップロードしたい。私のhtmlファイルには1つのテキストボックスと1つのファイルチューザーがあります。ユーザーは、テキストボックスにFilePath(ローカルまたはリモートマシンのフォルダーの場所)を入力します。この問題を解決する方法を提案してください。

ここに私のコードがあります:

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>

ploadFileService.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)
9
JLyon

私は以下のクラスのメソッドのシグネチャとその動作を更新しました。 _@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();
    }

   }

   }
_
8
JLyon

別の可能な解決策

@Consumesアノテーションは、アプリケーションオクテットストリームに設定します。 PUT httpメソッドを使用します。次に、クライアントでファイルからバイトを読み取り、アップロードします。

RESTファイルを圧縮するサービス)のサンプルコードはこちら- https://stackoverflow.com/a/32253028/15789

お役に立てれば。

1