2

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();
    }
carlspring
  • 31,231
  • 29
  • 115
  • 197
Siddharth
  • 9,349
  • 16
  • 86
  • 148

2 Answers2

3

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[]

Community
  • 1
  • 1
eugen
  • 5,856
  • 2
  • 29
  • 26
  • Why not to use a [] ? I tried the MyResponseItem[] that too did not work. So I had to create a wrapper object. – Siddharth Oct 27 '12 at 05:13
2

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.

  • Actually I noticed that, still did not work. I basically need to send a object like a post call, and get a Object[] in return like a get. I am using Produces and Consumes, I know I am missing something basic here. – Siddharth Oct 26 '12 at 08:38
  • Updated my exception. I have the same exception. – Siddharth Oct 26 '12 at 08:41