Wildfly,Apache CXF和@SchemaValidation
在過去的幾天中,我一直在進(jìn)行從JBoss 4到Wildfly 8的應(yīng)用程序遷移。 該應(yīng)用程序使用了不同的技術(shù),但是我們這里將重點(diǎn)放在XML Web Services JAX-WS上 。 是的,我知道它們已不再流行,但是這些是很久以前開發(fā)的,因此需要維護(hù)以解決兼容性問題。
 無論如何,遷移這些服務(wù)的方法并不容易。 我正在分享一些問題和修補(bǔ)程序,希望這些可以幫助其他開發(fā)人員解決同樣的問題。 
樣本定義
這是舊系統(tǒng)JBoss 4中Web服務(wù)定義的示例:
@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 {幸運(yùn)的是,大多數(shù)定義都使用標(biāo)準(zhǔn)的Java EE注釋。 只有@org.jboss.ws.annotation.EndpointConfig和@org.jboss.ws.annotation.SchemaValidation來自舊的JBossWS庫(kù)。
我們可以輕松擺脫@org.jboss.ws.annotation.EndpointConfig因?yàn)槲覀冊(cè)谛聭?yīng)用程序中將不需要它。 作為參考,它用于設(shè)置要通過端點(diǎn)預(yù)定義的額外配置數(shù)據(jù)。 檢查文檔預(yù)定義的客戶端和端點(diǎn)配置 。
我們要保留@org.jboss.ws.annotation.SchemaValidation 。 作為參考,此批注根據(jù)端點(diǎn)wsdl契約中的相關(guān)模式驗(yàn)證傳入和傳出SOAP消息。 由于注釋不再存在于JBossWS中,因此我們必須使用Apache CXF ,這是Wildfly上JAX-WS的基礎(chǔ)實(shí)現(xiàn)。
問題
這是我遇到的一些問題:
SchemaValidation批注
注釋@org.jboss.ws.annotation.SchemaValidation不再存在。 您必須使用Apache CXF的注釋org.apache.cxf.annotations.SchemaValidation 。
添加以下Maven依賴項(xiàng)以使用Apache CXF批注:
<dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-api</artifactId><version>2.7.11</version><scope>provided</scope> </dependency>另外,請(qǐng)注意,在原始批注中,我們可以定義errorHandler屬性。 舊的應(yīng)用程序使用自定義錯(cuò)誤處理程序來針對(duì)架構(gòu)驗(yàn)證錯(cuò)誤設(shè)置自定義錯(cuò)誤消息。 新注釋中沒有等效項(xiàng),因此我們需要以另一種方式進(jìn)行。 為了復(fù)制舊的行為,我使用了Apache CXF攔截器 。 創(chuàng)建一個(gè)攔截器類并擴(kuò)展AbstractPhaseInterceptor 。 這是一個(gè)示例:
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服務(wù)器都使用攔截器。 執(zhí)行傳入和傳出攔截鏈以進(jìn)行常規(guī)處理以及發(fā)生錯(cuò)誤時(shí)。 在這種情況下,我們要覆蓋Schema Validation消息,因此我們需要將攔截器綁定到錯(cuò)誤輸出攔截器鏈中。 您可以為該行為使用注釋@OutFaultInterceptors 。 每個(gè)鏈都分為多個(gè)階段。 您可以通過在構(gòu)造函數(shù)中傳遞Phase.MARSHAL來定義希望攔截器運(yùn)行的Phase.MARSHAL 。 還有其他階段,但是由于我們要更改錯(cuò)誤消息,因此我們?cè)贛ARSHAL階段進(jìn)行此操作。
不同的WSDL
舊的Web服務(wù)具有在部署時(shí)自動(dòng)生成的WSDL文件。 不幸的是,在某些情況下,JBoss 4和Wildfly 8生成的WSDL是不同的。 這可能會(huì)導(dǎo)致您的外部呼叫者出現(xiàn)問題。 在這種情況下,主要問題在于架構(gòu)驗(yàn)證。 在Wildfly 8中執(zhí)行時(shí),在JBoss 4中有效的請(qǐng)求不再有效。
此行為的原因是在目標(biāo)名稱空間中。 如果在Web Service參數(shù)中使用帶注釋的@XmlRootElement ,而未在注釋中定義namespace屬性,則JBoss 4 WS會(huì)生成帶有黑色名稱空間的目標(biāo)WSDL元素。 如果CWSF元素為空,則Apache CXF將使用Web服務(wù)默認(rèn)名稱空間來綁定WSDL元素。 作為參考,這是通過CXF代碼完成的: org.apache.cxf.jaxws.support.JaxWsServiceConfiguration#getParameterName 。
可以通過更改CXF代碼來解決此問題,但是我們選擇將舊生成的WSDL文件放置在遷移的應(yīng)用程序源中,并將其包含在發(fā)行版中。 它不再自動(dòng)生成,這意味著如果我們更改API,則需要手動(dòng)生成WSDL。 我們需要小心確保未在WSDL中破壞任何內(nèi)容。 這種方法似乎比必須維護(hù)我們自己的CXF版本更好。 我們可能也可以為此提交修復(fù)程序,但是我們認(rèn)為JBoss 4行為不是故意的。
啟動(dòng)CXF
要使用CXF中的特定API,還不足以為其具有項(xiàng)目依賴關(guān)系。 實(shí)際上,在最初的幾次嘗試更改之前,似乎沒有與CXF相關(guān)的功能。 發(fā)生這種情況是因?yàn)閃ildfly只在尋找標(biāo)準(zhǔn)的Java EE JAX-WS注釋。 為了使所有CXF行為正常工作,我們需要告訴Wildfly我們的應(yīng)用程序依賴于CXF ,即使這些庫(kù)已經(jīng)在服務(wù)器上了。 是的,這有點(diǎn)令人困惑。
該應(yīng)用程序部署在EAR文件中。 因此,您需要?jiǎng)?chuàng)建一個(gè)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文件中,則顯然無法使用。 有關(guān)更多信息,請(qǐng)檢查WildFly中的類加載 。
如果您想使用其他CXF功能,尤其是與Spring鏈接的功能,則可能會(huì)有些棘手。 看一下這篇文章: 有關(guān)JBoss的各種事實(shí)。 事實(shí)6:JBoss和CXF:天造地設(shè)的對(duì)決 。
最終定義
這應(yīng)該是我們對(duì)Web服務(wù)的最終定義:
@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服務(wù)從JBoss 4遷移到Wildfly所需的更改只是其中的一部分。 但是,如果您不了解一些細(xì)微的細(xì)節(jié),可能會(huì)長(zhǎng)時(shí)間阻止您。 也許您有不同的設(shè)置,并且遇到的問題也有所不同。 如果您只是想通過Wildfly設(shè)置CXF ,這也可以有所幫助,我希望本文對(duì)您有所幫助。
翻譯自: https://www.javacodegeeks.com/2015/05/wildfly-apache-cxf-and-schemavalidation.html
總結(jié)
以上是生活随笔為你收集整理的Wildfly,Apache CXF和@SchemaValidation的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: JavaFX技巧20:有很多需要展示的地
- 下一篇: 怎样用无线网卡连电脑上网(电脑怎样连接无
