springboot拦截器过滤token,并返回结果及异常处理操作
1.springboot拦截器处理过滤token,并且返回结果
importorg.apache.commons.lang3.StringUtils; importorg.apache.shiro.subject.Subject; importorg.springframework.lang.Nullable; importorg.springframework.stereotype.Component; importorg.springframework.web.servlet.HandlerInterceptor; importorg.springframework.web.servlet.ModelAndView; importjavax.servlet.http.HttpServletRequest; importjavax.servlet.http.HttpServletResponse; importjava.io.IOException; importjava.io.PrintWriter; importjava.util.Map; @Component publicclassECInterceptorimplementsHandlerInterceptor{ /** *@Description在业务处理器处理请求之前被调用。预处理,可以进行编码、安全控制等处理; *@Date2019/5/1416:04 *@Version1.0 */ @Override publicbooleanpreHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler)throwsException{ System.out.println(request.getRequestURL()+"===========preHandle==========="); Stringtoken=request.getParameter("token"); if(StringUtils.isNotEmpty(token)){ Subjectsubject=ShiroUtil.getSubject(token); if(subject!=null&&subject.isAuthenticated()){ returntrue; }else{ //返回校验token结果 returnJson(response); //returnfalse;//我做的时候返回数据后忘记returnfalse了,所以导致异常 } } returntrue; } @Override publicvoidpostHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler,@NullableModelAndViewmodelAndView)throwsException{ System.out.println(request.getContextPath()+"============postHandle=========="); } /** *@Description在DispatcherServlet完全处理完请求后被调用,也就是说视图渲染已经完毕或者调用者已经拿到结果 *@Date2019/5/1416:05 *@Version1.0 */ @Override publicvoidafterCompletion(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler,@NullableExceptionex)throwsException{ System.out.println(request.getContextPath()+"============afterCompletion=========="); } privatevoidreturnJson(HttpServletResponseresponse){ PrintWriterwriter=null; response.setCharacterEncoding("UTF-8"); response.setContentType("application/json;charset=utf-8"); try{ writer=response.getWriter(); Mapresult=PackageReturnResult.returnJson(400,"用户令牌token无效"); result.put("data",null); writer.print(result); }catch(IOExceptione){ LoggerUtil.logError(ECInterceptor.class,"拦截器输出流异常"+e); }finally{ if(writer!=null){ writer.close(); } } } }
2.java.lang.IllegalStateException:getWriter()hasalreadybeencalledforthisresponse异常
我再做拦截器处理response数据后忘记returnfalse返回,导致拦截器被调用两次,报java.lang.IllegalStateException:getWriter()hasalreadybeencalledforthisresponse异常,犯这样低级错误花了很长时间才解决,谨记!!!
[2019-05-2709:27:17.690][http-nio-8080-exec-1][ERROR][o.a.c.c.C.[.[.[.[dispatcherServlet]:175]-Servlet.service()forservlet[dispatcherServlet]incontextwithpath[]threwexception[Requestprocessingfailed;nestedexceptionisjava.lang.IllegalStateException:getWriter()hasalreadybeencalledforthisresponse]withrootcause java.lang.IllegalStateException:getWriter()hasalreadybeencalledforthisresponse atorg.apache.catalina.connector.Response.getOutputStream(Response.java:548) atorg.apache.catalina.connector.ResponseFacade.getOutputStream(ResponseFacade.java:210) atjavax.servlet.ServletResponseWrapper.getOutputStream(ServletResponseWrapper.java:105) atorg.springframework.http.server.ServletServerHttpResponse.getBody(ServletServerHttpResponse.java:83) atorg.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:255) atorg.springframework.http.converter.AbstractGenericHttpMessageConverter.write(AbstractGenericHttpMessageConverter.java:103) atorg.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:290) atorg.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:180) atcom.uufund.ecapi.config.returnvalue.HandlerMethodReturnValueHandlerProxy.handleReturnValue(HandlerMethodReturnValueHandlerProxy.java:40) atorg.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:82) atorg.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:119) atorg.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:892) atorg.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797) atorg.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) atorg.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1038) atorg.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942) atorg.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005) atorg.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897) atjavax.servlet.http.HttpServlet.service(HttpServlet.java:634) atorg.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882) atjavax.servlet.http.HttpServlet.service(HttpServlet.java:741) atorg.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) atorg.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) atorg.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) atorg.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) atorg.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) atorg.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449) atorg.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365) atorg.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90) atorg.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83) atorg.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:387) atorg.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362) atorg.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125) atorg.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) atorg.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) atcom.uufund.ecapi.config.filter.ECWebFilter.doFilter(ECWebFilter.java:24) atorg.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) atorg.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) atorg.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) atorg.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) atorg.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) atorg.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) atorg.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92) atorg.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) atorg.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) atorg.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) atorg.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93) atorg.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) atorg.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) atorg.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) atorg.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) atorg.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) atorg.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) atorg.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) atorg.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:200) atorg.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) atorg.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490) atorg.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) atorg.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) atorg.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) atorg.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) atorg.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408) atorg.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) atorg.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:834) atorg.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1415) atorg.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) atjava.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) atjava.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) atorg.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) atjava.lang.Thread.run(Thread.java:748)
补充知识:springboot拦截器过滤权限和错误处理
先说异常处理,增加一个异常处理的类MyControllerAdvice就可以了,不需要其他地方使用,注意使用注解@ControllerAdvice
@ControllerAdvice publicclassMyControllerAdvice{ @Resource GetRootPathgetRootPath; privatestaticfinalLoggerlogger=LoggerFactory.getLogger(MyControllerAdvice.class); publicvoidoutput(Objectjson,HttpServletRequestrequest,HttpServletResponseresponse)throwsIOException{ Stringheader=request.getHeader("Origin"); response.setContentType("application/json;charset=UTF-8;"); PrintWriterout=response.getWriter(); out.println(json); out.flush(); out.close(); } /*** *404处理 *@parame *@return */ @ExceptionHandler(NoHandlerFoundException.class) publicvoidnotFountHandler(HttpServletRequestrequest,HttpServletResponseresponse,Modelmodel,NoHandlerFoundExceptione)throwsIOException,JSONException{ JSONObjectjson=newJSONObject(); json.put("code",500); json.put("content",null); json.put("msg","未找到路径:"+request.getServletPath()); output(json,request,response); } /** *运行时异常 * *@paramexception *@return */ @ExceptionHandler({RuntimeException.class}) @ResponseStatus(HttpStatus.OK) publicvoidprocessException(HttpServletRequestrequest,HttpServletResponseresponse,Modelmodel,RuntimeExceptionexception)throwsJSONException,IOException{ JSONObjectjson=newJSONObject(); json.put("code",500); json.put("content",null); json.put("msg",exception.getMessage()); output(json,request,response); } /** *Excepiton异常 * *@paramexception *@return */ @ExceptionHandler({Exception.class}) @ResponseStatus(HttpStatus.OK) publicvoidprocessException(HttpServletRequestrequest,HttpServletResponseresponse,Modelmodel,Exceptionexception)throwsJSONException,IOException{ JSONObjectjson=newJSONObject(); json.put("code",500); json.put("content",null); json.put("msg",exception.getMessage()); output(json,request,response); } }
再来权限验证的,接手的项目框架中只有验证是否登录的,没有验收权限的,增加一个类WebMvcConfig,注意使用注解@Configuration,不需要在其他地方引用即可起作用,并注意使用excludePathPatterns去掉不需要拦截的部分,否则会拦截掉静态资源。
@Configuration publicclassWebMvcConfigimplementsWebMvcConfigurer{ /** *添加拦截器 */ @Override publicvoidaddInterceptors(InterceptorRegistryregistry){ //静态资源不拦截 registry.addInterceptor(newLoginInterceptor()).addPathPatterns("/**").excludePathPatterns("/static/**"); } }
增加拦截器类LoginInterceptor
publicclassLoginInterceptorextendsHandlerInterceptorAdapter{ /** *检查是否已经登录 */ @Override publicbooleanpreHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler)throwsException{ Objectusername=request.getSession().getAttribute(Constants.LOGIN_USER); StringservletPath=request.getServletPath(); Stringtype=request.getHeader("X-Requested-With")==null?"":request.getHeader("X-Requested-With"); if(username!=null){ //检查页面访问的权限 if(!"XMLHttpRequest".equals(type)){ intuserId=Integer.valueOf(request.getSession().getAttribute(Constants.LOGIN_USERID).toString()); ListmoduleList=(List )request.getSession().getAttribute(Constants.USER_MODULE); booleanchkResult=methodPermissionLimit(moduleList,servletPath); if(!chkResult){ JSONObjectoutputMSg=newJSONObject(); outputMSg.put("code",500); outputMSg.put("content",""); outputMSg.put("msg","没有权限"); output(outputMSg,request,response); returnfalse; }else{ returntrue; } }else{ //如果是json访问,则不做检查 returntrue; } }else{ //检查是否登录允许 if(methodLoginLimit(handler)){ returntrue; }else{ if("XMLHttpRequest".equals(type)){ JSONObjectoutputMSg=newJSONObject(); outputMSg.put("code",500); outputMSg.put("content",""); outputMSg.put("msg","登录过期,请重新登陆"); output(outputMSg,request,response); returnfalse; }else{ StringredirectUrl=request.getContextPath()+"/login"; response.sendRedirect(redirectUrl); returnfalse; } } } } publicbooleanmethodLoginLimit(Objecthandler){ HandlerMethodmethod=(HandlerMethod)handler; //获取当前方法PermessionLimit LoginLimitloginLimit=method.getMethodAnnotation(LoginLimit.class); if(loginLimit==null){ //获取控制器的PermessionLimit loginLimit=method.getMethod().getDeclaringClass().getAnnotation(LoginLimit.class); } if(loginLimit!=null&&!loginLimit.limit()){ returntrue; }else{ returnfalse; } } /** *检查权限 * *@parammoduleList *@parampath *@return */ publicbooleanmethodPermissionLimit(List moduleList,Stringpath){ booleanhavePermission=moduleList.stream().anyMatch(f->f.getPath().toLowerCase().equals(path.toLowerCase())); returnhavePermission; } publicvoidoutput(Objectjson,HttpServletRequestrequest,HttpServletResponseresponse)throwsIOException{ Stringheader=request.getHeader("Origin"); response.setContentType("application/json;charset=UTF-8;"); PrintWriterout=response.getWriter(); out.println(json); out.flush(); out.close(); } }
这样的拦截器只对页面地址进行拦截,对ajax提交的数据不做处理,做普通项目的权限过滤是可以了。
以上这篇springboot拦截器过滤token,并返回结果及异常处理操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。