Spring MVCのカスタムクラス名パラメータバインディング

すべて知っているように、時間パラメータの間にスプリングMVCはバインディング。リクエストの前端部の後端部で定義されたクラス名パラメータ名は、一から一です。たとえば:名前のリクエストパラメータ値は、後端部に達しています。バックエンドのみのクラス、name属性を宣言し、その後、クラスを定義する必要があります。春のMVC値の送信要求が自動的にこの定義のクラス名に充填したとき。あなたは、このような問題が発生した場合はもちろんのバックエンドは、また、このような性質は、それに追加することができgoods_nameを宣言した場合、フロントエンドgoods_name(商品名)を定義することです。しかし、この操作は十分に優雅ではありません。

私はこの問題は行うに自動変換バネのアイデアの始まり経由で遭遇しました。しかし、それぞれの自動型変換は、それが動作しません見つけようとしています。最後に、結合スプリングMVCのリクエストパラメータ(HandlerMethodArgumentResolver)を使用すると、このような事をします。

次のようにアイデアは以下のとおりです。

リクエストパラメータのバインディングを行う場合には、リクエストパラメータリクエストメソッド内からオブジェクトを作成し、作成されたオブジェクトに要求対象データの内部に噴射依存ばねを介して注入します。

私の考えは通じ前述の2つの手順の間にカスタムパラメータパーサバインドパラメータです。その後、私の最初のリクエストパーサを結合カスタムパラメータ、およびは、協会内部のリクエストオブジェクトの対応するクラス属性と属性名に名前を付けるどのクラスにノートを宣言します。作成された後、対応するクラス属性の値は、その後に値設定部により反射されたリクエスト・オブジェクトから来ます。

具体的なコードは次のよう:

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