I have a large object which can be updated in a few steps. I'am facing a partial binding problem. My service consumes json and I can not use #InitBinder along with #RequestBody. Cutting this object to a few small ones is not good a solution, because there is a lot of cross-field validations between steps.
Do you have any ideas how to solve this? I'am looking for a clean solution like: registering a specific object mapper for given #RequestMapping or something like that. Thanks for help.
You should be able to use a PATCH HTTP method
Its the preferred method that you would use when you need partial updates, like in your case when you want to update just a few fields of a resource
Spring MVC added a support for it in the version 3.2, so you can do something like
#RequestMapping(value="/patch", method=RequestMethod.PATCH, consumes=MediaType.APPLICATION_JSON_VALUE)
public #ResponseBody String patch(#RequestBody Foo foo) {
return foo.toString();
}
and when sending the request, add only the properties you want to update to your PATCH request, the properties that are null or omited won't be updated
In the lack of better Spring MVC PATCH reference, I'm linking this SO thread as an interesting read Spring MVC PATCH method: partial updates
Related
I've been using arrow-kt and spring together a lot lately. I've actually constructed a bridge between the two with several key features, one of which is a spring controller that returns an Either will automatically unwrap it and either handle the exception (Left) or return the result (Right). My long term goal is to publish this as a library.
My latest obstacle is Swagger, or more accurately springdoc openapi. Obviously it is seeing the Either, but i want it to show only the Right value as the success response type. While I know there are annotations where I can set the response model on each controller method individually, I'm trying to avoid this.
My real goal is to setup some global converter so that wherever Swagger sees an Either it will automatically unpack this. I'm just not super familiar with the customization API in Spring doc, and everything I Google just points me to the ApiResponse annotation solution.
How can I define default handling for this type of response?
I reported this issue https://github.com/dotnet/runtime/issues/48816 and the developer that responded posted code explaining how to manually deserialize the function argument. Asp is supposed to have an automated system for this however. So if my function definition looks like:
[Authorize]
[HttpPost]
public async Task<IActionResult> Post(Session session)
{
...
then I am supposed to be able to just use session as a variable from that point without any special deserialization step. This suggests to me that there must be a way to set JsonSerializerOptions(JsonSerializerDefaults.Web) somewhere in a more global way so that it can consume the post data it is getting. Alternatively there might be a different way to serialize the post data differently on the client so that it does not get converted to camel case.
The main question is: what is the correct way to serialize and deserialize data objects for asp.net-core?
To Reproduce
Thanks for Roar S's comment, use [FromBody], it works.
I am trying figure out best possible way to write a common logic in Spring MVC application. I have a Controller A which would be called which would invoke any another Controller based on request attributes which return json data.
I want the response back in controller A so that i can write common enrichment logic and send it back to browser. My intent is write enrichment logic only at one place and every request goes through it.
What your are looking for are so called HandlerInterceptor or ControllerAdvice.
I made a small repository on Github about Spring MVC Interception a while ago, it is a small Spring Boot application, which is showing you the ways to intercept a request with Spring MVC.
The question is always what is your main goal:
Do you want to just manipulate the output (e.g. adding a common field)? Use ControllerAdvice.
Do you want to call a logic before and after, without manipulating the request? Go for filters.
Do you want to change the object fundamentally (e.g. wrap it with another object)? Go for HandlerInterceptor.
May be you can create abstract controller class and put the common logic or code in it. So wherever you want to use this common code just extend this class and use it.
For example :
public class AbstractController{
// common logic
}
public class A extends AbstractController{}
public class B extends AbstractController{}
public class C extends AbstractController{}
I am aware of [JsonIgnore] attribute. Unfortunatelly it ignores property on both, the Request and the Response.
I need a way to ONLY ignore it during RESPONSE. Having to work with two different classes for request and response (even by using inheritance) is not an acceptable solution as it introduces a whole a lot of object copying hassle.
Any help is appreciated.
JsonIgnore instructs the JsonSerializer not to serialize the public field or public read/write property value for both request and response.
It sounds like you have a design issue. Create your request/response data contracts separately and more properly.
I've got a web application built over Spring MVC, already working. I'm planning to give mobile users an app for communicating with the server, so they will find easier to interact with it. I've got the Model, the Views and the Controllers working fine, but everything was designed from the web's perspective.
So, I'm building up a few new Controllers for the mobile app, and here comes the question: since the ultimate rresponsible of the View is going to be the mobile app in question, where should I delegate everything to the app, in the Controller (preparing there a JSON for each response)? Or should I have a JSP with some JSON taglib enabled, so that the Controller gives the pieces to the JSP, and then I build the JSON response in the JSP?
I'm not clear about the MVC architecture on this scenario.
Thanks in advance.
When all you are doing is creating a REST API which mobile (or other clients) are going to use, Views do not come into play. It's the responsibility of the Controller to prepare the appropriate response for the client.
Luckily since returning JSON is such a common scenario, Spring MVC transparantly handles the serialization into JSON (using the Jackson library) so you don't have to.
As JB Nizet showed, you can use the #ResponseBody annotation to tell Spring MVC that the response should be returned as is (serialized to JSON because of the produces = MediaType.APPLICATION_JSON_VALUE) or if you are using Spring 4, you can completely ditch the #ResponseBody annotation and annotate your Controller with #RestController (which makes Spring behave as if #ResponeBody was added to every method mapping) instead of #Controller.
The controller methods should simply return obejcts (or collections of objects), that will be serialized to JSON automatically thanks to the #ResponseBody annotation:
#RequestMapping(value = "/api/users",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
#ResponseBody
public List<User> listUsers() {
...
}