Wildfly,Apache CXF和@SchemaValidation
在過去的幾天中,我一直在進行從JBoss 4到Wildfly 8的應用程序遷移。 該應用程序使用了不同的技術(shù),但是我們這里將重點放在XML Web Services JAX-WS上 。 是的,我知道它們已不再流行,但是這些是很久以前開發(fā)的,因此需要維護以解決兼容性問題。
無論如何,遷移這些服務的方法并不容易。 我正在分享一些問題和修補程序,希望這些可以幫助其他開發(fā)人員解決同樣的問題。
樣本定義
這是舊系統(tǒng)JBoss 4中Web服務定義的示例:
@javax.jws.WebService(endpointInterface = "some.pack.age.WebService") @javax.jws.soap.SOAPBinding(style = SOAPBinding.Style.DOCUMENT) @org.jboss.ws.annotation.EndpointConfig(configName = "Standard WSSecurity Endpoint") @javax.jws.HandlerChain(file = "handlers.xml") @org.jboss.ws.annotation.SchemaValidation(enabled = true, errorHandler = CustomErrorHandler.class) public class WebServiceImpl implements WebService {幸運的是,大多數(shù)定義都使用標準的Java EE注釋。 只有@org.jboss.ws.annotation.EndpointConfig和@org.jboss.ws.annotation.SchemaValidation來自舊的JBossWS庫。
我們可以輕松擺脫@org.jboss.ws.annotation.EndpointConfig因為我們在新應用程序中將不需要它。 作為參考,它用于設置要通過端點預定義的額外配置數(shù)據(jù)。 檢查文檔預定義的客戶端和端點配置 。
我們要保留@org.jboss.ws.annotation.SchemaValidation 。 作為參考,此批注根據(jù)端點wsdl契約中的相關模式驗證傳入和傳出SOAP消息。 由于注釋不再存在于JBossWS中,因此我們必須使用Apache CXF ,這是Wildfly上JAX-WS的基礎實現(xiàn)。
問題
這是我遇到的一些問題:
SchemaValidation批注
注釋@org.jboss.ws.annotation.SchemaValidation不再存在。 您必須使用Apache CXF的注釋org.apache.cxf.annotations.SchemaValidation 。
添加以下Maven依賴項以使用Apache CXF批注:
<dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-api</artifactId><version>2.7.11</version><scope>provided</scope> </dependency>另外,請注意,在原始批注中,我們可以定義errorHandler屬性。 舊的應用程序使用自定義錯誤處理程序來針對架構(gòu)驗證錯誤設置自定義錯誤消息。 新注釋中沒有等效項,因此我們需要以另一種方式進行。 為了復制舊的行為,我使用了Apache CXF攔截器 。 創(chuàng)建一個攔截器類并擴展AbstractPhaseInterceptor 。 這是一個示例:
public class SchemaValidationErrorInterceptor extends AbstractPhaseInterceptor<Message> {public SchemaValidationErrorInterceptor() {super(Phase.MARSHAL);}@Overridepublic void handleMessage(Message message) throws Fault {Fault fault = (Fault) message.getContent(Exception.class);Throwable cause = fault.getCause();while (cause != null) {if (cause instanceof SAXParseException) {fault.setMessage("Invalid XML: " + fault.getLocalizedMessage());break;}cause = cause.getCause();}} }您可以像這樣使用它:
@org.apache.cxf.interceptor.OutFaultInterceptors(classes = SchemaValidationErrorInterceptor.class )CXF客戶端和CXF服務器都使用攔截器。 執(zhí)行傳入和傳出攔截鏈以進行常規(guī)處理以及發(fā)生錯誤時。 在這種情況下,我們要覆蓋Schema Validation消息,因此我們需要將攔截器綁定到錯誤輸出攔截器鏈中。 您可以為該行為使用注釋@OutFaultInterceptors 。 每個鏈都分為多個階段。 您可以通過在構(gòu)造函數(shù)中傳遞Phase.MARSHAL來定義希望攔截器運行的Phase.MARSHAL 。 還有其他階段,但是由于我們要更改錯誤消息,因此我們在MARSHAL階段進行此操作。
不同的WSDL
舊的Web服務具有在部署時自動生成的WSDL文件。 不幸的是,在某些情況下,JBoss 4和Wildfly 8生成的WSDL是不同的。 這可能會導致您的外部呼叫者出現(xiàn)問題。 在這種情況下,主要問題在于架構(gòu)驗證。 在Wildfly 8中執(zhí)行時,在JBoss 4中有效的請求不再有效。
此行為的原因是在目標名稱空間中。 如果在Web Service參數(shù)中使用帶注釋的@XmlRootElement ,而未在注釋中定義namespace屬性,則JBoss 4 WS會生成帶有黑色名稱空間的目標WSDL元素。 如果CWSF元素為空,則Apache CXF將使用Web服務默認名稱空間來綁定WSDL元素。 作為參考,這是通過CXF代碼完成的: org.apache.cxf.jaxws.support.JaxWsServiceConfiguration#getParameterName 。
可以通過更改CXF代碼來解決此問題,但是我們選擇將舊生成的WSDL文件放置在遷移的應用程序源中,并將其包含在發(fā)行版中。 它不再自動生成,這意味著如果我們更改API,則需要手動生成WSDL。 我們需要小心確保未在WSDL中破壞任何內(nèi)容。 這種方法似乎比必須維護我們自己的CXF版本更好。 我們可能也可以為此提交修復程序,但是我們認為JBoss 4行為不是故意的。
啟動CXF
要使用CXF中的特定API,還不足以為其具有項目依賴關系。 實際上,在最初的幾次嘗試更改之前,似乎沒有與CXF相關的功能。 發(fā)生這種情況是因為Wildfly只在尋找標準的Java EE JAX-WS注釋。 為了使所有CXF行為正常工作,我們需要告訴Wildfly我們的應用程序依賴于CXF ,即使這些庫已經(jīng)在服務器上了。 是的,這有點令人困惑。
該應用程序部署在EAR文件中。 因此,您需要創(chuàng)建一個jboss-deployment-structure.xml并添加以下內(nèi)容:
<jboss-deployment-structure><sub-deployment name="application.war"><dependencies><module name="org.apache.cxf"/></dependencies></sub-deployment></jboss-deployment-structure>如果將WAR文件中的MANIFEST.MF部署在EAR文件中,則顯然無法使用。 有關更多信息,請檢查WildFly中的類加載 。
如果您想使用其他CXF功能,尤其是與Spring鏈接的功能,則可能會有些棘手。 看一下這篇文章: 有關JBoss的各種事實。 事實6:JBoss和CXF:天造地設的對決 。
最終定義
這應該是我們對Web服務的最終定義:
@WebService(wsdlLocation = "WebService.wsdl",endpointInterface = "some.pack.age.WebService" ) @SOAPBinding(style = SOAPBinding.Style.DOCUMENT) @HandlerChain(file = "/handlers.xml") @SchemaValidation(type = SchemaValidation.SchemaValidationType.IN) @OutFaultInterceptors(classes = SchemaValidationErrorInterceptor.class) public class WebServiceImpl implements BDNSWebService {如您所見,將Web服務從JBoss 4遷移到Wildfly所需的更改只是其中的一部分。 但是,如果您不了解一些細微的細節(jié),可能會長時間阻止您。 也許您有不同的設置,并且遇到的問題也有所不同。 如果您只是想通過Wildfly設置CXF ,這也可以有所幫助,我希望本文對您有所幫助。
翻譯自: https://www.javacodegeeks.com/2015/05/wildfly-apache-cxf-and-schemavalidation.html
總結(jié)
以上是生活随笔為你收集整理的Wildfly,Apache CXF和@SchemaValidation的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JavaFX技巧20:有很多需要展示的地
- 下一篇: 拼图项目的动机和目标