当前位置: 首页 > 后端技术 > Java

个人学习系列-解决后台获取不到拦截器操作请求参数的问题

时间:2023-04-02 10:35:38 Java

因为项目需要使用拦截器操作请求参数,但是请求流只能操作一次,导致后面的方法无法获取不再获得流量。新建一个SpringBoot项目1.新建一个拦截器WebConfig.java/***@date:2023/2/611:21*@author:周兆东*@description:*/@ConfigurationpublicclassWebConfigimplementsWebMvcConfigurer{/***添加Web项目拦截器*/@OverridepublicvoidaddInterceptors(InterceptorRegistryregistry){//所有访问路径都被MyInterceptor类型的拦截器拦截//释放登录页面、登录操作、静态资源registry.addInterceptor(newMyInterceptor()).addPathPatterns("/**").excludePathPatterns("/","/login","/index.html","/user/login","/css/**","/images/**","/js/**","/fonts/**");}}2。获取请求参数及流程逻辑/***@date:2023/2/612:46*@author:zhouzhaodong*@description:获取请求参数及流程*/publicclassRequestWrapperextendsHttpServletRequestWrapper{privatefinalLoggerlogger=LoggerFactory.getLogger(RequestWrapper.class);私有最终字节[]主体;公共RequestWrapper(HttpServletRequestrequest){super(request);StringsessionStream=getBodyString(请求);body=sessionStream.getBytes(StandardCharsets.UTF_8);}publicStringgetBodyString(){returnnewString(body,StandardCharsets.UTF_8);}/***@date:2023/2/612:46*@author:zhouzhaodong*@description:获取请求体*/publicStringgetBodyString(finalServletRequestrequest){StringBuildersb=newStringBuilder();输入流inputStream=null;BufferedReader阅读器=null;尝试{inputStream=cloneInputStream(request.getInputStream());reader=newBufferedReader(newInputStreamReader(inputStream,StandardCharsets.UTF_8));字符串行="";while((line=reader.readLine())!=null){sb.append(line);}}catch(IOExceptione){e.printStackTrace();}最后{如果(inputStream!=null){尝试{inputStream.close();}catch(IOExceptione){e.printStackTrace();}}if(reader!=null){try{reader.close();}catch(IOExceptione){e.printStackTrace();}}}logger.info("获取body请求参数:"+sb);返回sb.toString();}/***@date:2023/2/612:46*@author:周照东*@description:复制输入流*/publicInputStreamcloneInputStream(ServletInputStreaminputStream){ByteArrayOutputStreambyteArrayOutputStream=newByteArrayOutputStream();字节[]缓冲区=新字节[1024];国际长度;尝试{while((len=inputStream.read(buffer))>-1){byteArrayOutputStream.write(buffer,0,len);}byteArrayOutputStream.flush();}catch(IOExceptione){e.printStackTrace();}返回新的ByteArrayInputStream(byteArrayOutputStream.toByteArray());}@OverridepublicBufferedReadergetReader(){返回新的BufferedReader(newInputStreamReader(getInputStream()));}@OverridepublicServletInputStreamgetInputStream(){finalByteArrayInputStreambais=newByteArrayInputStream(body);返回新的ServletInputStream(){@Overridepublicintread(){returnbais.read();}@OverridepublicbooleanisFinished(){返回false;}@OverridepublicbooleanisReady(){返回false;}@OverridepublicvoidsetReadListener(ReadListenerreadListener){}};}}3。现实HandlerInterceptor接口/***@date:2023/2/611:19*@author:zhouzhaodong*@description:实际HandlerInterceptor接口*/publicclassMyInterceptorimplementsHandlerInterceptor{privatefinalLoggerlogger=LoggerFactory.getLogger(MyInterceptor.class);/***@date:2023/2/611:19*@author:zhouzhaodong*@description:访问控制器方法前处理*/@OverridepublicbooleanpreHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler){logger.info("================进入手柄======================");logger.info(newDate()+"--preHandle:"+request.getRequestURL());logger.info("***************************【请求开始】***************************”);logger.info("----------------StartProcessingRequest----------------");尝试{longcurrentTime=System.currentTimeMillis();SimpleDateFormat格式化程序=newSimpleDateFormat("yyyy/MM/ddHH:mm:ss");数据edate=newDate(currentTime);logger.info("当前时间:{}",formatter.format(date));logger.info("响应时间:{}",(System.currentTimeMillis()-currentTime)+"ms");StringrequestUrl=request.getRequestURI();logger.info("RequestURL:{}",requestUrl);logger.info("GetMethod:{}",handler);字符串方法=request.getMethod();logger.info("方法:{}",方法);//获取请求参数RequestWrapperrequestWrapper=newRequestWrapper(request);//这里getBodyString()方法没有参数logger.info("RequestBody:{}",requestWrapper.getBodyString());}catch(Exceptione){logger.error("MVC业务处理-拦截器异常:",e);}logger.info("----------------------------结束---------------------");返回真;}/***@日期:2023/2/612:46*@author:zhouzhaodong*@description:访问控制器方法后执行*/@OverridepublicvoidpostHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler,ModelAndViewmodelAndView){logger.info(newDate()+"--postHandle:"+request.getRequestURL());}/***@date:2023/2/612:46*@author:zhouzhaodong*@description:postHandle方法执行后执行,一般用于释放资源*/@OverridepublicvoidafterCompletion(HttpServletRequestrequest,HttpServletResponse响应,对象处理程序,异常ex){logger.info(newDate()+"--afterCompletion:"+request.getRequestURL());}}4.application.ymlspring:main:#当出现同名类注册时,允许覆盖注册allow-bean-definition-overriding:true5.为启动类添加@ServletComponentScan注解6.新建TestController.java/***@date:2023/2/612:24*@author:zhouzhaodong*@description:Test*/@RestControllerpublicclassTestController{@PostMapping("/one/abc")publicStringabc(@RequestBodyUseruser){returnuser.getName();}}7.测试不处理看结果请求结果:控制台输出:可以看到stream被读取了一次,然后后台获取不到8.通过filter获取参数,传递给下面的程序",filterName="channelFilter")publicclassChannelFilterimplementsFilter{privatefinalLoggerlogger=LoggerFactory.getLogger(ChannelFilter.class);@Overridepublicvoidinit(FilterConfigfilterConfig){}@OverridepublicvoiddoFilter(ServletRequestservletRequest,ServletResponseservletResponse,FilterChainfilterChain)抛出IOException,ServletException{logger.info("================输入过滤器==================================//防止流被读取一次就丢失,所以需要把流写出来HttpServletRequesthttpServletRequest=(HttpServletRequest)servletRequest;RequestWrapperrequestWrapper=newRequestWrapper(httpServletRequest);filterChain.doFilter(requestWrapper,servletResponse);}@Overridepublicvoiddestroy(){}}9.流处理后测试请求结果:控制台输出:已解决!!!源代码路径然后https://github.com/zhouzhaodo...

最新推荐
猜你喜欢