I want to apply both Put and Post mapping request to a method as show below. It does work for PUT, but not for POST requests. What am I dong wrong?
#RestController
#RequestMapping("/PQR")
public class XController {
#PutMapping("xyz")
#PostMapping("xyz")
public MyDomainObject createOrUpdateDAO(
HttpServletRequest request,
#RequestBody String body) throws IOException {
//...
}
}
When I make a POST request, I get a 405 HTTP status code:
[nio-8080-exec-3] o.s.web.servlet.PageNotFound: Request method 'POST' not supported
If I look at this example, same method has same method is mapped for GET and POST requests.
#RequestMapping(value="/method3", method = { RequestMethod.POST,RequestMethod.GET })
#ResponseBody
public String method3() {
return "method3";
}
Remove #PostMapping and #PutMapping annotations and add method to your #RequestMapping, i.e:
#RequestMapping(value={"/PQR", "xyz"},
method={RequestMethod.POST,RequestMethod.PUT})
Related
I am getting this error while calling an API from postman, after I hosted my spring app in VM. Locally it works. But Get methods in my VMs are working.
[http-nio-8081-exec-4] PageNotFound - Request method 'GET' not supported
My controller method looks like this:
#RestController
#RequestMapping("/orders/")
public class OrdersController {}
#PostMapping(value = "create", produces = "text/plain")
private String createOrder(#RequestBody POCreationRequest request) throws ParseException {
The API request running forever and dont get any response. I found the exception in my log. Any idea on this issue?
You created two urls there:
url/orders/ -> accepts get/post/etc... (though its not implemented)
url/orders/create -> accepts post
#RestController
#RequestMapping("/orders")
public class OrdersController {
#PostMapping(value = "create", produces = "text/plain")
private String createOrder(#RequestBody POCreationRequest request) throws ParseException {
System.out.println(request)}
}
You can try the above code.
You are trying to make a GET request on an only POST endpoint, thus then not loading the page. Your endpoint should be of type GET. You can also have the same endpoint for GET and POST requests as follows:
#RestController
#RequestMapping("/orders/")
public class OrdersController {}
#PostMapping(value = "create", produces = "text/plain")
private String createOrder(#RequestBody POCreationRequest request) throws ParseException {
//Parse post requests
}
#GetMapping(value= "create")
private String servePage() {
return create; //create is the name of the html view.
}
Now when going to localhost:8080/orders/create it should serve the view.
You can also make the GET mapping return a JSON object by:
#GetMapping(value= "create")
private String serveJSON() {
return "{\"hello\": \"world\"}"; //The string is treated as JSON and not as a view.
}
I have a spring RestController and want to redirect to POST method in same controller with RequestBody.
any solution welcomes, not only redirect.
MyController:
#RequestMapping(value = "/addCompany", method = RequestMethod.POST)
public String addCompany(#Valid Company company, BindingResult result,
HttpServletRequest request, Model model) throws Exception {
//some logic
//need to pass Company Object as RequestBody
return "redirect:/app/postmethod/";
}
//Method to redirected
#RequestMapping(value = "/postmethod", method = {RequestMethod.POST, RequestMethod.GET})
public String getData( #RequestBody(required=false) Company compnay, HttpServletRequest request, Model model) throws Exception {
//some logic
//required company object
return "htmlpage";
}
I need to redirect my request to /postmethod from addCompany method in the same controller, I am open to use any feasible solution.
Check here:
https://www.baeldung.com/spring-redirect-and-forward#redirecting-an-http-post-request
As per HTTP 1.1 protocol reference, status codes 301 (Moved
Permanently) and 302 (Found) allow the request method to be changed
from POST to GET. The specification also defines the corresponding 307
(Temporary Redirect) and 308 (Permanent Redirect) status codes that
don't allow the request method to be changed from POST to GET.
#PostMapping("/redirectPostToPost")
public ModelAndView redirectPostToPost(HttpServletRequest request) {
request.setAttribute(
View.RESPONSE_STATUS_ATTRIBUTE, HttpStatus.TEMPORARY_REDIRECT);
return new ModelAndView("redirect:/redirectedPostToPost");
}
#PostMapping("/redirectedPostToPost")
public ModelAndView redirectedPostToPost() {
return new ModelAndView("redirection");
}
The request body will be passed. Here is an example using your code:
#RestController
#RequestMapping("app")
public class TestController {
#PostMapping("/addCompany")
public ModelAndView addCompany(#RequestBody Company company, HttpServletRequest request) {
System.out.println("First method: " + company.name);
request.setAttribute(
View.RESPONSE_STATUS_ATTRIBUTE, HttpStatus.TEMPORARY_REDIRECT);
return new ModelAndView("redirect:/app/postmethod/");
}
#PostMapping("/postmethod")
public void getData(#RequestBody Company company) {
System.out.println("Redirected: " + company.name);
}
public static class Company {
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
When using POST request to http://localhost:8080/app/addCompany with body {"name": "Test Company"}, in the output I receive next:
First method: Test Company
Redirected: Test Company
I found a good explanation on this page here.
For protecting users against inadvertently (re)submitting a POST transaction which they had not intended, or submitting a POST into a context which they would not have wanted.
So you can set the data in session and using get method to call post method if you want to do this.
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 implemented a Request filter (extends OncePerRequestFilter)
and I return a HttpServletRequestWrapper where I have overridden the
ACCEPT header.
When the controller method is invoked:
#ResponseBody
public Foo getFoo(HttpServletRequest request,
#RequestHeader(value=ACCEPT) String injectedAcceptHeader,
#PathVariable ("fooId") String fooId) {
log.info("injected accept header: {}", injectedAcceptHeader);
log.info("accept header value from request: {}",
request.getHeader(ACCEPT));
...
The injectedAcceptHeader is not the same as the one from the Request.
Is this expected behaviour?
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