【问题标题】:Spring MVC, deserialize single JSON?Spring MVC,反序列化单个 JSON?
【发布时间】:2012-02-15 07:05:08
【问题描述】:

如何轻松分离在同一请求中发送的 JSON 值?

鉴于我将 JSON 发布到我的服务器:

{"first":"A","second":"B"}

如果我在Controller中实现以下方法:

@RequestMapping(value = "/path", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
public void handleRequest(@RequestBody String input) { 
    // ...
}

那么input 参数将与整个JSON 对象{"first":"A","second":"B"} 构成一个字符串。我真正想要的是两个单独的字符串(或一个字符串和一个适合特定请求的整数),只有两个值(客户端可能发送的其他键/值对应该被忽略)。

如果字符串是作为请求参数而不是 JSON 请求正文发送的,那就很简单了:

@RequestMapping(value = "/path", method = RequestMethod.POST)
public void handleRequest(@RequestParam("first") String first, 
                          @RequestParam("second") String second) { 
    // ...
}

我知道我可以创建一个简单的 bean 类,它可以与 @RequestBody 注释结合使用,使用时将包含 AB,但这似乎是一个弯路,因为它们将有网络应用内的不同用途。

依赖关系: org.springframework:spring-web:3.1.0.RELEASE org.codehaus.jackson:杰克逊-映射器-asl:1.9.3

【问题讨论】:

    标签: java json spring spring-mvc jackson


    【解决方案1】:

    POJO

    public class Input {
        private String first;
        private String second;
    
        //getters/setters
    }
    

    ...然后:

    public void handleRequest(@RequestBody Input input)
    

    在这种情况下,您需要 Jackson 在 CLASSPATH 上可用。

    地图

    public void handleRequest(@RequestBody Map<String, String> input)
    

    【讨论】:

    • POJO 对应于我建议的 bean 类解决方案(我应该写在问题中)。地图可能是一个可行的解决方案...
    • 我建议使用 JsonNode 作为中间类型,而不是 Map。没什么大不了的,只是更方便、更安全。
    • JsonNode 看起来很有趣,特别是如果您需要将输入转换为字符串以外的其他类型,或者如果 JSON 结构比一级键/值映射更复杂。
    • 如果您有两个扩展超类型的子类型类怎么办?我假设您不能将父类放在 requestmapping 方法参数中?
    【解决方案2】:

    我已经写了一个自定义的WebArgumentResolver 来做这个,并结合了一个自定义的注解。

    我现在没有可用的源代码,但基本上我是这样注释我的方法的:

    @RequestMapping(value = "/path", method = RequestMethod.POST)
    public void handleRequest(@JsonField("first") String first, @JsonField("second") String second) { 
        // ...
    }
    

    然后我的JsonFieldWebArgumentResolver 检查方法参数是否使用JsonField 进行注释,如果是,它会从参数中提取实际类型(如果您还想处理泛型参数,结果不是很直接,例如List&lt;String&gt;List&lt;Pojo&gt;),并手动调用Jackson 的JsonParser 以创建正确的类型。很遗憾我不能向你展示任何代码,但这就是它的要点。

    然而,该解决方案适用于 Spring MVC 3.0,如果您使用的是 3.1,我认为您最好使用自定义HandlerMethodArgumentResolver 代替。但是思路应该是一样的。

    【讨论】:

    • 优雅。像您的 @JsonField 这样的注释将非常适合我的问题。我特别喜欢让它通用的想法,但我必须阅读这个主题和@StaxMan 评论过的JsonNode API。然而,客户目前发布了非常简单的键/值字符串,所以我很难激发额外的成本。我一定会记住这个建议。
    猜你喜欢
    • 1970-01-01
    • 2015-07-11
    • 2012-01-03
    • 1970-01-01
    • 2015-10-02
    • 2023-04-10
    • 1970-01-01
    • 1970-01-01
    • 2019-08-06
    相关资源
    最近更新 更多