Jon*_*ahl 9 java spring json spring-mvc jackson
我正在尝试构建一个Spring MVC控制器,它将接收带有JSON格式参数的POSTed表单,并让Spring自动将其转换为Java对象.
application/x-www-form-urlencodeddata.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";
}
}
Run Code Online (Sandbox Code Playgroud)
这就是MyMessage对象的样子:
public class MyMessage {
private String id;
// Getter/setter omitted for brevity
}
Run Code Online (Sandbox Code Playgroud)
也许并不奇怪,发布带有参数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
Run Code Online (Sandbox Code Playgroud)
如果我正确读取MappingJackson2HttpMessageConverter文档,则由Content-Type触发Jackson JSON转换application/json,我显然无法使用,因为这是一个表单POST(我不控制POST部分).
是否有可能让Spring将JSON字符串转换为MyMessage的实例,或者我应该放弃,将其作为字符串读取并自己执行转换?
Sot*_*lis 18
Spring @RequestMapping使用反射调用您的方法.要解决它将传递给调用的每个参数,它使用的实现HandlerMethodArgumentResolver.对于带@RequestParam注释的参数,它使用RequestParamMethodArgumentResolver.此实现将请求参数绑定到单个对象,通常是一种String或某种Number类型.
但是,您的用例更为罕见.您很少收到json请求参数,这就是为什么我认为您应该重新考虑您的设计,但如果您没有其他选择,则需要注册一个自定义PropertyEditor,它将把请求参数的json值转换为您的自定义类型.
@InitBinder在您@Controller班级的注释方法中注册很简单
@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);
}
});
}
Run Code Online (Sandbox Code Playgroud)
在这种特殊情况下,我们不需要PropertyEditor接口的所有方法,因此我们可以使用PropertyEditorSupport哪个是有用的默认实现PropertyEditor.我们只需实现我们关心的两种方法,即使用我们想要的任何JSON解析器.我用过,Gson因为它可用.
当Spring看到它有你请求的请求参数时,它将检查参数类型,找到类型MyMessage并查找为该类型注册PropertyEditor的.它会找到它,因为我们注册了它,然后它将使用它来转换值.
您可能需要实现其他方法,PropertyEditor具体取决于您接下来要做什么.
我的建议是永远不要将JSON作为请求参数发送.将您的请求内容类型设置为application/json并发送json作为请求正文.然后用@RequestBody它来解析它.
小智 8
你也可以@RequestPart像这样使用:
@RequestMapping(value = "/issues", method = RequestMethod.POST, headers = "Content-Type=multipart/form-data")
public String uploadIssue(@RequestParam("image") MultipartFile file, @RequestPart("issue") MyMessage issue)
Run Code Online (Sandbox Code Playgroud)