我使用cxf开发了一个Web服务。如果由于请求不符合xsd架构的错误而导致错误,我会自定义发送给客户端的错误。为此:
1-我在web-services.xml中添加了一个特定的EventHandlerValidator和一个特定的FaultOutInterceptor
<jaxws:endpoint id="getNewCustomerOrderId" implementor="#getNewCustomerOrderIdWS" address="/GetNewCustomerOrderId">
<jaxws:properties>
<entry key="jaxb-validation-event-handler">
<ref bean="getNewCustomerOrderIdEventHandlerValidator"/>
</entry>
<entry key="schema-validation-enabled" value="IN"/>
<entry key="set-jaxb-validation-event-handler" value="true"/>
</jaxws:properties>
<jaxws:outFaultInterceptors>
<ref bean="getNewCustomerOrderIdCXFFaultOutInterceptor"/>
</jaxws:outFaultInterceptors>
</jaxws:endpoint>`enter code here
2 - 我已经实现了这些类:
在handleValidator中,我只是用代码和消息
抛出我自己的异常public class GetNewCustomerOrderIdEventHandlerValidator implements ValidationEventHandler {
@Override
public boolean handleEvent(ValidationEvent event) {
throw new MyException(MyExceptionCode.ERCC_GNCOI_100, event.getMessage());
}
}
FaultExceptionInterceptor为webservice调用期间抛出的每个异常运行。我只想用代码ERCC_GNCOI_100来捕获MyException以进行自定义,所以:
public class GetNewCustomerOrderIdCXFFaultOutInterceptor extends AbstractSoapInterceptor {
private static final Logger LOGGER = LoggerFactory.getLogger(CreateCustomerOrderCXFFaultOutInterceptor.class);
@Inject
private CreateCustomerOrderFaultExceptionService createCustomerOrderFaultExceptionService;
private static final JAXBContext jaxbContext;
static {
try {
jaxbContext = JAXBContext.newInstance(CreateCustomerOrderException.class);
} catch (JAXBException e) {
LOGGER.error(CormoranMarker.TECH, "Error during JAXBContext instantiation");
throw new RuntimeException(e);
}
}
public GetNewCustomerOrderIdCXFFaultOutInterceptor() {
super(Phase.MARSHAL);
}
@Override
public void handleMessage(SoapMessage message) throws Fault {
Fault exceptionFault = (Fault) message.getContent(Exception.class);
exceptionFault.setMessage("My custom message");
if (exceptionFault.getCause() instanceof MyException) {
MyException myException = (MyException) exceptionFault
.getCause();
if (myException.getCode().equals(myException.ERCC_GNCOI_100)) {// validation
// schema
// errors
Element elt = buildExceptionFaultDetail(cormoranFunctionalException);
exceptionFault.setDetail(elt);
}
}
}
private Element buildExceptionFaultDetail(CormoranFunctionalException cormoranFunctionalException) {
// Build custom response
}
}
然而,在拦截器中我无法捕捉到我的异常:
Fault exceptionFault = (Fault) message.getContent(Exception.class);
这一行得到一个解组异常:
Unmarshalling Error: cvc-complex-type.2.4.a: Invalid content was found starting with element 'customerOrderType1'. One of '{customerOrderID, version, customerOrderType, depositDate}' is expected.
在日志中,我看到我的异常已被抛出:
12:32:27.338 [qtp200426125-38] ERROR c.o.c.c.e.MyException - [] - MyException : Non-respect du schéma (XSD) du WebService exposé par Cormoran : cvc-complex-type.2.4.a: Invalid content was found starting with element 'customerOrderType1'. One of '{customerOrderID, version, customerOrderType, depositDate}' is expected.
你能帮帮我吗?
提前谢谢!
AURI
答案 0 :(得分:1)
Interceptor有两个问题。
首先,您需要在进行更改后将新内容设置为消息。为此,您可以在代码
后面的handleMessage
方法中添加以下内容
message.setContent(Exception.class, exceptionFault);
其次,您选择的阶段为时已晚,无法更改Fault对象。看起来PRE_STREAM
是允许更改的最新阶段。 CXF Interceptor documentation有完整的阶段列表。
答案 1 :(得分:0)
您可以按如下方式修改消息。
Fault exceptionFault = (Fault) message..getExchange().getContent(Exception.class);