springboot项目拦截前端请求中的特殊字符串 您所在的位置:网站首页 springboot自定义拦截器拦截所有请求 springboot项目拦截前端请求中的特殊字符串

springboot项目拦截前端请求中的特殊字符串

2024-02-03 12:15| 来源: 网络整理| 查看: 265

项目场景:

springboot项目中,需要对前端请求数据进行过滤,拦截特殊字符。

问题描述

GET请求可以很方便的通过处理URL判断是否包含特殊字符,POST类型请求需要对form-data/json特殊处理,使用@RequestBody注解的controller获取不到数据

原因分析:

request中的getInputStream()方法和getReader()方法只能获取一次数据,通过@RequestBody注解再次获取getInputStream()拿到结果为空,此处通过重写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); } // 获取请求中的流,将取出来的字符串,再次转换成流,然后把它放入到新request对象中 // 在chain.doFiler方法中传递新的request对象 if(requestWrapper == null) { chain.doFilter(request, response); } else { chain.doFilter(requestWrapper, response); } } @Override public void destroy() { } }

3、自定义保存流数据

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; /** * 自定义保存流数据 * @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(); } /** * 复制输入流 * @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的数据格式只能为json和json数组,根据业务场景自行调整)

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参数转义 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 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数组中是否含有特殊字符 * @param request 前端请求(包含json数据) * @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数组,包含则先遍历数组再遍历对象值 if (sb.toString().contains("[")){ List objectList = JSONObject.parseObject(sb.toString(), new TypeReference() {}); for(Object objTemp:objectList){ Map map = JSONObject.parseObject(JSONObject.parseObject(objTemp.toString()).toJSONString(), new TypeReference() {}); for (Object object : map.values()) { if (object != null) { Matcher m = Pattern.compile(REG_EX).matcher(object.toString()); if (m.find()) { return true; } } } } }else{ Map map = JSONObject.parseObject(JSONObject.parseObject(sb.toString()).toJSONString(), new TypeReference() {}); 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、实现拦截器

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请求类型数据值 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("请求参数中包含特殊字符"); } } else{ if(UrlFilter.checkSpecials(httpServletRequest)){ throw new Exception("请求的数据中包含特殊字符 "); } } } 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 { } }


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有