I have following jersey method declaration:
#POST
#Path("/fooPath")
#Produces({MediaType.APPLICATION_JSON})
#Consumes({MediaType.APPLICATION_JSON})
public Response isSellableOnline(#FormParam("productCodes") final List<String> productCodes,
#FormParam("storeName") final String storeName,
#Context HttpServletRequest request) {
In rest client I try to invoke following method like this:
When I debug method I see that received parameters are null:
How to rewrite method declaration?
It is because on the isSellableOnlie method you are expecting or trying to extract form parameters, but the incoming POST request is JSON.
Well if you want JSON you should make POJO Class to be able to serialize the JSON.
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement
public class Store {
private String storeName;
private List<String> productCodes;
public Store() {
}
public String getName() {
return name;
}
public List<String> getProductCodes() {
return productCodes;
}
}
And then in your method:
#POST
#Path("/fooPath")
#Produces({MediaType.APPLICATION_JSON})
#Consumes({MediaType.APPLICATION_JSON})
public Response isSellableOnline(Store store) {
store.getName();
...
}
Related
I'd like to create a single method and configure both GET + POST on it, using spring-mvc:
#RestController
public class MyServlet {
#RequestMapping(value = "test", method = {RequestMethod.GET, RequestMethod.POST})
public void test(#Valid MyReq req) {
//MyReq contains some params
}
}
Problem: with the code above, any POST request leads to an empty MyReq object.
If I change the method signature to #RequestBody #Valid MyReq req, then the post works, but the GET request fails.
So isn't is possible to just use get and post together on the same method, if a bean is used as input parameters?
The best solution to your problem seems to be something like this:
#RestController
public class MyServlet {
#RequestMapping(value = "test", method = {RequestMethod.GET})
public void testGet(#Valid #RequestParam("foo") String foo) {
doStuff(foo)
}
#RequestMapping(value = "test", method = {RequestMethod.POST})
public void testPost(#Valid #RequestBody MyReq req) {
doStuff(req.getFoo());
}
}
You can process the request data in different ways depending on how you receive it and call the same method to do the business logic.
#RequestMapping(value = "/test", method = { RequestMethod.POST, RequestMethod.GET })
public void test(#ModelAttribute("xxxx") POJO pojo) {
//your code
}
This will work for both POST and GET. (make sure the order first POST and then GET)
For GET your POJO has to contain the attribute which you're using in request parameter
like below
public class POJO {
private String parameter1;
private String parameter2;
//getters and setters
URl should be like below
/test?parameter1=blah
Like this way u can use it for both GET and POST
I was unable to get this working on the same method and I'd like to know a solution, but this is my workaround, which differs from luizfzs's in that you take the same request object and not use #RequestParam
#RestController
public class Controller {
#GetMapping("people")
public void getPeople(MyReq req) {
//do it...
}
#PostMapping("people")
public void getPeoplePost(#RequestBody MyReq req) {
getPeople(req);
}
}
I have created a Spring Boot with Spring REST application.
This is my controller code.
#RestController
public class SampleController {
#RequestMapping(value = "/sample/get", method = RequestMethod.GET, produces = "application/json")
#ResponseBody
public Response getResponse(SampleDTO dto) {
Response response = new Response();
response.setResponseMsg("Hello "+dto.getFirstName());
return response;
}
}
This is my SampleDTO
public class SampleDTO {
#JsonProperty("firstname")
private String firstName;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
}
and this is my Response object
public class Response {
private String responseMsg;
public String getResponseMsg() {
return responseMsg;
}
public void setResponseMsg(String responseMsg) {
this.responseMsg = responseMsg;
}
}
When I try to access service this way
http://localhost:8080/sample/get?firstName=mvg
I am getting this expected output
{"responseMsg":"Hello mvg"}
When I try to access service this way
http://localhost:8080/sample/get?firstname=mvg
I am getting this output
{"responseMsg":"Hello null"}
My question is how do I map 'firstname' in request parameter with 'firstName' of DTO?
Thanks in advance
When you are setting #JsonProperty("firstname") make sure you are imported the this statement "import com.fasterxml.jackson.annotation.JsonProperty ;". One thing more if you are sending more properties and your bean class does not have that you can set the #JsonIgnoreProperties(ignoreUnknown=true) on the top of the bean name.
You are also missing the #RequestBody annotation. You should take this as (#RequestBody SampleDTO dto)in getResponse method.
Simply create a Pojo Java Bean with fields with names that match your request parameters.
Then use this class as an argument for your request handler method (without any additional annotations)
see this
First you need to choose which approach do you need (or want to use) param or model. When you use something like this http://localhost:8080/sample/get?firstName=mvg , you are passing data as request parameters. So you need to use the #RequestParam annotation.
Sample using #RequestParam annotation (use is explained in the docs)
#RequestMapping(method = RequestMethod.GET)
public Response foo(#RequestParam("firstName") String firstName) {
Response response = new Response();
response.setResponseMsg("Hello "+ firstName );
return response;
}
Let's assume that I have simple class:
public class Test
{
#Path("/test")
#POST
#Produces(APPLICATION_JSON)
#Consumes(APPLICATION_JSON)
public TestResponse post(TestResponse request, #HeaderParam("text") String text)
{
return new TestResponse(request.getData());
}
}
and I want to test this class. So how I can param in code like this:
Entity<TestRequest> requestEntity = Entity.entity(request, MediaType.APPLICATION_JSON);
final TestResponse response = target("test").request().post(requestEntity, TestResponse.class);
target("test").request().header("text", "value").post(...);
When you call request(). You get back an Invocation.Builder. You can take a look at the other methods. For the most part they all return the same Invocation.Builder, so can just chain the calls.
I have a rest webservice. For some reason I don't want to return class which needed to be converted to interface. I want to return interface and in the JSON I want to see only the methods(which starts get) values. Not the all attributes from the implemented class.
Say for an example:
#Path("getValues/")
#GET
#Produces( MediaType.APPLICATION_JSON)
public DetailInterface getClientDetail() {
return new DetailImpl();
}
and consider the interface:
public interface DetailInterface {
public String getName();
public String getAge();
}
and consider the implementation
public class DetailImpl implements DetailInterface {
public String getName()
return "my name";
}
public String getAge(){
return "my age";
}
public String iDontWantThisinJSON() {
return "I don't want this in JSON output";
}
}
when I request the rest service I see the iDontWantThisinJSON attribute also comes in the JSON response. I don't want to include it in the response.
How can I fix this?
Have you tried #JsonIgnore annotation? Marking the field as transient may be also helpful - however I'm not sure if it's ok.
This is a more of a java concept than Rest or Json. You will have to modify the code as follows and it should work as you want it to work.
#Path("getValues/")
#GET
#Produces( MediaType.APPLICATION_JSON)
public DetailInterface getClientDetail() {
DetailInterface di = new DetailImpl()
return di;
}
Is it possible to retrieve http headers inside JAXRS resource method without explicitly specifying these headers as method parameters?
For example I have a following interface:
#Path("/posts")
public interface PostsResource {
#GET
public List<Post> getAllPosts();
}
and the following class that implements this interface:
public class PostsResourceImpl implements PostsResource {
#Autowired
private PostsService postsService;
public List<Post> getAllPosts() {
return postsService.getAllPosts();
}
}
I don't want to change my method signature to:
public List<Post> getAllPosts(#HeaderParam("X-MyCustomHeader") String myCustomHeader);
This header will be added by interceptor on the client side so the client code doesn't know what to put here and this should not be explicit method parameter.
You can inject an object of type HttpHeaders within your resource as class variable to have access to request headers, as described below:
#Path("/test")
public class TestService {
#Context
private HttpHeaders headers;
#GET
#Path("/{pathParameter}")
public Response testMethod() {
(...)
List<String> customHeaderValues = headers.getRequestHeader("X-MyCustomHeader");
System.out.println(">> X-MyCustomHeader = " + customHeaderValues);
(...)
String response = (...)
return Response.status(200).entity(response).build();
}
}
Hope it answers your question.
Thierry