当前位置: 首页 > 知识库问答 >
问题:

CXF SOAP如何将XSD ContrintException转换为有意义的消息?

萧升
2023-03-14

我有一个SOAP消息,我将使用CXF3.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>

这里的字段是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;

这里是在我的endpoint中使用的验证

<jaxws:features>
    <ref bean="commonValidationFeature" />
</jaxws:features>

<bean id="commonValidationFeature" class="org.apache.cxf.validation.BeanValidationFeature"/>
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...>
....

只有当出现错误时才会添加标记。我怎么能那么做?

共有1个答案

章兴发
2023-03-14

我找到了办法。我们必须创建一个消息响应,并用ContransViolution错误填充此消息。这里有一个例子

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;
}
 类似资料:
  • 我们的基础设施中有融合平台。核心是,我们使用kafka代理来分发事件。许多设备会生成Kafka主题的事件(每种类型的事件都有一个Kafka主题),事件在谷歌的protobuf中序列化。我们有confluent的模式注册表来跟踪protobuf模式。 我们需要的是,对于一些事件,我们需要应用一些转换,然后将转换输出发布到其他一些Kafka主题。当然,Kafka流是实现这一点的一种方法,如本例中所示。

  • 我正在尝试将单个输入消息转换为多个消息。我有一个带有以下签名的方法: 类类似于: 对于中的每个,我想创建一个的实例。我如何做到这一点并处理

  • 我有一条路由(Camel 2.17.3),它使用丰富的 DSL 调用Rest服务并将结果聚合到消息正文中。不过,我遇到了序列化问题。这是我正在尝试的。我的路线如下所示: 正如您所看到的,我想使用enrich()DSL调用一些现有服务,并将这些结果聚合起来,形成一个新的消息体,以便进一步处理。我需要将rest调用的结果从Json转换为MyResponse。我想用这个: 但我需要它已经在我的Aggre

  • 我将springboot控制器与@RequestBody一起使用。我有以下json请求正文 我有一个对应的POJO 我有控制器就像 显然它不起作用,因为是请求中的字符串,而它在MyObject中是布尔值。我希望它有一个逻辑,所以如果在请求中,它将在MyObject中转换为布尔值。Spring有什么机制来实现这一点?

  • 问题内容: 我在mySQL 5.1中有一个数据类型的日期列。如何将其转换为DATE? 这是我到目前为止所拥有的- 得到这个 错误-#1064-您的SQL语法有错误;查看与您的MySQL服务器版本相对应的手册以获取正确的语法,以在’FROM 7 FOR 4附近使用) 请帮忙。 问题答案: 您可以使用MySQL的功能 尽管我怀疑您使用Unix时间戳会更轻松

  • 问题内容: 有没有一种简单的方法可以避免处理文本编码问题? 问题答案: 您确实无法避免处理文本编码问题,但是Apache Commons中已有一些解决方案: 至: 至: 您只需要选择所需的编码即可。