Here is what I'm trying to achieve :
I have many spring rest reactive controller returning various Object such as Mono, Flux
I would like to wrap all these response in a ResponseEntity and so always return something like :
Mono<ResponseEntity<MyObjects>>
Any suggestion ?
Just use #ResponseBody Annotation on your controllers
When you use the #ResponseBody annotation on a method, Spring converts the return value and writes it to the http response automatically. Each method in the Controller class must be annotated with #ResponseBody.
See the example
Related
In Jersey Rest API
if any common request parameters are there then we can capture that value at RootResource level using the below code.
#QueryParam("q")
private String qQueryParams
Is there any similar approach in Spring Rest API.
In other words, all my endpoint URL will contain the query parameter "q". How to capture this data at class level instead of every request.
Thanks, Vijay
you can use #RequestMapping({q}/test) above controller and pass #PathVariable String q as method argument.
#Controller
#RequestMapping(value = "{q}/test")
class TestController {
#RequestMapping(value="/abc")
public ModelAndView doSomething(#PathVariable String q) {
// do something with q...
}
}
How to access RequestBody parameters which is of Mono type. Spring Boot Webflux reactive.
I would like to return a ResponseEntity and not a Mono.
#RequestMapping(value = "/poststudentdata", method = RequestMethod.POST, headers={"content-type=application/json"})
public ResponseEntity<String> poststudentData(#Valid #RequestBody Mono<Student> student, BindingResult bindingResult) {
// How can i access student.getName() etc.... RequestBodt parameters
// Not able to access as have declared Student as Mono.
}
Don't try to return a non-reactive type when your input is provided asynchronously via a reactive type (Mono), because it means you'll likely end up blocking the IO thread on which the request was processed, which assumes non-blocking behavior of Controllers. This brings up the risk of not only blocking the current request's processing, but processing of all other requests in the application.
So change the return type to Mono<ResponseEntity>, rename student to studentMono for clarity and process your student in a map (or possibly flatMap if you have asynchronous transformations to apply):
return studentMono.map(student -> ResponseEntity.ok(student.getName()));
I am using spring boot 2.0.2.
My controller is
#RequestMapping(
value = "/process",
method = RequestMethod.POST)
public Response<String> abcd(#RequestBody Map<String, Object> payload) {
System.out.println(payload);
Response<String> s = new Response<>();
s.setData("aaaa");
return s;
}
So basically input is json. Now I want to sanitize my json via some library(not part of question).
My question is how can I do this? I mean where should I write this code?
I want a centralized solution like using AOP (aspect-oriented programming)?
How do i write my AOP?
What i just want is that I should get input as json, and return sanitized json and request body works as it is.
If you want to do this with AOP you could write an after advice for the code doing the json serialization and do the sanitize you want there. I think Spring boot use ObjectMapper to do the serialization. You can try to add your advice to the method writeValueAsString in the ObjectMapper class.
You can find a short intro on how to use AOP with Spring boot on https://www.baeldung.com/spring-aop.
I am trying to build RESTful web service by using spring 4.0
I have a controller:
#Controller
#RequestMapping("test")
public class Controller{
#RequestMapping("fetch",method=RequestMethod.GET)
#ResponseStatus(value=HttpStatus.OK)
#ResponseBody
public ResultResponse fetchController(ResultRequest req){
if((req.getName).equals("John"))
return new ResultResponse(100);
else
return new ResultResponse(0);
}
}
and my ResultRequest.class
public class ResultRequest{
private String name;
//getter,setter
}
If I hit the url to //host//contextPath/test/fetch?name=John
the controller will return the object ResultResponse(100)
my question is, there no #RequestParam or other annotation in the request parameter,
how does the spring controller know to set the query parameter "name" as the property of wrapper class
ResultRequest ?
Thanks
Spring uses implementations of an interface called HandlerMethodArgumentResolver for resolving arguments to pass to handler methods, ie. methods annotated with #RequestMapping.
One of these is a ModelAttributeMethodProcessor. Its javadoc states
Resolves method arguments annotated with #ModelAttribute and handles
return values from methods annotated with #ModelAttribute.
Model attributes are obtained from the model or if not found possibly
created with a default constructor if it is available. Once created,
the attributed is populated with request data via data binding and
also validation may be applied if the argument is annotated with
#javax.validation.Valid.
When this handler is created with annotationNotRequired=true, any
non-simple type argument and return value is regarded as a model
attribute with or without the presence of an #ModelAttribute.
Spring registers two objects of this type. One to handle parameters annotated with #ModelAttribute and one to handle ones without.
Further reading:
Form submit in Spring MVC 3 - explanation
An Errors/BindingResult argument is expected to be declared immediately after the model attribute, the #RequestBody or the #RequestPart arguments
I'm using spring annotation based controller. I want my URL /user/messages to map to some controller a if query parameter tag is present otherwise to some different controller b. This is required because when parameter tag is present then some more parameters can be present along with that which i want to handle in different controller to keep the implementation clean.Is there any way to do this in spring. Also is there any other elegant solution to this problem ?
You can use the params attribute of the #RequestMapping annotation to select an controller method depending on Http parameters.
See this example:
#RequestMapping(params = "form", method = RequestMethod.GET)
public ModelAndView createForm() {
...
}
#RequestMapping(method = RequestMethod.GET)
public ModelAndView list() {
...
}
It is a REST style like Spring ROO uses: if the request contains the parameter forms then the createForm handler is used, if not the list method is used.
If you want to go the Spring route, you can checkout the HandlerInterceptor mentioned here. The Interceptor can take a look at your query param and redirect the link to something else that can be caught by another SimpleUrlMapper.
The other way is to send it to a single controller and let the controller forward to another action if the query parameter is "b".