程序启动时如果需要添加某些初始化代码可以使用以下事件处理
import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationListener; import org.springframework.stereotype.Component; /** * 程序初始化事件 */ @Component public class ApplicationEventListener implements ApplicationListener { @Override public void onApplicationEvent(ApplicationEvent event) { // if (event instanceof ApplicationEnvironmentPreparedEvent) { // // 初始化环境变量 // }else if(event instanceof ApplicationPreparedEvent){ // // 初始化完成 // }else if (event instanceof ContextRefreshedEvent) { // // 应用刷新 // }else if (event instanceof ApplicationReadyEvent) { // // 应用已启动完成 // }else if (event instanceof ContextStartedEvent) { // // 应用启动,需要在代码动态添加监听器才可捕获 // }else if (event instanceof ContextStoppedEvent) { // // 应用停止 // }else if (event instanceof ContextClosedEvent) { // // 应用关闭 // }else {} } }
过滤用户登录状态验证时普遍使用拦截器或过滤器spring boot 2.0使用以下方式
import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 请求拦截器 * 参考资料:https://www.cnblogs.com/holly8/p/6178828.html * 普遍继承HandlerInterceptorAdapter抽象类,其中多提供了一个异步拦截方法afterConcurrentHandlingStarted(),我们用不到所以直接实现基础接口 * 调用顺序:preHandler(可多个) -> Controller -> postHandler(可多个) -> model渲染-> afterCompletion(可多个) */ public class RequestInterceptor implements HandlerInterceptor { /** * Action执行前调用 */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { try { System.out.println("调用拦截器"); //判断用户会话状态 if (0 > 0) { System.out.println("拦截验证-已登录"); return true; } else { System.out.println("拦截验证-未登录"); //根据header标识判断当前请求是否为Ajax请求 if (request.getHeader("x-requested-with") == null){ //如果不是Ajax请求则重定向 response.sendRedirect("/admin");//重定向回登录页 }else { //如果是Ajax则更改状态码通知前端 //response.sendError(580,"自定义错误");//如果想提示错误并根据配置文件自动跳转到错误页面,则使用sendError response.setStatus(401);//登录异常(401)权限验证不通过(403)如果只是改变状态码自己做后续处理,则使用setStatus /* 下面是直译官方API文档的内容: sendError(int sc):使用指定的状态码并清空缓冲,发送一个错误响应至客户端。如果响应已经被提交,这个方法会抛出IllegalStateException。使用这个方法后,响应则应该被认为已被提交,且不应该再被进行写操作了。 sendError(int sc, String msg):使用指定的状态码发送一个错误响应至客户端。服务器默认会创建一个HTML格式的服务错误页面作为响应结果,其中包含参数msg指定的文本信息,这个HTML页面的内容类型为“text/html”, 保留cookies和其他未修改的响应头信息。如果一个对应于传入的错误码的错误页面已经在web.xml中声明,那么这个声明的错误页面将会优先于建议的msg参数服务于客户端。(ps:相比较上面的方法,我更倾向于前者。 使用上面的方法,可以通过定制不同状态的响应结果显示于客户端,我们应该不想让客户端看到服务器创建出的简单粗暴的页面吧?) setStatus(int sc):设置响应的状态码。这个方法被用于当响应结果正常时(例如,状态码为SC_OK或SC_MOVED_TEMPORARTLY)设置响应状态码。如果发生错误,而且来访者希望调用在web应用中定义的错误页面作为显示, 那么应该使用sendError方法代替之。使用setStatus方法之后,容器会清空缓冲并设置Location响应头,保留cookies和其他响应头信息。 总结:sendError适用于报错且存在对应的报错页面配置作为输出显示的情况,而setStatus适用于正常响应的情况,仅仅可以改变响应状态码而已。 */ } return false; } } catch (Exception e) { e.printStackTrace(); return false; } } /** * Action执行后,View渲染前调用 */ @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) { } /** * View渲染后调用,整个流程执行结束调用 */ @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { } }
注入拦截器到web中
import org.springframework.context.annotation.Configuration; import org.springframework.util.AntPathMatcher; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.PathMatchConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /** * 配置类 * WebMvcConfigurerAdapter已被废弃,官方推荐改用WebMvcConfigurer */ @Configuration public class MyInterceptorConfig implements WebMvcConfigurer { /** * 注入拦截器 */ @Override public void addInterceptors(InterceptorRegistry registry) { //将拦截器注入进程序,可同时注入多个拦截器 //registry.addInterceptor(new RequestInterceptor()).addPathPatterns("/**"); /* 使用addPathPatterns增加拦截规则,使用excludePathPatterns排除拦截规则 /admin/**:代表http://域名/admin/** 拦截该目录下的所有目录及子目录 /admin:代表http://域名/admin 仅拦截此形式访问(无法拦截/admin/ 形式) /admin/*:代表http://域名/admin/* 拦截该目录的所有下级目录不包含子目录(可以拦截/admin/ 形式) */ registry.addInterceptor(new RequestInterceptor()) .addPathPatterns("/admin/**") .excludePathPatterns("/admin") .excludePathPatterns("/admin/*") .excludePathPatterns("/admin/content/**"); } /** * 注入路径匹配规则 */ @Override public void configurePathMatch(PathMatchConfigurer configurer) { //设置忽略请求URL的大小写 AntPathMatcher matcher = new AntPathMatcher(); matcher.setCaseSensitive(false); configurer.setPathMatcher(matcher); //设置匹配规则 /* setUseSuffixPatternMatch : 设置是否是后缀模式匹配,如“/user”是否匹配/user.*,默认true即匹配 setUseTrailingSlashMatch : 设置是否自动后缀路径模式匹配,如“/user”是否匹配“/user/”,默认true即匹配 */ configurer.setUseSuffixPatternMatch(false).setUseTrailingSlashMatch(true); } }