I am using Spring Boot and I have a method defined like this in my controller
@PostMapping("/update)
public void update(@RequestBody User user) {
...
}
However in my post request from client(frontend or postman for example), I have something like this:
{
"firstName" : "John",
"lastName" : "Doe",
"id" : 1234,
"metaInfoId" : "5457sdg26sg4636"
}
The thing is my User pojo has only firstName
, id
and lastName
instance fields in it.However in my request I have to send
metaInfoId
as well for some other needs. So how can I retrieve or separate metaInfoId
and User
model in my controller method above?
Do I have to create another model class called UserModelRequest
and add all User
fields along with metaInfoId
field and then use @RequestBody
? Is there a way to simply remove metaInfoId
from the request and then take everything else and dump it into User
pojo? You could do this easily in nodejs for example(just splice your object and take what you need).
So is there a way to do it in java spring without having to create another model class?
requestBody consists of the content object, an optional Markdown-formatted description , and an optional required flag ( false by default).
Remember, we don't need to annotate the @RestController-annotated controllers with the @ResponseBody annotation since Spring does it by default.
@RequestBody : Annotation indicating a method parameter should be bound to the body of the HTTP request. @ResponseBody annotation can be put on a method and indicates that the return type should be written straight to the HTTP response body (and not placed in a Model, or interpreted as a view name).
You can annotate your POJO with @JsonIgnoreProperties(ignoreUnknown = true)
so the fields that it does not contain are ignored. Ex
@JsonIgnoreProperties(ignoreUnknown = true)
public class User {
private int id;
private String firstName;
private String lastName;
... getters & setters ...
}
Additionally, you should not include metadata in the body of your rest request. The correct place for this information would be in a headers. This would change your method signature to:
@PostMapping("/update)
public void update(@RequestBody User user, @RequestHeader(value="metaInfoId") String metaInfoId) {
...
}
If you must add the information in the request, then your would need to update the User pojo class to include this field (Or have it extend a class with the metaInfoId field)
Lastly, you really don't want to create a new type. You can change the signature to accept a map and retrieve the necessary info like:
@PostMapping("/update)
public void update(@RequestBody Map<String, Object> userMap) {
String metaInfoId = userMap.get("metaInfoId");
ObjectMapper mapper = new ObjectMapper(); // jackson's objectmapper
final User user = mapper.convertValue(userMap, User.class);
}
I understand from the question that you may need two cases:
User
object. In that case, you need to still use the User
object with the supplied fields and ignoring the rest that was provided in the JSONUser
object without defining those extra properties specifically in the object. I think in both cases, it is better to use Jackson than Gson as it has richer marshaling controls over the objects. Thus, my below solution assumes that you will use Jackson with Spring web - the maven dependency for Jackson is as follows:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
First Case
In this case, you need Jackson to ignore the metaInfoId
property when it deserializes the JSON to the User
object. To achieve this, please add this annotation to the top of your User
class.
@JsonIgnoreProperties(ignoreUnknown = true)
class User {
private String firstName;
private String lastName;
// the rest of the class definition
}
Second Case
In the second case, you still need to capture the extra properties. I'd suggest adding a catch all HashMap
that accepts the extra undefined properties and you can access it by key/value. To achieve this, you'll need to add the following to your User
class, or better to create an abstract class that has this code where User
extends it.
class User {
private String firstName;
private String lastName;
private Map<String, Object> extra;
@JsonAnySetter
public void addExtra(final String key, final Object value){
this.extra.put(key, value);
}
@JsonAnyGetter
public Map<String, Object> getExtra() {
return Collections.unmodifiableMap(this.extra);
}
// the rest of the class definition
}
Hope this helps
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With