今天有个动态筛选条件不能正常筛选,估计是没有拿到查询条件。因查询条件是由入参调微服务接口查询拿到的,故先看微服务的producer端日志,发现了个HttpMessageNotWritableException,类型转换失败。
先看日志:
2021-11-29 15:13:39 [ERROR] userId:108340 c.l.c.b.c.LSControllerAdvice >> 程序产生未知异常:o(╥﹏╥)o ==> 接口地址:/client/customer/regRelation/querySupervisedIds ==> Referer: null ==> 请求参数:{"regulatorId":["104323"],"dataFlag":["0"]} org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: (was java.lang.ClassCastException); nested exception is com.fasterxml.jackson.databind.JsonMappingException: (was java.lang.ClassCastException) (through reference chain: java.util.ArrayList[0]) at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:354) at org.springframework.http.converter.AbstractGenericHttpMessageConverter.write(AbstractGenericHttpMessageConverter.java:104) at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:277) at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:181) at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:78) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:124) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1060) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:962) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) at javax.servlet.http.HttpServlet.service(HttpServlet.java:626) 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 cn.lonsun.core.base.filter.BaseFilter.doFilter(BaseFilter.java:85) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.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:97) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:888) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1597) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.base/java.lang.Thread.run(Thread.java:829) Caused by: com.fasterxml.jackson.databind.JsonMappingException: (was java.lang.ClassCastException) (through reference chain: java.util.ArrayList[0]) at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:397) at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:368) at com.fasterxml.jackson.databind.ser.std.StdSerializer.wrapAndThrow(StdSerializer.java:338) at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContentsUsing(CollectionSerializer.java:178) at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:116) at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:107) at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:25) at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480) at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:400) at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1512) at com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:1006) at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:345) ... 47 common frames omitted Caused by: java.lang.ClassCastException: null
拿到问题后仔细核对了自己的微服务接口,发现并没有问题。
@FeignClient(value = "admin-server", contextId = "xxxxxx") public interface CustomerRegRelationClient { @GetMapping(value = "/client/customer/regRelation/querySupervisedIds?dataFlag=0", consumes = MediaType.APPLICATION_JSON_VALUE) List<Long> querySupervisedIds(@RequestParam("regulatorId") Long regulatorId); }
故认为返回值类型不能被转换为List<Long>
, 分析dao层方法:
default List<Long> querySupervisedIdList(Long regulatorId) { List<Long> supervisedIdList = new ArrayList<>(); String sql = "select child_organ_id from customer_reg_relation " + "where parent_organ_id = :regulatorId"; Map<String, Object> params = new HashMap<>(); params.put("regulatorId", regulatorId); List<?> objectsBySql = getObjectsBySql(sql, params); if (null != objectsBySql && objectsBySql.size() != 0){ supervisedIdList = (List<Long>) objectsBySql; } return supervisedIdList; }
认为此处强转并没有生效。
强转无泛型集合类的时候,不会生效,需遍历转换。Collection<?>类型的集合,采用强转可以用任意泛型替代问号,强转本身不报错,但实际类型并没有发生变化。
但是postMan单独测试微服务producer端的接口,能正常输出。
分析:强转没有生效,但直接测试接口输出时候,是转化成字符串,并不涉及类型转换,所以不会报错。当使用微服务接口调用时,需要转换数据类型,而(List<Long>)
并未强转每个对象,故会报错。
分析后,采用单个类型转换为Long型的方式
此时,考虑数据库类型bigint如何转换为java类型的long。采用Number来进行中间转化。
default List<Long> querySupervisedIdList(Long regulatorId) { List<Long> supervisedIdList = new ArrayList<>(); String sql = "select child_organ_id from customer_reg_relation " + "where parent_organ_id = :regulatorId"; Map<String, Object> params = new HashMap<>(); params.put("regulatorId", regulatorId); List<?> objectsBySql = getObjectsBySql(sql, params); if (null != objectsBySql && objectsBySql.size() != 0){ for (Object o : objectsBySql) { Long l = ((Number) o).longValue(); supervisedIdList.add(l); } } return supervisedIdList; }
此时,微服务接口能正常访问。