Java Spring MVC @RequestBody 接收具有非原始属性的对象包装器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19703540/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring MVC @RequestBody receive an Object wrapper with non-primitive attributes
提问by mannuk
I create the JSON as follows:
我按如下方式创建 JSON:
var manager = {
username: "admin",
password: "admin"
};
var userToSubscribe = {
username: "newuser",
password: "newpassword",
email: "[email protected]"
};
var openid = "myopenid";
var subscription = {
manager: manager,
userToSubscribe : userToSubscribe,
openid : openid
};
$.ajax({
url: '/myapp/rest/subscribeUser.json',
type: 'POST',
dataType: 'json',
contentType: 'application/json',
mimeType: 'application/json',
data: JSON.stringify({subscription : subscription})
});
This is the JSON that is sent:
这是发送的 JSON:
{"subscription":{"manager":{"username":"admin","password":"admin"},"userToSubscribe":{"username":"newuser","password":"newpassword","email":"[email protected]"},"openid":"myopenid"}}
And I would like to map this JSON to a Wrapper Class. This is the wrapper:
我想将此 JSON 映射到 Wrapper 类。这是包装器:
private class Subscription{
private User manager;
private User userToSubscribe;
private String openid;
public User getManager() {
return manager;
}
public void setManager(User manager) {
this.manager = manager;
}
public User getUserToSubscribe() {
return userToSubscribe;
}
public void setUserToSubscribe(User userToSubscribe) {
this.userToSubscribe = userToSubscribe;
}
public String getOpenid() {
return openid;
}
public void setOpenid(String openid) {
this.openid = openid;
}
}
The Hymanson dependency in the pom.xml (I'm using spring 3.1.0.RELEASE):
pom.xml 中的 Hymanson 依赖项(我使用的是 spring 3.1.0.RELEASE):
<dependency>
<groupId>org.codehaus.Hymanson</groupId>
<artifactId>Hymanson-mapper-asl</artifactId>
<version>1.9.10</version>
</dependency>
The mapping in rest-servlet.xml
rest-servlet.xml 中的映射
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="jsonConverter" />
</list>
</property>
</bean>
<bean id="jsonConverter" class="org.springframework.http.converter.json.MappingHymansonHttpMessageConverter">
<property name="supportedMediaTypes" value="application/json" />
</bean>
And the header of the controller method:
和控制器方法的标题:
public @ResponseBody SimpleMessage subscribeUser(@RequestBody Subscription subscription)
As a result of the POST I receive a 400 Incorrect request error. Is it possible to do this or do i need to do it with @RequestBody
String or @RequestBody Map<String,Object>
and decode the JSON myself?
作为 POST 的结果,我收到 400 Incorrect request 错误。是否可以这样做,或者我是否需要使用@RequestBody
String 或@RequestBody Map<String,Object>
自己解码 JSON?
Thanks!
谢谢!
采纳答案by mannuk
I'm going to answer my own question. First of all special thanks to Sotirios Delimanolis because he gave me the key in order to investigate what it was happening.
我要回答我自己的问题。首先要特别感谢 Sotirios Delimanolis,因为他给了我钥匙,以便我调查正在发生的事情。
As you know, I create the following json from the view:
如您所知,我从视图中创建了以下 json:
{"manager":{"username":"admin","password":"admin"},"userToSubscribe":{"username":"newuser","password":"newpassword","email":"[email protected]"},"openid":"https://myopenid..."}
I changed it a little bit because I realised that is not necessary to create a object Subscription and a var Subscription. If you build the JSON like this, it will work perfectly:
我稍微改变了它,因为我意识到没有必要创建一个对象订阅和一个 var 订阅。如果您像这样构建 JSON,它将完美运行:
var manager = {
username: "admin",
password: "admin"
};
var userToSubscribe = {
username: "newuser",
password: "newpassword",
email: "[email protected]"
};
var openid = "https://myopenid...";
$.ajax({
url: '/dp/rest/isUserSuscribed.json',
type: 'POST',
dataType: 'json',
contentType: 'application/json',
mimeType: 'application/json',
data: JSON.stringify({manager : manager, userToSubscribe : userToSubscribe, openid : openid})
});
The controller receives this json:
控制器接收到这个 json:
@RequestMapping(method=RequestMethod.POST, value="/isUserSuscribed.json")
public @ResponseBody ResponseMessageElement<Boolean> isUserSuscribed(@RequestBody SubscriptionWrapper subscription){
And the SubscriptionWrapper...
和订阅包装...
private static class SubscriptionWrapper {
BasicUser manager;
BasicUser userToSubscribe;
String openid;
public BasicUser getManager() {
return manager;
}
public void setManager(BasicUser manager) {
this.manager = manager;
}
public BasicUser getUserToSubscribe() {
return userToSubscribe;
}
public void setUserToSubscribe(BasicUser userToSubscribe) {
this.userToSubscribe = userToSubscribe;
}
public String getOpenid() {
return openid;
}
public void setOpenid(String openid) {
this.openid = openid;
}
}
So... What is the problem? I was receiving an Incorrect Request 400 error... I debugged the MappingHymanson2HttpMessageConverter as Sotirios suggested and there was an exception (No suitable constructor). Hymanson Mapping is not able to build an inner class whether this class is not static. Setting SubscriptionWrapper to static was the solution to my problem.
那么……有什么问题吗?我收到了一个 Incorrect Request 400 错误……我按照 Sotirios 的建议调试了 MappingHymanson2HttpMessageConverter,但出现了一个异常(没有合适的构造函数)。无论此类不是静态的,Hymanson Mapping 都无法构建内部类。将 SubscriptionWrapper 设置为 static 是我问题的解决方案。
You can also check these answers:
http://stackoverflow.com/questions/8526333/Hymanson-error-no-suitable-constructor
您还可以查看这些答案:
http://stackoverflow.com/questions/8526333/Hymanson-error-no-suitable-constructor
http://stackoverflow.com/questions/12139380/how-to-convert-json-into-pojo-in-java-using-Hymanson
http://stackoverflow.com/questions/12139380/how-to-convert-json-into-pojo-in-java-using-Hymanson
And if you have problems to deserialize, check this:
http://stackoverflow.com/questions/17400850/is-Hymanson-really-unable-to-deserialize-json-into-a-generic-type
如果您有反序列化问题,请检查以下内容:
http://stackoverflow.com/questions/17400850/is-Hymanson-really-unable-to-deserialize-json-into-a-generic-type
Thanks for all the replies.
感谢所有的答复。
回答by mvb13
You don't need to do this by yourself. You need to add this dependency in your pom:
你不需要自己做这件事。您需要在 pom 中添加此依赖项:
<dependencies>
<dependency>
<groupId>org.codehaus.Hymanson</groupId>
<artifactId>Hymanson-mapper-asl</artifactId>
<version>1.8.5</version>
</dependency>
</dependencies>
After that Spring will do conversion for you.
之后,Spring 将为您进行转换。
回答by Sotirios Delimanolis
Looking at your JSON
查看您的 JSON
{
"subscription": {
"manager": {
"username": "admin",
"password": "admin"
},
"userToSubscribe": {
"username": "newuser",
"password": "newpassword",
"email": "[email protected]"
},
"openid": "myopenid"
}
}
The root element is subscription
and it is a JSON object. Your Subscription
class doesn't have a subscription
field. So there is nothing to map the subscription
element to and it therefore fails with a 400 Bad Request.
根元素是subscription
并且它是一个 JSON 对象。你的Subscription
班级没有subscription
字段。所以没有什么可以映射subscription
元素,因此它失败了 400 Bad Request。
Create a class SubscriptionWrapper
创建一个班级 SubscriptionWrapper
public class SubscriptionWrapper {
private Subscription subscription;
public Subscription getSubscription() {
return subscription;
}
public void setSubscription(Subscription subscription) {
this.subscription = subscription;
}
}
and change your handler method to accept an argument of this type
并更改您的处理程序方法以接受这种类型的参数
public @ResponseBody SimpleMessage subscribeUser(@RequestBody SubscriptionWrapper subscriptionWrapper)
You might need to configure the ObjectMapper
in MappingHymansonHttpMessageConverter
(FYI you should be using MappingHymanso2nHttpMessageConverter
), so that it ignores missing properties.
您可能需要配置ObjectMapper
in MappingHymansonHttpMessageConverter
(仅供参考,您应该使用MappingHymanso2nHttpMessageConverter
),以便它忽略缺少的属性。