zoukankan      html  css  js  c++  java
  • springboot接口入参下划线转驼峰以及返回参数驼峰转下划线实现

    1.背景

    在实际开发中,通常来说java里面是使用驼峰的命名规则;

    但是有时候在对接其他三方平台的接口时,要求使用下划线的命名规则,这时候就涉及到如何让自己的接口满足三方平台的下划线;

    实现方式有

    1.java里面也使用下下划线的方式接收和响应,但是不推荐这样,因为虽然满足了接口需求,但是不符合java里面的命名规范;

    2.java里面使用驼峰,接收到参数后手动转换,这样做太麻烦.

    3.java里面使用驼峰,写一个工具方法,通过注解的方式,统一转换,推荐,也是实际开发中常用的方式

    那些地方需要转换

    1.传入参数的时候(下换线转为驼峰)

    2.响应结果的时候(驼峰转为下划线)

    因为响应结果的时候(驼峰转为下划线)比较简单,先搞定这个

    2.响应结果的时候(驼峰转为下划线)

    方式一:在返回对象的类上加注解(推介)

    @JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
    案例如下:

    方法二:在字段上注解

    @JsonProperty(value = "order_card")

    3.传入参数的时候(下换线转为驼峰)

    方式一:自己手动封装,不推荐,略;

    方式二:接收为Map对接,通过Json转换(如果系统中只有少数个别接口需要转换,可以这样写);

    步骤一:接收对象上的字段上加注解 @JsonProperty(value = "order_card")

     步骤二:控制层出的写法如下

    方式三:通过实现接口HandlerMethodArgumentResolver的方式,强烈推荐

    步骤一:自定义注解 ParameterConvert

    @Target(value = ElementType.PARAMETER)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface ParameterConvert {
    }
    View Code

    步骤二:自定义类AbstractCustomizeResolver

    import org.springframework.core.Conventions;
    import org.springframework.core.MethodParameter;
    import org.springframework.core.annotation.AnnotationUtils;
    import org.springframework.validation.BindingResult;
    import org.springframework.validation.Errors;
    import org.springframework.validation.annotation.Validated;
    import org.springframework.web.bind.MethodArgumentNotValidException;
    import org.springframework.web.bind.WebDataBinder;
    import org.springframework.web.bind.support.WebDataBinderFactory;
    import org.springframework.web.context.request.NativeWebRequest;
    import org.springframework.web.method.support.HandlerMethodArgumentResolver;
    import org.springframework.web.method.support.ModelAndViewContainer;
    
    import java.lang.annotation.Annotation;
    
    /**
     * @Copyright (C) XXXXXXXXXXX科技股份技有限公司
     * @Author: lidongping
     * @Date: 2021-05-13 19:24
     * @Description:
     */
    public abstract class AbstractCustomizeResolver implements HandlerMethodArgumentResolver {
        /**
         * 校验
         *
         * @param parameter
         * @param mavContainer
         * @param webRequest
         * @param binderFactory
         * @param arg
         * @throws Exception
         */
        protected void valid(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory, Object arg) throws Exception {
            String name = Conventions.getVariableNameForParameter(parameter);
            WebDataBinder binder = binderFactory.createBinder(webRequest, arg, name);
            if (arg != null) {
                validateIfApplicable(binder, parameter);
                if (binder.getBindingResult().hasErrors() && isBindExceptionRequired(binder, parameter)) {
                    throw new MethodArgumentNotValidException(parameter, binder.getBindingResult());
                }
            }
            mavContainer.addAttribute(BindingResult.MODEL_KEY_PREFIX + name, binder.getBindingResult());
        }
    
        /**
         * @param binder
         * @param parameter
         */
        protected void validateIfApplicable(WebDataBinder binder, MethodParameter parameter) {
            Annotation[] annotations = parameter.getParameterAnnotations();
            for (Annotation ann : annotations) {
                Validated validatedAnn = AnnotationUtils.getAnnotation(ann, Validated.class);
                if (validatedAnn != null || ann.annotationType().getSimpleName().startsWith("Valid")) {
                    Object hints = (validatedAnn != null ? validatedAnn.value() : AnnotationUtils.getValue(ann));
                    Object[] validationHints = (hints instanceof Object[] ? (Object[]) hints : new Object[]{hints});
                    binder.validate(validationHints);
                    break;
                }
            }
        }
    
        protected boolean isBindExceptionRequired(WebDataBinder binder, MethodParameter parameter) {
            int i = parameter.getParameterIndex();
            Class<?>[] paramTypes = parameter.getMethod().getParameterTypes();
            boolean hasBindingResult = (paramTypes.length > (i + 1) && Errors.class.isAssignableFrom(paramTypes[i + 1]));
            return !hasBindingResult;
        }
    
    }
    View Code

    步骤三:自定义类 UnderlineToCamelArgumentResolver

    import org.springframework.beans.BeanUtils;
    import org.springframework.beans.BeanWrapper;
    import org.springframework.beans.PropertyAccessorFactory;
    import org.springframework.core.MethodParameter;
    import org.springframework.web.bind.support.WebDataBinderFactory;
    import org.springframework.web.context.request.NativeWebRequest;
    import org.springframework.web.method.support.ModelAndViewContainer;
    
    import java.util.Iterator;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    public class UnderlineToCamelArgumentResolver extends AbstractCustomizeResolver {
        /**
         * 匹配_加任意一个字符
         */
        private static final Pattern UNDER_LINE_PATTERN = Pattern.compile("_(\w)");
    
        @Override
        public boolean supportsParameter(MethodParameter methodParameter) {
            return methodParameter.hasParameterAnnotation(ParameterConvert.class);
        }
    
        @Override
        public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer,
                                      NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
            Object org = handleParameterNames(methodParameter, nativeWebRequest);
            valid(methodParameter, modelAndViewContainer, nativeWebRequest, webDataBinderFactory, org);
            return org;
        }
    
        /**
         * 处理参数
         *
         * @param parameter
         * @param webRequest
         * @return
         */
        private Object handleParameterNames(MethodParameter parameter, NativeWebRequest webRequest) {
            Object obj = BeanUtils.instantiate(parameter.getParameterType());
            BeanWrapper wrapper = PropertyAccessorFactory.forBeanPropertyAccess(obj);
            Iterator<String> paramNames = webRequest.getParameterNames();
            while (paramNames.hasNext()) {
                String paramName = paramNames.next();
                Object o = webRequest.getParameter(paramName);
                System.out.println(paramName + "=" + o);
                wrapper.setPropertyValue(underLineToCamel(paramName), o);
            }
            return obj;
        }
    
        /**
         * 下换线转驼峰
         *
         * @param source
         * @return
         */
        private String underLineToCamel(String source) {
            Matcher matcher = UNDER_LINE_PATTERN.matcher(source);
            StringBuffer result = new StringBuffer();
            while (matcher.find()) {
                matcher.appendReplacement(result, matcher.group(1).toUpperCase());
            }
            matcher.appendTail(result);
            return result.toString();
        }
    }
    View Code

    步骤四:整合到springboot中,在WebConfig中添加如下代码

     @Override
        public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
            argumentResolvers.add(new UnderlineToCamelArgumentResolver());
        }
    View Code

     步骤五:使用,很简单,在接收参数的对象前加注解

    4.完美 

  • 相关阅读:
    (二分查找 拓展) leetcode 69. Sqrt(x)
    (二分查找 拓展) leetcode 162. Find Peak Element && lintcode 75. Find Peak Element
    (链表) lintcode 219. Insert Node in Sorted Linked List
    (二分查找 拓展) leetcode 34. Find First and Last Position of Element in Sorted Array && lintcode 61. Search for a Range
    (最短路 Floyd) P2910 [USACO08OPEN]寻宝之路Clear And Present Danger 洛谷
    (字符串 数组 递归 双指针) leetcode 344. Reverse String
    (二叉树 DFS 递归) leetcode 112. Path Sum
    (二叉树 DFS 递归) leetcode 101. Symmetric Tree
    (二叉树 递归) leetcode 144. Binary Tree Preorder Traversal
    (二叉树 递归 DFS) leetcode 100. Same Tree
  • 原文地址:https://www.cnblogs.com/newAndHui/p/14767675.html
Copyright © 2011-2022 走看看