spring MVC控制器中的JSON参数

时间:2021-08-26 18:03:00

I have

我有

@RequestMapping(method = RequestMethod.GET)
@ResponseBody
SessionInfo register(UserProfile profileJson){
  ...
}

I pass profileJson this way:

我通过以下方式传递profileJson:

http://server/url?profileJson={"email": "mymail@gmail.com"}

but my profileJson object has all null fields. What should I do to make spring parse my json?

但是我的profileJson对象拥有所有空字段。如何让spring解析json?

5 个解决方案

#1


25  

This could be done with a custom editor, that converts the JSON into a UserProfile object:

这可以通过自定义编辑器完成,该编辑器将JSON转换为UserProfile对象:

public class UserProfileEditor extends PropertyEditorSupport  {

    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        ObjectMapper mapper = new ObjectMapper();

        UserProfile value = null;

        try {
            value = new UserProfile();
            JsonNode root = mapper.readTree(text);
            value.setEmail(root.path("email").asText());
        } catch (IOException e) {
            // handle error
        }

        setValue(value);
    }
}

This is for registering the editor in the controller class:

这是用于在控制器类中注册编辑器:

@InitBinder
public void initBinder(WebDataBinder binder) {
    binder.registerCustomEditor(UserProfile.class, new UserProfileEditor());
}

And this is how to use the editor, to unmarshall the JSONP parameter:

这就是如何使用编辑器,解调JSONP参数:

@RequestMapping(value = "/jsonp", method = RequestMethod.GET, produces = {MediaType.APPLICATION_JSON_VALUE})
@ResponseBody
SessionInfo register(@RequestParam("profileJson") UserProfile profileJson){
  ...
}

#2


30  

The solution to this is so easy and simple it will practically make you laugh, but before I even get to it, let me first emphasize that no self-respecting Java developer would ever, and I mean EVER work with JSON without utilizing the Jackson high-performance JSON library.

解决这一问题的方法是如此简单和简单,它实际上会让你发笑,但在我开始之前,让我先强调一下,没有一个有自尊的Java开发人员会,而且我的意思是,在没有使用Jackson高性能JSON库的情况下使用JSON。

Jackson is not only a work horse and a defacto JSON library for Java developers, but it also provides a whole suite of API calls that makes JSON integration with Java a piece of cake (you can download Jackson at http://jackson.codehaus.org/).

Jackson不仅是Java开发人员的工作机器和实际的JSON库,而且它还提供一整套API调用,使JSON与Java集成成为轻而易举的事情(您可以从http://jackson.codehaus.org/下载Jackson)。

Now for the answer. Assuming that you have a UserProfile pojo that looks something like this:

现在的答案。假设有一个UserProfile pojo,它看起来是这样的:

public class UserProfile {

private String email;
// etc...

public String getEmail() {
    return email;
}

public void setEmail(String email) {
    this.email = email;
}

// more getters and setters...
}

...then your Spring MVC method to convert a GET parameter name "profileJson" with JSON value of {"email": "mymail@gmail.com"} would look like this in your controller:

…然后您的Spring MVC方法将一个GET参数名称“profileJson”转换为JSON值为{“email”:“mymail@gmail.com”}的GET参数名称“profileJson”在您的控制器中会是这样的:

import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper; // this is your lifesaver right here

//.. your controller class, blah blah blah

@RequestMapping(value="/register", method = RequestMethod.GET) 
public SessionInfo register(@RequestParam("profileJson") String profileJson) 
throws JsonMappingException, JsonParseException, IOException {

    // now simply convert your JSON string into your UserProfile POJO 
    // using Jackson's ObjectMapper.readValue() method, whose first 
    // parameter your JSON parameter as String, and the second 
    // parameter is the POJO class.

    UserProfile profile = 
            new ObjectMapper().readValue(profileJson, UserProfile.class);

        System.out.println(profile.getEmail());

        // rest of your code goes here.
}

Bam! You're done. I would encourage you to look through the bulk of Jackson API because, as I said, it is a lifesaver. For example, are you returning JSON from your controller at all? If so, all you need to do is include JSON in your lib, and return your POJO and Jackson will AUTOMATICALLY convert it into JSON. You can't get much easier than that. Cheers! :-)

砰!你就完成了。我鼓励大家浏览一下Jackson API的大部分内容,因为正如我所说,它是一个救命稻草。例如,是否从控制器返回JSON ?如果是这样,您只需在库中包含JSON,然后返回POJO, Jackson将自动将其转换为JSON。再简单不过了。干杯!:-)

#3


1  

This does solve my immediate issue, but I'm still curious as to how you might pass in multiple JSON objects via an AJAX call.

这确实解决了我眼前的问题,但我仍然对如何通过AJAX调用传入多个JSON对象感到好奇。

The best way to do this is to have a wrapper object that contains the two (or multiple) objects you want to pass. You then construct your JSON object as an array of the two objects i.e.

最好的方法是拥有一个包含您想要传递的两个(或多个)对象的包装器对象。然后,将JSON对象构建为两个对象的数组,即

[
  {
    "name" : "object1",
    "prop1" : "foo",
    "prop2" : "bar"
  },
  {
    "name" : "object2",
    "prop1" : "hello",
    "prop2" : "world"
  }
]

Then in your controller method you recieve the request body as a single object and extract the two contained objects. i.e:

然后在控制器方法中,您将请求体作为一个对象接收并提取两个包含的对象。即:

@RequestMapping(value="/handlePost", method = RequestMethod.POST, consumes = {      "application/json" })
public void doPost(@RequestBody WrapperObject wrapperObj) { 
     Object obj1 = wrapperObj.getObj1;
     Object obj2 = wrapperObj.getObj2;

     //Do what you want with the objects...


}

The wrapper object would look something like...

包装器对象看起来像……

public class WrapperObject {    
private Object obj1;
private Object obj2;

public Object getObj1() {
    return obj1;
}
public void setObj1(Object obj1) {
    this.obj1 = obj1;
}
public Object getObj2() {
    return obj2;
}
public void setObj2(Object obj2) {
    this.obj2 = obj2;
}   

}

#4


-1  

You can create your own Converter and let Spring use it automatically where appropriate:

您可以创建自己的转换器,让Spring在适当的时候自动使用它:

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;

@Component
class JsonToUserProfileConverter implements Converter<String, UserProfile> {

    private final ObjectMapper jsonMapper = new ObjectMapper();

    public UserProfile convert(String source) {
        return jsonMapper.readValue(source, UserProfile.class);
    }
}

As you can see in the following controller method nothing special is needed:

正如您在下面的控制器方法中看到的,不需要任何特殊的东西:

@GetMapping
@ResponseBody
public SessionInfo register(@RequestParam UserProfile userProfile)  {
  ...
}

Spring picks up the converter automatically if your using component scanning and annotate the converter class with @Component.

如果您使用组件扫描并使用@Component注释转换器类,Spring会自动选择转换器。

Learn more about Spring Converter and type conversions in Spring MVC.

了解有关Spring MVC中的Spring转换器和类型转换的更多信息。

#5


-5  

Just add @RequestBody annotation before this param

只需在此参数之前添加@RequestBody注释

#1


25  

This could be done with a custom editor, that converts the JSON into a UserProfile object:

这可以通过自定义编辑器完成,该编辑器将JSON转换为UserProfile对象:

public class UserProfileEditor extends PropertyEditorSupport  {

    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        ObjectMapper mapper = new ObjectMapper();

        UserProfile value = null;

        try {
            value = new UserProfile();
            JsonNode root = mapper.readTree(text);
            value.setEmail(root.path("email").asText());
        } catch (IOException e) {
            // handle error
        }

        setValue(value);
    }
}

This is for registering the editor in the controller class:

这是用于在控制器类中注册编辑器:

@InitBinder
public void initBinder(WebDataBinder binder) {
    binder.registerCustomEditor(UserProfile.class, new UserProfileEditor());
}

And this is how to use the editor, to unmarshall the JSONP parameter:

这就是如何使用编辑器,解调JSONP参数:

@RequestMapping(value = "/jsonp", method = RequestMethod.GET, produces = {MediaType.APPLICATION_JSON_VALUE})
@ResponseBody
SessionInfo register(@RequestParam("profileJson") UserProfile profileJson){
  ...
}

#2


30  

The solution to this is so easy and simple it will practically make you laugh, but before I even get to it, let me first emphasize that no self-respecting Java developer would ever, and I mean EVER work with JSON without utilizing the Jackson high-performance JSON library.

解决这一问题的方法是如此简单和简单,它实际上会让你发笑,但在我开始之前,让我先强调一下,没有一个有自尊的Java开发人员会,而且我的意思是,在没有使用Jackson高性能JSON库的情况下使用JSON。

Jackson is not only a work horse and a defacto JSON library for Java developers, but it also provides a whole suite of API calls that makes JSON integration with Java a piece of cake (you can download Jackson at http://jackson.codehaus.org/).

Jackson不仅是Java开发人员的工作机器和实际的JSON库,而且它还提供一整套API调用,使JSON与Java集成成为轻而易举的事情(您可以从http://jackson.codehaus.org/下载Jackson)。

Now for the answer. Assuming that you have a UserProfile pojo that looks something like this:

现在的答案。假设有一个UserProfile pojo,它看起来是这样的:

public class UserProfile {

private String email;
// etc...

public String getEmail() {
    return email;
}

public void setEmail(String email) {
    this.email = email;
}

// more getters and setters...
}

...then your Spring MVC method to convert a GET parameter name "profileJson" with JSON value of {"email": "mymail@gmail.com"} would look like this in your controller:

…然后您的Spring MVC方法将一个GET参数名称“profileJson”转换为JSON值为{“email”:“mymail@gmail.com”}的GET参数名称“profileJson”在您的控制器中会是这样的:

import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper; // this is your lifesaver right here

//.. your controller class, blah blah blah

@RequestMapping(value="/register", method = RequestMethod.GET) 
public SessionInfo register(@RequestParam("profileJson") String profileJson) 
throws JsonMappingException, JsonParseException, IOException {

    // now simply convert your JSON string into your UserProfile POJO 
    // using Jackson's ObjectMapper.readValue() method, whose first 
    // parameter your JSON parameter as String, and the second 
    // parameter is the POJO class.

    UserProfile profile = 
            new ObjectMapper().readValue(profileJson, UserProfile.class);

        System.out.println(profile.getEmail());

        // rest of your code goes here.
}

Bam! You're done. I would encourage you to look through the bulk of Jackson API because, as I said, it is a lifesaver. For example, are you returning JSON from your controller at all? If so, all you need to do is include JSON in your lib, and return your POJO and Jackson will AUTOMATICALLY convert it into JSON. You can't get much easier than that. Cheers! :-)

砰!你就完成了。我鼓励大家浏览一下Jackson API的大部分内容,因为正如我所说,它是一个救命稻草。例如,是否从控制器返回JSON ?如果是这样,您只需在库中包含JSON,然后返回POJO, Jackson将自动将其转换为JSON。再简单不过了。干杯!:-)

#3


1  

This does solve my immediate issue, but I'm still curious as to how you might pass in multiple JSON objects via an AJAX call.

这确实解决了我眼前的问题,但我仍然对如何通过AJAX调用传入多个JSON对象感到好奇。

The best way to do this is to have a wrapper object that contains the two (or multiple) objects you want to pass. You then construct your JSON object as an array of the two objects i.e.

最好的方法是拥有一个包含您想要传递的两个(或多个)对象的包装器对象。然后,将JSON对象构建为两个对象的数组,即

[
  {
    "name" : "object1",
    "prop1" : "foo",
    "prop2" : "bar"
  },
  {
    "name" : "object2",
    "prop1" : "hello",
    "prop2" : "world"
  }
]

Then in your controller method you recieve the request body as a single object and extract the two contained objects. i.e:

然后在控制器方法中,您将请求体作为一个对象接收并提取两个包含的对象。即:

@RequestMapping(value="/handlePost", method = RequestMethod.POST, consumes = {      "application/json" })
public void doPost(@RequestBody WrapperObject wrapperObj) { 
     Object obj1 = wrapperObj.getObj1;
     Object obj2 = wrapperObj.getObj2;

     //Do what you want with the objects...


}

The wrapper object would look something like...

包装器对象看起来像……

public class WrapperObject {    
private Object obj1;
private Object obj2;

public Object getObj1() {
    return obj1;
}
public void setObj1(Object obj1) {
    this.obj1 = obj1;
}
public Object getObj2() {
    return obj2;
}
public void setObj2(Object obj2) {
    this.obj2 = obj2;
}   

}

#4


-1  

You can create your own Converter and let Spring use it automatically where appropriate:

您可以创建自己的转换器,让Spring在适当的时候自动使用它:

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;

@Component
class JsonToUserProfileConverter implements Converter<String, UserProfile> {

    private final ObjectMapper jsonMapper = new ObjectMapper();

    public UserProfile convert(String source) {
        return jsonMapper.readValue(source, UserProfile.class);
    }
}

As you can see in the following controller method nothing special is needed:

正如您在下面的控制器方法中看到的,不需要任何特殊的东西:

@GetMapping
@ResponseBody
public SessionInfo register(@RequestParam UserProfile userProfile)  {
  ...
}

Spring picks up the converter automatically if your using component scanning and annotate the converter class with @Component.

如果您使用组件扫描并使用@Component注释转换器类,Spring会自动选择转换器。

Learn more about Spring Converter and type conversions in Spring MVC.

了解有关Spring MVC中的Spring转换器和类型转换的更多信息。

#5


-5  

Just add @RequestBody annotation before this param

只需在此参数之前添加@RequestBody注释