弹簧MVC控制器中的JSON参数

2022-09-01 09:38:16

我有

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

我以这种方式传递配置文件Json:

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

但是我的 profileJson 对象具有所有空字段。我该怎么做才能让spring解析我的json?


答案 1

解决这个问题是如此简单明了,它实际上会让你发笑,但在我开始之前,让我首先强调一下,没有一个有自尊心的Java开发人员会这样做,我的意思是永远不要使用JSON而不使用Jackson高性能JSON库。

Jackson 不仅是 Java 开发人员的工作马和事实上的 JSON 库,而且还提供了一整套 API 调用,使 JSON 与 Java 的集成变得轻而易举(您可以在 http://jackson.codehaus.org/ 下载 Jackson)。

现在来看看答案。假设您有一个如下所示的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...
}

...然后,您的Spring MVC方法将GET参数名称“profileJson”转换为JSON,JSON值为{“email”:“mymail@gmail.com”},在您的控制器中将如下所示:

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.
}

砰!大功告成。我鼓励你浏览一下 Jackson API 的大部分内容,因为正如我所说,它是一个救命稻草。例如,您是否从控制器返回 JSON?如果是这样,您需要做的就是在库中包含JSON,然后返回您的POJO,Jackson会自动将其转换为JSON。没有比这更容易的了。干杯!:-)


答案 2

这可以通过自定义编辑器来完成,该编辑器将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);
    }
}

这是为了在控制器类中注册编辑器:

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

这就是如何使用编辑器来取消JSONP参数的marshall:

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