Siddharth
Siddharth

Reputation: 9584

Jersey calling a get with object as parameter does not work

I am new to Jersey, I am trying to develop a GET for search results. For this I need to send a object with the search criteria and data. I wonder what I am doing wrong. I am getting the following exception on my Junit test case

com.sun.jersey.api.client.UniformInterfaceException: GET http://localhost:8081/mCruiseOnCarPool4All/carpool4all/Search/Request/com.mcruiseon.carpool.concrete.SearchConcrete@676e3f returned a response status of 404 Not Found
at com.sun.jersey.api.client.WebResource.handle(WebResource.java:686)
at com.sun.jersey.api.client.WebResource.access$200(WebResource.java:74)
at com.sun.jersey.api.client.WebResource$Builder.get(WebResource.java:507)
at test.carpool4all.SingleSearchTest.testPost(SingleSearchTest.java:89)

My Server side GET

    @GET
    @Path ("Request/{search}")
    @Consumes({ MediaType.APPLICATION_JSON })
    @Produces({ MediaType.APPLICATION_JSON })
    public Response search(@PathParam("search") SearchConcrete searchConcrete) {
        SearchJourneyRequest request = new SearchJourneyRequest(searchConcrete) ;
        SearchJourneyResponse response ;
        clientSession = sessionManager.getClientSession(searchConcrete.getIdentityHash()) ;
        clientSession.getSendQueue().sendRequest(request) ;
        try {
            response = (SearchJourneyResponse)clientSession.waitAndGetResponse(request) ;
        } catch (WaitedLongEnoughException e) {
            return Response.serverError().build() ;
        } catch (UnableToResolveResponseException e) {
            return Response.serverError().build() ;
        }
        return Response.ok(response.getSearchResults()).build();
    }

Client Side Junit test

SearchConcrete searchProvider = new SearchConcrete(Globals.SearchCriteria.FlexiTime,
    identityHash,
    // more parameters
    );
    service = client.resource(UriBuilder.fromUri("http://localhost:8081/mCruiseOnCarPool4All/carpool4all/Search/Request/"+searchProvider).build());
    Object[] searchResults = service.type(MediaType.APPLICATION_JSON).get(Object[].class);

Edit : Thanks to @eugen, to solve this, I added a concrete class with my Object[] as a private member. Instead of a GET, I used a POST here is the fixed code. Now my carpool search results are coming :).

service = client.resource(UriBuilder.fromUri(

"http://localhost:8081/mCruiseOnCarPool4All/carpool4all/Search/Request").build());
            SearchResultsConcrete searchResults = service.type(MediaType.APPLICATION_JSON).post(SearchResultsConcrete.class, searchProvider);
            assertNotNull(searchResults);
            assertNotNull(searchResults.getSearchResults()) ;
            assertTrue(searchResults.getSearchResults().length == 3) ;
            assertTrue(searchResults.getSearchResults()[SearchJourneyResponse.FLEXI_POSITION].length > 0) ;
            assertTrue(searchResults.getSearchResults()[SearchJourneyResponse.FLEXIENDTIME_POSITION].length > 0) ;


@POST
    @Path ("Request")
    @Consumes({ MediaType.APPLICATION_JSON })
    @Produces({ MediaType.APPLICATION_JSON })
    public Response search(JAXBElement<SearchConcrete> element) {
        SearchJourneyRequest request = new SearchJourneyRequest((SearchConcrete)element.getValue()) ;
        SearchJourneyResponse response ;
        clientSession = sessionManager.getClientSession(((SearchConcrete)element.getValue()).getIdentityHash()) ;
        clientSession.getSendQueue().sendRequest(request) ;
        try {
            response = (SearchJourneyResponse)clientSession.waitAndGetResponse(request) ;
        } catch (WaitedLongEnoughException e) {
            return Response.serverError().build() ;
        } catch (UnableToResolveResponseException e) {
            return Response.serverError().build() ;
        }
        return Response.ok(response.getSearchResults()).build();
    }

Upvotes: 2

Views: 5186

Answers (2)

eugen
eugen

Reputation: 5916

You are doing things wrong. First lets analyze your error :

com.sun.jersey.api.client.UniformInterfaceException: GET http://localhost:8081/mCruiseOnCarPool4All/carpool4all/Search/Request/com.mcruiseon.carpool.concrete.SearchConcrete@676e3f returned a response status of 404 Not Found.

We can see that com.mcruiseon.carpool.concrete.SearchConcrete@676e3f is appended at the end of the url of your request (confirmed by your test case "http://localhost:8081/mCruiseOnCarPool4All/carpool4all/Search/Request/"+searchProvider). It does not make sense.

I assume you want to send a json with your GET request? You can't do that! GET has no body but only the url (and the headers), and appending json to your url does not make sense. If you want to send json you must do a POST.

You are trying to do something similar to this post What is the maximum length of JSON object received by JAX-RS web service using GET?, have a look at my answer.

Here is how to do what you want with Genson library http://code.google.com/p/genson/. Download genson with maven, it will automaticaly enable json support when it is in your classpath and handle all the databinding. Then change your server side method:

@POST
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public Response search(SearchConcrete searchConcrete) {
    ...
}

Change your test to:

// configure your client to use genson
ClientConfig config = new DefaultClientConfig();
config.getClasses().add(GensonJsonConverter.class);
cli = Client.create(config);

// then the test code
TypeOfTheResponse response = cli.resource("http://localhost:8081/mCruiseOnCarPool4All/carpool4all/Search/Request")
   .accept(MediaType.APPLICATION_JSON)
   .type(MediaType.APPLICATION_JSON)
   .post(TypeOfTheResponse.class, searchProvider);

Remarks: do not use Object[] as the response, use a concrete java class like MyResponseItem[]

Upvotes: 3

user647772
user647772

Reputation:

You are missing a slash / here:

"...Request"+searchProvider

This must be

"...Request/" + searchProvider

Edit

You can't just add an Object to an URL. This

"http://localhost:8081/mCruiseOnCarPool4All/carpool4all/Search/Request/"+searchProvider

will cause the toString() method of SearchConcrete to be called. The result is

com.mcruiseon.carpool.concrete.SearchConcrete@676e3f 

The server has no way to reconstruct the SearchConcrete from this.

Upvotes: 2

Related Questions