Spring JSON请求体未映射到Java POJO

31

我正在使用Spring来实现一个RESTful Web服务。其中一个端点接受一个JSON字符串作为请求体,我希望将其映射到一个POJO上。然而,目前似乎传入的JSON字符串没有正确地映射到POJO上。

这是@RestController接口:

@RequestMapping(value="/send", headers="Accept=application/json", method=RequestMethod.POST)
public void sendEmails(@RequestBody CustomerInfo customerInfo);
数据模型
public class CustomerInfo {
    private String firstname;
    private String lastname; 
    public CustomerInfo() {
        this.firstname = "first";
        this.lastname = "last";
    }

    public CustomerInfo(String firstname, String lastname)
    {
        this.firstname = firstname;
        this.lastname = lastname;
    }

    public String getFirstname(){
        return firstname;
    }

    public void setFirstname(String firstname){
        this.firstname = firstname;
    }

    public String getLastname(){
        return lastname;
    }

    public void getLastname(String lastname){
        this.lastname = lastname;
    }
}

最后是我的POST请求:

{"CustomerInfo":{"firstname":"xyz","lastname":"XYZ"}}

使用Content-Type设置为application/json。

然而,当我打印对象值时,输出了默认值(“first”和“last”),而不是我传入的值(“xyz”和“XYZ”)。

有人知道为什么我没有得到预期的结果吗?

解决方案

事实证明,请求体的值未被传递,因为我需要在接口中以及实际的方法实现中都加上@RequestBody注释。一旦我这样做了,问题就解决了。


嗨@mszymborski,我已经尝试过了,但也没有起作用。默认构造函数被使用了。 - Y. Chen
不要使用 headers,而是在 @RequestMapping 中尝试使用 consumes 属性。 - 11thdimension
@Y.Chen:你的 setter 函数有问题 - 它被称为 getLastname - 如果你修复它,会发生什么变化? - mszymborski
@mszymborski 我同意问题可能出在我的Spring配置上。我是否应该为CustomerInfo类创建一个bean? - Y. Chen
@11thdimension 程序会抱怨“找不到默认构造函数”... - Y. Chen
显示剩余13条评论
6个回答

20
所以结果是,请求体的值没有传递,因为我需要在实际的方法实现中不仅在接口中添加@RequestBody注释。一旦我这样做了,问题就得到了解决。

9
你可以使用多种方式来实现它,这里我将以以下不同的方式进行实现-
注意:请求数据应为 {"customerInfo":{"firstname":"xyz","lastname":"XYZ"}}
第一种方法:我们可以将上述数据绑定到以下地图中。
@RequestMapping(value = "/send", headers = "Accept=application/json", method = RequestMethod.POST)
public void sendEmails(@RequestBody HashMap<String, HashMap<String, String>> requestData) {

    HashMap<String, String> customerInfo = requestData.get("customerInfo");
    String firstname = customerInfo.get("firstname");
    String lastname = customerInfo.get("lastname");
    //TODO now do whatever you want to do.
}

第二种方法:我们可以直接将它绑定到POJO(Plain Old Java Object)。

步骤1:创建DTO类UserInfo.java

public class UserInfo {
    private CustomerInfo customerInfo1;

    public CustomerInfo getCustomerInfo1() {
        return customerInfo1;
    }

    public void setCustomerInfo1(CustomerInfo customerInfo1) {
        this.customerInfo1 = customerInfo1;
    }
}

步骤 1. 创建另一个 dto 类CustomerInfo.java

class CustomerInfo {
        private String firstname;
        private String lastname;

        public String getFirstname() {
            return firstname;
        }

        public void setFirstname(String firstname) {
            this.firstname = firstname;
        }

        public String getLastname() {
            return lastname;
        }

        public void setLastname(String lastname) {
            this.lastname = lastname;
        }
    }

第三步 将请求体数据绑定到 POJO 对象上

 @RequestMapping(value = "/send", headers = "Accept=application/json", method = RequestMethod.POST)
    public void sendEmails(@RequestBody UserInfo userInfo) {

        //TODO now do whatever want to do with dto object
    }

我希望这能帮助你解决问题。谢谢。


非常感谢您提供如此详细的答案。您提出的所有方法都可以完成转换操作。虽然它们不是解决我的问题的方案,但我仍然很高兴学到了这些知识。 - Y. Chen
有没有一种简单的方法将其绑定到方法参数名称,而不是引入一个新的Java类或将其任意映射到键值对映射中? - user1048931

1
这个格式很糟糕,但对于Jackson配置来说应该有效。
<!-- Use Jackson for JSON conversion (POJO to JSON outbound). -->
<bean id="jsonMessageConverter"
            class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/> 

<!-- Use JSON conversion for messages -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
    <property name="messageConverters">
        <list>
            <ref bean="jsonMessageConverter"/>
        </list>
    </property>
</bean>

另外,正如评论中提到的那样,您的JSON对象是错误的。

{"firstname":"xyz",‌​"lastname":"XYZ"}

看起来这是你的对象的正确JSON格式。


0

示例数据:

[  
{  
  "targetObj":{  
     "userId":1,
     "userName":"Devendra"
  }
},
{  
  "targetObj":{  
     "userId":2,
     "userName":"Ibrahim"
  }
},
{  
  "targetObj":{  
     "userId":3,
     "userName":"Suraj"
  }
}
]

对于上述数据,这个打印控制器方法对我有效:

@RequestMapping(value="/saveWorkflowUser", method = RequestMethod.POST)
public void saveWorkflowUser (@RequestBody List<HashMap<String ,HashMap<String , 
  String>>> userList )  {
    System.out.println(" in saveWorkflowUser : "+userList);
 //TODO now do whatever you want to do.
}

0
我遇到了类似的问题,问题是在DTO字段中没有添加@JsonProperty。
@JsonProperty("UnitId")
private String UnitId;

@JsonProperty("ComponentId")
private String ComponentId;

-2

从默认构造函数中删除那两个语句并尝试


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接