스프링 MVC 사용자 정의 클래스 이름 매개 변수 바인딩

모두 알다시피, 시간 매개 변수 중 스프링 MVC 바인딩. 요청의 전단의 후방 단부에 의해 형성되는 클래스 이름 파라미터 이름 12시 59분이다. 예를 들어 이름 요청 파라미터 값이 후단에 도달 하였다. 백엔드 단지 클래스의 이름 속성을 선언 한 후 클래스를 정의 할 필요가있다. 스프링 MVC 값의 전송 요청은 자동이 정의의 클래스 이름에 충전하는 경우. 당신은 그런 문제가 발생하면 물론 백엔드, 또한 속성이 추가 될 수 goods_name를 선언하는 경우, 프런트 엔드 goods_name (상품명)을 정의하는 것입니다. 그러나이 작업은 충분히 우아하지 않다.

나는이 문제가 할 수있는 자동 변환 스프링의 아이디어의 시작 통해 발생했습니다. 그러나 각 자동 유형 변환은 작동하지 않습니다 찾기 위해 노력하고 있습니다. 마지막으로, 바인딩 스프링 MVC 요청 매개 변수 (HandlerMethodArgumentResolver)를 사용하는 등의 일을합니다.

다음과 같은 아이디어는 다음과 같습니다

그것은 요청 파라미터 요청 방식 내부에서 객체를 생성 파라미터 바인딩 요청을 한 후 생성 된 객체의 요청 대상 데이터 안에 주입 의존성 스프링을 주입하는 경우.

내 생각을 통해 위의 두 사이의 단계로 사용자 정의 매개 변수 파서 바인드 매개 변수입니다. 후 내 첫번째 요청 파서 바인딩 맞춤 매개 변수, 그리고 상기 연관 내부 요청 객체의 대응하는 클래스의 속성 이름 속성 이름 어느 클래스에 메모를 선언. 생성 한 후, 대응하는 클래스 속성의 값은 다음에 값 설정 부에 의해 반사되어 상기 요청 개체 온.

특정 코드는 다음과 같이 :

1 Key.java

사용자 정의 주석 클래스, 연결 요청 요청 객체 클래스의 속성과 속성 이름

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Key {

    String value() default "";

}

2, EnableKey

해상도 요청 URL 요청에 해당하는 바인딩 매개 변수 매개 변수 구문 분석 요청에 레이블을 선언 파서에 대한 주석 사용자 정의 클래스.

@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface EnableKey {

}

3 CustomModelAttributeMethodProcessor.java

사용자 정의 클래스를 구문 분석 매개 변수 사용자 지정 매개 변수에 대한 클래스 이름 바인딩.

public class CustomModelAttributeMethodProcessor extends ModelAttributeMethodProcessor {

    public CustomModelAttributeMethodProcessor(boolean annotationNotRequired) {
        super(annotationNotRequired);
    }

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(EnableKey.class);
    }

    @Override
    protected Object createAttribute(String attributeName, MethodParameter parameter, WebDataBinderFactory binderFactory, NativeWebRequest request) throws Exception {
        Object result = super.createAttribute(attributeName, parameter, binderFactory, request);
        Class<?> targetClazz = result.getClass();
        for (PropertyDescriptor pd : BeanUtils.getPropertyDescriptors(targetClazz)) {
            //skip class
            if (pd.getName().equals("class")){
                continue;
            }
            TypeDescriptor td = build(targetClazz, pd);
            Key key = td.getAnnotation(Key.class);
            if(key != null && StringUtils.isNotBlank(key.value())){
                ServletRequest servletRequest = request.getNativeRequest(ServletRequest.class);
                MutablePropertyValues mpvs = new ServletRequestParameterPropertyValues(servletRequest);
                addBindValues(mpvs, servletRequest);
                PropertyValue propertyValue = mpvs.getPropertyValue(key.value());
                if(propertyValue != null){
                    String value = (String) propertyValue.getValue();
                    pd.getWriteMethod().invoke(result, value);
                }
            }

        }
        return result;
    }

    private TypeDescriptor build(Class<?> beanClz, PropertyDescriptor pd) {
        Property p = new Property(beanClz, pd.getReadMethod(), pd.getWriteMethod(), pd.getName());
        return new TypeDescriptor(p);
    }

    protected void addBindValues(MutablePropertyValues mpvs, ServletRequest request) {
        String attr = HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE;
        Map<String, String> uriVars = (Map<String, String>) request.getAttribute(attr);
        if (uriVars != null) {
            uriVars.forEach((name, value) -> {
                if (mpvs.contains(name)) {
                    if (logger.isWarnEnabled()) {
                        logger.warn("Skipping URI variable '" + name +
                                "' because request contains bind value with same name.");
                    }
                }
                else {
                    mpvs.addPropertyValue(name, value);
                }
            });
        }
    }

    @Override
    protected void bindRequestParameters(WebDataBinder binder, NativeWebRequest request) {
        ServletRequest servletRequest = request.getNativeRequest(ServletRequest.class);
        Assert.state(servletRequest != null, "No ServletRequest");
        ServletRequestDataBinder servletBinder = (ServletRequestDataBinder) binder;
        servletBinder.bind(servletRequest);
    }

}

4 WebMvcConfig.java

스프링 MVC 구성 클래스, 파서는 파라미터의리스트 중에서 사용자 정의 파라미터 리졸버 스프링 MVC에 첨가된다.

@EnableWebMvc
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

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

}

5, User.java

POJO 클래스는 요청 매개 변수를 수신 정의된다.

@Data
public class User {

    private String id;
    private String name;
    private boolean flag;
    @Key("bank_type")
    private String bankType;

}

6 UserController.java

컨트롤러 테스트 클래스.

@RestController
@RequestMapping(value = "test")
public class UserController {

    @RequestMapping(value = "/user/add")
    public void add(@EnableKey User user){
        System.out.println(user);
    }

}

우체부를 사용하여 요청을 보내기 :

그림 삽입 설명 여기
콘솔은 사용자 개체가 필요합니다

그림 삽입 설명 여기
이러한 요청 객체가 배경 bank_type bankType 위의 속성에 바인딩 할 수 있습니다.

게시 된 173 개 원래 기사 · 원 찬양 221 · 전망 700 000 +

추천

출처blog.csdn.net/u012410733/article/details/100732730