SpringMVC:Controller請求報錯The request sent by the client was syntactically incorrect
阿新 • • 發佈:2018-12-03
因為Spring預設的parser是StringParser,而我傳入的是組合類,SpringMVC解析出錯。
@Data public class QQGameGetCouponDto { private BaseParams baseParams; private QQGameGetCouponBizParam bizParams; }
對於入參為組合類的情況,需要提供特定的parser,使用@Json註解來使用:
public class JsonMapperArgumentResolver implements HandlerMethodArgumentResolver { private static final Logger log = LoggerFactory.getLogger(JsonMapperArgumentResolver.class); private ObjectMapper objectMapper = ObjectMapperFactoryBean.getObjectMapper(); private static final String PATH_DELIMITER = "/"; public JsonMapperArgumentResolver() { } public boolean supportsParameter(MethodParameter parameter) { return parameter.hasParameterAnnotation(Json.class); } public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { try { Json jsonAnn = (Json)parameter.getParameterAnnotation(Json.class); String path = jsonAnn.path(); String allParam = this.getAllParam(webRequest); if (allParam != null && !allParam.equals("")) { JsonNode node = this.objectMapper.readTree(allParam); if (path != null && !"".equals(path)) { String[] paths = path.split("/"); String[] var10 = paths; int var11 = paths.length; for(int var12 = 0; var12 < var11; ++var12) { String p = var10[var12]; node = node.path(p); } return node == null ? null : this.objectMapper.readValue(node, this.getReferenceType(parameter, jsonAnn)); } else { log.debug("[JsonMapperArgumentResolver][resolveArgument] {} {}", parameter.getParameterType().toString(), parameter.getParameterIndex()); path = this.getParameterName(parameter); if (node.has(path)) { return this.objectMapper.readValue(node.path(path), this.getReferenceType(parameter, jsonAnn)); } else { try { return this.objectMapper.readValue(allParam, this.getReferenceType(parameter, jsonAnn)); } catch (Throwable var14) { return null; } } } } else { return null; } } catch (Exception var15) { log.error(parameter.getParameterName(), var15); throw var15; } } private String getParameterName(MethodParameter parameter) { String parameterName = null; int i = 0; while(i < 3) { try { parameterName = parameter.getParameterName(); break; } catch (Exception var5) { log.error("[JsonMapperArgumentResolver][getParameterName]", var5); ++i; } } return parameterName; } private JavaType getReferenceType(MethodParameter parameter, Json annt) { Class[] types = annt.types(); if (types.length == 1 && types[0].equals(Object.class)) { return this.objectMapper.getTypeFactory().constructType(parameter.getParameterType()); } else if (Collection.class.isAssignableFrom(parameter.getParameterType())) { return this.objectMapper.getTypeFactory().constructCollectionType(parameter.getParameterType(), types[0]); } else if (Map.class.isAssignableFrom(parameter.getParameterType())) { return types.length >= 2 ? this.objectMapper.getTypeFactory().constructMapType(parameter.getParameterType(), types[0], types[1]) : this.objectMapper.getTypeFactory().constructMapType(parameter.getParameterType(), types[0], Object.class); } else { StringBuilder buffer = new StringBuilder(); buffer.append("Unsuppored Reference To JavaType : ").append(parameter.getParameterType().getName()).append("<"); int i = 0; Class[] var6 = types; int var7 = types.length; for(int var8 = 0; var8 < var7; ++var8) { Class type = var6[var8]; if (i++ > 0) { buffer.append(","); } buffer.append(type.getSimpleName()); } buffer.append(">"); throw new UnsupportedOperationException(buffer.toString()); } } private String getAllParam(NativeWebRequest webRequest) throws IOException { HttpServletRequest httpServletRequest = (HttpServletRequest)webRequest.getNativeRequest(HttpServletRequest.class); String method = httpServletRequest.getMethod(); if (!method.equals("GET") && !method.equals("DELETE")) { StringBuilder buffer = new StringBuilder(); BufferedReader reader = httpServletRequest.getReader(); String line; while((line = reader.readLine()) != null) { buffer.append(line); } return buffer.toString(); } else { return httpServletRequest.getQueryString(); } } }
使用:
public ResponseVo getCoupon(@Json QQGameGetCouponDto param){}