2012-06-13 4 views
3

В настоящее время я экспериментирую с некоторыми RESTful JAX, и я хочу проверить пользовательский ввод. Обычно регулярное выражение будет хорошо, но мне нужно сделать более обширную проверку (~ 10 различных шаблонов регулярных выражений). Я нашел this page при поиске проверки jaxrs. Я отметил, что он говорит «Проект», но я думал, что попробую.JAX-RS custom pathparam validator

я написал параметр аннотацию вроде этого:

@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); 
    } 
} 

Веб-сервис выглядит следующим образом:

@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» веб-сервис e получает вызов, и я представлен «проверен с: 11». Веб-сервис работает отлично, за исключением того, что валидатор не вызван.

Я попытался установить точки останова в классе валидатора и интерфейсе аннотации, но ни один из них не попал.

У меня есть подозрительное подозрение, что я делаю то, что невозможно из-за заголовка «Черновик» в документации, на которую ссылается. Поэтому, если я делаю что-то неправильно или есть альтернативы, я рад это слышать.

+1

Если вы используете реализацию RestEasy JAX-RS, вы можете интегрировать esily JAX-RS с проверкой Bean (JSR 303) http://docs.jboss.org/seam/3/rest/latest/reference/en-US/html /rest.validation.html –

ответ

2

Благодаря подсказке @ PiotrKochański дал мне, я успешно внедрил точно, что я хотел. Самая большая проблема заключалась в том, что я обязан использовать Glassfish. По умолчанию Glassfish использует Джерси для обработки вещей JAX.

Мне потребовалось более 10 часов, чтобы завершить это, поэтому пусть это будет хранителем времени для всех, кто натыкается на это.

Прежде всего, использование Maven, это делает вашу жизнь намного проще.

Второй шаг, добавьте репозиторий 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> 

Третий шаг, добавить зависимости к 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> 

Последняя зависимость у меня ушло довольно много времени. The docs @PiotrKochański pointed to не упоминал об этом. Однако в another version of the docs я нашел это:

Интеграция между реализацией API и Resteasy осуществляется через компонент Resteasy-hibernatevalidator-провайдера. Чтобы интегрировать, нам нужно добавить restaasy-hibernatevalidator-provider и hibernate-validator в путь к классам.С мавена это просто вопрос в том числе следующую зависимость:

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

Четвертый шаг должен был добавить это к 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> 

Пятый шаг должен был изменить класс веб-службы, как это:

@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; 
    } 
} 

Шестой шаг должен был изменить @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 {}; 
} 

Также в качестве бонуса; Я наткнулся на a presentation about Bean Validation by Emmanuel Bernard Я думал, что могу поделиться, так как это объясняет много интересного.

+0

Итак, почему downvote? – siebz0r

0

Вы нашли одно из предложений о том, что следует использовать в JAX-RS 2.0 (что не является окончательным и его реализация не является). План JAX-RS 2.0 для интеграции с Bean Validation - но, как я уже сказал, это еще не реализовано.

В настоящее время, если вы хотите проверить ввод, вы можете объявить параметр как String (вместо Long) и выполнить проверку как часть метода ресурса. Затем конвертируйте в Long, если проверка прошла.