CXF SOAP如何将XSD矛盾异常转换为有意义的消息?

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

我将使用CXF 3.0.3中的commonValidationFeature验证一条SOAP消息。验证器可以工作,但它会返回一个soap错误,而没有有意义的错误消息

我希望捕获ValidationException并将其转换为SOAP消息,其中包含状态错误代码中的错误。稍后我将描述输出消息

这里返回了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>
我希望得到的输出是这样的

<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;
}