如何使用注释配置PayloadValidatingInterceptor

时间:2015-10-28 15:06:50

标签: spring spring-boot spring-ws

我正在尝试开发Spring Web服务并遵循本教程https://spring.io/guides/gs/producing-web-service/

项目结构(和配置类名称)与本教程中提到的相同。 我试图使用注释做所有可能的配置,并希望避免所有基于xml的配置。到目前为止,我甚至通过使用java配置避免了applicationContext.xml和web.xml。但是,现在我想引入XSD验证,如本教程所示: http://stack-over-flow.blogspot.com/2012/03/spring-ws-schema-validation-using.html,即通过扩展PayloadValidatingInterceptor类。如教程所示,然后需要使用以下xml配置注册此自定义验证器拦截器:

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

<bean id="validatingInterceptor" class="com.test.ValidationInterceptor ">
     <property name="schema" value="/jaxb/test.xsd"/>
</bean>

但是,我没有起诉如何使用注释进行上述配置。即将XSD文件设置为拦截器。我试过重写&#34; addInterceptor&#34; WsConfigurerAdaptor类注册拦截器。如果我需要这样做,或者使用注释完成整个事情的正确方法,请告诉我。

4 个答案:

答案 0 :(得分:3)

我正在使用spring-boot,我正在寻找一种方法来做同样的事情,我发现了这个:

@EnableWs
@Configuration
public class WebServiceConfig extends WsConfigurerAdapter {

  @Override
  public void addInterceptors(List<EndpointInterceptor> interceptors) {
    PayloadValidatingInterceptor validatingInterceptor = new PayloadValidatingInterceptor();
    validatingInterceptor.setValidateRequest(true);
    validatingInterceptor.setValidateResponse(true);
    validatingInterceptor.setXsdSchema(resourceSchema());
    interceptors.add(validatingInterceptor);
  }

  @Bean
  public ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext) {
    MessageDispatcherServlet servlet = new MessageDispatcherServlet();
    servlet.setApplicationContext(applicationContext);
    servlet.setTransformWsdlLocations(true);
    return new ServletRegistrationBean(servlet, "/api/*");
  }

  @Bean(name = "registros")
  public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema countriesSchema) {
    DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
    wsdl11Definition.setPortTypeName("ResourcePort");
    wsdl11Definition.setLocationUri("/api");
    wsdl11Definition.setTargetNamespace("http://resource.com/schema");
    wsdl11Definition.setSchema(resourceSchema());
    return wsdl11Definition;
  }

  @Bean
  public XsdSchema resourceSchema() {
    return new SimpleXsdSchema(new ClassPathResource("registro.xsd"));
  }
}

在此示例中, addInterceptors 方法很重要,其他3方法是公开WSDL API的基础。

也许它会对其他人有用。

答案 1 :(得分:0)

我能够通过以下方式解决它。

@Override
    public void addInterceptors(List<EndpointInterceptor> interceptors) {
        HotelDirectUpdateRQValidator validatingInterceptor = new HotelDirectUpdateRQValidator();
        validatingInterceptor.setValidateRequest(true);
        validatingInterceptor.setValidateResponse(false);
        validatingInterceptor.setXsdSchemaCollection(new XsdSchemaCollection() {
            @Override
            public XsdSchema[] getXsdSchemas() {
                return null;
            }

            @Override
            public XmlValidator createValidator() {
                try {
                    return XmlValidatorFactory.createValidator(getSchemas(), "http://www.w3.org/2001/XMLSchema");
                } catch (Exception e) {
                    LOGGER.error("Failed to create validator e={}", e);
                }
                return null;
            }

            public Resource[] getSchemas() {
                return new Resource[]{
                        new ClassPathResource("/schemas/OTA/OTA_HotelRateAmountNotifAndHotelAvailNotifRQValidate.xsd"),
                        new ClassPathResource("/schemas/HotelDirectUpdateRQ.xsd")
                };
            }
        });

        interceptors.add(validatingInterceptor);
    }

答案 2 :(得分:0)

在spring.xml中配置验证器拦截器类,如下所示:

<sws:interceptors>

    <bean id="validatingInterceptor"
            class="com.kalra.xsd.validator.WSDLValidator">
            <property name="xsdSchema" ref="types" />
            <property name="validateRequest" value="true" />
            <property name="validateResponse" value="true" />
    </bean>


</sws:interceptors>

需要在此标签sws:interceptors中添加bean ValidatingInterceptor,以便拦截器将自动注册。对于sws前缀,需要在spring.xml中添加xmlns是“ xmlns:sws =” http://www.springframework.org/schema/web-services“

我们应该为自己的QNAME编写PayloadValidatingInterceptor的wsdlvalidator子类,以便在出现故障异常后显示响应,否则它将选择sprint ws的默认qname。

WSDLValidator代码快照:

import javax.xml.namespace.QName;
import org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor;

public class WSDLValidator extends PayloadValidatingInterceptor {

    public WSDLValidator(){
    }

    @Override
    public QName getDetailElementName() {
        return new QName(Constants.XMLNamespaces.TNS_URI, "SoapValidationFault");
    }

}

SoapValidationFault是XSD中的复杂类型声明,而TNS_URI是wsdl和xsd中定义的目标名称空间。

答案 3 :(得分:-1)

我可以使用以下方法解决它:

@Override
public void addInterceptors(List<EndpointInterceptor> interceptors) {
    interceptors.add(validationInterceptor());
}
@Bean
ValidationInterceptor validationInterceptor() {
        final ValidationInterceptor payloadValidatingInterceptor = new ValidationInterceptor();
        payloadValidatingInterceptor.setSchema(new ClassPathResource(
                "XSD/Pay.xsd"));
        return payloadValidatingInterceptor;
    }

然后我必须使用以下

从验证器类中读取模式文件
SchemaFactory schemaFactory = SchemaFactory.newInstance(getSchemaLanguage());
        Schema schema = schemaFactory.newSchema(getSchemas()[0].getURL());
        Validator validator = schema.newValidator();