3

Web サービス内で Bean 検証を使用したいと考えています。最良のアプローチは、次のような Spring MVC バインディングに似ています。

@WebMethod void sayHello(@Valid HelloDTO hello) {...}

目標は、Web サービスの実装ですべての検証メソッドを取り除くことです。検証は横断的な関心事として扱いたいと思います。

私が知っているように、Hibernate Validator > 4.2 と Apache BeanValidation はメソッドパラメーターを検証できるはずです。しかし、JAX-WS メソッドのパラメーター バインディングにフックする方法がわかりません。

メッセージを傍受するハンドラーを作成しようとしましたが、パラメーターが何であるかを判断できなかったため、一般的な方法でペイロードを非整列化するのが困難でした。さらに、ハンドラーは非常に厳密な検証になります。入力パラメーターを検証するかどうかは、Web サービスの開発者に決めてもらいたいと思います。

編集
その間、Spring AOPを使用してエンドポイントへの呼び出しを傍受するソリューションを見つけました。ただし、ハンドラーを使用したソリューションの方が優れています。これは、検証の横断的な関心事が、より適切で事前定義された場所 (ハンドラー チェーン) で定義されるためです。

これは春の解決策です:

アスペクトを作成します。

@Aspect
public class ValidationAspect {
    @Autowired private Validator validator;

    // Alternative: use @annotation(javax.validation.Valid) to validate only methods annotated with @Valid
    @Pointcut("execution(* (@javax.jws.WebService *).*(..))")
    public void webServiceWebMethods() {}

    @Before("webServiceWebMethods()")
    public void validateWebService(JoinPoint jp) throws WebParamValidationFault {
        for (Object arg : jp.getArgs()) {
            Collection<ConstraintViolation<Object>> errors = validator.validate(arg);
            // check validation and throw exception if errors occured
        }
    }

Spring-AOP を構成します。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <aop:aspectj-autoproxy proxy-target-class="true" />
    <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
    <bean id="validationAspect" class="ValidationAspect" />
</beans>

これproxy-target-class="true"により、cglib プロキシが有効になります。JAX-WS ランタイムは Web サービスの JDK 動的プロキシを使用できないため、これが必要です。その理由は、@WebService継承可能ではなく、プロキシが欠落している注釈について主張しているためです。解決策は、cglib を使用して、Web サービスの Spring バインディングの実装クラスを宣言することです

<wss:binding url="/demo">
    <wss:service>
        <ws:service bean="#DemoEndpoint" impl="com.example.DemoEndpoint" />
    </wss:service>
</wss:binding>

アスペクトを使用しないソリューションは高く評価されます。

4

0 に答える 0