2018年12月12日 星期三

在 Spring Boot 中使用 Jersey

Spring Boot 作為 Spring Framework 的入門套件,底下可以抽換不同的 RESTful 架構,預設雖然會使用 Spring MVC,但其實需要的話也可以抽換成像是 Jersey 或者其他的架構。在這裡要紀錄的就是使用 Jersey 作為 RESTful 架構的方法。

如果按照 Spring Boot 官方的教學文件,要建立 RESTful API 應該會在 dependecy 中加入 spring-boot-starter-web,這個套件是引入 Spring MVC 的架構。不過如果要改用 Jersey,則可以改成加入 spring-boot-starter-jersey。

Maven 設定

本來我以為 Spring Boot 加上 Jersey 的狀況是會基於 Spring MVC 去橋接,不過實際看起來好像不用。在 Maven 的設定上只需要引入 spring-boot-starter-jersey 就可以正常在 Spring Boot 中使用 Jersey 了。

<parent>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-parent</artifactId>
 <version>2.0.6.RELEASE</version>
</parent>

<dependencies>
 <!-- Spring Boot with Jersey -->
 <dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-jersey</artifactId>
 </dependency>
</dependencies>
程式進入點

實作 main() 的部份跟一般 Spring Boot 應用程式沒什麼兩樣,就是透過 annotation 標記啟用 Spring Boot 就好。這裡是直接透過 @SpringBootApplication 來簡化 annotation。

@SpringBootApplication
public class Application {
  public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
  }
}
建立 Jersey 設定檔

因為沒有要使用 XML 來為 Jersey 做設定,因此需要建立 ResourceConfig 來設定 Jersey。另外因為需要在這裡註冊會用到的 Jersey 相關元件,因此會先註冊以下兩個東西:

  1. RESTful API - 假設名稱為 MyRestfulService.class
  2. Application Listener - 假設名稱為 MyApplicationEventListener.class。這個是看自己需要建立的,這裡只是要放一個不是 API 的 Jersey 元件而已。

import org.glassfish.jersey.server.ResourceConfig;
import org.springframework.stereotype.Component;

@Component
public class JaxrsConfig extends ResourceConfig {
  public JaxrsConfig () {
    register(MyApplicationEventListener.class);
    register(MyRestfulService.class);
  }
}

需要稍微注意的地方是,在 ResourceConfig 上頭要標記 @Component,這樣 Spring Boot 啟動時的 Component Scan 階段才會發現這個設定程式的存在。另外,依照 [2] 的說法,好像這個設定程式不能命名為 JerseyConfig~XD。

實作 RESTful API

RESTful API 的寫法就照一般 Jersey 的寫法就好:

@Provider
@Path("/")
public class MyRestfulService {  
  @GET
  public Response getGoldPrice () {
    return Response.ok().build();
  }
}
實作 ApplicationEventListener(非必要)

作為實驗的範例,在這邊多放了一個 ApplicationEventListener 的實作。不過其實也沒什麼特別的,跟 API 一樣是按照 Jersey 正常的寫法即可。

@Provider
public class MyApplicationEventListener 
    implements ApplicationEventListener {
  
  @Override
  public void onEvent(ApplicationEvent event) {
    switch(event.getType()) {
      case INITIALIZATION_START:
      case DESTROY_FINISHED:
      case INITIALIZATION_APP_FINISHED:
      case INITIALIZATION_FINISHED:
      case RELOAD_FINISHED:
    }
  }

  @Override
  public RequestEventListener onRequest(RequestEvent requestEvent) {
    return null;
  }
}

在這裡沒有特別寫上什麼東西,不過本來放上這個主要是想確認 Spring 的 @autowired 是否能夠正常運作。然後結果顯示因為整個 Jersey 被納入 Spring Boot 管轄,透過 Jersey 的 annotation 被觸發的元件也都會正常地被 Spring Boot 管理,因此在這些元件當中使用 @autowired 也是可以正常注入。

參考資料
  1. Spring Boot Jersey tutorial - using Jersey in a Spring Boot application
  2. Spring Boot 2 Jersey Implementation not working
  3. Jersey 2 ApplicationEventListener onEvent() not called

沒有留言: