spirngmvc 前端请求体json传输单值,后端@RequestBody接收

前端通过请求体传输json对象,后端无法直接转换成相应的数据类型,这时候需要单独处理这种情况

处理的逻辑是:

  1. 编写标记,用于在方法上获取字段名称,并且只处理添加标记的方法;
@Retention(RetentionPolicy.RUNTIME)
public @interfce CustomSignleParams{
     /**
      * 字段名称
     */
     String name() default "";
}

2.编写自定义处理类,拦截请求,发现有标记的请求,则执行:

/**
 * json参数解析
 */
public class JsonParamProvider  implements HandlerMethodArgumentResolver {
    /**
     * 请求body格式
     */
    private static final String CONTENT_TYPE = "application/json";

    /**
     * 判断是否是需要我们解析的参数类型
     */
    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        return methodParameter.hasParameterAnnotation(CustomSignleParams.class);
    }
        /**
     * 真正解析的方法
     */
    @Override
    public Object resolveArgument(@NonNull MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest,
                                  WebDataBinderFactory webDataBinderFactory) {
        HttpServletRequest request = nativeWebRequest.getNativeRequest(HttpServletRequest.class);
        if (request == null) {
            return null;
        }
        String contentType = request.getContentType();
        if (StringUtils.isEmpty(contentType) || !contentType.toLowerCase().contains(CONTENT_TYPE)) {
            return null;
        }
        JSONObject jsonObject=new JSONObject();
        try (BufferedReader streamReader = new BufferedReader(new InputStreamReader(request.getInputStream(),
                StandardCharsets.UTF_8))) {
            StringBuilder responseStrBuilder = new StringBuilder();
            String inputStr;
            while ((inputStr = streamReader.readLine()) != null) {
                responseStrBuilder.append(inputStr);
            }
            jsonObject = JSON.parseObject(responseStrBuilder.toString());
        } catch (Exception e) {

        }
        CustomSignleParams jsonParam = methodParameter.getParameterAnnotation(CustomSignleParams.class);
        if (jsonParam == null) {
            return null;
        }
        //获取参数名
        String paramName = jsonParam.name();

        String paramType = methodParameter.getParameter().getType().getSimpleName();
        if (jsonObject != null && jsonObject.containsKey(paramName)) {
            String data = String.valueOf(jsonObject.get(paramName));

            return initValue(paramType, data);
        }
        return null;
    }

    /**
     * 给基本类型参数注入值
     *
     * @param type 类型
     * @param data 值
     * @return java.lang.Object
     */
    private Object initValue(String type, String data) {
        try {
            if ("int".equalsIgnoreCase(type) || "integer".equalsIgnoreCase(type)) {
                return Integer.valueOf(data);
            } else if ("double".equalsIgnoreCase(type)) {
                return Double.valueOf(data);
            } else if ("long".equalsIgnoreCase(type)) {
                return Long.valueOf(data);
            }
        } catch (NumberFormatException e) {

        }
        return data;
    }
}

上面的类用于处理请求中的数据,字段名称从CustomSignleParams字段获取,然后再赋值给controller中的字段;
3.接着,把处理类注册到处理链中:

@Configuration
public class WebMvcCustomConfigurer implements WebMvcConfigurer {
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        JsonParamProvider jsonParamProvider=new JsonParamProvider ();
        resolvers.add(jsonParamProvider);
    }
}

注入之后,一旦有controller上添加了注解,会触发参数的处理;
这样会把json解析,然后把json中的value赋值给controller中的参数;
例子:

@CustomSignleParams(name = "id")String id

该类只能处理单值参数
有一个问题:为何springmvc不添加对单值的处理呢?????

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lixiaolinzq

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值