Reputation: 9584
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
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
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