SpringBoot的使用
SpringBoot的使用
在SpringBoot
开发web
应用的过程中,常常会使用到。
而是一个很常用的功能,它支持我们在HTTP
请求到达Controller
之前添加一些自定义的逻辑
比如说,在到达Controller
之前,将对一些敏感词汇进行检测,一旦出现敏感词,看你是过滤,还是直接返回异常
这就是的一个简单应用,通过本篇文章,您将会了解到SpringBoot
的功能使用
的使用可以分为两个步骤
- 实现
HandlerInterceptor
,编写自己的 - 对上面写好的进行注册
首先我们先确定好自己需要做什么,就按照前言那样说的,我们对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
,使用过滤器即可
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
方式进行传参
先来看看成功的请求,能够正常进行插入
再来看看请求失败,被拦截的请求
为什么HttpServletRequest
的输入流只能读取一次呢?当我们调用其getInputStream()
方法,返回来的只是一个输入流对象,实际类型为ServletInputStream
这个对象read()
方法内部维护了一个属性,标记着当前读取字节的坐标位置
想要重新开始读取,只能将这个属性重新设置为0
而InputStream
当中,有一个reset()
方法,但是方法中会抛出异常,只能交给子类去实现
但巧的是ServletInputStream
没有重写这个方法,所以重复读取就会显得很麻烦
参考文档:SpringBoot项目中,获取Post方法的请求body_获取body参数-CSD博客
好在,我们可以用另外一种方式去解决,这样一来,我们就能实现所需要的功能了
#感谢您对电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格的认可,转载请说明来源于"电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格
推荐阅读
留言与评论(共有 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(); } } }有了此类之后 |