Spring boot jersey + Jboss注意點(diǎn)

原本打算用spring mvc的,但想想配置太麻煩,所以就選擇了spring boot。因公司要求要采用JAX-RS規(guī)范,所以用了jersey。 Spring boot已支持jersey,且提供了專門的依賴:spring-boot-start-jersey,所以整合起來比較簡單。

Spring boot:2.0.0.RELEASE

JDK:1.8

Jboss:7.0.4

maven:3.3.3

部署:打成war包,發(fā)布到j(luò)boss

pom.xml

因?yàn)橐虺蓋ar包,所以在pom.xml中加上如下代碼:
<packaging>war</packaging>

因?yàn)橛懈竚odules,所以用下面的方式引入spring boot的父依賴,同時(shí)也附上了一些主要的依賴,詳細(xì)介紹可以參考官網(wǎng)

<dependencyManagement>
        <dependencies>
        <dependency>
            <!-- Import dependency management from Spring Boot -->
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>2.0.0.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <!-- Add typical dependencies for a web application -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jersey</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
        <!-- 因?yàn)橐渴鸬絡(luò)boss,所以要把內(nèi)置的tomcat去掉 -->
        <!-- 官網(wǎng)的描述:To build a war file that is both executable and deployable into an external container, you need to mark the embedded container dependencies as “provided”-->
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

application.properties

路徑:src/java/resources
Spring boot的默認(rèn)配置文件是application.properties。

數(shù)據(jù)源是用jndi,下面是spring boot中jndi的配置

spring.datasource.jndi-name=java:jboss/datasources/customers

引入了jersey, 可以使用下面的配置來定義jersey請求的路徑

# Path that serves as the base URI for the application.
spring.jersey.application-path=/jersey

Spring boot自身提供了一些Endpoint, 可以利用這些Endpoint可以查看Spring boot一些自動(dòng)配置的信息、beans、health等等,幫助開發(fā)者學(xué)習(xí)Spring boot的一些自動(dòng)配置及監(jiān)控我們的Application。默認(rèn)的路徑是/actuator,如:/actuator/health, /actuator/beans。有些Endpoint是安全控制的,需要特殊配置,具體可以參考官網(wǎng)。可以在properties里面配置下面參數(shù)來改變默認(rèn)路徑:

management.endpoints.web.base-path=/manage

如果要用這些自帶的Endpoint,需要在pom.xml中加入下面的依賴:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
</dependencies>

介紹這2個(gè)路徑的配置是為了引入一個(gè)問題,在Spring boot 2.0.0之前的版本,自帶的Endpoint默認(rèn)路徑是/ *, 而jersey的默認(rèn)路徑也是/ *。自帶的Endpoint是基于Spring MVC dispatcher,jersey是基于jersey dispatcher. 如果2個(gè)根路徑是一樣的話,Spring boot就有可能不知道請求要基于哪個(gè)dispatcher來處理,進(jìn)而報(bào)錯(cuò)。最新版本應(yīng)該沒有這個(gè)問題,因?yàn)镾pring boot已經(jīng)給自帶的Endpoint的默認(rèn)路徑改為/actuator。

Jersey注冊自定義的Endpoint

Jersey注入

@Component
public class JerseyConfig extends ResourceConfig {
    public JerseyConfig() {
        register(Endpoint.class);
    }
}

Endpoint

基于目前的配置,該URL:host:port/[projectname]/jersy/hello

@Component
@Path("/hello")
public class Endpoint {
    @GET
    public String message() {
        return "Hello";
    }
}

啟動(dòng)類

下面這段是引處官網(wǎng)的,我的理解:沒有用內(nèi)置的tomcat做部署,所以得重寫configure方法,把外部的web容器上下文引入。

The first step in producing a deployable war file is to provide a SpringBootServletInitializer subclass and override its configure method. Doing so makes use of Spring Framework’s Servlet 3.0 support and lets you configure your application when it is launched by the servlet container. Typically, you should update your application’s main class to extend SpringBootServletInitializer, as shown in the following example:

@SpringBootApplication
public class Application extends SpringBootServletInitializer {
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(Application.class);
    }
    public static void main(String[] args) throws Exception {
        SpringApplication.run(Application.class, args);
    }
}

Spring Boot會(huì)自動(dòng)掃描@SpringBootApplication所在類的同級包及下級包里的所有bean,所以建議啟動(dòng)類放在最外層的包下。

jboss相關(guān)配置

位置:src/main/webapp/WEB-INF

jboss-web.xml

配置web context信息,web context是URL的根目錄。若不配,默認(rèn)項(xiàng)目名為web context。 如下是配置的例子,那么根URL為:host:port/demo/

<!DOCTYPE jboss-web PUBLIC "-//JBoss//DTD Web Application 5.0//EN"  
"http://www.jboss.org/j2ee/dtd/jboss-web_5_0.dtd">  
<jboss-web>  
    <context-root>demo</context-root> 
</jboss-web>    

jboss-deployment-structure.xml

jboss中,自帶了一些jar包,spring boot項(xiàng)目中會(huì)用到一些jboss中自帶的jar包,但項(xiàng)目中用的jar版本可能和jboss中自帶的jar不匹配,代碼部署到j(luò)boss,啟動(dòng)過程中會(huì)報(bào)一些類找不到的錯(cuò)誤。

有兩種解決辦法:

1. 改jboss中的jar包,使之與項(xiàng)目匹配

2. 在項(xiàng)目中添加jboss-deployment-structure.xml,exclude jboss中那些版本不匹配的jar包,再在項(xiàng)目中的pom.xml添加exclude掉的正確版本的jar依賴:

<?xml version="1.0" encoding="UTF-8"?>    
<jboss-deployment-structure>    
    <deployment>    
        <!-- Exclusions allow you to prevent the server from automatically adding some dependencies     -->    
        <exclusions>   
          <module name=“com.fasterxml.jackson.core.jackson-core” />
          <module name=“com.fasterxml.jackson.core.jackson-annotations” />
          <module name=“com.fasterxml.jackson.core.jackson-data bind” />
          <module name=“com.fasterxml.jackson.jaxrs.jackson-jaxrs-Jason-provider” />
          <module name=“org.jboss.resteasy.resteasy-jackson2-provider” />
          <module name=“org.jboss.resteasy.resteasy-jackson-provider” />
          <module name="javax.ws.rs.api"/>      
        </exclusions>    
    </deployment>    
</jboss-deployment-structure>   

當(dāng)然,這兩種方法可能都會(huì)引起其他相關(guān)聯(lián)jar的版本沖突,需要一一排查

調(diào)用ejb

在代碼里調(diào)用remote ejb,啟動(dòng)jboss時(shí),發(fā)現(xiàn)一些ClassCastException。這個(gè)異常,還是因?yàn)榘鼪_突引起的。
在上一步中,exclude掉了jboss中自帶的javax.ws.rs-api,在pom.xml里又引入了該jar的2.1版本,導(dǎo)致jboss中ejb用到的相關(guān)class與新版本的javax.ws.rs-api中的class沖突。
因不想再處理這些包沖突,也因jboss中的ejb還有其他application在用,所以干脆降低了springboot版本為1.5.8,去掉上一步中的<module name="javax.ws.rs.api"/>這句代碼(不引入新版本jar,直接使用jboss自帶的javax.ws.rs-api.jar),問題就解決了。

總結(jié):經(jīng)常解決完問題后,過些日子就忘記了,年紀(jì)大了,不得不服老呀!所以整理一下記下來,也許能利己也利各方碼農(nóng)呢...

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容