spring 在spring mvc控制器接收json并反序列化为对象列表

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23012841/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 06:39:55  来源:igfitidea点击:

receiving json and deserializing as List of object at spring mvc controller

springspring-mvcHymanson

提问by HKumar

My code is as below:

我的代码如下:

controller

控制器

@RequestMapping(value="/setTest", method=RequestMethod.POST, consumes="application/json")
public @ResponseBody ModelMap setTest(@RequestBody List<TestS> refunds, ModelMap map) {
    for(TestS r : refunds) {
        System.out.println(r.getName());
    }
    // other codes
}

TestS pojo

TestS pojo

public class TestS implements Serializable {
    private String name;
    private String age;
    //getter setter
}

Json request

JSON 请求

var z = '[{"name":"1","age":"2"},{"name":"1","age":"3"}]';
$.ajax({
    url: "/setTest",
    data: z,
    type: "POST",
    dataType:"json",
    contentType:'application/json'               
});

It's giving this error

它给出了这个错误

java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.air.cidb.entities.TestS

java.lang.ClassCastException:java.util.LinkedHashMap 无法转换为 com.air.cidb.entities.TestS

I am using spring 3.1.2and Hymanson 2.0.4

我正在使用spring 3.1.2Hymanson 2.0.4

Edit:I want to receive list of TestS objects at my controller method, and process them. I am not able to find if I am sending wrong json or my method signature is wrong.

编辑:我想在我的控制器方法中接收 TestS 对象列表,并处理它们。我无法确定是我发送了错误的 json 还是我的方法签名错误。

回答by Shailendra

Here is the code that works for me. The key is that you need a wrapper class.

这是对我有用的代码。关键是你需要一个包装类。

public class Person {

    private String name;
    private Integer age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }

A PersonWrapper class

PersonWrapper 类

public class PersonWrapper {

    private List<Person> persons;

    /**
     * @return the persons
     */
    public List<Person> getPersons() {
        return persons;
    }

    /**
     * @param persons the persons to set
     */
    public void setPersons(List<Person> persons) {
        this.persons = persons;
    }
}

My Controller methods

我的控制器方法

@RequestMapping(value="person", method=RequestMethod.POST,consumes="application/json",produces="application/json")
    @ResponseBody
    public List<String> savePerson(@RequestBody PersonWrapper wrapper) {
        List<String> response = new ArrayList<String>();
        for (Person person: wrapper.getPersons()){
        personService.save(person);
         response.add("Saved person: " + person.toString());
    }
        return response;
    }

The request sent is json in POST

发送的请求是 POST 中的 json

{"persons":[{"name":"shail1","age":"2"},{"name":"shail2","age":"3"}]}

And the response is

回应是

["Saved person: Person [name=shail1, age=2]","Saved person: Person [name=shail2, age=3]"]

回答by Dirk Lachowski

This is not possible the way you are trying it. The Hymanson unmarshalling works on the compiled java code aftertype erasure. So your

这在您尝试的方式中是不可能的。Hymanson 解组类型擦除对已编译的 Java 代码起作用。所以你的

public @ResponseBody ModelMap setTest(@RequestBody List<TestS> refunds, ModelMap map) 

is really only

真的只是

public @ResponseBody ModelMap setTest(@RequestBody List refunds, ModelMap map) 

(no generics in the list arg).

(列表 arg 中没有泛型)。

The default type Hymanson creates when unmarshalling a Listis a LinkedHashMap.

Hymanson 在解组 a 时创建的默认类型List是 a LinkedHashMap

As mentioned by @Saint you can circumvent this by creating your own type for the list like so:

正如@Saint 所提到的,您可以通过为列表创建自己的类型来规避这一点,如下所示:

class TestSList extends ArrayList<TestS> { }

and then modifying your controller signature to

然后将您的控制器签名修改为

public @ResponseBody ModelMap setTest(@RequestBody TestSList refunds, ModelMap map) {

回答by Deepak

@RequestMapping(
         value="person", 
         method=RequestMethod.POST,
         consumes="application/json",
         produces="application/json")
@ResponseBody
public List<String> savePerson(@RequestBody Person[] personArray) {
    List<String> response = new ArrayList<String>();
    for (Person person: personArray) {
        personService.save(person);
        response.add("Saved person: " + person.toString());
    }
    return response;
}

We can use Array as shown above.

我们可以使用如上所示的 Array。

回答by Jis Mathew

I believe this will solve the issue

我相信这将解决问题

var z = '[{"name":"1","age":"2"},{"name":"1","age":"3"}]';
z = JSON.stringify(JSON.parse(z));
$.ajax({
    url: "/setTest",
    data: z,
    type: "POST",
    dataType:"json",
    contentType:'application/json'               
});

回答by Pratik Goenka

For me below code worked, first sending json string with proper headers

对我来说,下面的代码有效,首先发送带有正确标题的 json 字符串

$.ajax({
        type: "POST",
        url : 'save',
        data : JSON.stringify(valObject),
        contentType:"application/json; charset=utf-8",
        dataType:"json",
        success : function(resp){
            console.log(resp);
        },
        error : function(resp){
            console.log(resp);
        }
    });

And then on Spring side -

然后在春天方面 -

@RequestMapping(value = "/save", 
                method = RequestMethod.POST,
                consumes="application/json")
public @ResponseBody String  save(@RequestBody ArrayList<KeyValue> keyValList) {
    //Saving call goes here
    return "";
}

Here KeyValue is simple pojo that corresponds to your JSON structure also you can add produces as you wish, I am simply returning string.

这里 KeyValue 是一个简单的 pojo,对应于您的 JSON 结构,您也可以根据需要添加产品,我只是返回字符串。

My json object is like this -

我的 json 对象是这样的 -

[{"storedKey":"vc","storedValue":"1","clientId":"1","locationId":"1"},
 {"storedKey":"vr","storedValue":"","clientId":"1","locationId":"1"}]

回答by AmitG

Solution works very well,

解决方案效果很好,

public List<String> savePerson(@RequestBody Person[] personArray)  

For this signature you can pass Personarray from postman like

对于此签名,您可以Person从邮递员传递数组,例如

[
{
  "empId": "10001",
  "tier": "Single",
  "someting": 6,
  "anything": 0,
  "frequency": "Quaterly"
}, {
  "empId": "10001",
  "tier": "Single",
  "someting": 6,
  "anything": 0,
  "frequency": "Quaterly"
}
]

Don't forget to add consumestag:

不要忘记添加consumes标签:

@RequestMapping(value = "/getEmployeeList", method = RequestMethod.POST, consumes="application/json", produces = "application/json")
public List<Employee> getEmployeeDataList(@RequestBody Employee[] employeearray) { ... }