天天看點

jaxws-tomcat-spring

jaxws 完美融合 tomcat+spring,共用一個端口,科科。。。

主要是包含jaxws模式實驗。

目前,在網絡上主要是包含兩種模式

1.jaxws+tomcat 模式

但是,這種方式 不能使用spring的自動注入功能,在實際項目中難于使用。

2.jaxws+spring 模式

這種模式,每一個webservice要配置專門的banding。實際使用麻煩。

那麼jaxws有沒有一種類似CXF的實作方式呢,咳咳。。。

經過這段時間反複檢視源代碼,檢視資料。總算發現如下辦法,其效率有待驗證。。。

1.通過配置web.xml,使得jaxws配置所有/ws/*路徑

<listener>

<!-- 固定值:使用jaxws-ri中的監聽器 -->

<listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>

</listener>

<servlet>

<servlet-name>JaxWsServlet</servlet-name>

<servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>JaxWsServlet</servlet-name>

<url-pattern>/ws/*</url-pattern>

</servlet-mapping>

2.配置WEB-INF/sun-jaxws.xml

<?xml version="1.0" encoding="UTF-8"?>

<endpoints xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime" version="2.0">

<!-- implementation:對外開放WebServices接口的實作類 -->

<!-- url-pattern:浏覽器通路字尾 -->

<endpoint name="webservice1"

implementation="com.jadyer.service.HelloServiceImpl"

url-pattern="/ws/webservice1"/>

</endpoints>

通過配置1的通配符,配置2中所有的webservice都要被比對到。

TODO:這個地方可以省略掉/ws/就好了。嗯,下次研究下,問題不大

3.WSServletContextListener 會周遊sun-jaxws.xml 配置的所有endpoint。并封裝為EndService,放到adapters裡面。

最後,wsservielt.getDelegate.getAdapters,可以拿到所有的adapter,根據url_pattern,比對到對應的 adapter,加以處理。

這裡的關鍵問題是 沒法使用 autowired。查資料發現spring官網發現SpringBeanAutowiringSupport可以支援,但是隻有簡單描述沒有demo。崩潰。。。

通過檢視SpringBeanAutowiringSupport的源代碼,發現ContextLoader.getCurrentWebApplicationContext()擷取的對象WebApplicationContext為空。

根據listener -> filter -> servlet 加載順序,org.springframework.web.context.ContextLoaderListener 優先加載,然後是com.sun.xml.ws.transport.http.servlet.WSServletContextListener,

然後是org.springframework.web.servlet.DispatcherServlet,最後是com.sun.xml.ws.transport.http.servlet.WSServlet。

當我看到ContextLoader.getCurrentWebApplicationContext()的ContextLoader屬于spring-web-4.2.4.RELEASE.jar中,果斷猜測ContextLoader應該是在org.springframework.web.servlet.DispatcherServlet

中初始化的,是以通過com.sun.xml.ws.transport.http.servlet.WSServletContextListener去加載@WebService且extends SpringBeanAutowiringSupport的類時,當然不能注入,因為這時springmvc都還沒有初始化。

是以我果斷實作com.huimark.jaxws.WSSpringServlet2 完全複制 WSServletContextListener的邏輯,隻是從Listener換位Servlet實作了,而且 順序在DispatcherServlet之後(重要),

在 com.sun.xml.ws.transport.http.servlet.WSServlet 之前。(這個應該無所謂,懶得測試了)

後記:

後來我發現com.sun.xml.ws.transport.http.servlet.WSServletContextListener這個類始終會執行,這是由于jaxws-rt-2.2.10.jar/META-INF/services中配置了

javax.servlet.ServletContainerInitializer。删掉即可。

通過連結1,通路實作 數字+1

http://localhost:8080/jaxws-tomcat-spring/add.do

通過account.wsdl右鍵通路,實作 數字+1.

發現兩種通路方式 可以實作 數字 持續增長,證明 通路的是同一個 計數器