JAX-RSをやってみる (4) - MessageBodyReader -
前回の「JAX-RSをやってみる (3) – AutoDiscoverable -」とかだと
package sample.controller;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import sample.bean.SampleBean;
import static javax.ws.rs.core.MediaType.*;
@Path("/sample")
public class Home {
@Path("save")
@POST
@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON)
public SampleBean save(SampleBean bean) {
return bean;
}
}
なんていうので
package sample.controller;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Application;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Test;
import sample.SampleApplication;
import sample.bean.SampleBean;
import static javax.ws.rs.core.MediaType.*;
import static org.junit.Assert.*;
import static org.hamcrest.Matchers.*;
public class HomeTest extends JerseyTest {
@Override
protected Application configure() {
return new SampleApplication();
}
@Test
public void test_save() {
Entity<SampleBean> entity = Entity.entity(
new SampleBean("hoge"),
APPLICATION_JSON
);
SampleBean response = target("/sample/save").request().post(entity, SampleBean.class);
assertThat(response, notNullValue());
}
}
なんていうテストをやってみると「not found MessageBodyReader」なんていうエラーになるわけで。もちろん前回のはMessageBodyWriterは実装してあるけど、MessageBodyReaderが実装されてないので。っていう事でMessageBodyReaderを実装してみた
GsonReaderProvider.java
package sample.provider;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import javax.inject.Singleton;
import javax.ws.rs.Consumes;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyReader;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
@Singleton
@Consumes(MediaType.APPLICATION_JSON)
public class GsonReaderProvider implements MessageBodyReader<Object> {
private Gson gson = new GsonBuilder().create();
@Override
public boolean isReadable(Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType) {
return true;
}
@Override
public Object readFrom(Class<Object> type, Type genericType,
Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
throws IOException, WebApplicationException {
Object value = null;
try (Reader reader = new InputStreamReader(entityStream)) {
value = gson.fromJson(reader, genericType);
}
return value;
}
}
んまぁMessageBodyReaderを実装するだけ。んでもって前回のSampleFeatureで
package sample.internal;
import javax.ws.rs.core.Configuration;
import javax.ws.rs.core.Feature;
import javax.ws.rs.core.FeatureContext;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.MessageBodyWriter;
import org.glassfish.jersey.CommonProperties;
import org.glassfish.jersey.internal.util.PropertiesHelper;
import sample.provider.GsonReaderProvider;
import sample.provider.GsonWriterProvider;
import static org.glassfish.jersey.internal.InternalProperties.JSON_FEATURE;
public class SampleFeature implements Feature {
private static final String SAMPLE_JSON_FEATURE = SampleFeature.class.getSimpleName();
@Override
public boolean configure(final FeatureContext context) {
final Configuration config = context.getConfiguration();
final String jsonFeature = CommonProperties.getValue(
config.getProperties(),
config.getRuntimeType(),
JSON_FEATURE,
null,
String.class
);
if (jsonFeature != null) {
return false;
}
context.property(
PropertiesHelper.getPropertyNameForRuntime(JSON_FEATURE, config.getRuntimeType()),
SAMPLE_JSON_FEATURE
);
if (!config.isRegistered(GsonWriterProvider.class)) {
context.register(GsonWriterProvider.class, MessageBodyWriter.class);
}
// 追加
if (!config.isRegistered(GsonReaderProvider.class)) {
context.register(GsonReaderProvider.class, MessageBodyReader.class);
}
return true;
}
}
な感じでGsonReaderProviderをregisterしておく。あとは上記で書いてるテストをそのまま実行してテストがずっこけなければオッケー
っていう感じでgsonを使ってJAX-RSなレスポンスをエンコードしたり、JSONデータなリクエストをデコードしたり等な件はひとまずこれにて終了