Consider this case:-
I am injecting HttpServletRequest in a Rest Service like
#Context
HttpServletRequest request;
And use it in a method like:-
#GET
#Path("/simple")
public Response handleSimple() {
System.out.println(request.getParameter("myname"));
return Response.status(200).entity("hello.....").build();
}
This works fine but when I try to send it through POST method and replace the #GET by #POST annotation, I get the parameter value null.
Please suggest me where I am mistaking.
You do not need to get your parameters etc out of the request. The JAX-RS impl. handles that for you.
You have to use the parameter annotations to map your parameters to method parameters. Casting converting etc. is done automaticly.
Here your method using three differnt ways to map your parameter:
// As Pathparameter
#POST
#Path("/simple/{myname}")
public Response handleSimple(#PathParam("myname") String myName) {
System.out.println(myName);
return Response.status(200).entity("hello.....").build();
}
// As query parameter
#POST
#Path("/simple")
public Response handleSimple(#QueryParam("myname") String myName) {
System.out.println(myName);
return Response.status(200).entity("hello.....").build();
}
// As form parameter
#POST
#Path("/simple")
public Response handleSimple(#FormParam("myname") String myName) {
System.out.println(myName);
return Response.status(200).entity("hello.....").build();
}
Documentation about JAX-RS Annotations from Jersey you can find here:
https://jersey.java.net/documentation/latest/jaxrs-resources.html
Related
Is it possible to access the Request object in a REST method under JAX-RS?
I just found out
#Context Request request;
On JAX-RS you must annotate a Request parameter with #Context:
#GET
public Response foo(#Context Request request) {
}
Optionally you can also inject:
UriInfo
HttpHeaders
SecurityContext
HttpServletRequest
To elaborate on #dfa's answer for alternatives, I find this to be simpler than specifying the variable on each resource method signature:
public class MyResource {
#Context
private HttpServletRequest httpRequest;
#GET
public Response foo() {
httpRequest.getContentType(); //or whatever else you want to do with it
}
}
I have a resource which I would like to test. To do that, I want to extract myObject from javax.ws.rs.core.Response. How can I do that?
The resource looks like this:
#Post
#Path("/test")
public MyObjectClass myresource(){return myObject}
My test:
#Test
public void test(){
Response response = resources.getJersyTest()
.target("/test")
.request()
.post(javax.ws.rs.client.Entity.json(String.class));
assertThat...
}
In general it is not a good idea to return custom object from Rest resource. You may reconsider to use one of standard formats JSON or XML and return a Response instead of MyObjectClass. also you need to take either request or String (or both) as parameter(s) to the resource method to work with what you posts in request.
As example:
#Post
#Path("/test")
#Produces(MediaType.APPLICATION_JSON)
public Response myresource(#Context HttpServletRequest request, String postedBody){
MyObjectClass myObject = new MyObjectClass();
// ... set myObject properties ...
return Response.status(200).entity(myObject).build();
}
Of course for JSON your MyObjectClass must be annotated for JSON...
Then in your response on client side you will have JSON representation of your myObject in the response.getEntity and it can be unmarshalled back to MyObjectClass.
but if you still want to return your custom object you have to create a mechanism to marshal/unmarshal your object on both sides.
Check this answer for it RestEasy - Jax-rs - Sending custom Object in response body
From other hands in the unit test you can call your resource method directly and just cast result.
I found an other solution, just specify the type of the response in the function post:
#Test
public void test(){
MyObjectClass response = resources.getJersyTest()
.target("/test")
.request()
.post(javax.ws.rs.client.Entity.json(String.class), MyObjectClass.class);
assertThat(...
}
I tried something like below, M getting error
[[FATAL] No injection source found for a parameter of type public Response
#context UriInfo wont work as i need different data types as query param,like it may be integers and date.Kindly Help.
#GET
#Path("/getdetails")
#Produces({ "application/json", "application/xml" })
public Response getDetails(#QueryParam("field1") String fieldOne,#QueryParam("field2") List<HasMap<String,String>> fieldTwo){
//Processing
}
You will have to use POST and attach the list inside the request body
If the list your passing is json, you should also add the appropriate #Consumes value.
#POST
#Produces({MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN})
#Consumes(MediaType.APPLICATION_JSON)
public void getDetails(List<HasMap<String,String>> listFromClient) {
// do something with your list..
}
I am new to Spring and my other controller running good but when I am trying to call getmyfriends endpoint, I got the 405 Method Not Allowed:
#Controller
#Path("friends")
public class FreindsJersey {
#Autowired
private FriendsService friendsService;
#POST
#Path("getmyfriends")
#Produces(MediaType.APPLICATION_JSON)
public Response getAllMyFriends(String json) {
ReturnData returnData = (ReturnData) Parser.getJsonFromString(json, ReturnData.class);
return Response.ok(friendsService.getMyFriendsList(returnData).getContainer()).build();
}
#GET
#Path("unfriend/{userId}/{friendId}")
#Produces(MediaType.APPLICATION_JSON)
public Response unfriendUser(#PathParam("userId") long userId, #PathParam("friendId") long friendId) {
return Response.ok(friendsService.deleteAFriendOfTheUser(userId, friendId).getContainer()).build();
}
}
The URL I'm calling is http://localhost:8080/Indulgge/friends/getmyfriends
TL;DR: getAllMyFriends requires POST
When you enter a URL into your browser, it will use GET. You cannot POST from the URL bar.
Your code only allows POST.
#POST // <-- here
#Path("getmyfriends")
#Produces(MediaType.APPLICATION_JSON)
public Response getAllMyFriends(String json) {
ReturnData returnData = (ReturnData) Parser.getJsonFromString(json, ReturnData.class);
return Response.ok(friendsService.getMyFriendsList(returnData).getContainer()).build();
}
In fact, you have it backwards - safe and idempotent requests should be GET (such as getAllMyFriends); unsafe and non-idempotent requests should be POST (such as unfriendUser).
I have currently trying to learn the basics of Java REST, using JAX-RS.
Within the UserService class (near bottom) of this example there is both an #GET AND #PUT method with the same #path annotation:
#GET
#Path("/users")
#Produces(MediaType.APPLICATION_XML)
public List<User> getUsers() {
return userDao.getAllUsers();
}
and
#PUT
#Path("/users")
#Produces(MediaType.APPLICATION_XML)
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public String createUser(#FormParam("id") int id,
#FormParam("name") String name,
#FormParam("profession") String profession,
#Context HttpServletResponse servletResponse) throws IOException {
User user = new User(id, name, profession);
int result = userDao.addUser(user);
if(result == 1) {
return SUCCESS_RESULT;
}
return FAILURE_RESULT;
}
How does the Program know which method to invoke, considering that they are both point at the same #path ?
Resource classes have methods that are invoked when specific HTTP method requests are made, referred to as resource methods. In order to create Java methods that will be invoked with specific HTTP methods, a regular Java method must be implemented and annotated with one of the JAX-RS #HttpMethod annotated annotations (namely, #GET, #POST, #PUT, and #DELETE).
For more info take a look at this example1 and example2
JAX-RS evaluates the HTTP method of the request and then calls the appropriate Java method in UserService.