1 2018-08-28 17:26:02,208 [http-bio-9090-exec-1][][][][][] ERROR com.wjs.member.plugin.intercepter.ServiceExecutionInterceptor 116 - Incompatible types: declared root type ([map type; class java.util.Map, [simple type, class java.lang.String] -> [collection type; class java.util.List, contains [simple type, class com.wjs.member.clientVo.deduct.DeductCurVo]]]) vs com.wjs.common.web.JsonResult 2 org.codehaus.jackson.map.JsonMappingException: Incompatible types: declared root type ([map type; class java.util.Map, [simple type, class java.lang.String] -> [collection type; class java.util.List, contains [simple type, class com.wjs.member.clientVo.deduct.DeductCurVo]]]) vs com.wjs.common.web.JsonResult 3 at org.codehaus.jackson.map.ser.StdSerializerProvider._reportIncompatibleRootType(StdSerializerProvider.java:687) ~[jackson-mapper-asl-1.9.13.jar:1.9.13] 4 at org.codehaus.jackson.map.ser.StdSerializerProvider._serializeValue(StdSerializerProvider.java:647) ~[jackson-mapper-asl-1.9.13.jar:1.9.13] 5 at org.codehaus.jackson.map.ser.StdSerializerProvider.serializeValue(StdSerializerProvider.java:271) ~[jackson-mapper-asl-1.9.13.jar:1.9.13] 6 at org.codehaus.jackson.map.ObjectWriter.writeValue(ObjectWriter.java:325) ~[jackson-mapper-asl-1.9.13.jar:1.9.13] 7 at org.codehaus.jackson.jaxrs.JacksonJsonProvider.writeTo(JacksonJsonProvider.java:557) ~[jackson-jaxrs-1.9.13.jar:1.9.13] 8 at org.jboss.resteasy.core.interception.AbstractWriterInterceptorContext.writeTo(AbstractWriterInterceptorContext.java:137) ~[resteasy-jaxrs-3.6.0.Final.jar:3.6.0.Final] 9 at org.jboss.resteasy.core.interception.ServerWriterInterceptorContext.writeTo(ServerWriterInterceptorContext.java:61) ~[resteasy-jaxrs-3.6.0.Final.jar:3.6.0.Final] 10 at org.jboss.resteasy.core.interception.AbstractWriterInterceptorContext.proceed(AbstractWriterInterceptorContext.java:124) ~[resteasy-jaxrs-3.6.0.Final.jar:3.6.0.Final] 11 at com.wjs.member.plugin.intercepter.RestContextInteceptor.aroundWriteTo(RestContextInteceptor.java:77) ~[com.wjs.dubbo-demo.service-180830-SNAPSHOT.jar:na] 12 at org.jboss.resteasy.core.interception.AbstractWriterInterceptorContext.proceed(AbstractWriterInterceptorContext.java:129) ~[resteasy-jaxrs-3.6.0.Final.jar:3.6.0.Final] 13 at org.jboss.resteasy.core.ServerResponseWriter.lambda$writeNomapResponse$2(ServerResponseWriter.java:140) ~[resteasy-jaxrs-3.6.0.Final.jar:3.6.0.Final] 14 at org.jboss.resteasy.core.interception.ContainerResponseContextImpl.filter(ContainerResponseContextImpl.java:395) ~[resteasy-jaxrs-3.6.0.Final.jar:3.6.0.Final]
在封裝dubbo的rest請求返回值的時候,對於List和Map返回值,會出現如上錯誤。其緣由是resteasy的AbstractWriterInterceptorContext調用JSON序列化的時候,傳入的entity和genericType不一致,java
codehaus.jackson的StdSerializerProvider類對entity和genericType比對不一致,並報錯。web
解決辦法,在封裝返回值的時候,修改WriterInterceptorContext的GenericType類型,以下代碼紅色部分。app
1 @Override 2 public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException { 3 4 // System.err.println("進入結果處理——aroundWriteTo"); 5 // 針對須要封裝的請求對結構進行封裝處理。這裏須要注意的是對返回類型已是封裝類(好比:異常處理器的響應可能已是封裝類型)時要忽略掉。 6 Object originalObj = context.getEntity(); 7 String wrapTag = context.getProperty("Not-Wrap-Result") == null ? "" : context.getProperty("Not-Wrap-Result").toString(); // 客戶端顯示提醒不要對返回值進行封裝 8 Boolean wraped = originalObj instanceof JsonResult; // 已經被封裝過了的,不用再次封裝 9 if (StringUtils.isBlank(wrapTag) && !wraped){ 10 JsonResult<Object> result = new JsonResult<>(true, "執行成功"); 11 result.setData(context.getEntity()); 12 context.setEntity(result); 13 // 如下兩處set避免出現Json序列化的時候,對象類型不符的錯誤 14 context.setType(result.getClass()); 15 context.setGenericType(result.getClass().getGenericSuperclass()); 16 } 17 context.proceed(); 18 19 }