您现在的位置是:首页 > 编程 > 

SpringBoot的使用

2025-07-23 01:57:50
SpringBoot的使用 一、前言在SpringBoot开发web应用的过程中,常常会使用到。而是一个很常用的功能,它支持我们在HTTP请求到达Controller之前添加一些自定义的逻辑比如说,在到达Controller之前,将对一些敏感词汇进行检测,一旦出现敏感词,看你是过滤,还是直接返回异常这就是的一个简单应用,通过本篇文章,您将会了解到SpringBoot的

SpringBoot的使用

一、前言

SpringBoot开发web应用的过程中,常常会使用到。

而是一个很常用的功能,它支持我们在HTTP请求到达Controller之前添加一些自定义的逻辑

比如说,在到达Controller之前,将对一些敏感词汇进行检测,一旦出现敏感词,看你是过滤,还是直接返回异常

这就是的一个简单应用,通过本篇文章,您将会了解到SpringBoot的功能使用

二、代码

的使用可以分为两个步骤

  1. 实现HandlerInterceptor,编写自己的
  2. 对上面写好的进行注册

首先我们先确定好自己需要做什么,就按照前言那样说的,我们对request中的body参数进行检测,只要有敏感词就将异常抛出

但是有个问题,HttpServletRequest的输入流只够读取一次,如果这边用了,那么后面controller就读取不到body流了

解决办法也是有的,就是使用HttpServletRequestWrapper装饰,在进入的时候HttpServletRequest替换为这个装饰类

我们先写一个类,用来继承实现自己的缓存

代码语言:javascript代码运行次数:0运行复制
 package com.;
 ​
 import javax.servlet.ReadListener;
 import javax.servlet.ServletInputStream;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletRequestWrapper;
 import java.io.*;
 ​
 public class CachedBodyHttpServletRequest extends HttpServletRequestWrapper {
 ​
     private final byte[] cachedBody;
 ​
     public CachedBodyHttpServletRequest(HttpServletRequest request) throws IOException {
         super(request);
         InputStream requestInputStream = request.getInputStream();
          = toByteArray(requestInputStream);
     }
 ​
     @Override
     public ServletInputStream getInputStream() throws IOException {
         return new CachedBodyServletInputStream();
     }
 ​
     @Override
     public BufferedReader getReader() throws IOException {
         ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream();
         return new BufferedReader(new InputStreamReader(byteArrayInputStream));
     }
 ​
     private byte[] toByteArray(InputStream input) throws IOException {
         ByteArrayOutputStream output = new ByteArrayOutputStream();
         byte[] buffer = new byte[1024];
         int n;
         while ((n = input.read(buffer)) != -1) {
             output.write(buffer, 0, n);
         }
         return ();
     }
 ​
     private static class CachedBodyServletInputStream extends ServletInputStream {
         private final ByteArrayInputStream buffer;
 ​
         public CachedBodyServletInputStream(byte[] contents) {
             this.buffer = new ByteArrayInputStream(contents);
         }
 ​
         @Override
         public boolean isFinished() {
             return buffer.available() == 0;
         }
 ​
         @Override
         public boolean isReady() {
             return true;
         }
 ​
         @Override
         public void setReadListener(ReadListener readListener) {
             throw new UnsupportedOperationException();
         }
 ​
         @Override
         public int read() throws IOException {
             return buffer.read();
         }
     }
 }

有了此类之后,我们还需要在之前,将我们的HttpServletRequest替换为CachedBodyHttpServletRequest,使用过滤器即可

代码语言:javascript代码运行次数:0运行复制
 package com.;
 ​
 import slf4j.Slf4j;
 import org.springframework.stereotype.Component;
 ​
 import javax.servlet.*;
 import javax.servlet.http.HttpServletRequest;
 import java.io.IOException;
 ​
 @Slf4j
 @Component
 public class ReplaceStreamFilter implements Filter {
 ​
     @Override
     public void doFilter(ServletRequest request, ServletRespe respe, FilterChain chain) throws IOException, ServletException {
         ServletRequest requestWrapper = new CachedBodyHttpServletRequest((HttpServletRequest) request);
         chain.doFilter(requestWrapper, respe);
     }
 }

如此一来,body流的情况就解决了


现在我们再来编写我们的

代码语言:javascript代码运行次数:0运行复制
 package com.;
 ​
 import cn.io.IoUtil;
 import com.banmoon.BanmoonException;
 import org.jetbrains.;
 import org.springframework.stereotype.Component;
 import org.springframework.web.servlet.HandlerInterceptor;
 ​
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletRespe;
 import java.io.BufferedReader;
 ​
 @Component
 public class SensitiveWordsInterceptor implements HandlerInterceptor {
 ​
     public static final String SESITIVE_WORDS = "敏感词";
 ​
     @Override
     public boolean preHandle(@otull HttpServletRequest request, @otull HttpServletRespe respe, @otull Object handler) throws Exception {
         BufferedReader reader = request.getReader();
         String read = IoUtil.read(reader);
         if ((SESITIVE_WORDS)) {
             throw new BanmoonException("包含敏感词");
         }
         return HandlerInterceptor.super.preHandle(request, respe, handler);
     }
 }

整个判断非常简单,如果请求参数中有敏感词,则拦截请求,返回错误信息

我们写完了,但按照前面所说的步骤,我们还需要将这个进行注册,代码如下

代码语言:javascript代码运行次数:0运行复制
 package com.;
 ​
 import org.annotation.Configuration;
 import org.springframework.web.annotation.InterceptorRegistry;
 import org.springframework.web.annotation.WebMvcConfigurationSupport;
 ​
 import javax.annotation.Resource;
 ​
 @Configuration
 public class WebMvcConfig extends WebMvcConfigurationSupport {
 ​
     @Resource
     private SensitiveWordsInterceptor sensitiveWordsInterceptor;
 ​
     @Override
     protected void addInterceptors(InterceptorRegistry registry) {
         registry.addInterceptor(sensitiveWordsInterceptor)
                 .addPathPatterns("/**");
     }
 }

继承WebMvcConfigurationSupport类,重写addInterceptors方法,将添加进去即可

同时,也可以指定所拦截的路径,/**代表所有路径


那么现在可以启动项目,来进行验证了,controller接口我了一个以前的一个插入更新的接口,使用body方式进行传参

先来看看成功的请求,能够正常进行插入

image-2025011015202022

再来看看请求失败,被拦截的请求

image-20250110152017
三、最后

为什么HttpServletRequest的输入流只能读取一次呢?当我们调用其getInputStream()方法,返回来的只是一个输入流对象,实际类型为ServletInputStream

这个对象read()方法内部维护了一个属性,标记着当前读取字节的坐标位置

想要重新开始读取,只能将这个属性重新设置为0

InputStream当中,有一个reset()方法,但是方法中会抛出异常,只能交给子类去实现

但巧的是ServletInputStream没有重写这个方法,所以重复读取就会显得很麻烦

参考文档:SpringBoot项目中,获取Post方法的请求body_获取body参数-CSD博客

好在,我们可以用另外一种方式去解决,这样一来,我们就能实现所需要的功能了

#感谢您对电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格的认可,转载请说明来源于"电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格

本文地址:http://www.dnpztj.cn/biancheng/1186600.html

相关标签:无
上传时间: 2025-07-22 12:32:29
留言与评论(共有 14 条评论)
本站网友 造血干细胞捐献
18分钟前 发表
获取Post方法的请求body_获取body参数-CSD博客好在
本站网友 殷亦晴
28分钟前 发表
如果请求参数中有敏感词
本站网友 宁波个人房屋出租
20分钟前 发表
只能将这个属性重新设置为0而InputStream当中
本站网友 霹雳贝贝
17分钟前 发表
看你是过滤
本站网友 恒基兆业
4分钟前 发表
HttpServletRequest的输入流只够读取一次
本站网友 婴儿游泳的好处
21分钟前 发表
SpringBoot的使用 一
本站网友 减肥什么方法最好
28分钟前 发表
前言在SpringBoot开发web应用的过程中
本站网友 大脚丫
1分钟前 发表
标记着当前读取字节的坐标位置想要重新开始读取
本站网友 金色阳光花园
25分钟前 发表
/**代表所有路径那么现在可以启动项目
本站网友 激光雕刻
6分钟前 发表
用来继承实现自己的缓存代码语言:javascript代码运行次数:0运行复制 package com.; ​ import javax.servlet.ReadListener; import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import java.io.*; ​ public class CachedBodyHttpServletRequest extends HttpServletRequestWrapper { ​ private final byte[] cachedBody; ​ public CachedBodyHttpServletRequest(HttpServletRequest request) throws IOException { super(request); InputStream requestInputStream = request.getInputStream(); = toByteArray(requestInputStream); } ​ @Override public ServletInputStream getInputStream() throws IOException { return new CachedBodyServletInputStream(); } ​ @Override public BufferedReader getReader() throws IOException { ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(); return new BufferedReader(new InputStreamReader(byteArrayInputStream)); } ​ private byte[] toByteArray(InputStream input) throws IOException { ByteArrayOutputStream output = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int n; while ((n = input.read(buffer)) != -1) { output.write(buffer
本站网友 早产儿奶粉
13分钟前 发表
它支持我们在HTTP请求到达Controller之前添加一些自定义的逻辑比如说
本站网友 爱情不是两三天
13分钟前 发表
则拦截请求
本站网友 芦荟的功效与作用
8分钟前 发表
n); } return (); } ​ private static class CachedBodyServletInputStream extends ServletInputStream { private final ByteArrayInputStream buffer; ​ public CachedBodyServletInputStream(byte[] contents) { this.buffer = new ByteArrayInputStream(contents); } ​ @Override public boolean isFinished() { return buffer.available() == 0; } ​ @Override public boolean isReady() { return true; } ​ @Override public void setReadListener(ReadListener readListener) { throw new UnsupportedOperationException(); } ​ @Override public int read() throws IOException { return buffer.read(); } } }有了此类之后