Spring MVC 4.0中JSON表单参数的自动转换

2024-03-18

我正在尝试构建一个 Spring MVC 控制器,它将接收带有 JSON 格式参数的 POSTed 表单,并让 Spring 自动将其转换为 Java 对象。

  • 请求内容类型为application/x-www-form-urlencoded
  • 包含 JSON 字符串的参数名称为data.json

这是控制器:

@Controller
public class MyController {
    @RequestMapping(value = "/formHandler", method = RequestMethod.POST)
    public @ResponseBody String handleSubscription(
        @RequestParam("data.json") MyMessage msg) {
        logger.debug("id: " + msg.getId());
        return "OK";
    }
}

MyMessage 对象如下所示:

public class MyMessage {
    private String id;
    // Getter/setter omitted for brevity
}

也许并不奇怪,使用参数 data.json={"id":"Hello"} 发布表单会导致 HTTP 错误 500,但存在以下异常:

org.springframework.beans.ConversionNotSupportedException:
    Failed to convert value of type 'java.lang.String' to required type 'MyMessage' 
nested exception is java.lang.IllegalStateException:
    Cannot convert value of type [java.lang.String] to required type [MyMessage]: no matching editors or conversion strategy found

如果我读到MappingJackson2HttpMessageConverter 文档 http://docs.spring.io/spring/docs/4.0.x/javadoc-api/org/springframework/http/converter/json/MappingJackson2HttpMessageConverter.html正确的是,Jackson JSON 转换是由 Content-Type 触发的application/json,我显然无法使用它,因为这是一个表单 POST(并且我不控制 POSTing 部分)。

是否可以让 Spring 将 JSON 字符串转换为 MyMessage 的实例,或者我应该放弃,将其读取为字符串并自己执行转换?


Spring 调用你的@RequestMapping方法与反思。为了解析它将传递给调用的每个参数,它使用以下实现HandlerMethodArgumentResolver. For @RequestParam带注释的参数,它使用RequestParamMethodArgumentResolver。此实现将请求参数绑定到单个对象,通常是String或一些Number type.

但是,您的用例比较罕见。你很少收到json作为请求参数,这就是为什么我认为你应该重新考虑你的设计,但如果你别无选择,你需要注册一个自定义PropertyEditor这将负责转换请求参数的json值到您的自定义类型。

注册很简单@InitBinder你的注释方法@Controller class

@InitBinder
public void initBinder(WebDataBinder dataBinder) {
    dataBinder.registerCustomEditor(MyMessage.class, new PropertyEditorSupport() {
        Object value;
        @Override
        public Object getValue() {
            return value;
        }

        @Override
        public void setAsText(String text) throws IllegalArgumentException {
            value = new Gson().fromJson((String) text, MyMessage.class);
        }
    });
}

在这种特殊情况下,我们不需要所有的方法PropertyEditor接口,所以我们可以使用PropertyEditorSupport这是一个有用的默认实现PropertyEditor。我们只需使用我们想要的 JSON 解析器来实现我们关心的两个方法。我用了Gson因为它是可用的。

当Spring发现有你请求的请求参数时,它会检查参数类型,找到类型MyMessage并寻找已注册的PropertyEditor对于那种类型。它会找到它,因为我们注册了它,然后它会使用它来转换值。

您可能需要实现其他方法PropertyEditor取决于你接下来要做什么。

我的建议是永远不要将 JSON 作为请求参数发送。将您的请求内容类型设置为application/json并发送json作为请求的正文。然后使用@RequestBody来解析它。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring MVC 4.0中JSON表单参数的自动转换 的相关文章

随机推荐