JerseyでMulti-partのファイルアップロード


ハマって2時間ほど[415 Unsupported media type](http://www.checkupdown.com/status/E415.html)と格闘したので、メモ...

# 目的

[Jersey]でRestのファイルアップロードを実装したい

# 必要なJarのdependency

jersey-media-multipart.jarが必要なので、mavenの場合はこう

```xml:pom.xml
<dependencies>
  ...
  <dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-multipart</artifactId>
    <version>2.13</version>
  </dependency>
  ...
</dependencies>
```

Gradleの場合はこう書く

```:build.gradle
dependencies {
  ...
  compile 'org.glassfish.jersey.media:jersey-media-multipart:2.13'
  ...
}
```

# コードを書く

Jersey普通のやり方と同様、まずJAX-RSで普通に実装する。

```java:MultiPartAPI.java
package com.your.company;

import java.io.BufferedInputStream;
import java.util.List;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.glassfish.jersey.media.multipart.BodyPart;
import org.glassfish.jersey.media.multipart.BodyPartEntity;
import org.glassfish.jersey.media.multipart.FormDataMultiPart;

@Path("/multipart")
public class MultiPartAPI {

    @POST
    @Path(value = "/upload")
    @Consumes(MediaType.MULTIPART_FORM_DATA) // ここがMultipart対応
    public Response uploadFile(FormDataMultiPart multiPart) {
    
        String filedata = "<pre>";
        List<BodyPart> bodyPartList = multiPart.getBodyParts();

        for (BodyPart bodyPart : bodyPartList) {
            BodyPartEntity bodyPartEntity = (BodyPartEntity) bodyPart.getEntity();
            BufferedInputStream bf = new BufferedInputStream(bodyPartEntity.getInputStream());
            byte[] fbytes = new byte[1024];

            try {
                while ((bf.read(fbytes)) >= 0) {
                    filedata = filedata + new String(fbytes);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        filedata = filedata + "</pre>";

        return Response.status(200).entity(filedata).build();
    }
}
```

Client側のHTML (てきとう)

```html:index.html
<html>
<head>
<title>hoge</title>
</head>
<body>
  <form method="post" action="multipart/upload/" enctype="multipart/form-data">
    <input type="file" name="file" size="50" />
    <p><input type="submit" value="Send it!"></p>
  </form>
</body>
</html>
```

# JerseyでMultipartを有効にする

はまったところ。これをちゃんとしないと↑で書いたコードは動かない。
Multipart機能を有効化する為のクラスを書く

```java:MultiPartApp.java
package com.your.company;

import javax.ws.rs.ApplicationPath;
import org.glassfish.jersey.media.multipart.MultiPartFeature;
import org.glassfish.jersey.server.ResourceConfig;

@ApplicationPath("/")
public class MultiPartApp extends ResourceConfig {

public MultiPartApp() {
    super(MultiPartFeature.class);
    }
}
```

↑で作ったクラスをweb.xmlに書いて、登録する

```xml:web.xml
<init-param>
  <param-name>javax.ws.rs.Application</param-name>
  <param-value>com.your.company.MultiPartApp</param-value>
</init-param>
```

これで、[Jersey]のMultipart機能を使ったコードが動く様になる

# 参考にしたサイト

* [Jersey - 8.3 Multipart]
* [stackoverflow]


[Jersey]:https://jersey.java.net/
[Jersey - 8.3 Multipart]:https://jersey.java.net/documentation/latest/media.html#multipart
[stackoverflow]:http://stackoverflow.com/questions/18339987/unsupported-media-type-415-error-while-implementing-file-upload-using-jersey-i