java - 如何自定义spring webservice的PayloadValidatingInterceptor响应消息?

标签 java web-services spring xsd spring-ws

我有一个使用 jaxb 和 spring webservice 构建的 java web 服务应用程序。

我在 xsd 中有一个复杂类型,如下所示:

...

<complexType name="GetRecordsRequest">
    <sequence>
        <element name="maxRecords" type="int" maxOccurs="1" minOccurs="1"/>
    </sequence>
</complexType>

...

使用xjc,我从xsd生成了jaxb类:

public class GetRecordsRequest {
    protected int maxRecords;

    public int getMaxRecords() {
        return maxRecords;
    }

    public void setMaxRecords(int value) {
        this.maxRecords = value;
    }
}

我在 spring context.xml 中使用了 PayloadValidatingInterceptor 来确保用户无法为 maxRecords 输入除整数之外的任何内容:

<bean class="org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping">
    <property name="interceptors">
        <list>
            <ref local="validatingInterceptor" />
        </list>
    </property>
</bean>

<bean id="validatingInterceptor" class="org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor">
    <property name="schema" value="/WEB-INF/schemas/webservice.xsd" />
    <property name="validateRequest" value="true" />
    <property name="validateResponse" value="true" />
</bean>

当我在 Soap UI 中输入此肥皂请求 xml 时:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.test.com/ns1">
   <soapenv:Header/>
   <soapenv:Body>
      <ns1:GetRecordsRequest>
         <ns1:maxRecords></ns1:maxRecords>
      </ns1:GetRecordsRequest>
   </soapenv:Body>
</soapenv:Envelope>

我收到的回复消息是:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
   <SOAP-ENV:Header/>
   <SOAP-ENV:Body>
      <SOAP-ENV:Fault>
         <faultcode>SOAP-ENV:Client</faultcode>
         <faultstring xml:lang="en">Validation error</faultstring>
         <detail>
            <spring-ws:ValidationError xmlns:spring-ws="http://springframework.org/spring-ws">cvc-datatype-valid.1.2.1: '' is not a valid value for 'integer'.</spring-ws:ValidationError>
            <spring-ws:ValidationError xmlns:spring-ws="http://springframework.org/spring-ws">cvc-type.3.1.3: The value '' of element 'cis:maxRecords' is not valid.</spring-ws:ValidationError>
         </detail>
      </SOAP-ENV:Fault>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

您可以看到结果是仅一个字段的两行神秘消息。我可以通过只写一行来使响应消息更漂亮吗?有没有办法自定义验证错误响应消息?

最佳答案

您可以通过扩展PayloadValidatingInterceptor并覆盖handleRequestValidationErrors来自定义验证错误消息。我们可以在messageContext的body中设置自定义的错误消息。

1) 您可以返回带有验证错误消息的自定义 xml 响应,而不是请求验证错误的 SOAP 错误。

2) SAXParseException[] 错误包含请求验证错误。您可以选择仅返回一个错误作为响应。 (或者)对于某些预定义的错误,您可以返回自定义错误消息,而不是 SAXParseException 中返回的错误消息。

/**
* The Class CustomValidatingInterceptor.
*/
public class CustomValidatingInterceptor extends PayloadValidatingInterceptor{

/* (non-Javadoc)
 * @see org.springframework.ws.soap.server.endpoint.interceptor.AbstractFaultCreatingValidatingInterceptor#handleRequestValidationErrors(org.springframework.ws.context.MessageContext, org.xml.sax.SAXParseException[])
 */
@Override
protected boolean handleRequestValidationErrors(MessageContext messageContext, SAXParseException[] errors) throws TransformerException {
    JAXBContext jaxbContext;
    StringWriter stringWriter = new StringWriter();
    ResponseTransactionDetail transactionDetail = null;

    for (SAXParseException error : errors) {
        logger.debug("XML validation error on request: " + error.getMessage());
    }
    if (messageContext.getResponse() instanceof SoapMessage) {

        /**
         * Get SOAP response body in message context (SOAP Fault)
         */

        SaajSoapMessage soapMessage = (SaajSoapMessage)messageContext.getResponse();
        SoapBody body = soapMessage.getSoapBody();

        // marshal custom error response to stringWriter

        /**
        * Transform body
        */
        Source source = new StreamSource(new StringReader(stringWriter.toString()));
        identityTransform.transform(source, body.getPayloadResult());
        stringWriter.close();
    }
    return false;
}

关于java - 如何自定义spring webservice的PayloadValidatingInterceptor响应消息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15741592/

相关文章:

c# - 将 Web 服务配置转换为代码

java - RabbitMQ:消息保留为 "Unacknowledged"

java - 有没有一种简单的方法可以判断 Java 项目是从 NetBeans 还是 Eclipse 编写的?

web-services - 在虚拟机上通过Jersey部署REST服务时出错

java - Spring集成-入站 channel 适配器是多线程的吗?

spring - 通过 Java 配置通过 CommonAnnotationBeanPostProcessor 激活 @PostConstruct 的正确方法是什么?

java - HTTP 状态 500 - 无法为 JSP 编译类,方法未定义

java - 关闭 Java FileInputStream

Java jks keystore with CA, intermediate and website cert on tomcat in docker on AWS gives "Peer' s Certificate issuer is not recognised"

java - 如何在 Spring Boot 中禁用 ErrorPageFilter?