在Spring MVC 4.0中自动转换JSON表单参数 [英] Automatic conversion of JSON form parameter in Spring MVC 4.0

查看:699
本文介绍了在Spring MVC 4.0中自动转换JSON表单参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to build a Spring MVC controller which will receive a POSTed form with a parameter in JSON format, and have Spring automatically convert it to a Java object.


  • 请求内容类型为 application / x-www-form-urlencoded

  • 参数名称包含JSON字符串的是 data.json

  • Request content type is application/x-www-form-urlencoded
  • The name of the parameter that contains a JSON string is 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对象的样子: / p>

And this is what the MyMessage object looks like:

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

也许并不奇怪,发布带有参数data.json = {id:Hello}的表单会导致HTTP错误500,并出现此异常:

Perhaps not surprisingly, posting a form with parameter data.json={"id":"Hello"} results in HTTP error 500 with this exception:

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 docs 正确,Jackson JSON转换由Content-Type application / json 触发,我显然无法使用,因为这是一个表单POST (和我不控制POSTing部分。)

If I read the MappingJackson2HttpMessageConverter docs correctly, Jackson JSON conversion is triggered by Content-Type application/json, which I obviously cannot use since this is a form POST (and I don't control the POSTing part).

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

Is it possible to get Spring to convert the JSON string into an instance of MyMessage, or should I just give up, read it as a String and perform the conversion myself?

推荐答案

Spring调用你的 @RequestMapping 带反射的方法。要解析它将传递给调用的每个参数,它使用 HandlerMethodArgumentResolver 的实现。对于 @RequestParam 带注释的参数,它使用 RequestParamMethodArgumentResolver 。此实现将请求参数绑定到单个对象,通常是 String 或某些 Number 类型。

Spring invokes your @RequestMapping methods with reflection. To resolve each argument it's going to pass to the invocation, it uses implementations of HandlerMethodArgumentResolver. For @RequestParam annotated parameters, it uses RequestParamMethodArgumentResolver. This implementation binds a request parameter to a single object, typically a String or some Number type.

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

However, your use case is a little more rare. You rarely receive json as a request parameter, which is why I think you should re-think your design, but if you have no other choice, you need to register a custom PropertyEditor that will take care of converting the request parameter's json value into your custom type.

@Controller @InitBinder 带注释的方法中注册很简单c $ c> class

Registration is simple in an @InitBinder annotated method in your @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);
        }
    });
}

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

In this particular case, we don't need all the methods of the PropertyEditor interface, so we can use PropertyEditorSupport which is a helpful default implementation of PropertyEditor. We simply implement the two methods we care about using whichever flavor of JSON parser we want. I used Gson because it was available.

当Spring看到它有你请求的请求参数时,它将检查参数类型,找到类型 MyMessage 并查找该类型的已注册 PropertyEditor 。它会找到它,因为我们注册了它然后它会用它来转换它。

When Spring sees that it has a request parameter that you requested, it will check the parameter type, find the type MyMessage and look for a registered PropertyEditor for that type. It will find it because we registered it and it it will then use it to convert the value.

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

You might need to implement other methods of PropertyEditor depending on what you do next.

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

My recommendation is to never send JSON as a request parameter. Set your request content type to application/json and send the json as the body of the request. Then use @RequestBody to parse it.

这篇关于在Spring MVC 4.0中自动转换JSON表单参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆