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 { }
步驟二:自定義類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; } }
步驟三:自定義類 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(); } }
步驟四:整合到springboot中,在WebConfig中添加如下代碼
@Override public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) { argumentResolvers.add(new UnderlineToCamelArgumentResolver()); }

步驟五:使用,很簡單,在接收參數的對象前加注解

