Jersey 2.x系でのJSONサービスに関して

Jerseyのバージョンアップで、いろいろ大変だったから残しておく。
えっと、なんか2系から結構変わってるwww。
かなり違うのと、設定がよくわからんかったけど、
なんとか動く様には、なった。
厳密には、まだ、完全に調べきれてないけど。
もともとのソースがSpringとの連動とかやってたので、
若干大変だったかなぁ。
それと、公式ドキュメントがかなり読みづらかった気がする。
設定とかが分散していて、Try ant Errorみたい感じになってしまった。
それで、とりあえずのmavenのpomの設定。

<dependency>
	<groupId>org.glassfish.jersey.containers</groupId>
	<artifactId>jersey-container-servlet</artifactId>
	<version>2.6</version>
</dependency>
<dependency>
	<groupId>org.glassfish.jersey.media</groupId>
 	<artifactId>jersey-media-json-jackson</artifactId>
	<version>2.6</version>
</dependency>
<dependency>
	<groupId>org.glassfish.jersey.media</groupId>
 	<artifactId>jersey-media-json-processing</artifactId>
	<version>2.6</version>
</dependency>

Springも使うから、下の設定も追加します。

<dependency>
  <groupId>org.glassfish.jersey.ext</groupId>
   <artifactId>jersey-spring3</artifactId>
   <version>2.6</version>
   <exclusions>
     <exclusion>
       <groupId>org.springframework</groupId>
       <artifactId>spring-context</artifactId>
     </exclusion>
     <exclusion>
       <groupId>org.springframework</groupId>
       <artifactId>spring-beans</artifactId>
     </exclusion>
     <exclusion>
       <groupId>org.springframework</groupId>
       <artifactId>spring-web</artifactId>
     </exclusion>
   </exclusions>
</dependency>

それと、JAXBも使うので、下のリンクの設定も追加します。
JAXBに関して - クロノスの技術系ブログ
これで、とりあえずMavenの設定は、完了。
以前、書いたエントリーをバージョンアップする方法で書こうかと思います。
以前のエントリーは、下にあります。
JerseyでのJSONサービス - クロノスの技術系ブログ
1.x系の時は、こんな感じで、記述していました。

@Path("/service")
public class JsonService {
   @GET
   @Path("/get")
   public JSONWithPadding get(
      @QueryParam("callback") @DefaultValue("callback") String callback)  {
      CategoryResouce resouce = ObjectFactory().createCategoryResouce();
      List<CategoryList.Category> categoryList = resouce.getCategory();
      CategoryList.Category category1 = new CategoryList.Category();
      category1.setKey("1000");
      category1.setValue("AAAAA");
      categoryList.add(category1);
      CategoryList.Category category2 = new CategoryList.Category();
      category2.setKey("1000");
      category2.setValue("AAAAA");
      categoryList.add(category2);
      return new JSONWithPadding(resource, callback);
   }
}

2.x系からJSONを戻す場合、JSONWithPaddingではなく、アノテーションになります。
そもそもJSONWithPaddingクラスは、ないようです。
あと、JSONPのコールバックの設定も若干違います。
なので、下の書き方になります。

@Path("/service")
public class JsonService {
   @GET
   @JSONP
   @Produces({"application/json", "application/javascript"})
   @Path("/get")
   public CategoryResouce get(
      @QueryParam(JSONP.DEFAULT_QUERY) String callback)  {
      CategoryResouce resouce = ObjectFactory().createCategoryResouce();
      List<CategoryList.Category> categoryList = resouce.getCategory();
      CategoryList.Category category1 = new CategoryList.Category();
      category1.setKey("1000");
      category1.setValue("AAAAA");
      categoryList.add(category1);
      CategoryList.Category category2 = new CategoryList.Category();
      category2.setKey("1000");
      category2.setValue("AAAAA");
      categoryList.add(category2);
      return resource;
   }
}

サービス自体は、これで、終わりなんですが、
web.xmlも前と書き方が違うようで、

<listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>/WEB-INF/config/spring/applicationContext.xml</param-value>
</context-param>
<servlet>
  <servlet-name>SpringApplication</servlet-name>
  <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>SpringApplication</servlet-name>
  <url-pattern>/service/*</url-pattern>
</servlet-mapping>

こんな定義です。
まぁ...ここまでは、公式ドキュメント読んで、書けたんですけど、
案の定、動かんない...
別の設定がいるようで、コンテナの設定がですね...
設定クラスが必要になるみたいで、

package com.chronos.web.resource;

import javax.json.stream.JsonGenerator;

import org.glassfish.jersey.jsonp.JsonProcessingFeature;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.server.spring.scope.RequestContextFilter;

public class WebApplicationResourceConfig extends ResourceConfig {
	public WebApplicationResource() {
		register(JsonProcessingFeature.class);
		packages("com.chronos.web.resource");
		register(RequestContextFilter.class);
		property(JsonGenerator.PRETTY_PRINTING, true);
	}
}

JAX-RSのプロバイダがどのパッケージ配下にあるか設定する必要があって、
その設定クラスを書かない駄目みたいです。
それで、作成した設定クラスをweb.xmlのコンテナのところに
定義しないといけない仕様になってました。

<servlet>
  <servlet-name>SpringApplication</servlet-name>
  <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
  <init-param>
    <param-name>javax.ws.rs.Application</param-name>
    <param-value>com.chronos.web.resource.WebApplicationResourceConfig</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
</servlet>

これで動くところまでは、確認しましたが、
なぜかXML形式で戻ってしまう?
あら?でも起動とか、呼び出してもエラーにならん?
下のライブラリーも必要なようです。

<dependency>
	<groupId>org.glassfish.jersey.media</groupId>
	<artifactId>jersey-media-moxy</artifactId>
	<version>2.6</version>
</dependency>

おお!JSONで、戻るようになった。
Springは?
これはですね、jersey-spring3のライブラリがあるとですね、
コンテナの起動ログをデバックしてたら
自動的にSpringの設定がよまれて、Jerseyと自動的に連動される仕組みになっている
ようでした。