spring boot 自定義引數解析器實現form表單型別請求或位址列請求引數下劃線轉駝峰屬性
阿新 • • 發佈:2018-11-27
一、定義引數解析註解
@Target(value = ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface ParameterModel {
}
二、定義抽象類AbstractCustomizeResolver繼承HandlerMethodArgumentResolver
public abstract class AbstractCustomizeResolver implements HandlerMethodArgumentResolver { //校驗 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()); } /** * Validate the binding target if applicable. * <p>The default implementation checks for {@code @javax.validation.Valid}, * Spring's {@link Validated}, * and custom annotations whose name starts with "Valid". * @param binder the DataBinder to be used * @param parameter the method parameter descriptor * @since 4.1.5 * @see #isBindExceptionRequired */ 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繼承AbstractCustomizeResolver
public class UnderlineToCamelArgumentResolver extends AbstractCustomizeResolver { /** * Whether the given {@linkplain MethodParameter method parameter} is * supported by this resolver. * @param parameter the method parameter to check * @return {@code true} if this resolver supports the supplied parameter; * {@code false} otherwise */ @Override public boolean supportsParameter(MethodParameter parameter) { return parameter.hasParameterAnnotation(ParameterModel.class); } /** * 裝載引數 * * @param methodParameter 方法引數 * @param modelAndViewContainer 返回檢視容器 * @param nativeWebRequest 本次請求物件 * @param webDataBinderFactory 資料繫結工廠 * @return the resolved argument value, or {@code null} * @throws Exception in case of errors with the preparation of argument values */ @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; } //處理引數 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); wrapper.setPropertyValue(StringHelpers.underLineToCamel(paramName), o); } return obj; } }
4、定義工具類StringHelpers處理駝峰與下劃線的互換
public class StringHelpers { /** * 匹配_加任意一個字元 */ private static final Pattern UNDER_LINE_PATTERN = Pattern.compile("_(\\w)"); /*** * 下劃線命名轉為駝峰命名 * * @param source * 下劃線命名的字串 */ public static String underlineToHump(String source) { StringBuffer result = new StringBuffer(); String a[] = source.split("_"); for (String s : a) { if (result.length() == 0) { result.append(s.toLowerCase()); } else { result.append(s.substring(0, 1).toUpperCase()); result.append(s.substring(1).toLowerCase()); } } return result.toString(); } /*** * 駝峰命名轉為下劃線命名 * * @param source * 駝峰命名的字串 */ public static String humpToUnderline(String source) { StringBuffer sb = new StringBuffer(source); int temp = 0;//定位 for (int i = 0; i < source.length(); i++) { if (Character.isUpperCase(source.charAt(i))) { sb.insert(i + temp, "_"); temp += 1; } } return sb.toString().toUpperCase(); } /** * Create by lrt<br/> * Date:2018/10/10 * Description: 下劃線轉為駝峰格式 * * @param source 原字串 * @return java.lang.String 返回轉換後的駝峰格式字串 */ public static String underLineToCamel(String source) { //用Pattern類的matcher()方法生成一個Matcher物件 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(); } }