我有一条SOAP消息,我将使用CXF 3.0.3中的commonValidationFeature进行验证。验证器有效,但它返回一个没有有意义的错误消息的soap故障。
我想捕获ValidationException并将其转换为SOAP消息,并在状态错误代码中显示错误。我稍后会描述输出消息。
这里回收了肥皂故障:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<soap:Fault>
<faultcode>soap:Server</faultcode>
<faultstring>Fault occurred while processing.</faultstring>
</soap:Fault>
</soap:Body>
</soap:Envelope>
验证错误应为:
字段[xyz]无效,必须比0更好。(类似的东西)
这里的字段是XSD
<xs:element minOccurs="0" name="merchantId">
<xs:simpleType>
<xs:restriction base="xs:long">
<xs:minInclusive value="1" />
</xs:restriction>
</xs:simpleType>
</xs:element>
生成的java代码 @XmlElement(type = String.class) @XmlJavaTypeAdapter(Adapter2 .class) @DecimalMin( “1”) 受保护的Long merchantId;
这是我的终端中使用的验证
<jaxws:features>
<ref bean="commonValidationFeature" />
</jaxws:features>
<bean id="commonValidationFeature" class="org.apache.cxf.validation.BeanValidationFeature"/>
我试图创建我的拦截器以捕获错误,但是当我这样做时,我得到了解组的模式验证错误。与我之前的问题类似的消息:CXF SOAP JAX-WS WSS4JInInterceptor change namespace and cause Unmarshalling error
这是我的拦截器代码(测试代码)
public class ExceptionInterceptor extends AbstractSoapInterceptor {
ConstraintViolationExceptionMapper mapper = new ConstraintViolationExceptionMapper();
public ExceptionInterceptor() {
super(Phase.PRE_LOGICAL);
}
public void handleMessage(SoapMessage message) throws Fault {
Fault fault = (Fault) message.getContent(Exception.class);
Throwable ex = fault.getCause();
if (ex instanceof ConstraintViolationException) {
ConstraintViolationException e = (ConstraintViolationException) ex;
Response response = mapper.toResponse(e);
generateSoapFault(fault, e, response);
} else {
generateSoapFault(fault, null, null);
}
}
private void generateSoapFault(Fault fault, Exception e, Response response) {
fault.setFaultCode(createQName(response.getEntity().toString()));
}
private static QName createQName(String errorCode) {
return new QName("qname.com", errorCode);
}
}
我希望得到的是输出,就像那样
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns6:newOutputResponse xmlns:ns6="http://demo.test" >
<asset>
...
</asset>
<status>
<type>ERROR</type>
<description>[merchantId] is invalid, must be geater than 0.</description>
</....
</ns6...>
....
只有在出现错误时才会添加标签。我怎么能这样做?
答案 0 :(得分:0)
我找到了办法。我们必须创建一个消息响应并使用ContrainsViolation错误填充此消息。这是一个例子
public static StatusType createStatusType(Set<ConstraintViolation<?>> violations, Throwable ex, Fault fault){
StatusType status;
if(violations!=null) {
status = new StatusType();
status.setStatus(StatusFormat.ERROR);
for (ConstraintViolation<?> violation : violations) {
DetailType detailType = new DetailType();
detailType.setCode(ErrorMessageConstant.PARAMETER_VALIDATION_ERR_CODE);
detailType.setDescription(violation.getPropertyPath().toString() + " : " + violation.getMessage());
status.getDetail().add(detailType);
}
} else if(ex instanceof javax.xml.bind.UnmarshalException){
status = new StatusType();
status.setStatus(StatusFormat.ERROR);
DetailType detailType = new DetailType();
detailType.setCode(ErrorMessageConstant.PARAMETER_VALIDATION_ERR_CODE);
detailType.setDescription(((UnmarshalException) ex).getLinkedException().getMessage());
status.getDetail().add(detailType);
} else {
if(ex==null) {
status = MessageHelper.buildStatusType(StatusFormat.ERROR, ErrorMessageConstant.INTERNAL_SERVER_ERR_CODE, fault.getMessage());
} else {
status = MessageHelper.buildStatusType(StatusFormat.ERROR, ErrorMessageConstant.INTERNAL_SERVER_ERR_CODE, ex.toString());
}
}
return status;
}