1. 程式人生 > >SpringMVC:Controller請求報錯The request sent by the client was syntactically incorrect

SpringMVC:Controller請求報錯The request sent by the client was syntactically incorrect

因為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){}