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(ListmoduleList,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,并返回结果及异常处理操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。