1. 程式人生 > >SpringBoot使用者登陸攔截以及解決頁面重定向問題

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中,我也嘗試了資源的路徑配置,也嘗試過沒去配置,反正都沒有顯示,試了兩天了也沒出效果,所以在此集思廣益