SpringBoot:基于redis自定义注解实现后端接口防重复提交校验

SpringBoot:基于redis自定义注解实现后端接口防重复提交校验
SpringBoot:基于redis自定义注解实现后端接口防重复提交校验
 
一、添加依赖
 
        <dependency>
 
            <groupId>org.springframework.boot</groupId>
 
            <artifactId>spring-boot-starter-redis</artifactId>
 
            <version>1.4.4.RELEASE</version>
 
        </dependency>
 
        <dependency>
 
            <groupId>redis.clients</groupId>
 
            <artifactId>jedis</artifactId>
 
            <version>3.6.3</version>
 
        </dependency>
 
<dependency>
 
            <groupId>com.alibaba</groupId>
 
            <artifactId>fastjson</artifactId>
 
            <version>1.2.75</version>
 
        </dependency>
 
二、代码实现
 
1.构建可重复读取inputStream的request
 
package com.hl.springbootrepetitionsubmit.servlet;
 
import javax.servlet.*;
 
import javax.servlet.http.*;
 
import java.io.*;
 
import java.nio.charset.StandardCharsets;
 
/**
 
 * 构建可重复读取inputStream的request
 
 */
 
public class RepeatedlyRequestWrapper extends HttpServletRequestWrapper {
 
    private final String body;
 
    public RepeatedlyRequestWrapper(HttpServletRequest request, ServletResponse response) throws IOException {
 
        super(request);
 
        request.setCharacterEncoding("UTF-8");
 
        response.setCharacterEncoding("UTF-8");
 
        body = getBodyString(request);
 
    }
 
    @Override
 
    public BufferedReader getReader() throws IOException {
 
        return new BufferedReader(new InputStreamReader(getInputStream()));
 
    }
 
    public String getBody() {
 
        return body;
 
    }
 
    @Override
 
    public ServletInputStream getInputStream() throws IOException {
 
        final ByteArrayInputStream bais = new ByteArrayInputStream(body.getBytes(StandardCharsets.UTF_8));
 
        return new ServletInputStream() {
 
            @Override
 
            public int read() throws IOException {
 
                return bais.read();
 
            }
 
            @Override
 
            public int available() throws IOException {
 
                return body.length();
 
            }
 
            @Override
 
            public boolean isFinished() {
 
                return false;
 
            }
 
            @Override
 
            public boolean isReady() {
 
                return false;
 
            }
 
            @Override
 
            public void setReadListener(ReadListener readListener) {
 
            }
 
        };
 
    }
 
    /**
 
     * 获取Request请求body内容
 
     *
 
     * @param request
 
     * @return
 
     */
 
    private String getBodyString(ServletRequest request) {
 
        StringBuilder sb = new StringBuilder();
 
        BufferedReader reader = null;
 
        try (InputStream inputStream = request.getInputStream()) {
 
            reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
 
            String line = "";
 
            while ((line = reader.readLine()) != null) {
 
                sb.append(line);
 
            }
 
        } catch (IOException e) {
 
            e.printStackTrace();
 
        } finally {
 
            if (reader != null) {
 
                try {
 
                    reader.close();
 
                } catch (IOException e) {
 
                    e.printStackTrace();
 
                }
 
            }
 
        }
 
        return sb.toString();
 
    }
 
}
 
2.重写request
 
package com.hl.springbootrepetitionsubmit.filter;
 
import com.hl.springbootrepetitionsubmit.servlet.RepeatedlyRequestWrapper;
 
import org.springframework.http.MediaType;
 
import org.springframework.util.StringUtils;
 
import javax.servlet.*;
 
import javax.servlet.http.HttpServletRequest;
 
import java.io.IOException;
 
/**
 
 * 过滤器(重写request)
 
 */
 
public class RepeatableFilter implements Filter {
 
    @Override
 
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
 
        ServletRequest requestWrapper = null;
 
        //将原生的request变为可重复读取inputStream的request
 
        if (request instanceof HttpServletRequest
 
                && StringUtils.startsWithIgnoreCase(request.getContentType(), MediaType.APPLICATION_JSON_VALUE)) {
 
            requestWrapper = new RepeatedlyRequestWrapper((HttpServletRequest) request, response);
 
        }
 
        if (null == requestWrapper) {
 
            chain.doFilter(request, response);
 
        } else {
 
            chain.doFilter(requestWrapper, response);
 
        }
 
    }
 
}

推荐阅读