• SpringBoot静态资源路径问题、拦截器基础配置


    SpringBoot静态资源路径问题、拦截器基础配置

    1 前置基本知识

    1.1 SpringBoot项目静态资源默认读取路径及优先级

    优先级如下:1 -> 2 -> 3 -> 4

    • 优先级1:classpath:/META-INF/resources
    • 优先级2:classpath:/resources/
    • 优先级3:classpath:/static/
    • 优先级4: classpath:/public/

    1.2测试直接访问静态资源

    以上4个是SpringBoot默认读取静态资源文件目录,因此不需要配置任何参数,直接输入URL即可访问
    http://localhost:8080/b.html
    
    • 1
    • 2

    结果:
    在这里插入图片描述

    1.3 测试路径访问优先级

    静态资源项目结构:

    测试同时访问a.html

    在这里插入图片描述

    访问地址:

    http://localhost:8080/a.html
    
    • 1

    测试结果:
    在这里插入图片描述

    1.4 存在问题

    1)那么这个时候如果我们想要通过controller然后跳转到对应页面该怎么办呢?
    一般来说,controller跳转的页面都是放在templates目录下的,

    如果我们像之前访问static目录下的文件那样,直接访问templates下的html文件

    http://localhost:8080/test.html
    
    • 1

    结果:

    在这里插入图片描述

    • 因此,想要访问templates下的静态资源,需要通过controller内部转发或重定向
    @Controller//不能是@RestController【@RestController会转换为json格式】
    public class TestController {
    
        @RequestMapping("/test")
        public String test(){
            System.out.println("22222");
    //        return "/test.html"; //直接访问
    //        return "forward:/test.html";//请求转发
            return "redirect:/test.html";//重定向
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在这里插入图片描述
    结果:访问成功

    2)如果我们目录层级有多层呢?

    @Controller//不能是@RestController【@RestController会转换为json格式】
    public class TestController {
    
        @RequestMapping("/test")
        public String test(){
            System.out.println("3333");
            return "/html/test.html";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述

    可以直接通过在跳转的视图上添加上路径【但是如果路径太长就会有太多重复代码且不易扩展】
    
    • 1

    解决办法:
    ①可以通过yml配置文件+controller请求转发/重定向
    ②可以通过模板引擎如:thymeleaf
    导入jar包:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    
    • 1
    • 2
    • 3
    • 4

    配置前后缀:

    spring:
      #设置页面前后缀
      thymeleaf:
        prefix: classpath:/templates/html/
        suffix: .html
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2 application.yml配置

    2.1 spring.resources.static-location

    设置SpringBoot项目静态资源位置【修改之后,默认静态资源位置失效】

    spring.resources.static-location参数指定了SpringBoot-Web项目中静态文件存放位置,该参数默认设置为:classpath:/static,classpath:/public,classpath:/resources,classpath:/META-INF/resources,servlet context:/。
    以上地址中没有/template地址,当前配置文件中配置此项后,默认配置失效,使用自定义设置。

    • classpath:一般来说就是对应的项目中:web-pratice\src\main\resources文件目录。如:classpath:templates/是将resouces目录下的templates文件夹设置为静态文件目录。【classpath路径为:文件编译后在target/classes目录下的文件】
    • 静态文件目录:存放html、jsp、css、js、图片、文本等类型文件的目录。这些文件都可以通过浏览器URL进行访问。同时controller中转发的文件目录也必须被设置为静态文件目录。
    spring:
     web:
     resources:
     static-locations:  classpath:/templates/
    
    • 1
    • 2
    • 3
    • 4
    • static-path-pattern原理:当SpringBoot自动装配WebMvcAutoConfiguration时,当执行到addResourceHandlers方法时,其中的staticPathPattern默认值是/**。如果yml文件中存在配置项spring.mvc.static-path-pattern,默认配置会被覆盖。当通过浏览器进行访问时,springMVC使用SimpleURLHandlerMapping进行路由映射,当执行到方法AbstractURLHandlerMapping时,将会使用spring.mvc.static-path-pattern配置项来匹配路径URL

    2.2 spring.mvc.static-path-pattern

    设置静态资源访问路径【/login/test.html】

    ①在yml配置static-path-pattern

    spring:
      mvc:
        static-path-pattern: /login/**
        # /login/** 访问login目录下的资源及其子目录【多层目录】
        # /login/* 访问login目录下的资源,不包括子目录【单层】
    
    • 1
    • 2
    • 3
    • 4
    • 5

    ②这个时候,直接访问静态资源a.html
    http://localhost:8080/a.html
    报错:
    在这里插入图片描述
    ③在URL前面加上login,再访问:
    http://localhost:8080/login/a.html
    成功:
    在这里插入图片描述

    2.3 两大配置项总结(原理)

    • static-path-pattern:/login/**配置就是在访问静态资源的路径上追加login关键字。默认值是static-path-pattern:/**
    spring:
      mvc:
        static-path-pattern: /login/**
        # /login/** 访问login目录下的资源及其子目录【多层目录】
        # /login/* 访问login目录下的资源,不包括子目录【单层】
    
    • 1
    • 2
    • 3
    • 4
    • 5

    比如没有设置这个配置项之前,访问静态资源http://localhost:8080/test.html;设置了之后就必须是http://localhost:8080/login/test.html

    • static-locations:classpath:/static, classpath:templates , 用来指定存放静态资源的路径,查找静态资源时,会从上面的路径开始搜索,没有找到则返回404

    3 拓展

    3.1 请求转发与重定向

    • 请求转发:一次请求,服务器内部调用另外的组件处理,request和response可以共用【有限制性,只能转发到该应用中的某些资源、页面或controller请求】,可以直接访问WEB-INF目录下的页面
    • 重定向:两次请求,地址会改变,request和response不能共用,不能直接访问WEB-INF下面的资源【根据要跳转的资源,可以分为跳转到页面或跳转到其他controller】

    请求转发、重定向,三种方式:

    1. ModelAndView
    /**
     * 被跳转的controller
     */
    @Controller
    public class OtherController {
     
        /**
         * 被跳转的controller返回result.jsp
         * @return
         * @throws Exception
         */
        @RequestMapping("/other.do")
        public ModelAndView other()throws Exception{
     
            ModelAndView mv = new ModelAndView();
            mv.addObject("type", "被跳转的controller");
     
            mv.setViewName("result");
            return mv;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    1. 字符串方式【String】
    @Controller//不能是@RestController【@RestController会转换为json格式】
    public class TestController {
    
        @RequestMapping("/test")
        public String test(){
            System.out.println("6666");
            return "forward:/test.html";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    1. 通过servlet api【返回值为void】
    request.getRequestDispatcher("/jsp/result.jsp").forward(request, response);
    
    • 1

    如果templates有多层路径,可以通过在yml中配置静态资源路径+controller中的请求转发或重定向

    ①项目结构
    在这里插入图片描述
    ②yml文件

    spring:
      web:
        resources:
          static-locations: classpath:/templates/html/
    
    • 1
    • 2
    • 3
    • 4

    ③TestController

    @Controller//不能是@RestController【@RestController会转换为json格式】
    public class TestController {
    
        @RequestMapping("/test")
        public String test(){
            System.out.println("777");
            return "forward:/test.html";
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    3.2 WebMvcConfigurer(配置拦截、设置静态资源路径)

    实现方式:

    • 方式一实现WebMvcConfigurer接口(推荐)
    • 方式二继承WebMvcConfigurationSupport类

    主要作用:

    /* 拦截器配置 */
    void addInterceptors(InterceptorRegistry var1);
    /* 视图跳转控制器 */
    void addViewControllers(ViewControllerRegistry registry);
    /**
      *静态资源处理
      */
    void addResourceHandlers(ResourceHandlerRegistry registry);
    /* 默认静态资源处理器 */
    void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer);
    /**
      * 这里配置视图解析器
      */
    void configureViewResolvers(ViewResolverRegistry registry);
    /* 配置内容裁决的一些选项*/
    void configureContentNegotiation(ContentNegotiationConfigurer configurer);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    [1]拦截器功能

    ①配置拦截器
    首先,我们需要自定义拦截器

    public class SystemInterceptor implements HandlerInterceptor {
    
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            System.out.println("经过拦截器...");
            return false;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    ②注册拦截器

    @Configuration
    public class MyWebMvcConfigure implements WebMvcConfigurer {
        
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            //注册拦截器
            registry.addInterceptor(new SystemInterceptor()).addPathPatterns("/**").excludePathPatterns("/login");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    controller层

    @Controller
    public class TestController {
    
        @RequestMapping("/test")
        public String test(){
            System.out.println("3333");
            return "/html/test.html";
        }
    
        @RequestMapping("/login")
        public String login(){
            System.out.println("login...");
            return "login.html";
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    ④测试
    在这里插入图片描述

    1.访问test

    http://localhost:8080/test
    
    • 1

    结果:
    页面上空白,控制台打印:

    2022-09-05 20:20:27.971  INFO 25188 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Completed initialization in 1 ms
    经过拦截器...
    
    
    • 1
    • 2
    • 3

    2.访问login

    http://localhost:8080/login
    
    • 1

    结果:
    成功返回页面
    在这里插入图片描述

    [2]静态资源映射功能

    ①创建MyWebMvcConfigure类
    将URL路径上的sub映射为test333

    @Configuration
    public class MyWebMvcConfigure implements WebMvcConfigurer {
    
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            registry.addResourceHandler("/sub/**").addResourceLocations("classpath:/test333/");
        }
    
    //    @Override
    //    public void addInterceptors(InterceptorRegistry registry) {
    //        //注册拦截器
    //        registry.addInterceptor(new SystemInterceptor()).addPathPatterns("/**").excludePathPatterns("/login");
    //    }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    项目结构
    在这里插入图片描述
    ②访问http://localhost:8080/sub/test3.html

    映射之后为:classpath:/test333/test3.html

    在这里插入图片描述

    ③结果,成功响应
    在这里插入图片描述

  • 相关阅读:
    量化交易之One Piece篇 - linux - 定时任务(重启服务器、执行程序、验证)
    数据利器:营销人员的智能助手,助力精准营销,实现业务增长
    基于Python-Opencv实现哈哈镜效果
    机器学习入门三
    Linux下:文件与路径、用户管理、常用命令、vim
    Java多线程-初阶1
    粒子群算法求解电力系统环境经济调度+微电网调度(风、光、电动车、柴油机、主网)(Python代码实现)
    t-sne 数据可视化网络中的部分参数+
    python pip3 安装psycopg2报错
    消灭指标二义性!提效30%的指标管理如何炼成?
  • 原文地址:https://blog.csdn.net/weixin_45565886/article/details/126697686