IK.AM

@making's tech note


Apache Johnzon(JSR-353 JSON-P実装ライブラリ)をJAX-RSとSpring MVCで使ってみる

🗃 {Programming/Java/org/apache/johnzon}
🏷 JAX-RS 🏷 JSON-P 🏷 Java 🏷 Jersey 🏷 Johnzon 🏷 Spring 🏷 Spring Boot 🏷 Spring MVC 
🗓 Updated at 2014-10-27T05:55:55Z  🗓 Created at 2014-10-27T05:55:55Z   🌎 English Page

JSON-P(JSR-353)の実装がApacheから出ていたので使ってみた。

JSON-P RIとは異なり、JAX-RS用のMessageBodyReader/MessageBodyWriterも用意されている(多分)。

これをJAX-RS/Spring MVC両方で使ってみた。どっちもSpring Bootベース。Spring BootでJAX-RSを使う方法こちら

サンプルはGithubにあげた。

JAX-RS版

pom.xml

重要なところだけ、

<dependencies>
    <!-- JSR-353 -->
    <dependency>
        <groupId>org.apache.geronimo.specs</groupId>
        <artifactId>geronimo-json_1.0_spec</artifactId>
        <version>1.0-alpha-1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.johnzon</groupId>
        <artifactId>johnzon-core</artifactId>
        <version>0.1-incubating</version>
    </dependency>
    <dependency>
        <groupId>org.apache.johnzon</groupId>
        <artifactId>johnzon-jaxrs</artifactId>
        <version>0.1-incubating</version>
    </dependency>

    <!-- omitted -->
</dependencies>

リソースクラス

package demo;

import org.springframework.stereotype.Component;

import javax.json.Json;
import javax.json.JsonObject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;

@Component
@Path("/")
public class HelloResource {

    @GET
    public JsonObject hello() {
        return Json.createObjectBuilder()
                .add("name", "@making")
                .add("age", 18)
                .build();
    }
}

@Componentはなくてもいい。SpringのDIコンテナ管理のものをDIしたければ必要。

普通JavaBean作るので誰得感が強い。

Configクラス

package demo;

import org.glassfish.jersey.server.ResourceConfig;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig extends ResourceConfig {
    public AppConfig() {
        packages(true, "demo", "org.apache.johnzon");
    }
}

Johnzonが用意しているMessageBodyReader/MessageBodyWriterがスキャンされるように対象パッケージにorg.apache.johnzonを追加。

エントリポイントはSpring Bootのいつものやつなので省略。

E2Eテスト

package demo;

import com.jayway.restassured.RestAssured;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.IntegrationTest;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;

import static com.jayway.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.is;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = App.class)
@WebAppConfiguration
@IntegrationTest({"server.port:0"})
public class HelloResourceTest {
    @Value("${local.server.port}")
    int port;

    @Before
    public void setUp() throws Exception {
        RestAssured.port = port;
    }

    @Test
    public void testHello() throws Exception {

        given().header("Accept", "application/json")
                .log().all()
                .when().get("/").then()
                .log().all()
                .body("name", is("@making"))
                .body("age", is(18));
    }
}

Acceptヘッダを指定しないとレスポンスのContent-Typeapplication/octet-streamになっちゃって、テストユーティリティのRESTAssured側でこけた・・

Spring MVC版

pom.xml

重要なところだけ。

<dependencies>
    <!-- JSR-353 -->
    <dependency>
        <groupId>org.apache.johnzon</groupId>
        <artifactId>johnzon-core</artifactId>
        <version>${johnzon.version}</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-jsr353</artifactId>
        <version>${jackson.version}</version>
    </dependency>

    <!-- omitted -->
</dependencies>

Spring MVC用のMessageConverterは用意されていないので、代わりにJacksonが用意しているJSR-353用のモジュールを使用します。 (つまりSpring MVCにおいてはJohnzonつかってもRIつかっても大差ない)

Controller

package demo;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.json.Json;
import javax.json.JsonObject;

@RestController
public class HelloController {

    @RequestMapping("/")
    JsonObject hello() {
        return Json.createObjectBuilder()
                .add("name", "@making")
                .add("age", 18)
                .build();
    }
}

誰得(略)

Configクラス

package demo;

import com.fasterxml.jackson.datatype.jsr353.JSR353Module;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig {
    @Bean
    JSR353Module jsr353Module() {
        return new JSR353Module();
    }
}

Jacksonが用意しているJSR-353用のcom.fasterxml.jackson.databind.Module実装をBean定義して有効にする。

エントリポイントはSpring Bootのいつものやつなので省略。

E2Eテスト

全く同じ。


ソースはこちら。 誰得な内容ブログに書くの楽しい。


✒️️ Edit  ⏰ History  🗑 Delete