【spring boot】7.靜態資源和攔截器處理 以及繼承WebMvcConfigurerAdapter類進行更多自定義配置

  

開頭是雞蛋,後面全靠編!!!css

========================================================html

 1.默認靜態資源映射路徑以及優先順序java

 

Spring Boot 默認爲咱們提供了靜態資源處理,使用 WebMvcAutoConfiguration 中的配置各類屬性。jquery

建議你們使用Spring Boot的默認配置方式,提供的靜態資源映射以下:web

  • classpath:/META-INF/resourcesspring

  • classpath:/resourcesapache

  • classpath:/staticbootstrap

  • classpath:/public瀏覽器

 

製做【四個同名】的圖片,分別在圖片上標註對應要放在的【靜態資源文件夾】下tomcat

 

      

 

 

必定要重啓,讓項目從新加載目錄。而後再進行訪問

訪問地址:http://localhost:8080/123.png

而後把這個目錄下的圖片刪除,依次驗證,完成後得出結論:

上面這幾個都是靜態資源的映射路徑,優先級順序爲:META-INF/resources > resources > static > public

 

除此以外,這幾個映射路徑下能夠放置任何的靜態資源均可以被瀏覽器訪問到。

 

查看完整的配置文件:http://www.cnblogs.com/sxdcgaq8080/p/7724506.html

 

 能夠看到

spring.mvc.static-path-pattern=/**   靜態資源的映射路徑模式就是localhost:8080/下面,那好比訪問靜態資源路徑下的圖片就是localhost:8080/123.png
若是更改成
spring.mvc.static-path-pattern=/sxd/**  那訪問的時候就須要訪問localhost:8080/sxd/123.png
spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/
規定 靜態資源映射路徑就是根目錄下的這幾個,若是想要配置更多,請再以,逗號分隔跟在後面寫就行了

 

 

2.繼承WebMvcConfigurerAdapter類,在保留spring boot的配置狀況下,添加自定義的額外配置

實現自定義的額外配置的前提,是自定義一個配置類,並使用註解@Configuration

package com.sxd.util;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
public class MyConfig extends WebMvcConfigurerAdapter {

}

 

 

2.1經過重寫 WebMvcConfigurerAdapter 類的addResourceHandlers()方法,實現添加自定義的靜態資源映射地址

 實現方式以下:

package com.sxd.util;



import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
public class MyConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**").addResourceLocations("classpath:/sxd/");
        super.addResourceHandlers(registry);
    }


}
View Code
registry.addResourceHandler("/**")表明根訪問路徑,也就是localhost:8080/
addResourceLocations("classpath:/sxd/");表明規定classpath下的/sxd/爲靜態資源的映射地址
組合到一塊兒就是localhost:8080/123.png就能訪問到 resources文件夾下的sxd下的文件

 

 

這個圖片就是放在項目中,新建的sxd目錄下

而後檢測一下是否自定義的配置能夠成功,同時能夠檢測到 自定義的靜態資源映射地址和默認的映射地址哪一個的優先級更高

訪問以後發現,訪問到的是自定義的映射文件地址下的圖片。

 

 

那咱們修改一下上面的代碼:

 

package com.sxd.util;



import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
public class MyConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/sxd/**").addResourceLocations("classpath:/sxd/");
        super.addResourceHandlers(registry);
    }


}
View Code

訪問地址:http://localhost:8080/123.png

 訪問地址:http://localhost:8080/sxd/123.png

 

 

 能夠看出,即便是添加了自定義的靜態資源映射地址,本來默認的地址依舊能夠起做用。

 

一樣的,修改【addResourceLocations("file:E:/壁紙/");】能夠指定本地磁盤目錄爲靜態資源訪問路徑

 本地磁盤目錄以下:

 

package com.sxd.util;


        import org.springframework.context.annotation.Configuration;
        import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
        import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
public class MyConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/sxd/**").addResourceLocations("file:E:/壁紙/");
        super.addResourceHandlers(registry);
    }


}
View Code

而後重啓訪問:

 

 

最後,再次申明一點:

addResourceHandler("/**")          表明根訪問路徑,也就是localhost:8080/,就是對外暴露的地址
addResourceLocations("classpath:/sxd/");  表明規定classpath下的/sxd/爲靜態資源的映射地址,就是文件存放的目錄

==============================================================================================================

 2.2 重寫addViewControllers()方法,實現頁面跳轉的簡便化

 

前面有spring boot項目訪問jsp頁面:http://www.cnblogs.com/sxdcgaq8080/p/7712874.html

要訪問頁面,還得建立一個controller,而後controller中還得寫一個頁面跳轉的方法,才能訪問跳轉成功。

 

好如今建立一個hello2頁面

 

如今

package com.sxd.util;


        import org.springframework.context.annotation.Configuration;
        import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
        import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
        import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
public class MyConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/helloS").setViewName("hello2");
        super.addViewControllers(registry);
    }
}
View Code

 

同時我們原來的controller中原來的訪問方式依舊是能夠訪問到的。

package com.sxd.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class ViewController {

    @RequestMapping("/hello")
    public String hello(){
        return  "hello";
    }
}
View Code

 

 如今把controller中的訪問地址和自定義配置中的這個訪問地址設置爲同樣的,

controller:

@Controller
public class ViewController {

    @RequestMapping("/hello")
    public String hello(){
        return  "hello";
    }
}

 

配置類:

@Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/hello").setViewName("hello2");
        super.addViewControllers(registry);
    }

 

而後重啓,訪問:

contrller和自定義配置類的頁面跳轉相比較,controller中優先有效。

 

 

最後,若是想添加多個頁面跳轉,怎麼辦 ?

看下面代碼:

@Configuration
public class MyConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/hello2").setViewName("hello2");
        registry.addViewController("/hello3").setViewName("hello3");
        super.addViewControllers(registry);
    }
}

 

 重啓,訪問

 

  如此,甚好!!!!

 

===================================================================================================================

 3.實現HandlerInterceptor 接口,重寫addInterceptors方法實現自定義攔截器

好了,如今要實現自定義攔截器,在此以前咱們須要作一些工做:

整個項目目錄以下:

 

pom.xml文件以下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.sxd</groupId>
    <artifactId>orderdiscount</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>orderdiscount</name>
    <description>orderdiscount for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.8.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!--web 支持-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--jsp頁面使用jstl標籤-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
        </dependency>

        <!--用於編譯jsp-->
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
            <!--<scope>provided</scope>-->
        </dependency>
        <!--spring boot熱部署插件-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <!--開啓熱部署-->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <fork>true</fork><!--這個必須加上-->
                </configuration>
            </plugin>
        </plugins>
    </build>


</project>
View Code

 

 application.properties 配置文件:

spring.mvc.view.prefix = /WEB-INF/views/
spring.mvc.view.suffix = .jsp

User實體:

啓動類:

package com.sxd;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class OrderdiscountApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderdiscountApplication.class, args);
    }
}
View Code

登陸頁面跳轉控制器--MainController跳轉登陸:

【訪問localhost:8080/toLogin】就去找了根路徑下的login.jsp頁面,也就是classpath:/WEB-INF/views/login.jsp

package com.sxd.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class MainController {

    @RequestMapping("/toLogin")
    public String hello(){
        return  "login";
    }
}
View Code

登陸時驗證用戶信息控制器--ViewController驗證控制:

【若是用戶名和密碼都不爲null,返回1,表明登陸成功,而且放入session;不然返回2】

package com.sxd.controller;

import com.sxd.entity.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Controller
public class ViewController {

    @RequestMapping("/login")
    @ResponseBody
    public String hello(HttpServletRequest request, HttpServletResponse response, User user){
        System.out.println(user);
        if(!"".equals(user.getUsername()) && !"".equals(user.getPassword())){
            request.getSession().setAttribute("user",user);
            return  "1";
        }else{
            return  "2";
        }

    }
}
View Code

 

登陸頁面login.jsp:

<%--
  Created by IntelliJ IDEA.
  User: SXD
  Date: 2017/11/15
  Time: 13:51
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <title>登陸頁面</title>
    <link href="/bootstrap-3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
    <div class="container">
        <h1 class="text-center">測試登陸頁面</h1>

        <form class="form-horizontal loginForm">
            <div class="form-group-lg">
                <label class="col-lg-2 control-label">用戶名</label>
                <div class="col-lg-10">
                    <div class="input-group">
                        <span class="input-group-addon"><span class="glyphicon glyphicon-user"></span></span>
                        <input class="form-control" name="username" type="text" placeholder="輸入用戶名">
                    </div>
                </div>
            </div>
            <div class="form-group-lg ">
                <label class="col-lg-2 control-label">密碼</label>
                <div class="col-lg-10">
                    <div class="input-group">
                        <span class="input-group-addon"><span class="glyphicon glyphicon-lock"></span></span>
                        <input class="form-control" name="password" type="password" placeholder="輸入密碼">
                    </div>
                </div>
            </div>

            <div class="form-group-lg">
                <div class="col-lg-4 col-lg-offset-4">
                    <button class="btn btn-lg btn-primary btn-block" name="userLogin"><span class="glyphicon glyphicon-off"></span>登陸</button>
                </div>
            </div>
        </form>
    </div>

    <script src="/js/jquery-3.2.1.min.js"></script>
    <script src="/js/login.js"></script>
</body>
</html>
View Code

登錄成功頁面hello.jsp

<%--
  Created by IntelliJ IDEA.
  User: SXD
  Date: 2017/11/14
  Time: 14:59
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>歡迎頁面</title>
</head>
<body>
        登錄成功的歡迎頁面!!
</body>
</html>
View Code

 

login.js

$(document).ready(function(){

    /**
     * 登陸
     */
    $("button[name='userLogin']").click(function(){
        var user = $(".loginForm").serialize();

        $.post("/login?"+user,function(data){
            if(data == "1"){
                location.href = "/toHello";
            }else{
                alert("登陸失敗");
            }
        });


    });
});
View Code

 

和題目描述一致,要實現攔截器功能,須要下面兩個步驟:

  1》》建立本身的攔截器類實現HandlerInterceptor接口,並重寫對應的攔截方法

  2》》重寫WebMvcConfigurerAdapter中的addInterceptors方法,將自定義的攔截器類添加進來,而且規定攔截哪些,放過哪些地址

 

建立攔截器  MyInterceptpr.java

【關於重寫HandlerInterceptor的三個方法說明:請在文末查看 補充1】

 

【須要實現HandlerInterceptor接口,重寫preHandle()方法,判斷session中是否有用戶信息,如有則返回true並繼續執行接下來的程序,不然返回false並重定向到登陸頁面】

package com.sxd.interceptor;

import com.sxd.entity.User;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyInterceptpr  implements HandlerInterceptor{

    /**
     * 預處理方法,handler執行以前調用
     * @param httpServletRequest
     * @param httpServletResponse
     * @param o
     * @return  true/false  true便可執行以後的方法 不然 中斷
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        User user = (User) httpServletRequest.getSession().getAttribute("user");
        boolean flag = false;
        if(user != null){
            flag = true;
        }else{
            flag = false;
            httpServletResponse.sendRedirect("/toLogin");
        }

        return flag;
    }

    /**
     *handler執行以後調用
     * @param httpServletRequest
     * @param httpServletResponse
     * @param o
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

    /**
     *本次request完成後調用
     * @param httpServletRequest
     * @param httpServletResponse
     * @param o
     * @param e
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }
}
View Code

 

建立攔截器以後,須要將自定義的攔截器添加到自定義配置類MyConfig.java中:

package com.sxd.util;


        import com.sxd.interceptor.MyInterceptpr;
        import org.springframework.context.annotation.Configuration;
        import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
        import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
        import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
public class MyConfig extends WebMvcConfigurerAdapter {


        /**
         * 添加自定義攔截器
         * @param registry
         */
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
                registry.addInterceptor(new MyInterceptpr()).addPathPatterns("/**").excludePathPatterns("/toLogin","/login","/js/**","/bootstrap-3.3.7/**");
                super.addInterceptors(registry);
        }

        /**
         * 添加自定義頁面跳轉
         * @param registry
         */
        @Override
        public void addViewControllers(ViewControllerRegistry registry) {
                registry.addViewController("/toHello").setViewName("hello");
                super.addViewControllers(registry);
        }
}
View Code
.addPathPatterns("/**")要攔截的路徑
.excludePathPatterns("/toLogin","/login","/js/**","/bootstrap-3.3.7/**")要放過的路徑

/js/*  表明js下的子一級目錄

/js/**  表明js下的全部子級

 

這樣訪問的時候,若是未登陸就會跳轉到login.html頁面,而訪問http://localhost:8080/toLogin 和http://localhost:8080/login 不會被攔截。

=========================================================================================================================================

注意就是:

1.js和css的目錄都放置在webapp下,與/WEB-INF/同級而不是再其裏面

2.資源若是放在靜態資源的映射文件下,是能夠直接引用到的。。。

 

  以下,123.png放在static目錄下

在頁面上引用一下:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>歡迎頁面</title>
    <link rel="stylesheet" href="/bootstrap-3.3.7/css/bootstrap.min.css">
</head>
<body>
        <div class="container">
            <div class="row">
                <h1 class="text-center">
                    登錄成功頁面!!!
                </h1>
            </div>
            <div class="row text-center">
                <img class="img-thumbnai" src="/123.png">
            </div>

        </div>

</body>
</html>
View Code

效果以下:

 

 

=========================================================================================================================================

更多配置能夠查看WebMvcConfigurerAdapter的類的API。因其是WebMvcConfigurer接口的實現,因此WebMvcConfigurer的API方法也能夠用來配置MVC。

只是實現這個接口的話,要實現全部的方法,這樣仍是很不方便的唉。

因此仍是推薦使用繼承WebMvcConfigurerAdapter類來處理。

=========================================================================================================================================

=========================================================================================================================================

 

補充1:

HandlerInterceptor接口主要定義了三個方法: 
1. boolean preHandle (HttpServletRequest request, HttpServletResponse response, Object handle)方法:該方法將在請求處理以前進行調用,只有該方法返回true,纔會繼續執行後續的Interceptor和Controller,當返回值爲true 時就會繼續調用下一個Interceptor的preHandle 方法,若是已是最後一個Interceptor的時候就會是調用當前請求的Controller方法; 


2.void postHandle (HttpServletRequest request, HttpServletResponse response, Object handle, ModelAndView modelAndView)方法:該方法將在請求處理以後,DispatcherServlet進行視圖返回渲染以前進行調用,能夠在這個方法中對Controller 處理以後的ModelAndView 對象進行操做。 


3.void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex)方法:該方法也是須要當前對應的Interceptor的preHandle方法的返回值爲true時纔會執行,該方法將在整個請求結束以後,也就是在DispatcherServlet 渲染了對應的視圖以後執行。用於進行資源清理。

 

=========================================================================================================================================

=========================================================================================================================================

補充2:

關於HandlerInterceptor接口主要定義了三個方法的使用場景------spring boot 獲取到攔截方法的返回值 進行處理

代碼示例:

相關文章
相關標籤/搜索