最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

springboot集成Kaptcha實現(xiàn)圖片驗證碼過程

 更新時間:2025年06月24日 10:08:27   作者:yololee_  
這篇文章主要介紹了springboot集成Kaptcha實現(xiàn)圖片驗證碼過程,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

springboot:集成Kaptcha實現(xiàn)圖片驗證碼

  • 系統(tǒng)環(huán)境:
  • windows 10
  • jdk 1.8
  • springboot版本: 2.1.10.RELEASE

一、導(dǎo)入依賴

        <dependency>
            <groupId>com.github.penggle</groupId>
            <artifactId>kaptcha</artifactId>
            <version>2.3.2</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

系統(tǒng)配置文件

server:
  port: 81
spring:
  redis:
    database: 1
    host: 127.0.0.1
    port: 6379
    password:      # 密碼(默認為空)
    timeout: 6000ms  # 連接超時時長(毫秒)
    lettuce:
      pool:
        max-active: 1000  # 連接池最大連接數(shù)(使用負值表示沒有限制)
        max-wait: -1ms      # 連接池最大阻塞等待時間(使用負值表示沒有限制)
        max-idle: 10      # 連接池中的最大空閑連接
        min-idle: 5       # 連接池中的最小空閑連接

二、生成驗證碼

1、Kaptcha的配置

驗證碼文本生成器:這個需要自己生成并且修改下面的配置文件為你文件的路徑

package com.yolo.springboot.kaptcha.config;

import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.util.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Properties;

/**
 * @ClassName CaptchaConfig
 * @Description 驗證碼配置
 * @Author hl
 * @Date 2022/12/6 9:37
 * @Version 1.0
 */
@Configuration
public class CaptchaConfig {

    @Bean(name = "captchaProducerMath")
    public DefaultKaptcha getKaptchaBeanMath() {
        DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
        Properties properties = new Properties();
        // 是否有邊框 默認為true 我們可以自己設(shè)置yes,no
        properties.setProperty("kaptcha.border", "yes");
        // 邊框顏色 默認為Color.BLACK
        properties.setProperty("kaptcha.border.color", "105,179,90");
        // 驗證碼文本字符顏色 默認為Color.BLACK
        properties.setProperty("kaptcha.textproducer.font.color", "blue");
        // 驗證碼圖片寬度 默認為200
        properties.setProperty("kaptcha.image.width", "160");
        // 驗證碼圖片高度 默認為50
        properties.setProperty("kaptcha.image.height", "60");
        // 驗證碼文本字符大小 默認為40
        properties.setProperty("kaptcha.textproducer.font.size", "35");
        // KAPTCHA_SESSION_KEY
        properties.setProperty("kaptcha.session.key", "kaptchaCodeMath");
        // 驗證碼文本生成器
        properties.setProperty("kaptcha.textproducer.impl", "com.yolo.springboot.kaptcha.config.KaptchaTextCreator");
        // 驗證碼文本字符間距 默認為2
        properties.setProperty("kaptcha.textproducer.char.space", "3");
        // 驗證碼文本字符長度 默認為5
        properties.setProperty("kaptcha.textproducer.char.length", "6");
        // 驗證碼文本字體樣式 默認為new Font("Arial", 1, fontSize), new Font("Courier", 1,
        // fontSize)
        properties.setProperty("kaptcha.textproducer.font.names", "Arial,Courier");
        // 驗證碼噪點顏色 默認為Color.BLACK
        properties.setProperty("kaptcha.noise.color", "white");
        // 干擾實現(xiàn)類
        properties.setProperty("kaptcha.noise.impl", "com.google.code.kaptcha.impl.NoNoise");
        // 圖片樣式 水紋com.google.code.kaptcha.impl.WaterRipple
        // 魚眼com.google.code.kaptcha.impl.FishEyeGimpy
        // 陰影com.google.code.kaptcha.impl.ShadowGimpy
        properties.setProperty("kaptcha.obscurificator.impl", "com.google.code.kaptcha.impl.ShadowGimpy");
        Config config = new Config(properties);
        defaultKaptcha.setConfig(config);
        return defaultKaptcha;
    }
}

2、自定義驗證碼文本生成器

package com.yolo.springboot.kaptcha.config;

import com.google.code.kaptcha.text.impl.DefaultTextCreator;

import java.util.Random;

/**
 * @ClassName KaptchaTextCreator
 * @Description 驗證碼文本生成器
 * @Author hl
 * @Date 2022/12/6 10:14
 * @Version 1.0
 */
public class KaptchaTextCreator extends DefaultTextCreator {

    private static final String[] Number = "0,1,2,3,4,5,6,7,8,9,10".split(",");
    @Override
    public String getText()
    {
        int result;
        Random random = new Random();
        int x = random.nextInt(10);
        int y = random.nextInt(10);
        StringBuilder suChinese = new StringBuilder();
        int randomOperand = (int) Math.round(Math.random() * 2);
        if (randomOperand == 0) {
            result = x * y;
            suChinese.append(Number[x]);
            suChinese.append("*");
            suChinese.append(Number[y]);
        } else if (randomOperand == 1) {
            if (!(x == 0) && y % x == 0) {
                result = y / x;
                suChinese.append(Number[y]);
                suChinese.append("/");
                suChinese.append(Number[x]);
            } else {
                result = x + y;
                suChinese.append(Number[x]);
                suChinese.append("+");
                suChinese.append(Number[y]);
            }
        } else if (randomOperand == 2) {
            if (x >= y) {
                result = x - y;
                suChinese.append(Number[x]);
                suChinese.append("-");
                suChinese.append(Number[y]);
            } else {
                result = y - x;
                suChinese.append(Number[y]);
                suChinese.append("-");
                suChinese.append(Number[x]);
            }
        } else {
            result = x + y;
            suChinese.append(Number[x]);
            suChinese.append("+");
            suChinese.append(Number[y]);
        }
        suChinese.append("=?@").append(result);
        return suChinese.toString();
    }
}

3、具體實現(xiàn)

package com.yolo.springboot.kaptcha.controller;

import cn.hutool.json.JSONUtil;
import com.google.code.kaptcha.Producer;
import com.hl.springbootcommon.common.HttpResponseTemp;
import com.hl.springbootcommon.common.ResultStat;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.util.FastByteArrayOutputStream;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName CaptchaController
 * @Description 驗證碼
 * @Author hl
 * @Date 2022/12/6 9:45
 * @Version 1.0
 */
@RestController
@Slf4j
public class CaptchaController {

    @Autowired
    private Producer producer;

    @Autowired
    private StringRedisTemplate redisTemplate;

    public static final String DEFAULT_CODE_KEY = "random_code_";

   /**
      * @MethodName createCaptcha
      * @Description  生成驗證碼
      * @param httpServletResponse 響應(yīng)流
      * @Author hl
      * @Date 2022/12/6 10:30
      */
    @GetMapping("/create/captcha")
    public void createCaptcha(HttpServletResponse httpServletResponse) throws IOException {
        // 生成驗證碼
        String capText = producer.createText();
        String capStr = capText.substring(0, capText.lastIndexOf("@"));
        String result = capText.substring(capText.lastIndexOf("@") + 1);
        BufferedImage image = producer.createImage(capStr);
        // 保存驗證碼信息
        String randomStr = UUID.randomUUID().toString().replaceAll("-", "");
        System.out.println("隨機數(shù)為:" + randomStr);
        redisTemplate.opsForValue().set(DEFAULT_CODE_KEY + randomStr, result, 3600, TimeUnit.SECONDS);
        // 轉(zhuǎn)換流信息寫出
        FastByteArrayOutputStream os = new FastByteArrayOutputStream();
        try {
            ImageIO.write(image, "jpg", os);
        } catch (IOException e) {
            log.error("ImageIO write err", e);
            httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND);
            return;
        }

        // 定義response輸出類型為image/jpeg類型,使用response輸出流輸出圖片的byte數(shù)組
        byte[] bytes = os.toByteArray();
        //設(shè)置響應(yīng)頭
        httpServletResponse.setHeader("Cache-Control", "no-store");
        //設(shè)置響應(yīng)頭
        httpServletResponse.setHeader("randomstr",randomStr);
        //設(shè)置響應(yīng)頭
        httpServletResponse.setHeader("Pragma", "no-cache");
        //在代理服務(wù)器端防止緩沖
        httpServletResponse.setDateHeader("Expires", 0);
        //設(shè)置響應(yīng)內(nèi)容類型
        ServletOutputStream responseOutputStream = httpServletResponse.getOutputStream();
        responseOutputStream.write(bytes);
        responseOutputStream.flush();
        responseOutputStream.close();
    }
}

三、校驗驗證碼

這里校驗驗證碼,我用了過濾器來實現(xiàn)的,其中遇到了很多問題,下面有我詳細的解決方法

1、controller接口

    @PostMapping("/login")
    public HttpResponseTemp<?> login(@RequestBody LoginDto loginDto){

        System.out.println(JSONUtil.toJsonStr(loginDto));
        return ResultStat.OK.wrap("","成功");
    }

@Data
public class LoginDto {

    private String captcha;
    private String randomStr;
}

2、自定義前端過濾器

這里是我寫了一個簡單的前端頁面,然后發(fā)現(xiàn)這里會有一些前端的文件,所以需要過濾一下

package com.yolo.springboot.kaptcha.filter;

import cn.hutool.core.collection.ListUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.filter.ShallowEtagHeaderFilter;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

/**
 * @ClassName SuffixFilter
 * @Description 前端文件過濾
 * @Author hl
 * @Date 2022/12/6 12:40
 * @Version 1.0
 */
public class FrontFilter extends ShallowEtagHeaderFilter implements Filter {

    private static final List<String> suffix = ListUtil.of(".css",".eot",".gif",".ico",".js",".map",".png",".svg",".swf",".ttf",".TTF",".woff",".woff2");


    @Override
    protected boolean shouldNotFilterAsyncDispatch() {
        return false;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        response.setHeader("Server", "Apache-Coyote/1.1");
        response.setHeader("Cache-Control", "max-age=0");
        String uri = request.getRequestURI();
        if (!StringUtils.isBlank(uri)) {
            int index = uri.lastIndexOf(".");
            if (index > 0 && suffix.contains(uri.substring(index))) {
                response.setHeader("Cache-Control", "max-age=3600");
            }
            if (uri.startsWith("/lib")) {
                response.setHeader("Cache-Control", "max-age=3600, immutable");
            }
        }
        super.doFilterInternal(request, response, filterChain);
    }
}

然后需要把我們自定的過濾器加入到spring中讓他生效

package com.yolo.springboot.kaptcha.config;

import com.yolo.springboot.kaptcha.filter.FrontFilter;
import com.yolo.springboot.kaptcha.filter.ImgCodeFilter;
import com.yolo.springboot.kaptcha.filter.BodyReaderFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Configuration
public class FilterConfig {

    @Bean
    public FilterRegistrationBean<?> frontFilterRegistration() {
        FilterRegistrationBean<FrontFilter> registration = new FilterRegistrationBean<>();
        // 將過濾器配置到FilterRegistrationBean對象中
        registration.setFilter(new FrontFilter());
        // 給過濾器取名
        registration.setName("frontFilter");
        // 設(shè)置過濾器優(yōu)先級,該值越小越優(yōu)先被執(zhí)行
        registration.setOrder(0);
        List<String> urlPatterns = new ArrayList<>();
        urlPatterns.add("/*");
        // 設(shè)置urlPatterns參數(shù)
        registration.setUrlPatterns(urlPatterns);
        return registration;
    }
}

這里我給他設(shè)置的攔截全部請求,并且優(yōu)先級是第一位的

3、自定義驗證碼處理過濾器

package com.yolo.springboot.kaptcha.filter;

import com.alibaba.fastjson.JSONObject;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.stream.Collectors;

/**
 * @ClassName ImgCodeFilter
 * @Description 驗證碼處理
 * @Author hl
 * @Date 2022/12/6 10:35
 * @Version 1.0
 */
@AllArgsConstructor
public class ImgCodeFilter implements Filter {

    private final StringRedisTemplate redisTemplate;

    private final static String AUTH_URL = "/login";

    public static final String DEFAULT_CODE_KEY = "random_code_";


    /**
     * filter對象只會創(chuàng)建一次,init方法也只會執(zhí)行一次。
     */
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    /**
     * 主要的業(yè)務(wù)代碼編寫方法
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //只有轉(zhuǎn)換為HttpServletRequest 對象才可以獲取路徑參數(shù)
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        String requestURI = request.getRequestURI();
        if (!AUTH_URL.equalsIgnoreCase(requestURI)){
            //放行
            filterChain.doFilter(servletRequest, servletResponse);
        }

        try {
            String bodyStr = resolveBodyFromRequest(request);
            JSONObject bodyJson=JSONObject.parseObject(bodyStr);
            String code = (String) bodyJson.get("captcha");
            String randomStr = (String) bodyJson.get("randomStr");
            // 校驗驗證碼
            checkCode(code, randomStr);
        } catch (Exception e) {
            HttpServletResponse response = (HttpServletResponse) servletResponse;
            response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
            response.setHeader("Content-Type", "application/json;charset=UTF-8");
            response.sendError(HttpStatus.UNAUTHORIZED.value(),"驗證碼認證失敗或者過期");
        }
        filterChain.doFilter(servletRequest, servletResponse);
    }

    /**
     * 檢查code
     */
    @SneakyThrows
    private void checkCode(String code, String randomStr) {
        if (StringUtils.isBlank(code)) {
            throw new RuntimeException("驗證碼不能為空");
        }
        if (StringUtils.isBlank(randomStr)) {
            throw new RuntimeException("驗證碼不合法");
        }
        String key = DEFAULT_CODE_KEY + randomStr;
        String result = redisTemplate.opsForValue().get(key);
        redisTemplate.delete(key);
        if (!code.equalsIgnoreCase(result)) {
            throw new RuntimeException("驗證碼不合法");
        }
    }

    /**
       * @MethodName resolveBodyFromRequest
       * @Description  不能和@Requestbody搭配使用
       * 原因: getInputStream() has already been called for this request,流不能讀取第二次,@Requestbody已經(jīng)讀取過一次了
       * @param request 請求流
       * 解決方案: 重寫HttpServletRequestWrapper類,將HttpServletRequest的數(shù)據(jù)讀到wrapper的緩存中去(用 byte[] 存儲),再次讀取時讀緩存就可以了
       * 當(dāng)接口涉及到上傳下載時,會有一些異常問題,最好在過濾器中排除這些路徑
       * @return: java.lang.String
       * @Author hl
       * @Date 2022/12/6 15:18
       */

    private String resolveBodyFromRequest(HttpServletRequest request){
        String bodyStr = null;
        // 獲取請求體
        if ("POST".equalsIgnoreCase(request.getMethod())){
            try {
                bodyStr = request.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return bodyStr;
    }

    /**
     * 在銷毀Filter時自動調(diào)用。
     */
    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}

加入到配置中

這里校驗需要用到redis,用構(gòu)造方法給他注入

    @Autowired
    private StringRedisTemplate redisTemplate;
    @Bean
    public FilterRegistrationBean<?> imgCodeFilterRegistration() {
        FilterRegistrationBean<ImgCodeFilter> registration = new FilterRegistrationBean<>();
        // 將過濾器配置到FilterRegistrationBean對象中
        registration.setFilter(new ImgCodeFilter(redisTemplate));
        // 給過濾器取名
        registration.setName("imgCodeFilter");
        // 設(shè)置過濾器優(yōu)先級,該值越小越優(yōu)先被執(zhí)行
        registration.setOrder(2);
        List<String> urlPatterns = new ArrayList<>();
        urlPatterns.add("/login");
        // 設(shè)置urlPatterns參數(shù)
        registration.setUrlPatterns(urlPatterns);
        return registration;
    }

遇到的問題及解決思路

問題:流不能多次被調(diào)用

ERROR m.e.handler.GlobalExceptionHandler - getInputStream() has already been called for this request
java.lang.IllegalStateException: getInputStream() has already been called for this request
    at org.apache.catalina.connector.Request.getReader(Request.java:1212)
    at org.apache.catalina.connector.RequestFacade.getReader(RequestFacade.java:504)

根據(jù)報錯信息分析簡單來說,就是getInputStream()已經(jīng)被調(diào)用了,不能再次調(diào)用??墒俏铱创a上,我也沒調(diào)用。經(jīng)過一番檢索,原來@RequestBody注解配置后,默認會使用流來讀取數(shù)據(jù)

具體原因:

  • 默認配置時,getInputStream()和getReader()一起使用會報錯,使用兩遍getInputStream(),第二遍會為空
  • 當(dāng)存在@RequestBody等注解時,springMVC已讀取過一遍流,默認單獨使用getInputStream()或getReader()都為空。

實測,不加@RequestBody注解,可以如期獲得請求中的json參數(shù),但是又不得不加@RequestBody注解。這樣就需要新的思路

解決思路:

寫filter繼承HttpServletRequestWrapper,緩存InputStream,覆蓋getInputStream()和getReader()方法,使用ByteArrayInputStream is = new ByteArrayInputStream(body.getBytes());讀取InputStream。下面自定義BodyReaderFilter和BodyReaderWrapper就是具體解決方法

4、自定義BodyReaderFilter解決讀取body錯誤問題

BodyReaderWrapper

package com.yolo.springboot.kaptcha.filter;

import org.springframework.util.StreamUtils;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;

/**
 * 自定義 BodyReaderWrapper
 * 問題原因:在controller中我們通過@RequestBody注解來獲取前端傳過來的json數(shù)據(jù),這里已經(jīng)使用了一次request來獲取body中的值。再次通過request獲取body中的值,就會報錯
 * 使用場景:通過request能獲取到一次body中的值,有時候我們需要多次獲取body中的值的需求,因此需要對流再次封裝再次傳遞
 */
public class BodyReaderWrapper extends HttpServletRequestWrapper {
    private byte[] body;

    public BodyReaderWrapper(HttpServletRequest request) throws IOException {
        super(request);
        //保存一份InputStream,將其轉(zhuǎn)換為字節(jié)數(shù)組
        body = StreamUtils.copyToByteArray(request.getInputStream());
    }

    //轉(zhuǎn)換成String
    public String getBodyString(){
        return new String(body,StandardCharsets.UTF_8);
    }


    @Override
    public BufferedReader getReader() {
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }
	//把保存好的InputStream,傳下去
    @Override
    public ServletInputStream getInputStream() {
        final ByteArrayInputStream bais = new ByteArrayInputStream(body);
        return new ServletInputStream() {
            @Override
            public int read() {
                return bais.read();
            }
            @Override
            public boolean isFinished() {
                return false;
            }
            @Override
            public boolean isReady() {
                return false;
            }
            @Override
            public void setReadListener(ReadListener readListener) {
            }
        };
    }
    public void setInputStream(byte[] body) {
        this.body = body;
    }
}

BodyReaderFilter

package com.yolo.springboot.kaptcha.filter;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import org.apache.commons.lang3.StringUtils;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @ClassName RequestFilter
 * @Description 自定義BodyReaderFilter解決讀取controller中使用@Requestbody重復(fù)讀取流錯誤問題
 * @Author hl
 * @Date 2022/12/6 15:44
 * @Version 1.0
 */
public class BodyReaderFilter implements Filter {
    private List<String> noFilterUrls;

    @Override
    public void init(FilterConfig filterConfig){
        // 從過濾器配置中獲取initParams參數(shù)
        String noFilterUrl = filterConfig.getInitParameter("noFilterUrl");
        // 將排除的URL放入成員變量noFilterUrls中
        if (StringUtils.isNotBlank(noFilterUrl)) {
            noFilterUrls = new ArrayList<>(Arrays.asList(noFilterUrl.split(",")));
        }
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
        ServletRequest requestWrapper = null;
        String requestURI = null;

        if (servletRequest instanceof HttpServletRequest) {
            //獲取請求中的流如何,將取出來的字符串,再次轉(zhuǎn)換成流,然后把它放入到新request對象中。
            requestWrapper = new BodyReaderWrapper((HttpServletRequest) servletRequest);
            requestURI = ((HttpServletRequest) servletRequest).getRequestURI();
        }

        //如果請求是需要排除的,直接放行,例如上傳文件
        if ((CollUtil.isNotEmpty(noFilterUrls) && StrUtil.isNotBlank(requestURI) && noFilterUrls.contains(requestURI)) || requestWrapper == null){
            chain.doFilter(servletRequest, servletResponse);
        }else {
            // 在chain.doFiler方法中傳遞新的request對象
            chain.doFilter(requestWrapper, servletResponse);
        }
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}

加入到配置中

這里需要注意,攔截的是所有請求,上傳文件的時候需要排除,上傳文件的路徑

    @Bean
    public FilterRegistrationBean<?> bodyReaderFilterRegistration() {
        FilterRegistrationBean<BodyReaderFilter> registration = new FilterRegistrationBean<>();
        // 將過濾器配置到FilterRegistrationBean對象中
        registration.setFilter(new BodyReaderFilter());
        // 給過濾器取名
        registration.setName("bodyReaderFilter");
        // 設(shè)置過濾器優(yōu)先級,該值越小越優(yōu)先被執(zhí)行
        registration.setOrder(1);
        List<String> urlPatterns = new ArrayList<>();
        //這里需要填寫排除上傳文件的接口
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("noFilterUrl", "/test");
        // 設(shè)置initParams參數(shù)
        registration.setInitParameters(paramMap);
        urlPatterns.add("/*");
        // 設(shè)置urlPatterns參數(shù)
        registration.setUrlPatterns(urlPatterns);
        return registration;
    }

測試成功:這里我原本用的form-data傳參,然后一直獲取到body為空,用這種方法是需要在raw中進行填寫的

獲取form表單的數(shù)據(jù)

		//方式一:getParameterMap(),獲得請求參數(shù)map
        Map<String,String[]> map= request.getParameterMap();  //key 參數(shù)名稱 value:具體值
		//方式二:getParameterNames():獲取所有參數(shù)名稱
        Enumeration a = request.getParameterNames();

5、注意

自定義的過濾器不要交給spring管理,也就是說不要添加@Component注解,不然每一個請求都會進行過濾

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java并發(fā)工具類Phaser詳解

    Java并發(fā)工具類Phaser詳解

    這篇文章主要介紹了Java并發(fā)工具類Phaser詳解,Phaser(階段協(xié)同器)是一個Java實現(xiàn)的并發(fā)工具類,用于協(xié)調(diào)多個線程的執(zhí)行,它提供了一些方便的方法來管理多個階段的執(zhí)行,可以讓程序員靈活地控制線程的執(zhí)行順序和階段性的執(zhí)行,需要的朋友可以參考下
    2023-11-11
  • 解決java連接zookeeper很慢的問題

    解決java連接zookeeper很慢的問題

    這篇文章主要介紹了解決java連接zookeeper很慢的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Spring?Boot中使用Spring?Retry重試框架的操作方法

    Spring?Boot中使用Spring?Retry重試框架的操作方法

    這篇文章主要介紹了Spring?Retry?在SpringBoot?中的應(yīng)用,介紹了RetryTemplate配置的時候,需要設(shè)置的重試策略和退避策略,需要的朋友可以參考下
    2022-04-04
  • Springboot項目啟動到一半卡住了,不報錯問題及解決

    Springboot項目啟動到一半卡住了,不報錯問題及解決

    這篇文章主要介紹了Springboot項目啟動到一半卡住了,不報錯問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • Springboot如何使用OSHI獲取和操作系統(tǒng)和硬件信息

    Springboot如何使用OSHI獲取和操作系統(tǒng)和硬件信息

    這篇文章主要介紹了Springboot如何使用OSHI獲取和操作系統(tǒng)和硬件信息問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • Java優(yōu)秀測試框架TestNG詳解

    Java優(yōu)秀測試框架TestNG詳解

    這篇文章主要為大家詳細介紹了Java優(yōu)秀測試框架TestNG,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-02-02
  • java實現(xiàn)撲克牌分發(fā)功能

    java實現(xiàn)撲克牌分發(fā)功能

    這篇文章主要為大家詳細介紹了java實現(xiàn)撲克牌分發(fā),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • Maven deploy配置方法詳解

    Maven deploy配置方法詳解

    這篇文章主要介紹了Maven deploy配置方法詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • Java中的ByteArrayInputStream詳解

    Java中的ByteArrayInputStream詳解

    Java中,ByteArrayInputStream類是實現(xiàn)內(nèi)存級別的字節(jié)流讀取的工具,可以從字節(jié)數(shù)組中讀取數(shù)據(jù),這個類位于java.io包中,繼承自InputStream,ByteArrayInputStream的主要特點有:在內(nèi)存中操作,不涉及磁盤IO,可以重用流讀取數(shù)據(jù)
    2024-09-09
  • SpringMVC4 + MyBatis3 + SQL Server 2014整合教程(含增刪改查分頁)

    SpringMVC4 + MyBatis3 + SQL Server 2014整合教程(含增刪改查分頁)

    這篇文章主要給大家介紹了關(guān)于SpringMVC4 + MyBatis3 + SQL Server 2014整合的相關(guān)資料,文中包括介紹了增刪改查分頁等相關(guān)內(nèi)容,通過示例代碼介紹的非常詳細,分享出來供大家參考學(xué)習(xí),下面來一起看看吧。
    2017-06-06

最新評論

牟定县| 丹凤县| 岳池县| 扶余县| 大埔县| 潜江市| 馆陶县| 罗源县| 临高县| 陈巴尔虎旗| 当阳市| 昌宁县| 河北省| 延吉市| 博爱县| 邹城市| 疏勒县| 大厂| 临城县| 呼和浩特市| 嘉兴市| 肇州县| 陵川县| 涞水县| 工布江达县| 吉林市| 右玉县| 兰州市| 隆安县| 广德县| 巴彦县| 正蓝旗| 吴堡县| 石楼县| 重庆市| 博爱县| 托克托县| 景洪市| 栖霞市| 尚义县| 金阳县|