解决HttpServletRequest的输入流只能读取一次的问题Word文件下载.docx

上传人:b****5 文档编号:8558789 上传时间:2023-05-11 格式:DOCX 页数:12 大小:122.22KB
下载 相关 举报
解决HttpServletRequest的输入流只能读取一次的问题Word文件下载.docx_第1页
第1页 / 共12页
解决HttpServletRequest的输入流只能读取一次的问题Word文件下载.docx_第2页
第2页 / 共12页
解决HttpServletRequest的输入流只能读取一次的问题Word文件下载.docx_第3页
第3页 / 共12页
解决HttpServletRequest的输入流只能读取一次的问题Word文件下载.docx_第4页
第4页 / 共12页
解决HttpServletRequest的输入流只能读取一次的问题Word文件下载.docx_第5页
第5页 / 共12页
解决HttpServletRequest的输入流只能读取一次的问题Word文件下载.docx_第6页
第6页 / 共12页
解决HttpServletRequest的输入流只能读取一次的问题Word文件下载.docx_第7页
第7页 / 共12页
解决HttpServletRequest的输入流只能读取一次的问题Word文件下载.docx_第8页
第8页 / 共12页
解决HttpServletRequest的输入流只能读取一次的问题Word文件下载.docx_第9页
第9页 / 共12页
解决HttpServletRequest的输入流只能读取一次的问题Word文件下载.docx_第10页
第10页 / 共12页
解决HttpServletRequest的输入流只能读取一次的问题Word文件下载.docx_第11页
第11页 / 共12页
解决HttpServletRequest的输入流只能读取一次的问题Word文件下载.docx_第12页
第12页 / 共12页
亲,该文档总共12页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

解决HttpServletRequest的输入流只能读取一次的问题Word文件下载.docx

《解决HttpServletRequest的输入流只能读取一次的问题Word文件下载.docx》由会员分享,可在线阅读,更多相关《解决HttpServletRequest的输入流只能读取一次的问题Word文件下载.docx(12页珍藏版)》请在冰点文库上搜索。

解决HttpServletRequest的输入流只能读取一次的问题Word文件下载.docx

从上图中的部分源码可以看到,该类并没有真正去实现HttpServletRequest的方法,而只是在方法内又去调用HttpServletRequest的方法,所以我们可以通过继承该类并实现想要重新定义的方法以达到包装原生HttpServletRequest对象的目的。

首先我们要定义一个容器,将输入流里面的数据存储到这个容器里,这个容器可以是数组或集合。

然后我们重写getInputStream方法,每次都从这个容器里读数据,这样我们的输入流就可以读取任意次了。

具体的实现代码如下:

packagecom.example.wrapperdemo.controller.wrapper;

importlombok.extern.slf4j.Slf4j;

importjavax.servlet.ReadListener;

importjavax.servlet.ServletInputStream;

importjavax.servlet.ServletRequest;

importjavax.servlet.http.HttpServletRequest;

importjavax.servlet.http.HttpServletRequestWrapper;

importjava.io.*;

importjava.nio.charset.Charset;

/**

*@author01

*@programwrapper-demo

*@description包装HttpServletRequest,目的是让其输入流可重复读

*@create2018-12-2420:

48

*@since1.0

**/@Slf4jpublicclassRequestWrapperextendsHttpServletRequestWrapper{

/**

*存储body数据的容器

*/

privatefinalbyte[]body;

publicRequestWrapper(HttpServletRequestrequest)throwsIOException{

super(request);

//将body数据存储起来

StringbodyStr=getBodyString(request);

body=bodyStr.getBytes(Charset.defaultCharset());

}

*获取请求Body

*

*@paramrequestrequest

*@returnString

publicStringgetBodyString(finalServletRequestrequest){

try{

returninputStream2String(request.getInputStream());

}catch(IOExceptione){

log.error("

"

e);

thrownewRuntimeException(e);

*获取请求Bodyhttp:

//www.f-1.cc

publicStringgetBodyString(){

finalInputStreaminputStream=newByteArrayInputStream(body);

returninputStream2String(inputStream);

*将inputStream里的数据读取出来并转换成字符串

*@paraminputStreaminputStream

privateStringinputStream2String(InputStreaminputStream){

StringBuildersb=newStringBuilder();

BufferedReaderreader=null;

reader=newBufferedReader(newInputStreamReader(inputStream,Charset.defaultCharset()));

Stringline;

while((line=reader.readLine())!

=null){

sb.append(line);

}finally{

if(reader!

reader.close();

returnsb.toString();

@Override

publicBufferedReadergetReader()throwsIOException{

returnnewBufferedReader(newInputStreamReader(getInputStream()));

publicServletInputStreamgetInputStream()throwsIOException{

finalByteArrayInputStreaminputStream=newByteArrayInputStream(body);

returnnewServletInputStream(){

publicintread()throwsIOException{

returninputStream.read();

publicbooleanisFinished(){

returnfalse;

publicbooleanisReady(){

publicvoidsetReadListener(ReadListenerreadListener){

};

}

除了要写一个包装器外,我们还需要在过滤器里将原生的HttpServletRequest对象替换成我们的RequestWrapper对象,代码如下:

packagecom.example.wrapperdemo.controller.filter;

importcom.example.wrapperdemo.controller.wrapper.RequestWrapper;

importjavax.servlet.*;

importjava.io.IOException;

*@author01

*@description替换HttpServletRequest

*@create2018-12-2421:

04

**/@Slf4jpublicclassReplaceStreamFilterimplementsFilter{

publicvoidinit(FilterConfigfilterConfig)throwsServletException{

log.info("

StreamFilter初始化..."

);

publicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain)throwsIOException,ServletException{

ServletRequestrequestWrapper=newRequestWrapper((HttpServletRequest)request);

chain.doFilter(requestWrapper,response);

publicvoiddestroy(){

StreamFilter销毁..."

然后我们就可以在拦截器中愉快的获取json数据也不慌controller层会报错了:

packagecom.example.wrapperdemo.controller.interceptor;

importorg.springframework.http.MediaType;

importorg.springframework.web.servlet.HandlerInterceptor;

importorg.springframework.web.servlet.ModelAndView;

importjavax.servlet.http.HttpServletResponse;

*@description签名拦截器

08

**/@Slf4jpublicclassSignatureInterceptorimplementsHandlerInterceptor{

publicbooleanpreHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler)throwsException{

[preHandle]executing...requesturiis{}"

request.getRequestURI());

if(isJson(request)){

//获取json字符串

StringjsonParam=newRequestWrapper(request).getBodyString();

[preHandle]json数据:

{}"

jsonParam);

//验签逻辑...略...

returntrue;

publicvoidpostHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler,ModelAndViewmodelAndView)throwsException{

publicvoidafterCompletion(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler,Exceptionex)throwsException{

*判断本次请求的数据类型是否为json

*@returnboolean

privatebooleanisJson(HttpServletRequestrequest){

if(request.getContentType()!

returnrequest.getContentType().equals(MediaType.APPLICATION_JSON_VALUE)||

request.getContentType().equals(MediaType.APPLICATION_JSON_UTF8_VALUE);

编写完以上的代码后,还需要将过滤器和拦截器在配置类中进行注册才会生效,过滤器配置类代码如下:

packagecom.example.wrapperdemo.config;

importcom.example.wrapperdemo.controller.filter.ReplaceStreamFilter;

importorg.springframework.boot.web.servlet.FilterRegistrationBean;

importorg.springframework.context.annotation.Bean;

importorg.springframework.context.annotation.Configuration;

importjavax.servlet.Filter;

*@description过滤器配置类

06

**/@ConfigurationpublicclassFilterConfig{

*注册过滤器

*@returnFilterRegistrationBean

@Bean

publicFilterRegistrationBeansomeFilterRegistration(){

FilterRegistrationBeanregistration=newFilterRegistrationBean();

registration.setFilter(replaceStreamFilter());

registration.addUrlPatterns("

/*"

registration.setName("

streamFilter"

returnregistration;

*实例化StreamFilter

*@returnFilter

@Bean(name="

replaceStreamFilter"

publicFilterreplaceStreamFilter(){

returnnewReplaceStreamFilter();

拦截器配置类代码如下:

importcom.example.wrapperdemo.controller.interceptor.SignatureInterceptor;

importorg.springframework.web.servlet.config.annotation.InterceptorRegistry;

importorg.springframework.web.servlet.config.annotation.WebMvcConfigurer;

*@description

16

**/@ConfigurationpublicclassInterceptorConfigimplementsWebMvcConfigurer{

publicSignatureInterceptorgetSignatureInterceptor(){

returnnewSignatureInterceptor();

*注册拦截器

*@paramregistryregistry

publicvoidaddInterceptors(InterceptorRegistryregistry){

registry.addInterceptor(getSignatureInterceptor())

.addPathPatterns("

/**"

接下来我们就可以测试一下在拦截器中读取了输入流后在controller层是否还能正常接收数据,首先定义一个实体类,代码如下:

packagecom.example.wrapperdemo.param;

importlombok.AllArgsConstructor;

importlombok.Builder;

importlombok.Data;

importlombok.NoArgsConstructor;

11

**/@Data@Builder@NoArgsConstructor@AllArgsConstructorpublicclassUserParam{

privateStringuserName;

privateStringphone;

privateStringpassword;

然后写一个简单的Controller,代码如下:

packagecom.example.wrapperdemo.controller;

importcom.example.wrapperdemo.param.UserParam;

importorg.springframework.web.bind.annotation.PostMapping;

importorg.springframework.web.bind.annotation.RequestBody;

importorg.springframework.web.bind.annotation.RequestMapping;

importorg.springframework.web.bind.annotation.RestController;

*@programwrapper-demo

47

**/@RestController@RequestMapping("

/user"

)publicclassDemoController{

@PostMapping("

/register"

publicUserParamregister(@RequestBodyUserParam

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 幼儿教育 > 幼儿读物

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2