3

現在、いくつかの RESTful JAX を試していて、カスタム入力を検証したいと考えています。通常は正規表現で問題ありませんが、より広範なチェック (~10 の異なる正規表現パターン) を行う必要があります。jaxrs validation を検索すると、このページが見つかりました。「下書き」と書いてありましたが、やってみようと思いました。

パラメータ注釈を次のように書きました。

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = FooBarValidator.class)
public @interface FooBarParam
{
}

バリデータは次のようになります。

@Provider
public class FooBarValidator
        implements ConstraintValidator<FooBar, Long>
{
    @Override
    public void initialize(FooBar constraintAnnotation)
    {
    }

    @Override
    public boolean isValid(Long value, ConstraintValidatorContext context)
    {
        // validation goes here, this is a test validation
        return (value > 50);
    }
}

Web サービスは次のようになります。

@javax.ejb.Stateless
@Path("test")
public class testRS
{
    @GET
    @Path("foobar/{fooBar: [0-9]+}")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.TEXT_PLAIN)
    public String testService(@FooBar @PathParam("fooBar") Long fooBar)
    {
        return "tested with: " + fooBar;
    }
}

しかし、「http://localhost:8080/jaxtest/rest/test/foobar/11」を使用してブラウザで Web サービスを呼び出すと、Web サービスが呼び出され、「tested with: 11」と表示されます。バリデーターが呼び出されないことを除いて、Web サービスは正常に動作します。

バリデータ クラスと注釈インターフェイスにブレークポイントを設定しようとしましたが、どれもヒットしません。

参照ドキュメントの "Draft" ヘッダーが原因で、不可能なことを行っているのではないかと密かに疑っています。ですから、私が何か間違ったことをしている場合、または代替案がある場合は、それを聞いてうれしいです.

4

2 に答える 2

2

@PiotrKochański がくれたヒントのおかげで、私が望んでいたものを正確に実装することに成功しました。最大の問題は、Glassfish を使用しなければならないことです。デフォルトでは、Glassfish は Jersey を使用して JAX を処理します。

これを完了するのに 10 時間以上も苦労しました。

まず第一に、Mavenを使用してください。これにより、作業が非常に簡単になります。

2 番目のステップでは、JBoss リポジトリを pom.xml に追加します。

<repositories>
    <repository>
        <id>jboss-public-repository-group</id>
        <name>JBoss Public Maven Repository Group</name>
        <url>https://repository.jboss.org/nexus/content/groups/public-jboss/</url>
        <layout>default</layout>
        <releases>
            <enabled>true</enabled>
            <updatePolicy>never</updatePolicy>
        </releases>
        <snapshots>
            <enabled>true</enabled>
            <updatePolicy>never</updatePolicy>
        </snapshots>
    </repository>
</repositories>

3 番目のステップでは、依存関係を pom.xml に追加します

<!-- Needed for validator interceptors -->
<dependency>
    <groupId>org.jboss.seam.rest</groupId>
    <artifactId>seam-rest</artifactId>
    <version>3.1.0.Final</version>
</dependency>
<!-- JBoss' RS implementation -->
<dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-jaxrs</artifactId>
    <version>2.3.4.Final</version>
</dependency>
<!-- Because I use JSON I need RESTeasy be able to handle this --> 
<dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-jettison-provider</artifactId>
    <version>2.3.4.Final</version>
</dependency>
<!-- This is THE part that integrates validation in RESTeasy -->
<dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-hibernatevalidator-provider</artifactId>
    <version>2.3.4.Final</version>
</dependency>

最後の依存関係にはかなりの時間がかかりました。@PiotrKochańskiが指摘したドキュメントでは、これについて言及されていませんでした。ただし、ドキュメントの別のバージョンでは、次のことがわかりました。

API 実装と RESTEasy の統合は、resteasy-hibernatevalidator-provider コンポーネントを介して行われます。統合するには、resteasy-hibernatevalidator-provider と hibernate-validator をクラスパスに追加する必要があります。Maven では、次の依存関係を含めるだけです。

<dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-hibernatevalidator-provider</artifactId>
    <version>2.3-RC1</version>
</dependency>

4 番目のステップは、これを web.xml に追加することでした。

<context-param>
    <param-name>resteasy.scan</param-name>
    <param-value>true</param-value>
</context-param>
<context-param>
    <param-name>resteasy.servlet.mapping.prefix</param-name>
    <param-value>/rest</param-value>
</context-param>
<listener>
    <listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class>
</listener>
<servlet>
    <servlet-name>REST Service</servlet-name>
    <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>REST Service</servlet-name>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>

5 番目のステップは、Web サービス クラスを次のように変更することでした。

@javax.ejb.Stateless
@Path("test")
public class testRS
{
    @GET
    @Path("foobar/{fooBar}")
    @Produces(MediaType.APPLICATION_JSON)
    @org.jboss.resteasy.spi.validation.ValidateRequest
    public String testService(@FooBar @PathParam("fooBar") Long fooBar)
    {
        return "tested with: " + fooBar;
    }
}

6 番目のステップは、 を次のように変更することでした@interface

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = FooBarValidator.class)
public @interface FooBarParam
{
    String message() default "{constraint.FooBar}";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

おまけとしても。Emmanuel Bernard による Bean Validation に関するプレゼンテーションに出くわしました。これは多くの興味深いことを説明しているので、共有したいと思いました。

于 2012-06-15T21:27:42.450 に答える
0

あなたが見つけたページは、JAX-RS 2.0 に何を入れるべきかについての提案の 1 つです (これは最終的なものではなく、その実装はありません)。JAX-RS 2.0 を Bean Validation と統合する計画がありますが、前述のとおり、まだ実装されていません。

現在、入力を検証する場合は、パラメーターを (Long ではなく) String として宣言し、リソース メソッドの一部として検証を行うことができます。次に、検証に合格した場合は Long に変換します。

于 2012-06-14T13:30:46.303 に答える