ハマって2時間ほど415 Unsupported media typeと格闘したので、メモ...
目的
JerseyでRestのファイルアップロードを実装したい
必要なJarのdependency
jersey-media-multipart.jarが必要なので、mavenの場合はこう
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で普通に実装する。
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 (てきとう)
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機能を有効化する為のクラスを書く
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に書いて、登録する
web.xml
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.your.company.MultiPartApp</param-value>
</init-param>
これで、JerseyのMultipart機能を使ったコードが動く様になる