首先说一下当时的场景,其实就是一个很简单的添加操作,后台传递的值是json格式的,如下图
,后台对应的实体类,
@Data @EqualsAndHashCode(callSuper = false) public class Route implements Serializable { private static final long serialVersionUID = 1L; /** * id */ private String id; /** * 设备id */ private String deviceId; /** * 路由地址 */ private String destNetwork; /** * 下一跳 */ private String nextHop; /** * 路由所属zone */ private String zone; /** * 0:系统解析;1:明细路由;2:假路由 */ private String isReload; /** * nat路由 */ private String isNatDummyRoute; private String createTime; /** * 是否禁用,主要适用于系统解析路由 */ private String isDisabled; @TableField(exist = false) private Device device; /** * 路由转化后的对象 */ @TableField(exist = false) private IpAddr ipAddr; }
后台对应的Controller中的代码
@RequestMapping(value = "add",method = RequestMethod.POST) public R add(@RequestBody Route route){ String deviceIp = route.getDeviceId(); Device device = deviceService.getByIp(deviceIp); Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String dateStr = sdf.format(date); route.setDeviceId(device.getId()); route.setIsDisabled("0"); route.setCreateTime(dateStr); routeService.save(route); return R.success(); }
,看代码可知,页面传递到后台的值应该能直接转成实体类Route对应的字段。但是并没有,报错信息是如下:
2020/09/28-10:52:00 WARN [http-nio-8999-exec-6] MappingJackson2HttpMessageConverter - Failed to evaluate Jackson deserialization for type [[simple type, class com.interact.firewall.base.biz.entity.Route]]: com.fasterxml.jackson.databind.JsonMappingException: Conflicting setter definitions for property "parent": com.interact.firewall.core.bean.service.Service#setParent(1 params) vs com.interact.firewall.core.bean.service.Service#setParent(1 params) 2020/09/28-10:52:00 WARN [http-nio-8999-exec-6] MappingJackson2HttpMessageConverter - Failed to evaluate Jackson deserialization for type [[simple type, class com.interact.firewall.base.biz.entity.Route]]: com.fasterxml.jackson.databind.JsonMappingException: Conflicting setter definitions for property "parent": com.interact.firewall.core.bean.service.Service#setParent(1 params) vs com.interact.firewall.core.bean.service.Service#setParent(1 params) 2020/09/28-10:52:00 ERROR [http-nio-8999-exec-6] GlobalExceptionHandler - 捕获到Exception异常 org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/json;charset=UTF-8' not supported at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:225) at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.readWithMessageConverters(RequestResponseBodyMethodProcessor.java:158) at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:131) at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121) at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:167) at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:134) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:878) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:792) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) at javax.servlet.http.HttpServlet.service(HttpServlet.java:652) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) at javax.servlet.http.HttpServlet.service(HttpServlet.java:733) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1589) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:745)
于是我就按照这个异常信息去排查,
有人说是缺少依赖。但是并没有解决
有人说是字段没有映射对,就是说页面传递到后台的值跟实体类对应不上,但是我反复比对没有问题。
之前实体类中还写了一部分处理数据的方法,我也进行删除进行测试还是不行。
后来请教同事,同事也怀疑是实体类的问题,于是重新建了一个实体类,只要数据库的字段,不是数据库中的字段进行删除,结果可以了,于是继续排查,确认到底是哪个地方引起的,最终确认了,是因为实体类中引用了一个对象。将引用的这个对象删掉就没问题了,但是我们想了一下,其他的实体类也有因为需要关联查询直接引其他对象的,但是却没有出问题。为什么单单这个出问题呢。
其实报错中已经有提示了,在异常信息上边有两行警告代码:
Failed to evaluate Jackson deserialization for type [[simple type, class com.interact.firewall.base.biz.entity.Route]]: com.fasterxml.jackson.databind.JsonMappingException: Conflicting setter definitions for property "parent": com.interact.firewall.core.bean.service.Service#setParent(1 params) vs com.interact.firewall.core.bean.service.Service#setParent(1 params)
说的其实是序列化相关的问题,后来我们查看了一下在Route中引用的对象,确实,并没有实现Serializable 这个接口,导致这个问题的发生,但是这个对象又必须引用,那怎么办呢?想了一下,是不是有个注解能够忽略反序列化字段呢?于是查了一下,果然有
JsonIgnore这个注解就可以将被标记属性忽略反序列化功能。
总结一下:其实这个问题的根本原因就是实体类中引用了一个没有实现实现Serializable 接口的对象,无法被反序列化,只需要在这个对象上添加@JsonIgnore这个注解即可。对了 一直在说没有实现Serializable接口的对象是实体类中最后一个Ipaddr那个对象。
/** * 路由转化后的对象 */ @TableField(exist = false) @JsonIgnore private IpAddr ipAddr;