What is #PostMapping annotation in Spring Web MVC? - spring

For what purpose #PostMapping annotation is used in Spring MVC?

#PostMapping is a composed annotation that acts as a shortcut for #RequestMapping(method = RequestMethod.POST).
#PostMapping annotated methods handle the HTTP POST requests matched with given URI expression. e.g.
#PostMapping(path = "/members", consumes = "application/json", produces = "application/json")
public void addMember(#RequestBody Member member) {
//code
}
Follows this :example
Hope this helps..!

Spring Framework 4.3 has introduced #PostMapping annotation.
#PostMapping is a composed annotation that acts as a shortcut for
#RequestMapping(method = RequestMethod.POST)
Similarly the following annotations are available:
#GetMapping
#PutMapping
#DeleteMapping
#PatchMapping
These annotations can improve the readability of code.
Reference: Spring API documentation.

Related

Custom Schema for Spring Boot 2 OpenAPI 3 Documentation

I have a requirement to integrate OpenAPI 3 documentation for my Spring Boot 2 project. We did not used modals/DTOs on controllers.
Here is the sample controller:
#RestController
#RequestMapping(value = "/pet")
public class PetController {
#RequestMapping(value = "/save", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
#ResponseBody
public ResponseEntity<Map<String, Object>> savePet(
#RequestBody Map<String, Object> petObj, HttpServletRequest request)
throws Exception {
String petResponse = petDAO.savePet(petObj, request, true);
return new ResponseEntity<Map<String, Object>>(petResponse, HttpStatus.OK);
}
}
Request body:
{
"name":"Test",
"category":"school"
}
My response:
{
"petId":"1",
"petName":"Test",
"petCategory":"school",
"petStaus":"active"
}
I am not able to find a way to add the OpenAPI doc for my custom Map object. I want to add key, description, type, example(s) for each property in my Map manually.
Can anyone suggest how to do this?
This is the default behaviour of the springdoc-openapi library in order to ignore other injectable parameters supported by Spring MVC.
https://docs.spring.io/spring/docs/5.1.x/spring-framework-reference/web.html#mvc-ann-arguments
If you want to change this behaviour, you can just exlcude it as follow:
SpringDocUtils.getConfig().removeRequestWrapperToIgnore(Map.class);

Getting 404 not found when hitting spring boot end point

When trying to hit the rest api end point of spring boot application I get 404 not found, below is the project structure snapshot attached
This is my project structure
Controller -
#RestController
#RequestMapping("/users")
public class UserRestController {
private final UserService userService;
public UserRestController(UserService userService){
this.userService = userService;
}
#RequestMapping(value = "/create", method = RequestMethod.POST,
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
public void createUser(#RequestBody final UserDTO user){
userService.saveUser(user);
}
}
You are not scanning your controllers.
In the image you shared #ComponentScan only scans Service folder. But your controllers are in RestController folder.
Use #ComponentScan without any arguments. By default it will scan for beans in current folder and its sub folder.
e.g #ComponentScan()
#SpringBootApplication covers #EnableAutoConfiguration, #ComponentScan, #Configuration.
#RequestMapping(value = "/create", method = RequestMethod.POST,
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
and for this, you can simply do
#PostMapping(value ="/create"
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
Lets test it in postman, it should be POST and url must be
localhost:<your port>/users/create. Dont forget to add your UserDTO in your Postman Body.
In case you missing it, your application must be up and running.
imporatant Please check your HTTP method type when call end point form postman.it must be "post"
Bro if you are using Spring boot. then no need to write #EnableAutoConfiguration, #ComponentScan, #Configuration.
#SpringBootApplication Covers all these.
You just check your url it should be like http://localhost:8080/users/create
used autowired
#autowired
private final UserService userService;

How to change content-type header of http response provided by method in class annotated #RepositoryRestController

I have class:
#RepositoryRestController
#RequestMapping(value = "users")
public class UserController {
...other methods...
#GetMapping(value = "returnText", produces = MediaType.TEXT_PLAIN_VALUE)
public String returnText() {
return "my text";
}
}
And when this method is called by Postman, http response content-type header is application/hal+json but I used produces = MediaType.TEXT_PLAIN_VALUE.
Can I somehow change content-type header of response?
Can #RepositoryRestController only return application/hal+json?
I wanted to use #RepositoryRestController to return image/jpg contet-type also in another method and that does not work because of same reason.
I think this will work in #RestController class but why use that if my application is Spring Data Rest and I want to use #RepositoryRestController annotation for my controllers.
From SDR documentation:
...to take advantage of Spring Data REST’s settings, message converters, exception handling, and more, use the #RepositoryRestController annotation ...
If you’re NOT interested in entity-specific operations but still want to build custom operations underneath basePath, such as Spring MVC views, resources, etc. use #BasePathAwareController.
So try to use #BasePathAwareController instead of #RepositoryRestController.

RESTful Webservice Using Spring Framework

I have written some RESTful webservices using Spring Framework (by reading posts online / video tutorials etc.) , however I still have some doubts.
When we write a web-application using Spring MVC module we use controller code, similar to below:
#Controller
public class SimpleController {
#RequestMapping("/welcome")
ModelAndView handleIncomingWelcomeReq() {
ModelAndView mw = new ModelAndView("WelcomePage","welcomeKey","WelcomeKey's value!");
return mw;
}
}
In the above code there is ModelAndView object which this controller returns, and this can be invoked like this URL:
http://localhost:8080/contextRoot/welcome
Now, if we exclude the "view" part and return just the model doesn't it act like a web service?
So my doubt is, in Spring do we used the same API/jar's to create web-application or RESTful web services?
The things which I read is that for Spring REST support, it has annotation #RestController annotation (which itself is like #Contoller + #ResponseBody annotations).
So what is the difference in which the implementation of REST WS and web-applications differs in Spring Framework?
Can anyone help me understand this?
Yes we can write RestService & web application using Spring. Use #RestController to expose a REST service and #Controller for web application.
#RestController is a meta-annotation with #Controller and #ResponseBody. #Controller will search through the registered ViewResolvers, whereas #RestController will not.
#Controller
public class SimpleController {
#RequestMapping("/welcome", method = RequestMethod.GET, produces="application/json")
public #ResponseBody JSONObject handleIncomingWelcomeReq() {
JSONObject j = new JSONObject();
j.put("welcomeKey", "WelcocmeKey's value!");
return j;
}
Here is the code which returns response in json mostly user id Rest Apis.
I would suggest to use #Controller instead of #RestController, as #RestController, won't scan your views. So, in case if your application has it's own views and also needs to expose it's services, you can use #Controller along with the #ResponseBody annotations, with output as JSON.
Another option is to have completely different URL for RESTful webservices, where a different controller will handle the request. These different controllers can be annotated with #RestController.

Spring MVC web application - enabling / disabling controller from property

I have a web application running in Tomcat and using Spring MVC to define controllers and mappings. I have the following class:
#Controller("api.test")
public class TestController {
#RequestMapping(value = "/test", method = RequestMethod.GET)
public #ResponseBody String test(HttpServletRequest httpRequest, HttpServletResponse httpResponse) {
// body
}
}
I would like to make this controller and the ".../test" path available according to a property defined somewhere (e.g. file). If the property is, lets say, false, I would like the app to behave as if that path doesn't exist and if it is true, to behave normally. How can I do this? Thanks.
If you are using Spring 3.1+, make the controller available only in the test profile:
#Profile("test")
class TestController {
...
}
then enable that profile by e.g. passing the following system property at Tomcat boot:
-Dspring.profiles.active=test
To disable the controller simply omit the given profile.
Another way of doing it , may be simpler way of doing it, is to use #ConditionalOnProperty annotation with your RestController/Controller.
#RestController("api.test")
#ConditionalOnProperty(name = "testcontroller.enabled", havingValue = "true")
public class TestController {
#RequestMapping(value = "/test", method = RequestMethod.GET)
public String test(HttpServletRequest httpRequest, HttpServletResponse httpResponse) {
// body
}
}
Here testcontroller.enabled property in your yml properties say ,if not set to true , the TestController Bean is never created.
Tip: I suggest you to use RestController instead of Controller as its has #ResponseBody added by default. You can use #ConditionalOnExpression to arrive at the same solution but is little slower due to SpEL evaluation.

Resources