1.背景
在實際開發中,通常來說java裡面是使用駝峰的命名規則;
但是有時候在對接其他三方平台的接口時,要求使用下劃線的命名規則,這時候就涉及到如何讓自己的接口滿足三方平台的下劃線;
實作方式有
1.java裡面也使用下下劃線的方式接收和響應,但是不推薦這樣,因為雖然滿足了接口需求,但是不符合java裡面的命名規範;
2.java裡面使用駝峰,接收到參數後手動轉換,這樣做太麻煩.
3.java裡面使用駝峰,寫一個工具方法,通過注解的方式,統一轉換,推薦,也是實際開發中常用的方式
那些地方需要轉換
1.傳入參數的時候(下換線轉為駝峰)
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;
}
}
步驟三:自定義類 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());
}
步驟五:使用,很簡單,在接收參數的對象前加注解