Site Overlay

创建自定义注解映射自定义参数

一般从前台接收到的参数都是JSON之类的通用格式,或者通过@RequestBody自动映射实体类。但是如果想要将拿到的数据直接自动转换成一个非普通类实体,而不是拿到以后自己再封装。这时候最好就自定义一个注解,针对所需要的格式自动封装。

实现方法如下:

首先声明一个注解:(Dson为一个基于JSON格式的自定义二次封装类,对JSON格式进行空参判断,忽略引号,可以简易方法直接取值)

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

接下来写一个映射器,相当于上面自定义注解的实现方法。继承 AbstractMessageReaderArgumentResolver 类,实现其中两个方法,supportsParameter是判断该注解是否可以生效,true的话进入下面实现方法中进行实现,实现方法中resolveArgument进行处理后就传到@RequestBody中过一遍后传到Controller中进行逻辑处理。

package com.miracle.pay.anntoation;

import com.miracle.dson.Dson;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.core.ReactiveAdapterRegistry;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.codec.HttpMessageReader;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.util.Assert;
import org.springframework.web.reactive.BindingContext;
import org.springframework.web.reactive.result.method.annotation.AbstractMessageReaderArgumentResolver;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;


import java.util.List;
import java.util.Map;


/**
 * @Author Diuut
 * @Date 2020/4/29  10:23
 */
@Slf4j
public class DsonHandlerArgumentResolver extends AbstractMessageReaderArgumentResolver {


    public DsonHandlerArgumentResolver(List<HttpMessageReader<?>> readers) {

        super(readers);
    }

    protected DsonHandlerArgumentResolver(List<HttpMessageReader<?>> messageReaders, ReactiveAdapterRegistry adapterRegistry) {
        super(messageReaders, adapterRegistry);
    }

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        boolean hasParameterAnnotation = parameter.hasParameterAnnotation(RequestDson.class);
        log.info("supportsParameter: {}", hasParameterAnnotation);
        return hasParameterAnnotation;//绑定注解
    }

    @Override
    public Mono<Object> resolveArgument(MethodParameter parameter, BindingContext bindingContext, ServerWebExchange exchange) {
        RequestDson annotation = parameter.getParameterAnnotation(RequestDson.class);
        Assert.state(annotation != null, "No KIMBody annotation");
        ServerHttpRequest request = exchange.getRequest();
        if ("POST".equals(request.getMethodValue())) {
            Flux<DataBuffer> body = request.getBody();
            Mono<Object> mono = Mono.from(body.map(data -> {
                byte[] bytes = new byte[data.readableByteCount()];
                data.read(bytes);
                String bodyStr = new String(bytes);
                return Dson.fromMap(bodyStr);
            }));
            return mono;
        } else if ("GET".equals(request.getMethodValue())) {
            Map<String, String> stringStringMap2 = exchange.getRequest().getQueryParams().toSingleValueMap();
            for (Map.Entry<String, String> entry : stringStringMap2.entrySet()) {
                if (!entry.getKey().startsWith("{")) {
                    String replace = entry.getKey().replace('(', '{').replace(')', '}');
                    Dson dson = Dson.fromMap(replace);
                    return Mono.just(dson);
                } else {
                    Dson dson = Dson.fromMap(entry.getKey());
                    return Mono.just(dson);
                }
            }
        }
        return null;
    }
}

最后处理完之后,将该自定义注解配置加入spring中,将注解与映射器进行绑定

package com.miracle.pay.config;

import com.miracle.pay.anntoation.DsonHandlerArgumentResolver;

import org.springframework.context.annotation.Configuration;
import org.springframework.http.codec.DecoderHttpMessageReader;
import org.springframework.http.codec.HttpMessageReader;
import org.springframework.http.codec.json.Jackson2JsonDecoder;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.reactive.config.EnableWebFlux;
import org.springframework.web.reactive.config.WebFluxConfigurer;
import org.springframework.web.reactive.result.method.annotation.ArgumentResolverConfigurer;


import java.util.ArrayList;
import java.util.List;

/**
 * @Author Diuut
 * @Date 2020/4/28  14:45
 */
@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

    @Override
    public void configureArgumentResolvers(ArgumentResolverConfigurer configurer) {
        List<HttpMessageReader<?>> readers=new ArrayList<HttpMessageReader<?>>();
        //添加Http消息编解码器
        readers.add(new DecoderHttpMessageReader<>(new Jackson2JsonDecoder()));
        //消息编解码器与Resolver绑定
        configurer.addCustomResolver(new DsonHandlerArgumentResolver(readers));
    }

}

使用方法的话同在@RequestBody的位置替换为@RequestDson,即可从前台直接传Dson格式的数据到后台中直接使用。 以上。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

A beliving heart is your magic My heart
Copyright © 2020 Diuut. All Rights Reserved. | Catch Vogue by Catch Themes