Spring MVC控制器中的JSON参数

Ste*_*nko 27 java spring json spring-mvc

我有

@RequestMapping(method = RequestMethod.GET)
@ResponseBody
SessionInfo register(UserProfile profileJson){
  ...
}
Run Code Online (Sandbox Code Playgroud)

我以这种方式传递profileJson:

http://server/url?profileJson={"email": "mymail@gmail.com"}
Run Code Online (Sandbox Code Playgroud)

但我的profileJson对象具有所有空字段.我该怎么办才能让春天解析我的json?

The*_*int 30

这个解决方案非常容易和简单,实际上会让你发笑,但在我开始讨论之前,让我首先强调一点,没有自尊的Java开发人员,我的意思是在不使用Jackson的情况下使用JSON.性能JSON库.

Jackson不仅是Java工作者和Java开发人员的事实JSON库,它还提供了一整套API调用,使JSON与Java的集成变得轻而易举(您可以在http://jackson.codehaus下载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...
}
Run Code Online (Sandbox Code Playgroud)

...然后你的Spring MVC方法转换一个GET参数名称"profileJson",其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.
}
Run Code Online (Sandbox Code Playgroud)

巴姆!你完成了.我鼓励你仔细研究一下Jackson API,因为正如我所说,它是一个救星.例如,您是否从控制器返回JSON?如果是这样,您需要做的就是在您的lib中包含JSON,并返回您的POJO,Jackson将自动将其转换为JSON.你不可能比这更容易.干杯! :-)

  • 实际上,这是不正确的.首先,我假设"field"是指控制器类的实例变量.其次,我的例子的目的是演示ObjectMapper的使用,而不是提供最佳实践并深入研究对象实例化的更精细的架构细节.第三,最重要的是,将ObjectMapper作为控制器的实例变量只是简单的坏习惯,因为Spring控制器默认是单例.正确的方法是遵循标准MVC模式并自动装配包含ObjectMapper的服务类. (6认同)
  • 为每个请求创建ObjectMapper都不是一个好习惯.控制器应该有字段ObjectMapper. (3认同)
  • 创建一个`Converter`并让Spring MVC自动使用它会更优雅(也许效率更高)。有关示例,请参见我的[answer](/sf/answers/3524529991/)。 (2认同)

Ang*_*ity 26

这可以使用自定义编辑器完成,该编辑器将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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

@InitBinder
public void initBinder(WebDataBinder binder) {
    binder.registerCustomEditor(UserProfile.class, new UserProfileEditor());
}
Run Code Online (Sandbox Code Playgroud)

这是如何使用编辑器来解组JSONP参数:

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

  • 将此添加到调度程序servlet xml为我工作'<mvc:annotation-driven> <mvc:message-converters> <bean class ="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/> </ mvc:message-转换器> </ mvc:annotation-driven>' (3认同)

dea*_*mon 5

您可以创建自己的Converter并让 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

正如您在以下控制器方法中看到的那样,不需要什么特别的:

@GetMapping
@ResponseBody
public SessionInfo register(@RequestParam UserProfile userProfile)  {
  ...
}
Run Code Online (Sandbox Code Playgroud)

如果您使用组件扫描并使用@Component.

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