SpringBoot使用者登陸攔截以及解決頁面重定向問題
SpringBoot的預設啟動時,對資源攔截的控制檯資訊如下:
2018-04-13 10:02:30.090 INFO 78908 --- [ restartedMain] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler] 2018-04-13 10:02:30.090 INFO 78908 --- [ restartedMain] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler] 2018-04-13 10:02:30.157 INFO 78908 --- [ restartedMain] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
其中Spring Boot 預設將 /** 所有訪問對映到以下目錄:
classpath:/static
classpath:/public
classpath:/resources
classpath:/META-INF/resources
其中預設配置的 /webjars/** 對映到 classpath:/META-INF/resources/webjars/
那麼當我們自己來實現對靜態資源進行攔截控制的時候,就需要在控制類中進行@Configuration註解的配置,與此同時增加@EnableWebMvc,增加該註解之後,預設的WebMvcAutoConfiguration中配置就不會生效,就需要自己完成每一項的控制。當然如果你要更加細粒度以及控制的更精確,那肯定是要對WebMvcAutoConfiguration類瞭解的更加深入。
控制類程式碼如下:
@Configuration @EnableWebMvc //這個註解使得預設配置失效 public class DefineAdapter extends WebMvcConfigurerAdapter implements ApplicationContextAware { private static final Log logger = LogFactory.getLog(DefineAdapter.class); private ApplicationContext applicationContext; public DefineAdapter(){ super(); } @Bean public ViewResolver viewResolver() { logger.info("ViewResolver"); InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); viewResolver.setPrefix("/WEB-INF/views/"); viewResolver.setSuffix(".jsp"); return viewResolver; } @Override public void setApplicationContext(ApplicationContext arg0) throws BeansException { System.out.println("setApplicationContext方法"); this.applicationContext = applicationContext; } //這裡是實現使用者攔截的具體操作,類LoginInterceptor是使用者登入攔截器 @Override public void addInterceptors(InterceptorRegistry registry) { System.out.println("addInterceptors方法"); /* * 多個攔截器組成一個攔截器鏈 * excludePathPatterns 使用者排除攔截 * addPathPatterns 用於新增攔截規則 * 攔截規則:除了"/show/getLogin" 其他都攔截 * */ registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**").excludePathPatterns("/show/getLogin");//多個排除攔截的話,只需要用逗號隔開即可 //這邊還可以加好幾個攔截器組成攔截器鏈 super.addInterceptors(registry); } //可以方便的將一個請求對映成檢視,無需書寫控制器,addViewCOntroller("請求路徑").setViewName("請求頁面檔案路徑") @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/show/getLogin").setViewName("login"); } //自定義資源攔截路徑可以和springBoot預設的資源攔截一起使用,但是我們如果自己定義的路徑與預設的攔截重複,那麼我們該方法定義的就會覆蓋預設配置 @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { //這裡也可以採用ResourceUtils.CLASSPATH_URL_PREFIX 它是:classpath: registry.addResourceHandler("/images/**").addResourceLocations("classpath:/WEB-INF/resources/images/"); registry.addResourceHandler("/js/**").addResourceLocations("classpath:./WEB-INF/resources/js/"); registry.addResourceHandler("/css/**").addResourceLocations("classpath:/WEB-INF/resources/css/"); super.addResourceHandlers(registry); } }
使用者登入攔截器:LoginInterceptor
@Service
public class LoginInterceptor extends HandlerInterceptorAdapter{
protected static final Log logger = LogFactory.getLog(LoginInterceptor.class);
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException{
logger.info("------preHandle------");
//獲取session
HttpSession session = request.getSession(true);
//判斷使用者Name是否存在,不存在就跳轉到登入介面
if(request.getParameter("userName") == null){
//System.out.println("這是路徑地址:"+request.getRequestURI());
response.sendRedirect("/show/getLogin");
return false;
}else{
session.setAttribute("userName", session.getAttribute("name"));
return true;
}
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println(">>>LoginInterceptor>>>>>>>請求處理之後進行呼叫,但是在檢視被渲染之前(Controller方法呼叫之後)");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println(">>>LoginInterceptor>>>>>>>在整個請求結束之後被呼叫,也就是在DispatcherServlet 渲染了對應的檢視之後執行(主要是用於進行資源清理工作)");
}
}
介面訪問的控制器:PageController
@Controller
@RequestMapping(value = "/show")
public class PageController {
@RequestMapping("/getEditJsp")
public String editJsp(ModelMap map) {
return "editUser";
}
@RequestMapping(value = "/getLogin")
public String loginJsp(ModelMap map) {
return "login";
}
}
當我輸入localhost:埠號/show/getEditJsp時候會被攔截,進行判斷Session中的內容是否為空,空就跳轉到登入介面,此時這邊還涉及到了重定向帶來的js,css等靜態資源無法顯示的問題:
配置檔案中請如下配置:
resources:
#靜態資源掃描
static-locations: classpath:/WEB-INF/resources/
當然這個要和原本DefineAdapter中的靜態資源攔截一起配合使用,這是我的專案介面和靜態資源存放目錄:
那麼介面中靜態資源的引用如下:
<script src="../js/jquery/jquery-2.1.3.min.js"></script>
<script src="../js/bootstrap/bootstrap.js"></script>
<script src="../js/bootstrap/bootstrap.min.js"></script>
<link rel="stylesheet" type="text/css" href="../css/bootstrap.min.css"/>
<script type="text/javascript" src="../js/hello.js"></script>
那好,使用者攔截以及重定向靜態資源都已解決,但是如果你看我上一章搭配BootStrap使用會發現,原本我使用bootStarp和jquery都是使用maven進行版本管理的,為何現在是手動將js,css檔案放置在資料夾下。這個問題是這樣的,原本我採用maven進行管理的時候,當用戶被攔截重定向到登陸介面之後,我的靜態資源一直無法正常顯示,試了很多方式,但是好像都沒有很好的解決方式,我也不知道怎麼解決,如果哪位同志能很好的解決這個問題,歡迎在下面評論以及私聊。
springBoot管理的bootStrap和jquery預設放在resources資料夾下的static的webjars資料夾中,在介面的引用如下:
<script src="/webjars/jquery/jquery.min.js"></script>
<script src="/webjars/bootstrap/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="/webjars/bootstrap/css/bootstrap.min.css"/>
我在DefineAdapter中的靜態資源攔截是如下配置:
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/static/webjars/");
在application.yml中,我也嘗試了資源的路徑配置,也嘗試過沒去配置,反正都沒有顯示,試了兩天了也沒出效果,所以在此集思廣益