てきとうなメモ

本の感想とか技術メモとか

Jersey1.xでPOJOMappingFeatureのテスト

Jersey1.xでJSON入出力するにはJAXBを利用する方法もあるのだが、一番シンプルなのはPOJOJSONオブジェクトのマッピングを利用する。

デフォルトだとこれが有効になっていないので、POJOMappingFeatureを有効にする。サーブレットコンテナだとweb.xmlのinit-paramに指定すれば良い

    <init-param>
      <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
      <param-value>true</param-value>
    </init-param>

こんなリソースを用意すると

@Path("json")
public class JsonResource {
  
  @Path("foo")
  @GET
  @Produces(MediaType.APPLICATION_JSON)
  public List<String> foo() {
    return Arrays.asList("foo", "bar");
  }
}
["foo", "bar"]

のように出力される。


テストしたい場合はinitParamをするだけではダメのようで、clientConfigにJacksonJsonProviderを追加してあげる必要があるみたい

public class JsonResourceTest extends JerseyTest {

  @Override
  protected AppDescriptor configure() {
    ClientConfig cc = new DefaultClientConfig();
    cc.getClasses().add(JacksonJsonProvider.class);
    return new WebAppDescriptor.Builder(
        WebComponent.APPLICATION_CONFIG_CLASS,
        "sample.json.JsonResourceTest$App"
        )
        .clientConfig(cc)
        .initParam(
            "com.sun.jersey.api.json.POJOMappingFeature",
            "true"
        )
        .build();
  }

  @Test
  public void test() {
    List<String> words = 
      resource().path("json/foo")
      .accept(MediaType.APPLICATION_JSON)
      .get(new GenericType<List<String>>() {});
    
    assertThat(words.get(0), is("foo"));
  }

  public static class App extends Application {

    @Override
    public Set<Class<?>> getClasses() {
      Set<Class<?>> classes = new HashSet<>();
      classes.add(JsonResource.class);
      return classes;
    }
  }
}