国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Controller層自定義注解攔截request請求校驗

這篇具有很好參考價值的文章主要介紹了Controller層自定義注解攔截request請求校驗。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

一、背景

筆者工作中遇到一個需求,需要開發(fā)一個注解,放在controller層的類或者方法上,用以校驗請求參數(shù)中(不管是url還是body體內(nèi),都要檢查,有token參數(shù),且符合校驗規(guī)則就放行)是否傳了一個token的參數(shù),并且token符合一定的生成規(guī)則,符合就不予攔截,放行請求,否則攔截請求。

用法如下圖所示

Controller層自定義注解攔截request請求校驗,spring,java

可以看到?@TokenCheck?注解既可以放在類上,也可以放在方法上 ,放在類上則對該類中的所有的方法進行攔截校驗。

注意:是加了注解才會校驗是否攔截,不加沒有影響。

整個代碼都是使用的最新springboot版本開發(fā)的,所以servlet相關的類都是使用jakarta

Controller層自定義注解攔截request請求校驗,spring,java

Controller層自定義注解攔截request請求校驗,spring,java

Controller層自定義注解攔截request請求校驗,spring,java

如果你的springboot版本比較老?,請使用javax

先引入以下依賴(javax不飄紅不用引入)

<dependency>

? ? ? <groupId>javax.servlet</groupId>

? ? ? <artifactId>javax.servlet-api</artifactId>

? ? ? <version>4.0.1</version>

? ? ? <scope>provided</scope>

</dependency>

Controller層自定義注解攔截request請求校驗,spring,java

?Controller層自定義注解攔截request請求校驗,spring,java

Controller層自定義注解攔截request請求校驗,spring,java

我用到的第三方依賴

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.12.0</version>
</dependency>
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.24</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>6.0.11</version>
</dependency>

二、TokenCheck注解

package com.example.demo.interceptorToken;
 
import java.lang.annotation.*;
 
/**
 * 是否有token
 */
@Documented
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface TokenCheck {
}

三、請求包裝器RequestWrapper

主要是對request請求包裝下,因為攔截器會攔截request,會讀取其中的參數(shù)流,而流只能讀一次,后續(xù)再用到流的讀取會報錯,所以用一個包裝器類處理下,把流以字節(jié)形式讀出來,重寫了getInputStream(),后續(xù)可以重復使用。

package com.example.demo.interceptorToken;

import jakarta.servlet.ReadListener;
import jakarta.servlet.ServletInputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequestWrapper;
import org.apache.commons.lang3.StringUtils;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;

/**
 * @author hulei
 * @date 2024/1/11 19:48
 * @Description 由于 request中getReader()和getInputStream()只能調(diào)用一次 導致在Controller @ResponseBody的時候獲取不到 null 或 Stream closed
 * 在項目中,可能會出現(xiàn)需要針對接口參數(shù)進行校驗等問題
 * 構建可重復讀取inputStream的request
 */
public class RequestWrapper extends HttpServletRequestWrapper {
    // 將流保存下來
    private final byte[] requestBody;

    public RequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        requestBody = readBytes(request.getReader());
    }

    @Override
    public ServletInputStream getInputStream() {

        final ByteArrayInputStream basic = new ByteArrayInputStream((requestBody != null && requestBody.length >0) ? requestBody : new byte[]{});

        return new ServletInputStream() {

            @Override
            public int read() {
                return basic.read();
            }

            @Override
            public boolean isFinished() {
                return false;
            }

            @Override
            public boolean isReady() {
                return false;
            }

            @Override
            public void setReadListener(ReadListener readListener) {

            }
        };
    }

    @Override
    public BufferedReader getReader() {
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }

    /**
     * 通過BufferedReader和字符編碼集轉(zhuǎn)換成byte數(shù)組
     */
    private byte[] readBytes(BufferedReader br) throws IOException {
        String str;
        StringBuilder retStr = new StringBuilder();
        while ((str = br.readLine()) != null) {
            retStr.append(str);
        }
        if (StringUtils.isNotBlank(retStr.toString())) {
            return retStr.toString().getBytes(StandardCharsets.UTF_8);
        }
        return null;
    }
}

四、過濾器RequestFilter

自定義請求過濾器,把請求用自定義的包裝器RequestWrapper包裝下,往調(diào)用下文傳遞,也是為了讓request請求的流能多次讀取

package com.example.demo.interceptorToken;
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.NonNull;
import org.springframework.core.annotation.Order;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.support.StandardServletMultipartResolver;
import java.io.IOException;

/**
 * @author hulei
 * @date 2024/1/11 19:48
 * 自定義請求過濾器
 */
//排序優(yōu)先級,最先執(zhí)行的過濾器
@Order(0)
public class RequestFilter extends OncePerRequestFilter {

    //spring6.0版本后刪除了CommonsMultipartResolver,使用StandardServletMultipartResolver
    //如果是spring6.0版本,此行代碼不報錯請使用如下
    // private CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
    private final StandardServletMultipartResolver multipartResolver = new StandardServletMultipartResolver();
    /**
     *
     */
    @Override
    protected void doFilterInternal(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull FilterChain filterChain) throws ServletException, IOException {
        //請求參數(shù)有form_data的話,防止request.getHeaders()報已使用,單獨處理
        if (request.getContentType() != null && request.getContentType().contains("multipart/form-data")) {
            MultipartHttpServletRequest multiReq = multipartResolver.resolveMultipart(request);
            filterChain.doFilter(multiReq, response);
        }else{
            ServletRequest requestWrapper;
            requestWrapper = new RequestWrapper(request);
            filterChain.doFilter(requestWrapper, response);
        }
    }

}

五、請求過濾器配置類TokenFilterConfig

這個很好理解,把自定義配置類注入spring容器

package com.example.demo.interceptorToken;

import jakarta.servlet.Filter;
import jakarta.servlet.FilterConfig;
import jakarta.servlet.ServletContext;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Enumeration;


/**
 * @author hulei
 * @date 2024/1/11 19:48
 * 將過濾器注入spring容器中
 */
@Configuration
public class TokenFilterConfig implements FilterConfig {
    @Bean
    Filter bodyFilter() {
        return new RequestFilter();
    }

    @Bean
    public FilterRegistrationBean<RequestFilter> filters() {
        FilterRegistrationBean<RequestFilter> filterRegistrationBean = new FilterRegistrationBean<>();
        filterRegistrationBean.setFilter((RequestFilter) bodyFilter());
        filterRegistrationBean.addUrlPatterns("/*");
        filterRegistrationBean.setName("requestFilter");
        //多個filter的時候order的數(shù)值越小 則優(yōu)先級越高
        //filterRegistrationBean.setOrder(0);
        return filterRegistrationBean;
    }

    @Override
    public String getFilterName() {
        return null;
    }

    @Override
    public ServletContext getServletContext() {
        return null;
    }

    @Override
    public String getInitParameter(String s) {
        return null;
    }

    @Override
    public Enumeration<String> getInitParameterNames() {
        return null;
    }
}

?六、核心類RequestInterceptor攔截器

注意如果你的springboot版本也是低于3.0,請繼承HandlerInterceptorAdapter類,實現(xiàn)其中方法,基本不用改動類中的內(nèi)容,只需要 把implements HandlerInterceptor 改為extends HandlerInterceptorAdapter即可。

package com.example.demo.interceptorToken;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import jakarta.servlet.ServletInputStream;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.NonNull;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.StreamUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.support.StandardServletMultipartResolver;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.net.URLDecoder;
import java.nio.charset.Charset;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author hulei
 * @date 2024/1/11 19:48
 * 自定義請求攔截器(spring boot 3.0以下的版本,需要繼承HandlerInterceptorAdapter類,實現(xiàn)對應得方法)
 */

public class RequestInterceptor implements HandlerInterceptor {

    /**
     * 需要從請求里驗證的關鍵字參數(shù)名
     */
    private static final String TOKEN_STR = "token";

    /**
     * 進入攔截的方法前觸發(fā)
     * 這里主要從打了注解請求中查找有沒有token關鍵字,并且token的值是否符合一定的生成規(guī)則,是就放行,不是就攔截
     */
    @Override
    public boolean preHandle(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull Object handler) throws Exception {
        if (handler instanceof HandlerMethod handlerMethod) {
            //獲取token注解
            TokenCheck tokenCheck = getTokenCheckAnnotation(handlerMethod);
            //請求參數(shù)有form_data的話,防止request.getHeaders()或request.getInputStream()報已使用錯誤,單獨處理
            if (request.getContentType() != null && request.getContentType().contains("multipart/form-data")) {
                //判斷當前注解是否存在
                if (tokenCheck != null) {
                    final StandardServletMultipartResolver multipartResolver = new StandardServletMultipartResolver();
                    MultipartHttpServletRequest multipartHttpServletRequest = multipartResolver.resolveMultipart(request);
                    String urlOrBodyToken = "", tokenFromHeaders, tokenFromCookies;
                    //獲取全部參數(shù),不管是params里的還是body(form_data)里的
                    urlOrBodyToken = getTokenFromUrlOrBody(multipartHttpServletRequest);
                    //從headers獲取token
                    tokenFromHeaders = getTokenFromHeaders(multipartHttpServletRequest);
                    //從cookies獲取token
                    tokenFromCookies = getTokenFromCookies(multipartHttpServletRequest);
                    if (tokenRuleValidation(urlOrBodyToken) || tokenRuleValidation(tokenFromHeaders) || tokenRuleValidation(tokenFromCookies)) {
                        return true;
                    } else {
                        returnJson(response, "token校驗失敗");
                        return false;
                    }
                }
            } else {
                //判斷當前注解是否存在
                if (tokenCheck != null) {
                    // 獲取請求方式,如果需要根據(jù)請求方式做不同處理,則獲取后自行判斷即可
                    //String requestMethod = request.getMethod();
                    request = new RequestWrapper(request);
                    //token關鍵字,分別是來自url、headers、cookies、body中的token
                    String tokenFromUrl, tokenFromHeaders, tokenFromCookies, tokenFromBody;
                    //url獲取token請求參數(shù)
                    tokenFromUrl = getTokenFromUrl(request);
                    //從headers獲取token
                    tokenFromHeaders = getTokenFromHeaders(request);
                    //從cookies獲取token
                    tokenFromCookies = getTokenFromCookies(request);
                    //從body體獲取token參數(shù)
                    tokenFromBody = getTokenFromBody(request);
                    //token校驗判斷
                    if (tokenRuleValidation(tokenFromUrl) || tokenRuleValidation(tokenFromHeaders) || tokenRuleValidation(tokenFromCookies) || tokenRuleValidation(tokenFromBody)) {
                        return true;
                    } else {
                        returnJson(response, "token校驗失敗");
                        return false;
                    }
                }
            }
            return true;
        }
        return true;
    }

    /**
     * 獲取TokenCheck注解(先從類上優(yōu)先獲取)
     */
    private TokenCheck getTokenCheckAnnotation(HandlerMethod handler) {
        Method method = handler.getMethod();
        //獲取方法所屬的類,并獲取類上的@TokenCheck注解
        Class<?> clazz = method.getDeclaringClass();
        TokenCheck tokenCheck = null;
        if (clazz.isAnnotationPresent(TokenCheck.class)) {
            tokenCheck = clazz.getAnnotation(TokenCheck.class);
        }
        //類上沒有注解,則從方法上再獲取@TokenCheck
        tokenCheck = tokenCheck == null ? method.getAnnotation(TokenCheck.class) : tokenCheck;
        return tokenCheck;
    }

//===============================================================================================================================

    /**
     * form_data參數(shù)形式,從url和body中獲取符合生成規(guī)則條的token
     */
    private String getTokenFromUrlOrBody(HttpServletRequest multipartHttpServletRequest) {
        String urlOrBodyToken = "";
        Map<String, String[]> urlAndBodyParam = multipartHttpServletRequest.getParameterMap();
        String[] tokenFromUrlOrBody = urlAndBodyParam.get(TOKEN_STR);
        for (String tokenStr : tokenFromUrlOrBody) {
            if (tokenRuleValidation(tokenStr)) {
                urlOrBodyToken = tokenStr;
                break;
            }
        }
        return urlOrBodyToken;
    }
//===============================================================================================================================

    /**
     * 從headers獲取token
     */
    private String getTokenFromHeaders(HttpServletRequest request) {
        Map<String, String> headerMap = new HashMap<>();
        Enumeration<String> enumeration = request.getHeaderNames();
        while (enumeration.hasMoreElements()) {
            String name = enumeration.nextElement();
            String value = request.getHeader(name);
            headerMap.put(name, value);
        }
        return headerMap.get(TOKEN_STR) == null ? "" : String.valueOf(headerMap.get(TOKEN_STR));
    }
//===============================================================================================================================

    /**
     * 從cookies獲取token
     */
    private String getTokenFromCookies(HttpServletRequest request) {
        Map<String, String> cookieMap = new ConcurrentHashMap<>();
        Cookie[] cookies = request.getCookies();
        if (null != cookies) {
            Arrays.stream(cookies).forEach(element ->
                    cookieMap.put(element.getName(), element.getValue())
            );
        }
        return cookieMap.get(TOKEN_STR) == null ? "" : String.valueOf(cookieMap.get(TOKEN_STR));
    }

//===============================================================================================================================

    /**
     * 從請求體獲取token參數(shù)
     */
    private String getTokenFromBody(HttpServletRequest request) throws Exception {
        String bodyParamsStr = this.getPostParam(request);
        String tokenFromBody = "";
        //判斷是否是json數(shù)組
        boolean isJsonArray = JSONUtil.isTypeJSONArray(bodyParamsStr);
        if (!isJsonArray) {
            tokenFromBody = JSONUtil.parseObj(bodyParamsStr).getStr(TOKEN_STR);
        } else {
            JSONArray jsonArray = JSONUtil.parseArray(bodyParamsStr);
            Set<String> tokenSet = new HashSet<>();
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                if (StringUtils.isNotEmpty(jsonObject.getStr(TOKEN_STR))) {
                    tokenSet.add(jsonObject.getStr(TOKEN_STR));
                }
            }
            if (!tokenSet.isEmpty()) {
                tokenFromBody = tokenSet.stream().filter(this::tokenRuleValidation).findFirst().orElse("");
            }
        }
        return tokenFromBody;
    }

    private String getPostParam(HttpServletRequest request) throws Exception {
        RequestWrapper readerWrapper = new RequestWrapper(request);
        return StringUtils.isEmpty(getBodyParams(readerWrapper.getInputStream(), request.getCharacterEncoding())) ?
                "{}" : getBodyParams(readerWrapper.getInputStream(), request.getCharacterEncoding());
    }

    private String getBodyParams(ServletInputStream inputStream, String charset) throws Exception {
        String body = StreamUtils.copyToString(inputStream, Charset.forName(charset));
        if (StringUtils.isEmpty(body)) {
            return "";
        }
        return body;
    }

//===============================================================================================================================

    /**
     * 如果是get請求,則把url中的請求參數(shù)獲取到,轉(zhuǎn)換為map
     */
    public String getTokenFromUrl(HttpServletRequest request) throws UnsupportedEncodingException {
        //獲取當前請求的編碼方式,用于參數(shù)value解碼
        String encoding = request.getCharacterEncoding();
        String urlQueryString = request.getQueryString();
        Map<String, String> queryMap = new HashMap<>();
        String[] arrSplit;
        if (urlQueryString == null) {
            return "";
        } else {
            //每個鍵值為一組
            arrSplit = urlQueryString.split("&");
            for (String strSplit : arrSplit) {
                String[] arrSplitEqual = strSplit.split("=");
                //解析出鍵值
                if (arrSplitEqual.length > 1) {
                    queryMap.put(arrSplitEqual[0], URLDecoder.decode(arrSplitEqual[1], encoding));
                } else {
                    if (!"".equals(arrSplitEqual[0])) {
                        queryMap.put(arrSplitEqual[0], "");
                    }
                }
            }
        }
        return queryMap.get(TOKEN_STR) == null ? "" : String.valueOf(queryMap.get(TOKEN_STR));
    }

    /**
     * token 規(guī)則校驗
     *
     * @param token token關鍵字
     */
    private boolean tokenRuleValidation(String token) {
        return "AAABBB".equals(token);

    }

    /**
     * 離開攔截的方法后觸發(fā)
     */
    @Override
    public void postHandle(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull Object handler, ModelAndView modelAndView) {

    }

    /**
     * 返回response的json信息
     */
    private void returnJson(HttpServletResponse response, String json) throws IOException {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html; charset=utf-8");
        try (PrintWriter writer = response.getWriter()) {
            writer.print(json);
        }
    }
}

七、攔截器注冊InterceptorRegister

一個配置類,把自定義的攔截器注入spring

package com.example.demo.interceptorToken;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * @author hulei
 * @date 2024/1/11 19:48
 * 將攔截注入spring容器
 */
@Configuration
public class InterceptorRegister implements WebMvcConfigurer {

    @Bean
    public RequestInterceptor tokenInterceptor() {
        return new RequestInterceptor();
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(tokenInterceptor());
    }
}

?八、總結(jié)

本例主要是自定義注解,完成請求參數(shù)的攔截校驗,實際中可根據(jù)需求進行修改,如記錄日志,攔截校驗其他參數(shù),修改RequestInterceptor中的攔截前方法和攔截后方法的邏輯即可

gitee地址:?Token-Check-Demo: 自定義注解攔截request請求

注: 創(chuàng)作不易,轉(zhuǎn)載請標明原作地址文章來源地址http://www.zghlxwxcb.cn/news/detail-798201.html

到了這里,關于Controller層自定義注解攔截request請求校驗的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 微信小程序封裝request請求,包含請求攔截器,響應攔截器和請求重試功能

    微信小程序封裝request請求,包含請求攔截器,響應攔截器和請求重試功能

    在發(fā)送請求之前,先判斷用戶是否有token,沒有就執(zhí)行登陸請求,將token保存,然后再執(zhí)行原來請求; 擁有token,就直接執(zhí)行請求;但是用戶的這個token可能是過期的,如果執(zhí)行請求發(fā)現(xiàn)用戶登陸過期,就統(tǒng)一返回40001,然后對40001的響應統(tǒng)一處理,執(zhí)行登陸請求,再執(zhí)行原來請

    2024年02月13日
    瀏覽(28)
  • 【SpringBoot】常用的的各種注解(一):Controller中的請求參數(shù)

    【SpringBoot】常用的的各種注解(一):Controller中的請求參數(shù)

    請求路徑中的參數(shù),可以有一個或者多個 在Postman中也是直接在請求路徑中添加參數(shù)即可 獲取查詢參數(shù),形式為 url?name=張三 ,可以有一個或者多個。 在Postman中可以使用 Query Params 的方式添加參數(shù): 也可以使用Body中的 form-data 的形式添加參數(shù) 一般用于傳輸DTO參數(shù),只能有一

    2024年02月06日
    瀏覽(22)
  • controller接口上帶@PreAuthorize的注解如何訪問 (postman請求示例)
  • 自定義注解與攔截器實現(xiàn)不規(guī)范sql攔截(攔截器實現(xiàn)篇)

    自定義注解與攔截器實現(xiàn)不規(guī)范sql攔截(攔截器實現(xiàn)篇)

    最近考慮myBatis中sql語句使用規(guī)范的問題,如果漏下條件或者寫一些不規(guī)范語句會對程序性能造成很大影響。最好的方法就是利用代碼進行限制,通過攔截器進行sql格式的判斷在自測環(huán)節(jié)就能找到問題。寫了個簡單情景下的demo,并通過idea插件來將myBatis的mapper方法都打上攔截器

    2024年01月22日
    瀏覽(29)
  • SpringBoot 使用【AOP 切面+注解】實現(xiàn)在請求調(diào)用 Controller 方法前修改請求參數(shù)和在結(jié)果返回之前修改返回結(jié)果

    在項目中需要實現(xiàn) 在請求調(diào)用 Controller 方法前修改請求參數(shù)和在結(jié)果返回之前修改返回結(jié)果 。 我們可以使用 AOP 切面+注解的形式實現(xiàn)。這樣我們就可以在不修改原始代碼的情況下,通過切面類在方法調(diào)用前后插入額外的邏輯。 自定義注解 @PreProcess 自定義注解 @PreProcess 用于

    2024年03月20日
    瀏覽(38)
  • 防重復提交:自定義注解 + 攔截器(HandlerInterceptor)

    防重復提交:自定義注解 + 攔截器(HandlerInterceptor) 一、思路: 1、首先自定義注解; 2、創(chuàng)建攔截器實現(xiàn)類(自定義類名稱),攔截器(HandlerInterceptor); 3、創(chuàng)建類:配置攔截器路徑(攔截URL規(guī)則); 二、代碼示例: 1、首先自定義注解; 2、創(chuàng)建攔截器實現(xiàn)類(自定義類名

    2024年02月10日
    瀏覽(26)
  • SpringBoot定義攔截器+自定義注解+Redis實現(xiàn)接口防刷(限流)

    在攔截器Interceptor中攔截請求 通過地址+請求uri作為調(diào)用者訪問接口的區(qū)分在Redis中進行計數(shù)達到限流目的 定義參數(shù) 訪問周期 最大訪問次數(shù) 禁用時長 代碼實現(xiàn) 定義攔截器:實現(xiàn)HandlerInterceptor接口,重寫preHandle()方法 注冊攔截器:配置類實現(xiàn)WebMvcConfigurer接口,重寫addIntercep

    2024年02月05日
    瀏覽(32)
  • Spring Boot框架中Controller層API接口如何支持使用多個@RequestBody注解接受請求體參數(shù)

    Spring Boot框架中Controller層API接口如何支持使用多個@RequestBody注解接受請求體參數(shù)

    眾所周知,在Spring Boot框架中,Controller層API接口編碼獲取請求體參數(shù)時,在參數(shù)上會使用@RequestBody注解;如果一次請求中,請求體參數(shù)攜帶的內(nèi)容需要用多個參數(shù)接收時,能不能多次使用@RequestBody注解呢? 下面我們先測試一下,參考代碼: PostMan進行請求: 服務端后端日志:

    2024年01月17日
    瀏覽(22)
  • java 自定義xss校驗注解實現(xiàn)

    java 自定義xss校驗注解實現(xiàn)

    自定義一個注解@Xss。名字隨意 validator校驗類:XssValidator。這個校驗類要和上面的@Xss注解上的 @Constraint(validatedBy = { XssValidator.class })對應 具體使用在某個字段上加上注解;形如: 然后在控制層中增加@Validated注解校驗就可以了 ?以上代碼實現(xiàn)后。會自動針對某些增加了@Xss字符

    2024年02月14日
    瀏覽(22)
  • 后端表情包依賴+自定義注解實現(xiàn)校驗

    開發(fā)過程中遇到小程序登記信息填寫文本時可能輸入表情包,需要后端校驗 由于字段太多,所以用自定義注解的方式來實現(xiàn) 步驟1:在pom文件中加入表情包依賴 步驟2: 自定義注解類 步驟3: 在請求的實體使用這個注解,需要要在controller中加入@Validated注解,校驗才會生效

    2024年02月16日
    瀏覽(28)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包