Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can RestEasy serialize a POJO for a @GET method?

We use Resteasy and have problems figuring how to call some @GET methods.

If the interface for the method only has simple parameters, there is no problem. Ex:

@GET
@Path("/test/{myparam}")
public FacetQueryResultImpl testMethod(@PathParam("myparam")String myparam);

But if we try to use a POJO as the parameter, it seems RestEasy is not able to serialize it as querystring parameters. Ex:

@GET
@Path("/testGet")
public FacetQueryResultImpl testMethod(ParamPojo myparam);

or

@GET
@Path("/testGet")
public FacetQueryResultImpl testMethod(@QueryParam("myparam")ParamPojo myparam);

(with, ParamPojo.java:)

public class ParamPojo
{
    private String name;
    private String description;
    (...)
}

When we try this, sometimes the services are not found and sometimes we get a "A GET request cannot have a body." exception.

Using @POST we are able to use a POJO has the parameter, but some of our methods don't modify anything on the server, and therefore should use @GET.

A workaround is to "explode" the ParamPojo, and use all of its properties as separated parameters for the method. But this removes the "Easy" part of "RestEasy", doesn't it?

like image 844
electrotype Avatar asked Nov 22 '11 19:11

electrotype


2 Answers

You must use the @org.jboss.resteasy.annotations.Form annotation on your method parameter. http://docs.jboss.org/resteasy/docs/2.2.1.GA/userguide/html_single/#_Form

Example:

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;

import junit.framework.Assert;

import org.jboss.resteasy.annotations.Form;
import org.jboss.resteasy.core.Dispatcher;
import org.jboss.resteasy.mock.MockDispatcherFactory;
import org.jboss.resteasy.mock.MockHttpRequest;
import org.jboss.resteasy.mock.MockHttpResponse;
import org.junit.Test;

public class TestCase {
    @Path("/")
    public static class Service {

        @Path("")
        @GET
        public String get(@Form ValueObject vo){
            return vo.getParam();
        }
    }

    public static class ValueObject {
        @QueryParam("myparam")
        private String param;

        public String getParam() {
            return param;
        }
    }

    @Test
    public void test() throws Exception {
        Dispatcher dispatcher = MockDispatcherFactory.createDispatcher();
        dispatcher.getRegistry().addSingletonResource(new Service());

        MockHttpRequest request = MockHttpRequest.get("/?myparam=somevalue");
        MockHttpResponse response = new MockHttpResponse();

        dispatcher.invoke(request, response);

        Assert.assertEquals("somevalue", response.getContentAsString());
    }
}
like image 189
eiden Avatar answered Oct 16 '22 06:10

eiden


For binding the multiple queryParam into a single object we need to add @Form <POJO CLASS> as a arguments in response method. It works fine for us.

@GET    
@Path("/")  
@Produces("application/json")
@Consumes("application/json")
public Response search(@Form CatalogSearchRequest reqObject) {
    System.out.println("Entered into service" + reqObject.getAttribute());
}

POJO class should contain @QueryParam("") for every attributes, for example:

@QueryParam("pageSize")
public Integer pageSize;

@QueryParam("page")
public Integer page;

public Integer getPageSize() {
    return pageSize;
}

public void setPageSize(Integer pageSize) {
    this.pageSize = pageSize;
}

public Integer getPage() {
    return page;
}

public void setPage(Integer page) {
    this.page = page;
}
like image 23
Prasanna Avatar answered Oct 16 '22 04:10

Prasanna