自定义解析器,解决字符串转数组、List问题

本文介绍了一种在MVC框架中处理特殊请求参数的方法,当请求参数只能为字符串时,通过自定义注解和服务端的序列化转换,将JSON字符串转化为实体类。主要步骤包括创建注解、实现自定义解析处理、配置Spring MVC以及在接口上使用自定义注解。
摘要由CSDN通过智能技术生成

在多数的MVC请求中,不涉及此类问题,按照实际需要格式传参即可,但在特定情况下,比如请求方只能传字符串,则需要服务方在序列化到实体类之前,完成格式转换,实际操作方法如下:

说明,我们请求的参数结果大概如下

{
    "reqHead": {
        "bb": "xx"
    },
    "reqBody": {
        "aa": "xx"
    }
}

首先创建注解

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestObj {
    boolean required() default true;
}

然后就是自定义解析处理,至于如何request中获取json对象,分享的帖子比较多,此处不做过多赘述

@Component
public class HandlerArgumentsResolverImpl implements HandlerMethodArgumentResolver {
    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        return methodParameter.hasParameterAnnotation(RequestObj.class);
    }

    @Override
    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer,
                                  NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory)
            throws Exception {
        HttpServletRequest request = nativeWebRequest.getNativeRequest(HttpServletRequest.class);

        ServletRequest requestWrapper = new BodyReaderHttpServletRequestWrapper(request);
        String body = HttpHelper.getBodyString(requestWrapper);

        JSONObject jsonBody = JSONObject.parseObject(body);
        JSONObject jsonObject = jsonBody.getJSONObject("reqBody");
        Parameter[] parameters = methodParameter.getExecutable().getParameters();
        for (Parameter pr : parameters) {
            Class<?> oriType1 = pr.getType();
            if (!oriType1.isInstance(CommonBaseReqDto.class) && !oriType1.isAssignableFrom(HttpServletRequest.class)) {
                ParameterizedType parameterizedType = (ParameterizedType) pr.getParameterizedType();
                Type type = parameterizedType.getActualTypeArguments()[0];
                if (type instanceof Class) {
                    Class<?> aClass = (Class<?>) type;
                    Field[] declaredFields = aClass.getDeclaredFields();
                    for (Field p : declaredFields) {
                        Object s = jsonObject.get(p.getName());
                        if (jsonObject.containsKey(p.getName())) {
                            if (p.getType().isArray()) {
                                if (ObjectUtil.isEmpty(s)) {
                                    jsonObject.put(p.getName(), null);
                                } else if (s instanceof String) {
                                    jsonObject.put(p.getName(), JSONArray.parseArray(s.toString()).toArray(new Object[]{}));
                                }
                            } else if (p.getType().isInstance(List.class)) {
                                if (ObjectUtil.isEmpty(s)) {
                                    jsonObject.put(p.getName(), null);
                                } else if (s instanceof String) {
                                    jsonObject.put(p.getName(), JSONArray.parseArray(s.toString()));
                                }
                            } else {
                                if (ObjectUtil.isEmpty(s)) {
                                    jsonObject.put(p.getName(), null);
                                }
                            }
                        }
                    }
                }
                //找到指定泛型类
                break;
            }
        }
        return jsonBody.fluentPut("reqBody", jsonObject).toJavaObject(methodParameter.getGenericParameterType());
    }
}

然后是配置config,我是和拦截器共用的config

@Component
public class InterceptorConfig implements WebMvcConfigurer {


    @Autowired
    private HandlerArgumentsResolverImpl handlerArgumentsResolver;

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        resolvers.add(handlerArgumentsResolver);
    }
}

最后就是给需要的接口加上自定义注解就行了。

欢迎大家指正讨论

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值