[英]Spring @RequestBody without using a pojo?
I am using Spring Boot and I have a method defined like this in my controller 我正在使用Spring Boot,并且在控制器中定义了这样的方法
@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. 事情是我的用户pojo中只有
firstName
, id
和lastName
实例字段,但是在我的请求中我have to send
metaInfoId
来满足其他一些需求。 So how can I retrieve or separate metaInfoId
and User
model in my controller method above? 那么如何在上面的控制器方法中检索或分离
metaInfoId
和User
模型?
Do I have to create another model class called UserModelRequest
and add all User
fields along with metaInfoId
field and then use @RequestBody
? 我是否必须创建另一个名为
UserModelRequest
模型类,并将所有User
字段与metaInfoId
字段一起添加,然后使用@RequestBody
? Is there a way to simply remove metaInfoId
from the request and then take everything else and dump it into User
pojo? 有没有一种方法可以简单地从请求中删除
metaInfoId
,然后取出其他所有内容并将其转储到User
pojo中? You could do this easily in nodejs for example(just splice your object and take what you need). 例如,您可以在nodejs中轻松地做到这一点(只需拼接对象并获取所需的内容)。
So is there a way to do it in java spring without having to create another model class? 那么有没有一种方法可以在Java Spring中执行而不必创建另一个模型类?
You can annotate your POJO with @JsonIgnoreProperties(ignoreUnknown = true)
so the fields that it does not contain are ignored. 您可以使用
@JsonIgnoreProperties(ignoreUnknown = true)
注释POJO,以便忽略其中不包含的字段。 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) 如果必须在请求中添加信息,则需要更新User pojo类以包括此字段(或者让它使用metaInfoId字段扩展类)
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. User
对象中没有相应的字段。 In that case, you need to still use the User
object with the supplied fields and ignoring the rest that was provided in the JSON User
对象与提供的字段一起使用,并忽略JSON中提供的其余部分 User
object without defining those extra properties specifically in the object. User
对象中捕获它们, 而无需在对象中专门定义那些额外的属性。 I think in both cases, it is better to use Jackson than Gson as it has richer marshaling controls over the objects. 我认为在这两种情况下,使用Jackson都比Gson更好,因为它对对象具有更丰富的编组控制。 Thus, my below solution assumes that you will use Jackson with Spring web - the maven dependency for Jackson is as follows:
因此,我的以下解决方案假定您将在Spring Web上使用Jackson-杰克逊的maven依赖关系如下:
<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. 在这种情况下,当杰克逊将JSON反序列化为
User
对象时,您需要忽略metaInfoId
属性。 To achieve this, please add this annotation to the top of your User
class. 为此,请将此批注添加到
User
类的顶部。
@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. 我建议添加一个接受所有额外的未定义属性的catch
HashMap
,您可以通过键/值对其进行访问。 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. 为此,您需要将以下内容添加到您的
User
类中,或者更好地创建一个包含该代码的抽象类,以便User
扩展。
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 希望这可以帮助
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.