GetMapping and PostMapping - spring-boot

#RestController
public class HelloWorldController {
#GetMapping(path="/helloWorld")
public String helloWorld() {
return "Hello-World";
}
}
I am new to RestFul WebServices. I tried to annotate the helloWorld() with PostMapping but it failed. Using GetMapping, it successfully gets executed.
Can somebody tell me why PostMapping was not allowed?

PostMapping for POST request.
GetMapping for GET request.
If you want call PostMapping success, you can use Postman or SoapUI, curl for testing HTTP POST request.
Reference document:
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/bind/annotation/PostMapping.html
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/bind/annotation/GetMapping.html

In addition to #Do Nhu Vys answer. You will often encounter problems with CORS and CRFS while performing Post Requests.
References:
https://docs.spring.io/spring-security/site/docs/5.0.x/reference/html/csrf.html
https://spring.io/blog/2015/06/08/cors-support-in-spring-framework

Related

Spring Boot - Why I cannot produce a String in RestController?

In Spring Boot, I am configuring the server and everything is working, except of my RestController. I dont know why:
(SO doesnt allow to include pictures yet, so here is a link)
Thats the little Controller class. Notice, that the method name in my Intellij IDEA
is grey - it is not used.
package com.example.intermediate.controller;
import org.springframework.web.bind.annotation.*;
#RestController
public class GrakaController {
#GetMapping(value = "/graka", produces = "text/plain")
#ResponseBody
public String getSimpleString() {
return "IT WORKED!";
}
}
In Postman I try to get the String by using http://localhost:8080/graka: I am getting a 200 return code, but with empty response body, no matter which response body format I choose in Postman. But I should get "IT WORKED!" back I think.
I have been struggling for some hours with that. Who got any ideas? Thanks for every tip!
try this
#GetMapping("/graka")
public String getSimpleString(){
return "IT WORKED!";
}
With Spring 4, if your Controller is annotated with #RestController, you don't need the #ResponseBody annotation.
Use ResponseEntity.
#GetMapping("/graka")
public ResponseEntity<String> getSimpleString() {
LOG.info("REST request get string value");
return new ResponseEntity<>("{\"status\" : \"IT WORKED!\"}", HttpStatus.OK);
}

PostMapping errors asking for GetMapping

I am trying to save data to my Postgres database. This should use a PostMapping annotation on the method so that it sends the object accordingly. However, for some reason it is expecting a "GET" method. Any thoughts and if others have run into a similar issue. I also cannot debug into that method as well.
Inventory.java
#RestController
public class InventoryController {
#Autowired
private InventoryService inventoryService;
#RequestMapping(value="/add", method=RequestMethod.POST)
public Inventory addItem(#RequestBody(required = false) Inventory item) {
System.out.print("This is a test");
return inventoryService.save(item);
}
#GetMapping(path="/test")
#ResponseBody
public String testMethod() {
return "Method works!";
}
}
Stacktrace
There was an unexpected error (type=Method Not Allowed, status=405).
Request method 'GET' not supported
org.springframework.web.HttpRequestMethodNotSupportedException:
Request method 'GET' not supported at
org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping.handleNoMatch(RequestMappingInfoHandlerMapping.java:201)
at
org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.lookupHandlerMethod(AbstractHandlerMethodMapping.java:421)
at
org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:367)
at
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.getHandlerInternal(RequestMappingHandlerMapping.java:449)
at
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.getHandlerInternal(RequestMappingHandlerMapping.java:67)
at
org.springframework.web.servlet.handler.AbstractHandlerMapping.getHandler(AbstractHandlerMapping.java:393)
I have tried the following annotations on the "addItem" method and it still returns the aforementioned trace.
#RequestMapping(value="/add", method=RequestMethod.POST)
#PostMapping(path="/add")
I am running Spring Boot 2.2.0.RELEASE
It's not asking for GetMapping, the error said Request method 'GET' not supported. It means you call endpoint for HttpGet Method, but your defined endpoint in the Controller is HttpPost Method !
Call using curl, should be like below :
curl -d "param1=value1&param2=value2" -H "Content-Type: application/json" -X POST http://localhost:8080/add
You do not need to add #ResponseBody as in #RestController is combination of #Controller and #ResponseBody. Also try to test the code from PostMan alike tools before handing over API end points to Frontend or mobile team.
Example:
#RestController
#RequestMapping(value = "/users")
public class UserController {
...
...
#GetMapping
#PreAuthorize("hasRole('ADMIN')")
public List<User> getAllUsers() {
return userService.getAllUsers();
}
}
Also sometime if we get any particular resource by Id so we should check if resource is null than return blank object or standard NOT_FOUND error, error we can override with #RestControllerAdvice extended from ResponseEntityExceptionHandler where we can extended all the error on controller level.
But if error comes in resource server, so in that case we have to add entrypoints in websecurity configure -> http security method overrid and add custom entrypoint as well failure and success handlers.

How to add a request body to spring mockmvc

I have the following post endpoint:
#PostMapping(path = "/migration/sendStatements")
public void sendStatements(#RequestBody StatementsDTO StatementsDTO)
{....}
I would like to test this method. I am using Spring MVC and in my test class, I am using MockMVC.
When I try writing the method:
mockMvc.perform(post("/migration/sendStatements")); I don't get an option to add a request body. I want to add a request body to this endpoint. How do i do this?
Add request body using content method
String requestBody = "{.... }";
mockMvc.perform(post("/migration/sendStatements")
.content(requestBody));

404 error code when attempting to access an API endpoint but works normally on others

I have an endpoint in the com.project.users package that will fetch the information of the logged in user:
#RestController
#RequestMapping(path = "/api")
public class UserController {
#Autowired
private UserRepository repository;
#GetMapping("me")
public User me() {
Optional<User> ouser = repository.findById(1);
return ouser.get();
}
}
I have another controller within com.project.beneficiary and I am trying to access a method through a POST request but instead, I receive a 404 error message:
Request URL:http://localhost:8080/api/beneficiaries
Request method:POST
Remote address:127.0.0.1:8080
Status code:
404
Version:HTTP/1.1
Referrer Policy:no-referrer-when-downgrade
{"timestamp":"2019-04-16T01:46:37.395+0000","status":404,"error":"Not Found","message":"No message available","path":"/api/beneficiaries"}
#RestController
#RequestMapping(path = "/api/beneficiaries")
public class BeneficiaryController {
#Autowired
private BeneficiaryRepository repository;
#PostMapping("/")
public Beneficiary addBeneficiary(#Valid #RequestBody Beneficiary beneficiary) {
return repository.save(beneficiary);
}
}
I've dealt with CORS, and I think it worked because I see no message about it anywhere. All these packages are on the same level as the application's starting point, but it is weird why one is seen and the other is not. Something to do with the POST request?
I found something about setting up the context within application.properties, but whatever I put there will cause the 404 error even from Insomnia software. I tried adding the /beneficiaries, /api/beneficiares, and just /api, but I don't think it is anything to do with it. No error messages in the console are visible.
It's a typo :). I ran into a similar problem some time back. Took me hours to resolve. Just remove ("/") from your #PostMapping.

Set Jersey to Default to JSON

I am using Jersey with Jackson. I want to default all endpoints (defined or not) to return JSON.
Let's say I have an /hello endpoint that produces application/json over GET. Now if I were to call /hello with POST, it is returning XML.
How does one configure this to default to JSON instead of XML?
I think I found an answer to this. I have not tested this yet, but am pretty sure this will work.
#Provider
public class CommonExceptionMapper implements ExceptionMapper<Exception> {
#Override
public Response toResponse(Exception exception) {
return Response.status(statusCode).type(MediaType.APPLICATION_JSON).entity(restError).build();
}
}
I was missing the .type().

Resources