Jackson报错org.codehaus.jackson.map.JsonMappingException
来源:互联网 发布:java创建pdf文件 编辑:程序博客网 时间:2024/04/25 12:28
在使用Spring MVC + Jackson-1.9.12时报的一个异常,本文暂时也只是描述一下如何绕开这个异常,并简单说明一下出错原因。希望如果有大神碰巧看过这个问题,不吝赐教。
异常详细描述
主要是Jackson的异常:
org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: No serializer found for class org.springframework.validation.DefaultMessageCodesResolver and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: org.springframework.validation.support.BindingAwareModelMap["org.springframework.validation.BindingResult.GStation"]->org.springframework.validation.BeanPropertyBindingResult["messageCodesResolver"]); nested exception is org.codehaus.jackson.map.JsonMappingException: No serializer found for class org.springframework.validation.DefaultMessageCodesResolver and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: org.springframework.validation.support.BindingAwareModelMap["org.springframework.validation.BindingResult.GStation"]->org.springframework.validation.BeanPropertyBindingResult["messageCodesResolver"])org.springframework.http.converter.json.MappingJacksonHttpMessageConverter.writeInternal(MappingJacksonHttpMessageConverter.java:194)org.springframework.http.converter.AbstractHttpMessageConverter.write(AbstractHttpMessageConverter.java:179)org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter$ServletHandlerMethodInvoker.writeWithMessageConverters(AnnotationMethodHandlerAdapter.java:1037)org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter$ServletHandlerMethodInvoker.handleResponseBody(AnnotationMethodHandlerAdapter.java:995)org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter$ServletHandlerMethodInvoker.getModelAndView(AnnotationMethodHandlerAdapter.java:944)org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:441)org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:428)org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:838)javax.servlet.http.HttpServlet.service(HttpServlet.java:710)org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)javax.servlet.http.HttpServlet.service(HttpServlet.java:803)org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
因为使用Spring MVC框架控制器处理请求,所以同时会报Spring的异常:
org.codehaus.jackson.map.JsonMappingException: No serializer found for class org.springframework.validation.DefaultMessageCodesResolver and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: org.springframework.validation.support.BindingAwareModelMap["org.springframework.validation.BindingResult.GStation"]->org.springframework.validation.BeanPropertyBindingResult["messageCodesResolver"])org.codehaus.jackson.map.ser.impl.UnknownSerializer.failForEmpty(UnknownSerializer.java:52)org.codehaus.jackson.map.ser.impl.UnknownSerializer.serialize(UnknownSerializer.java:25)org.codehaus.jackson.map.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:446)org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:150)org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:112)org.codehaus.jackson.map.ser.std.MapSerializer.serializeFields(MapSerializer.java:262)org.codehaus.jackson.map.ser.std.MapSerializer.serialize(MapSerializer.java:186)org.codehaus.jackson.map.ser.std.MapSerializer.serialize(MapSerializer.java:23)org.codehaus.jackson.map.ser.StdSerializerProvider._serializeValue(StdSerializerProvider.java:610)org.codehaus.jackson.map.ser.StdSerializerProvider.serializeValue(StdSerializerProvider.java:256)org.codehaus.jackson.map.ObjectMapper.writeValue(ObjectMapper.java:1613)org.springframework.http.converter.json.MappingJacksonHttpMessageConverter.writeInternal(MappingJacksonHttpMessageConverter.java:191)org.springframework.http.converter.AbstractHttpMessageConverter.write(AbstractHttpMessageConverter.java:179)org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter$ServletHandlerMethodInvoker.writeWithMessageConverters(AnnotationMethodHandlerAdapter.java:1037)org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter$ServletHandlerMethodInvoker.handleResponseBody(AnnotationMethodHandlerAdapter.java:995)org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter$ServletHandlerMethodInvoker.getModelAndView(AnnotationMethodHandlerAdapter.java:944)org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:441)org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:428)org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:838)javax.servlet.http.HttpServlet.service(HttpServlet.java:710)org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)javax.servlet.http.HttpServlet.service(HttpServlet.java:803)org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
代码
前台代码使用jQuery的ajax异步调用,代码中利用Spring MVC可以直接将data数据赋值到pojo对象属性中。
$.ajax({ type : "post", url : "/businesssite/updStation", data : station, dataType : "json", success : function(data) { if(data && data.msg == "s") { alert("成功"); } else { alert("失败"); } }, error : function(e) { alert("错误:" + e.responseText); }});
后台代码Spring MVC的注解定义控制器请求路径及参数,station为需要获取ajax参数的对象,map为需要返回的对象(此处的map默认情况下会是Spring定义的BindingAwareModelMap的实例,Map、Model、ModelMap都是一样的。但由于Model接口没有clear方法,会影响其中一种处理bug的方法,下面会讲到。)
@RequestMapping(value = "/updStation", method = POST)@ResponseBodypublic Map<String, Object> updStation(GStation station, Map<String, Object> map) { try { log.debug(station); map.put("msg", "s"); } catch (Exception e) { log.error(e.getMessage(), e); map.put("msg", "e"); } return map;}
此时就会报出本文开头提到的异常。
现象
通过打断点,查看进入控制器的方法中各个对象实例的状态,发现正常程序与异常程序之间的区别:
- 把自定义类换成Java自带的封装类都能够正确运行;
- 当程序正常运行时,map是空的(不是null)。而异常程序的map包含两个值,一个是GStation对象的值,一个是org.springframework.validation.BindingResult.GStation=org.springframework.validation.BeanPropertyBindingResult: 0 errors。
有图为证:
1. 出现异常的代码中map或model的值
2. 未出现异常的代码中map或model的值
因此做出大胆假设,出错的原因是ajax传递多值至对象中时,Spring MVC会在map里面增加两个值(一个是传输的数据对象,一个是对于对象属性绑定的验证结果),而这两个值是Jackson将map处理成json格式时出错 。通过Spring文档中的内容也验证了这一说法,内容如下:
Command or form objects to bind request parameters to bean properties (via setters) or directly to fields, with customizable type conversion, depending on@InitBinder
methods and/or the HandlerAdapter configuration. See thewebBindingInitializer
property on RequestMappingHandlerAdapter
. Such command objects along with their validation results will be exposed as model attributes by default, using the command class class name - e.g. model attribute "orderAddress" for a command object of type "some.package.OrderAddress". The ModelAttribute
annotation can be used on a method argument to customize the model attribute name used.
所以,只要map是空的(非null)就行了。
解决办法
既然找到了解决思路,那方法就有多种了:
通过map.clear()方法将map清空(此方法适用于Map及MedalMap);
@RequestMapping(value = "/updStation", method = POST)@ResponseBodypublic Map<String, Object> updStation(GStation station, Map<String, Object> map) { map.clear(); try { log.debug(station); map.put("msg", "s"); } catch (Exception e) { log.error(e.getMessage(), e); map.put("msg", "e"); } return map;}
不需要Spring帮忙创建map,自己new一个。
@RequestMapping(value = "/updStation", method = POST)@ResponseBodypublic Map<String, Object> updStation(GStation station) { Map<String, Object> map = new HashMap<String, Object>(); try { log.debug(station); map.put("msg", "s"); } catch (Exception e) { log.error(e.getMessage(), e); map.put("msg", "e"); } return map;}
注:Spring MVC帮助定义的对象是BindingAwareModelMap,通过源码或API可以知道,这个类是LinkedHashMap的子类,也算是HashMap的子类,所以这的地方创建HashMap对象不算错。
后语
这个异常开始的时候感觉是Jackson的异常,但是起因似乎还是Spring MVC。在Map中多出的数据是Spring MVC对于向对象中赋值时增加的校验信息,当这些校验信息提交给Jackson时,Jackson无法将其转换成json数据,所以报出异常。
如果有大神路过,跪求指正。
- Jackson报错org.codehaus.jackson.map.JsonMappingException
- springmvc+hibernate时Jackson报错org.codehaus.jackson.map.JsonMappingException
- hadoop出现ava.lang.ClassNotFoundException: org.codehaus.jackson.map.JsonMappingException
- org.codehaus.jackson.map.JsonMappingException: No serializer found for class
- org.codehaus.jackson.map.JsonMappingException: Can not deserialize
- org.codehaus.jackson.map.JsonMappingException: Infinite recursion的解决
- 项目启动报错.NoClassDefFoundError: org/codehaus/jackson/map/ObjectMapper
- org.codehaus.jackson.map.JsonMappingException: No serializer found for class org.hibernate.proxy....
- HTTP请求数据返回解析Josn org.codehaus.jackson.map.JsonMappingException的解决方法
- org.codehaus.jackson.map.JsonMappingException: No suitable constructor found for type [si
- org.codehaus.jackson.map.JsonMappingException: Can not deserialize instance of java.util.ArrayList o
- springmvc返回json报错:java.lang.NoSuchMethodError: org.codehaus.jackson.map.SerializationConfig.isEnable
- jackson转化报jsonMappingException
- Hive报错java.lang.NoClassDefFoundError: org/codehaus/jackson/JsonFactory
- 解决org.codehaus.jackson.annotate.JsonUnwrapped报错的问题
- 包引用冲突 Jackson : NoSuchMethodError for org.codehaus.jackson.map...
- Could not find class 'org.codehaus.jackson.map.MappingJsonFactory'
- org.codehaus.jackson.map包下的ObjectMapper类源码
- 对java泛型的理解
- 读《Boost程序库完全开发指南》
- java中Servlet之域对象
- eclipse 与J2ee
- openMP的一点使用经验
- Jackson报错org.codehaus.jackson.map.JsonMappingException
- 人工智能领域会议总结
- 2014-07-05 日志
- Joining an array of keys to a hash with key value pairs like excel vlookup
- 西红柿炒鸡蛋
- windows下启动和关闭mysql数据库服务
- 显示scrollview时对滚动条进行任意位置的定位
- Android解析获取网络上的图片(支持bmp格式)
- 使用SDWebImage