Egemen
Egemen

Reputation: 2548

Resteasy Bean Validation Not Working on Remote Server

I have a problem similar to the one described here.

I am using RESTEasy within a standalone Jetty application. When I start the application locally and call a service (e.g. localhost:16880/rest/user/login) bean validation works fine, i.e. I get validation errors like this:

[PARAMETER]
[UserService#login(arg0).appKey]
[app_key may not be null or empty]
[]

However, when I deploy my application to a remote host and call the same service (e.g. remotehost:16880/rest/user/login) bean validation is not invoked at all.

I am using the @ValidateRequest annotation for the service and @Valid annotation for the bean parameter.

My Resteasy version is 3.0.13.Final, though I have tried earlier versions as well. I have tried to write my custom validator, but that didn't work either.

I am puzzled why the validation works locally, but not on remote server. Any suggestions would be highly appreciated.

Upvotes: 3

Views: 617

Answers (1)

darijan
darijan

Reputation: 9775

Since you are using Jetty as standalone server, you have to define RESTEasy validation providers where you define ServletContextHandler. Note that in standalone server there is no container to scan for @Provider classes and to activate them, so you must do it manually.

I expect that you create and start your server app something like:

//create a server listening at some port
Server server= new Server(port);

//add server handlers
HandlerList handlers= new HandlerList();
initHandlers(handlers);
server.setHandler(handlers);

//start the server
server.start();

In initHandlers you must have defined your RESTEasy support:

public void initHandlers(List<HandlerList> handlers) {
    //define root context handler
    ServletContextHandler servletContextHandler= new ServletContextHandler(ServletContextHandler.SESSIONS);
    servletContextHandler.setContextPath("/");
    handlers.addHandler(servletContextHandler);

    //define RESTEasy handler
    ServletHolder restServlet= new ServletHolder(new HttpServlet30Dispatcher());

    //since this is a standalone server, somewhere you have to define RESTful services and Singletons
    restServlet.setInitParameter("javax.ws.rs.Application", "com.exampleapp.MyRestApplication");
    restServlet.setInitParameter("resteasy.servlet.mapping.prefix", "rest");

    servletContextHandler.addServlet(restServlet, "rest/*");
}

So what is left to do now is to add Validation provider as init parameter:

restServlet.setInitParameter("resteasy.providers", "org.jboss.resteasy.plugins.validation.ValidatorContextResolver,org.jboss.resteasy.api.validation.ResteasyViolationExceptionMapper");

On this link I tried to find the name of the validator providers: https://docs.jboss.org/resteasy/docs/3.0.4.Final/userguide/html/Validation.html

RESTEasy obtains a bean validation implemenation by looking in the available META-INF/services/javax.ws.rs.Providers files for an implementation of ContextResolver

So it does not say what, but says where. Now open the "resteasy-hibernatevalidator-provider-3...*.jar (from Eclipse -> Maven dependencies or manually unzip) and look into META-INF/services/javax.ws.rs.ext.Providers It says:

org.jboss.resteasy.plugins.validation.hibernate.ValidatorContextResolver org.jboss.resteasy.api.validation.ResteasyViolationExceptionMapper

If you don't have this dependency, then add it to your pom file:

<dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-hibernatevalidator-provider</artifactId>
    <version>${resteasy.version}</version>
</dependency>

One more note: that at the same place where you described validation providers, you also add other providers, if you happen to need them (such as JacksonJaxbJson, etc).

Upvotes: 2

Related Questions