JerseyとSpringでのREST API

JerseyとSpringを使用したREST API

[.s1] ##

1. 概要

Jerseyは、RESTfulWebサービスを開発するためのオープンソースフレームワークです。 JAX-RSのリファレンス実装として機能します。

この記事では、we’ll explore the creation of a RESTful Web Service using Jersey 2。 また、Java構成でSpringの依存性注入(DI)を使用します。

2. Mavenの依存関係

pom.xmlに依存関係を追加することから始めましょう:


    org.glassfish.jersey.containers
    jersey-container-servlet
    2.26


    org.glassfish.jersey.media
    jersey-media-json-jackson
    2.26

また、Spring統合の場合、jersey-spring4依存関係を追加する必要があります。


    org.glassfish.jersey.ext
    jersey-spring4
    2.26

これらの依存関係の最新バージョンは、jersey-container-servletjersey-media-json-jackson、およびjersey-spring4で入手できます。

3. Web設定

Next, we need to set up a web project to do Servlet configuration.このために、SpringのWebApplicationInitializerを使用します。

@Order(Ordered.HIGHEST_PRECEDENCE)
public class ApplicationInitializer
  implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext)
      throws ServletException {

        AnnotationConfigWebApplicationContext context
          = new AnnotationConfigWebApplicationContext();

        servletContext.addListener(new ContextLoaderListener(context));
        servletContext.setInitParameter(
          "contextConfigLocation", "com.example.server");
    }
}

ここでは、@Order(Ordered.HIGHEST_PRECEDENCE)アノテーションを追加して、初期化子がJersey-Springのデフォルトの初期化子の前に実行されるようにします。

4. ジャージーJAX-RSを使用したサービス

4.1. リソース表現クラス

サンプルのリソース表現クラスを使用してみましょう。

@XmlRootElement
public class Employee {
    private int id;
    private String firstName;

    // standard getters and setters
}

@XmlRootElementのようなJAXBアノテーションは、(JSONに加えて)XMLサポートが必要な場合にのみ必要であることに注意してください。

4.2. サービス実装

次に、JAX-RSアノテーションを使用してRESTfulWebサービスを作成する方法を見てみましょう。

@Path("/employees")
public class EmployeeResource {

    @Autowired
    private EmployeeRepository employeeRepository;

    @GET
    @Path("/{id}")
    @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
    public Employee getEmployee(@PathParam("id") int id) {
        return employeeRepository.getEmployee(id);
    }

    @POST
    @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
    public Response addEmployee(
      Employee employee, @Context UriInfo uriInfo) {

        employeeRepository.addEmployee(new Employee(employee.getId(),
          employee.getFirstName(), employee.getLastName(),
          employee.getAge()));

        return Response.status(Response.Status.CREATED.getStatusCode())
          .header(
            "Location",
            String.format("%s/%s",uriInfo.getAbsolutePath().toString(),
            employee.getId())).build();
    }
}

The @Path annotation provides the relative URI path to the service.{id}変数が示すように、URI構文内に変数を埋め込むこともできます。 その後、実行時に変数が置換されます。 変数の値を取得するには、@PathParamアノテーションを使用できます。

@GET, @PUT, @POST, @DELETE and @HEAD define the HTTP method of the request。注釈付きのメソッドで処理されます。

The @Produces annotation defines the endpoint’s response type(MIMEメディアタイプ)。 この例では、HTTPヘッダーAcceptapplication/jsonまたはapplication/xml)の値に応じてJSONまたはXMLのいずれかを返すように構成しました。

On the other hand, the @Consumes annotation defines the MIME media types that the service can consume.この例では、サービスはHTTPヘッダーContent-Typeapplication/jsonまたはapplication/xml)に応じてJSONまたはXMLのいずれかを使用できます。

@Contextアノテーションは、クラスフィールド、Beanプロパティ、またはメソッドパラメータに情報を挿入するために使用されます。 この例では、これを使用してUriInfoを挿入しています。 これを使用して、ServletConfigServletContextHttpServletRequest、およびHttpServletResponse.を挿入することもできます。

5. ExceptionMapperの使用

ExceptionMapperを使用すると、例外をインターセプトして、適切なHTTP応答コードをクライアントに返すことができます。 次の例では、EmployeeNotFound例外がスローされると、HTTP応答コード404が返されます。

@Provider
public class NotFoundExceptionHandler
  implements ExceptionMapper {

    public Response toResponse(EmployeeNotFound ex) {
        return Response.status(Response.Status.NOT_FOUND).build();
    }
}

6. リソースクラスの管理

最後に、let’s wire up all service implementation classes and exception mappers against an application path:

@ApplicationPath("/resources")
public class RestConfig extends Application {
    public Set> getClasses() {
        return new HashSet>(
          Arrays.asList(
            EmployeeResource.class,
            NotFoundExceptionHandler.class,
            AlreadyExistsExceptionHandler.class));
    }
}

7. APIテスト

いくつかのライブテストでAPIをテストしてみましょう。

public class JerseyApiLiveTest {

    private static final String SERVICE_URL
      = "http://localhost:8082/spring-jersey/resources/employees";

    @Test
    public void givenGetAllEmployees_whenCorrectRequest_thenResponseCodeSuccess()
      throws ClientProtocolException, IOException {

        HttpUriRequest request = new HttpGet(SERVICE_URL);

        HttpResponse httpResponse = HttpClientBuilder
          .create()
          .build()
          .execute(request);

        assertEquals(httpResponse
          .getStatusLine()
          .getStatusCode(), HttpStatus.SC_OK);
    }
}

8. 結論

この記事では、Jerseyフレームワークを紹介し、シンプルなAPIを開発しました。 依存性注入機能にはSpringを使用しました。 ExceptionMapperの使用も確認しました。

いつものように、完全なソースコードはthis Github projectで入手できます。