CXF SOAP如何将XSD矛盾异常转换为有意义的消息?
我将使用CXF 3.0.3中的commonValidationFeature验证一条SOAP消息。验证器可以工作,但它会返回一个soap错误,而没有有意义的错误消息 我希望捕获ValidationException并将其转换为SOAP消息,其中包含状态错误代码中的错误。稍后我将描述输出消息 这里返回了soap错误:CXF SOAP如何将XSD矛盾异常转换为有意义的消息?,soap,xsd,cxf,validation,Soap,Xsd,Cxf,Validation,我将使用CXF 3.0.3中的commonValidationFeature验证一条SOAP消息。验证器可以工作,但它会返回一个soap错误,而没有有意义的错误消息 我希望捕获ValidationException并将其转换为SOAP消息,其中包含状态错误代码中的错误。稍后我将描述输出消息 这里返回了soap错误: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:B
<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>
我希望得到的输出是这样的
<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...>
....
只有在出现错误时才会添加标记。我该怎么做呢?我找到了一种方法。我们必须创建一个消息响应,并用containsViolation错误填充此消息。这里有一个例子
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;
}
塞巴斯蒂安找到你的问题的答案了吗?是的,我有些东西。谢谢你让我记得更新这个问题。我很快就会给出答案
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...>
....
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;
}