JAX-RS、特に

RESTEasy

のファイルアップロードの例はあまりありません。

ここでは、HTMLフォームからのファイルアップロードを処理する2つの完全なRESTEasyの例を示します。

  1. `MultipartFormDataInput`を介してアップロードされたファイルを処理する通常の方法

  2. `@ MultipartForm`を介してアップロードされたファイルをPOJOクラスにマップします.

1. RESTEasyマルチパート依存性

RESTEasyでは、マルチパートファイルのアップロードを処理するために ”

resteasy-multipart-provider.jar

“が必要です。


File:pom.xml

    <dependency>
        <groupId>org.jboss.resteasy</groupId>
        <artifactId>resteasy-jaxrs</artifactId>
        <version>2.2.1.GA</version>
    </dependency>

    <dependency>
        <groupId>org.jboss.resteasy</groupId>
        <artifactId>resteasy-multipart-provider</artifactId>
        <version>2.2.0.GA</version>
    </dependency>

    <!-- optional, good for handle I/O task -->
    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.0.1</version>
    </dependency>

2.ファイルアップロードHTMLフォーム

ファイルをアップロードするためのシンプルなHTMLフォーム。

<html>
<body>
    <h1>JAX-RS Upload Form</h1>

    <form action="rest/file/upload" method="post" enctype="multipart/form-data">

       <p>
        Select a file : <input type="file" name="uploadedFile" size="50"/>
       </p>

       <input type="submit" value="Upload It"/>
    </form>

</body>
</html>

3.1 MultipartFormDataInputの例

最初の例では、アップロードされたファイルは自動的に「

MultipartFormDataInput

」にマップされます。

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import org.apache.commons.io.IOUtils;
import org.jboss.resteasy.plugins.providers.multipart.InputPart;
import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput;

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

    private final String UPLOADED__FILE__PATH = "d:\\";

    @POST
    @Path("/upload")
    @Consumes("multipart/form-data")
    public Response uploadFile(MultipartFormDataInput input) {

        String fileName = "";

        Map<String, List<InputPart>> uploadForm = input.getFormDataMap();
        List<InputPart> inputParts = uploadForm.get("uploadedFile");

        for (InputPart inputPart : inputParts) {

         try {

            MultivaluedMap<String, String> header = inputPart.getHeaders();
            fileName = getFileName(header);

           //convert the uploaded file to inputstream
            InputStream inputStream = inputPart.getBody(InputStream.class,null);

            byte[]bytes = IOUtils.toByteArray(inputStream);

           //constructs upload file path
            fileName = UPLOADED__FILE__PATH + fileName;

            writeFile(bytes,fileName);

            System.out.println("Done");

          } catch (IOException e) {
            e.printStackTrace();
          }

        }

        return Response.status(200)
            .entity("uploadFile is called, Uploaded file name : " + fileName).build();

    }

   /** **
     **  header sample
     **  {
     **   Content-Type=[image/png],
     **   Content-Disposition=[form-data; name="file"; filename="filename.extension"]     **  }
     ** ** /   //get uploaded filename, is there a easy way in RESTEasy?
    private String getFileName(MultivaluedMap<String, String> header) {

        String[]contentDisposition = header.getFirst("Content-Disposition").split(";");

        for (String filename : contentDisposition) {
            if ((filename.trim().startsWith("filename"))) {

                String[]name = filename.split("=");

                String finalFileName = name[1].trim().replaceAll("\"", "");
                return finalFileName;
            }
        }
        return "unknown";
    }

   //save to somewhere
    private void writeFile(byte[]content, String filename) throws IOException {

        File file = new File(filename);

        if (!file.exists()) {
            file.createNewFile();
        }

        FileOutputStream fop = new FileOutputStream(file);

        fop.write(content);
        fop.flush();
        fop.close();

    }
}

この例では、ローカルのCドライブから ”

c:\\ abc.png

“ファイルを選択すると、送信ボタンをクリックすると ”

d:\ abc.png

“にアップロードされます。

ダウンロードする –

JAX-RS-FileUpload-Resteasy-Example1.zip

(8 KB)

3.2 MultipartFormの例

この例では、アップロードされたファイルをPOJOクラスにマップします。3.1のように `inputPart`を処理する必要はありません。


POJOファイル、アップロードされたファイルをこのクラスにマップします.

import javax.ws.rs.FormParam;
import org.jboss.resteasy.annotations.providers.multipart.PartType;

public class FileUploadForm {

    public FileUploadForm() {
    }

    private byte[]data;

    public byte[]getData() {
        return data;
    }

    @FormParam("uploadedFile")
    @PartType("application/octet-stream")
    public void setData(byte[]data) {
        this.data = data;
    }

}


アップロードされたファイルを処理します.

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;
import org.jboss.resteasy.annotations.providers.multipart.MultipartForm;

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

    @POST
    @Path("/upload")
    @Consumes("multipart/form-data")
    public Response uploadFile(@MultipartForm FileUploadForm form) {

        String fileName = "d:\\anything";

        try {
            writeFile(form.getData(), fileName);
        } catch (IOException e) {

            e.printStackTrace();
        }

        System.out.println("Done");

        return Response.status(200)
            .entity("uploadFile is called, Uploaded file name : " + fileName).build();

    }

   //save to somewhere
    private void writeFile(byte[]content, String filename) throws IOException {

        File file = new File(filename);

        if (!file.exists()) {
            file.createNewFile();
        }

        FileOutputStream fop = new FileOutputStream(file);

        fop.write(content);
        fop.flush();
        fop.close();

    }
}

問題は、アップロードしたファイル名を取得できないことです。これを修正するには、HTMLフォームにテキストボックスを置くことで、アップロードされたファイル名をキー入力し、 `@FormParam(” filename “)`を介して ”

FileUploadForm

“にマップすることができます。

それをダウンロードしてください://wp-content/uploads/2011/07/JAX-RS-FileUpload-Resteasy-Example2.zip[JAX-RS-FileUpload-Resteasy-Example2.zip](8 KB)

結論

全体的に、RESTEasyはマルチパートをうまく扱うことができますが、filenameのようにアップロードされたファイルヘッダー情報を取得することはむしろ困難です。または、私はRESTEasy APIの使い方を知らないかもしれませんか?

参考文献

jax-rsを使用してマルチパート/フォームファイルをアップロードしますか?]。

http://stackoverflow.com/questions/4875780/resteasy-multipart-data-form-file-upload-on-gae

[Resteasy

GAEのマルチパート/データ形式のファイルアップロード]

リンク://タグ/ファイルアップロード/[ファイルアップロード]リンク://タグ/jax-rs/[jax-rs]リンク://タグ/resteasy/[resteasy]