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

springboot項目攔截前端請求中的特殊字符串(解決方案)

 更新時間:2023年10月31日 15:15:05   作者:墨落成白123  
springboot項目中,需要對前端請求數(shù)據(jù)進行過濾,攔截特殊字符,本文通過實例代碼給大家分享完美解決方案,感興趣的朋友一起看看吧

項目場景:

springboot項目中,需要對前端請求數(shù)據(jù)進行過濾,攔截特殊字符。

問題描述

GET請求可以很方便的通過處理URL判斷是否包含特殊字符,POST類型請求需要對form-data/json特殊處理,使用@RequestBody注解的controller獲取不到數(shù)據(jù)

原因分析:

request中的getInputStream()方法和getReader()方法只能獲取一次數(shù)據(jù),通過@RequestBody注解再次獲取getInputStream()拿到結(jié)果為空,此處通過重寫getInputStream()方法和getReader()解決。貼出完整代碼如下。

解決方案:

1、注冊攔截器

package com.xxx;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
 * @author lsh
 * @version 1.0
 * @date 2022/4/1 16:54
 */
@Configuration
public class SpecialCharConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        if(registry!=null){
            registry.addInterceptor(new SpecialCharInterceptor()).addPathPatterns("/**");
        }
    }
}

2、注冊過濾器

package com.xxx;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
 * @author lsh
 * @version 1.0
 * @date 2022/4/1 17:03
 */
@Component
@WebFilter(filterName="specialCharFilter",urlPatterns="/*")
public class SpecialCharFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {
        ServletRequest requestWrapper = null;
        if (request instanceof HttpServletRequest){
            requestWrapper = new SpecialCharHttpServletRequestWrapper((HttpServletRequest) request);
        }
        // 獲取請求中的流,將取出來的字符串,再次轉(zhuǎn)換成流,然后把它放入到新request對象中
        // 在chain.doFiler方法中傳遞新的request對象
        if(requestWrapper == null) {
            chain.doFilter(request, response);
        } else {
            chain.doFilter(requestWrapper, response);
        }
    }
    @Override
    public void destroy() {
    }
}

3、自定義保存流數(shù)據(jù)

package com.xxx;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
/**
 * 自定義保存流數(shù)據(jù)
 * @author lsh
 * @version 1.0
 * @date 2022/4/1 16:56
 */
public class SpecialCharHttpServletRequestWrapper extends HttpServletRequestWrapper {
    public final HttpServletRequest  request;
    private final String bodyStr;
    public SpecialCharHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        this.request = request;
        this.bodyStr = getBodyString();
    }
    /**
     * 獲取請求Body
     * @return
     */
    public String getBodyString() {
        StringBuilder sb = new StringBuilder();
        InputStream inputStream = null;
        BufferedReader reader = null;
        try {
            inputStream = cloneInputStream(request.getInputStream());
            reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));
            String line = "";
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                }
                catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (reader != null) {
                try {
                    reader.close();
                }
                catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return sb.toString();
    }
    /**
     * 復(fù)制輸入流
     * @param inputStream 輸入流
     * @return
     */
    public InputStream cloneInputStream(ServletInputStream inputStream) {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len;
        try {
            while ((len = inputStream.read(buffer)) > -1) {
                byteArrayOutputStream.write(buffer, 0, len);
            }
            byteArrayOutputStream.flush();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        InputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
        return byteArrayInputStream;
    }
    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }
    @Override
    public ServletInputStream getInputStream() throws IOException {
        final ByteArrayInputStream bais = new ByteArrayInputStream(bodyStr.getBytes(Charset.forName("UTF-8")));
        return new ServletInputStream() {
            @Override
            public int read() throws IOException {
                return bais.read();
            }
            @Override
            public void setReadListener(ReadListener listener) {
            }
            @Override
            public boolean isReady() {
                return false;
            }
            @Override
            public boolean isFinished() {
                return false;
            }
        };
    }
}

4、特殊字符攔截類(application/json的數(shù)據(jù)格式只能為json和json數(shù)組,根據(jù)業(yè)務(wù)場景自行調(diào)整)

package com.xxx;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import org.apache.commons.lang3.StringUtils;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.URLDecoder;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * 攔截請求中包含的特殊字符
 * @author lsh
 * @version 1.0
 * @date 2022/4/1 16:27
 */
public class UrlFilter {
    /**
     * 特殊字符正則表達式
     */
    private final static String REG_EX = "[`~!@#$%^*()+|{}\\[\\].<>/??。ǎ尽俊唬骸薄?。,、\\\\]";
    /**
     * 判斷url中是否含有特殊字符
     * @param urls 前端請求鏈接
     * @return 是否包含特殊字符
     */
    public static boolean checkSpecials(String urls) {
        try {
            if (StringUtils.isNotEmpty(urls)) {
                // url參數(shù)轉(zhuǎn)義
                urls = URLDecoder.decode(urls, "utf-8");
                if (Pattern.compile(REG_EX).matcher(urls).find()) {
                    return true;
                }
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return false;
    }
    /**
     * 判斷formData值對象中是否包含特殊字符
     * @param map formData值對象
     * @return 是否包含特殊字符
     */
    public static boolean checkSpecials(Map<String,String[]> map){
        if(!map.isEmpty()){
            for(String[] paraArray : map.values()){
                for(String paraStr : paraArray){
                    if(Pattern.compile(REG_EX).matcher(paraStr).find()){
                        return true;
                    }
                }
            }
        }
        return false;
    }
    /**
     * 判斷前端傳過來的json和json數(shù)組中是否含有特殊字符
     * @param request 前端請求(包含json數(shù)據(jù))
     * @return 是否包含特殊字符
     */
    public static boolean checkSpecials(HttpServletRequest request) {
        try {
            SpecialCharHttpServletRequestWrapper wrapper = new SpecialCharHttpServletRequestWrapper(request);
            InputStream is = wrapper.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }
            if (sb.length() > 0) {
                //判斷json是否包含list數(shù)組,包含則先遍歷數(shù)組再遍歷對象值
                if (sb.toString().contains("[")){
                    List<Object> objectList = JSONObject.parseObject(sb.toString(), new TypeReference<List<Object>>() {});
                    for(Object objTemp:objectList){
                        Map<String, Object> map = JSONObject.parseObject(JSONObject.parseObject(objTemp.toString()).toJSONString(), new TypeReference<Map<String, Object>>() {});
                        for (Object object : map.values()) {
                            if (object != null) {
                                Matcher m = Pattern.compile(REG_EX).matcher(object.toString());
                                if (m.find()) {
                                    return true;
                                }
                            }
                        }
                    }
                }else{
                    Map<String, Object> map = JSONObject.parseObject(JSONObject.parseObject(sb.toString()).toJSONString(), new TypeReference<Map<String, Object>>() {});
                    for (Object object : map.values()) {
                        if (object != null) {
                            Matcher m = Pattern.compile(REG_EX).matcher(object.toString());
                            if (m.find()) {
                                return true;
                            }
                        }
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }
}

5、實現(xiàn)攔截器

package com.xxx;
import org.springframework.lang.Nullable;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * 特殊字符過濾
 * @author lsh
 * @version 1.0
 * @date 2022/4/1 16:25
 */
public class SpecialCharInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        if("GET".equals(httpServletRequest.getMethod())){
            if(UrlFilter.checkSpecials(httpServletRequest.getQueryString())){
                throw new Exception("url中包含特殊字符");
            }
        }else{
            String contentType = httpServletRequest.getContentType();
            //處理form-data請求類型數(shù)據(jù)值
            if (contentType != null && contentType.contains("multipart/form-data")) {
                MultipartResolver resolver = new CommonsMultipartResolver(httpServletRequest.getSession().getServletContext());
                MultipartHttpServletRequest multipartRequest = resolver.resolveMultipart(httpServletRequest);
                if(UrlFilter.checkSpecials(multipartRequest.getParameterMap())){
                    throw new Exception("請求參數(shù)中包含特殊字符");
                }
            }
            else{
                if(UrlFilter.checkSpecials(httpServletRequest)){
                    throw new Exception("請求的數(shù)據(jù)中包含特殊字符 ");
                }
            }
        }
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
    }
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
    }
}

到此這篇關(guān)于springboot項目攔截前端請求中的特殊字符串的文章就介紹到這了,更多相關(guān)springboot攔截特殊字符串內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java中equals()方法重寫實現(xiàn)代碼

    Java中equals()方法重寫實現(xiàn)代碼

    這篇文章主要介紹了Java中equals()方法重寫實現(xiàn)代碼的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • spring-cloud Sleuth的使用方法

    spring-cloud Sleuth的使用方法

    這篇文章主要介紹了spring-cloud Sleuth的使用方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-02-02
  • spring整合mybatis的底層原理分析

    spring整合mybatis的底層原理分析

    這篇文章主要介紹了spring整合mybatis的底層原理分析,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-05-05
  • 基于slf4j日志MDC輸出格式的問題

    基于slf4j日志MDC輸出格式的問題

    這篇文章主要介紹了基于slf4j日志MDC輸出格式的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • springboot如何配置Filter過濾器

    springboot如何配置Filter過濾器

    這篇文章主要介紹了springboot如何配置Filter過濾器問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • mybatis框架之mybatis中dao層開發(fā)的兩種方法

    mybatis框架之mybatis中dao層開發(fā)的兩種方法

    這篇文章主要介紹了mybatis框架之mybatis中dao層開發(fā)的兩種方法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • Spring Cloud入門教程之Zuul實現(xiàn)API網(wǎng)關(guān)與請求過濾

    Spring Cloud入門教程之Zuul實現(xiàn)API網(wǎng)關(guān)與請求過濾

    這篇文章主要給大家介紹了關(guān)于Spring Cloud入門教程之Zuul實現(xiàn)API網(wǎng)關(guān)與請求過濾的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-05-05
  • springboot多節(jié)點應(yīng)用里的雪花算法唯一性詳解

    springboot多節(jié)點應(yīng)用里的雪花算法唯一性詳解

    雪花算法在單節(jié)點下唯一,但在多副本Kubernetes環(huán)境中可能重復(fù),通過修改Pod名稱生成workId,解決了這個問題,同時避免了第三方組件和網(wǎng)絡(luò)請求,本文給大家介紹springboot多節(jié)點應(yīng)用里的雪花算法唯一性,感興趣的朋友一起看看吧
    2024-12-12
  • SpringBoot+輕量級分布式日志框架GrayLog實踐

    SpringBoot+輕量級分布式日志框架GrayLog實踐

    將SpringBoot日志遷移至GrayLog的實戰(zhàn)經(jīng)驗,稱其配置簡單、輕量高效,支持多環(huán)境分布式,通過GELF格式實現(xiàn)快速日志追蹤與報警,尤其強調(diào)traceId在跨服務(wù)定位中的關(guān)鍵作用,降低維護成本并提升故障排查效率
    2025-08-08
  • Java中for循環(huán)內(nèi)修改集合的常見陷阱與最佳實踐

    Java中for循環(huán)內(nèi)修改集合的常見陷阱與最佳實踐

    在Java編程中,for循環(huán)是遍歷集合(如List、Set)的常用方式,本文主要介紹了Java在for循環(huán)內(nèi)修改集合的常見陷阱與最佳實踐,希望對大家有所幫助
    2025-06-06

最新評論

五寨县| 景东| 池州市| 来宾市| 凤凰县| 桃园县| 叶城县| 深圳市| 洪湖市| 若羌县| 阳高县| 若羌县| 湘阴县| 英德市| 濮阳市| 连城县| 理塘县| 丁青县| 合阳县| 亚东县| 富顺县| 张家界市| 旌德县| 涟源市| 威信县| 新巴尔虎右旗| 新沂市| 江门市| 施甸县| 柘荣县| 东乡| 寿宁县| 通城县| 塔城市| 宜阳县| 鸡西市| 乌鲁木齐县| 太仆寺旗| 白水县| 凤庆县| 天气|