springmvc中静态资源放行、自定义视图解析、restful、WEB-INF下的资源请求混淆问题

实验结论

这篇文章记录的是springMVC中关于静态资源放行、自定义视图解析器以及WEB-INF下的资源请求问题,虽然学的时候这些概念都明白,但是在开发中却经常混淆,特地花两小时来做测试后才写下此篇文章

接下来说一下我得出的结论:
1. jsp文件不会经过单元方法匹配问题(但html、css、js、image等都会经过单元方法匹配)
2. 静态资源放行的优先级低于单元方法的匹配,静态资源放行的url不要和单元方法冲突,若冲突则静态资源放行不生效
3. WEB-INF下的资源虽然不能通过浏览器直接访问,但是我们可以通过请求转发和静态资源放行的机制访问
4. 访问jsp时不会经过静态资源放行(但html会)

踩坑记录

情景一:

先配置视图解析器,将请求转发至WEB-INF/page下,再配置restful格式的单元方法,该方法仅仅返回请求地址,作用是配合视图解析器使得浏览器可以访问WEB-INF下的资源。那我们来看看jsp请求能被单元方法匹配到并正确转发吗?

代码

静态资源放行、自定义视图解析器

<!-- 3.配置静态资源放行    -->
    <mvc:resources mapping="/js/**" location="/WEB-INF/js/"></mvc:resources>
    
    <mvc:resources mapping="/css/**" location="WEB-INF/css/"></mvc:resources>
    <mvc:resources mapping="/images/**" location="WEB-INF/images/"></mvc:resources>

    <!--  4.配置自定义视图解析器  -->
    <bean id="resourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/page/"></property>
        <property name="suffix" value=" "></property>
    </bean>

通过这段代码配置了静态资源放行以及自定义视图,我们可以看到当url匹配js/xxx、css/xxx、images/xxx的时候,我们可以通过静态资源放行跳转到WEB-INF/js(css、images)下的资源。我不配置后缀名的想法是我想通过该视图解析器访问WEB-INF/page下的任何资源,如果设置了后缀名就将资源类型限定死了。

restful代码

@RequestMapping("{page}/{url}")
    public String getPage(@PathVariable String url){
        System.out.println("restful:"+url);
        return url;
    }

该段代码的作用是配合自定义视图解析器使得浏览器可以访问WEB-INF下的资源

文件层级

在这里插入图片描述
我们可以看到WEB-INF下有一个page文件夹,接下来我们尝试通过匹配getPage方法,来访问此WEB-INF/page/index.jsp.

结果

在这里插入图片描述
我们可以看到结果是访问page/index.jsp时出现404,这是怎么回事呢?结论的第一条有说过,jsp文件不经过DispatcherServlet,根本就不会跟单元方法进行匹配。
可是我把restful改一改。

@RequestMapping("{url}/{xxx}")
    public String getPage(@PathVariable String url){
        System.out.println("restful:"+url);
        return url;
    }

在这里插入图片描述

在这里插入图片描述

不少小伙伴问,不是说jsp文件的请求不会和单元方法匹配嘛,这不还是匹配到了restful格式的方法,是的,的确匹配到了,但是它压根不是jsp请求。大家仔细看看
http://localhost:8080/springMVC_02_war_exploded/index.jsp/xxx这个格式是jsp请求嘛,jsp只是路径的一段而已,此时服务器将index.jsp解析为一个层级而已而不是jsp文件。

情景二

刚刚我们已经测试了jsp文件的请求不会经过单元方法,那它会经过静态资源放行吗?

代码

 <!-- 3.配置静态资源放行    -->
    <mvc:resources mapping="/js/**" location="/WEB-INF/js/"></mvc:resources>
    <mvc:resources mapping="/page/**" location="/WEB-INF/page/"></mvc:resources>
    <mvc:resources mapping="/css/**" location="WEB-INF/css/"></mvc:resources>
    <mvc:resources mapping="/images/**" location="WEB-INF/images/"></mvc:resources>

    <!--  4.配置自定义视图解析器  -->
    <bean id="resourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/page/"></property>
        <property name="suffix" value=""></property>
    </bean>
单元方法
@RequestMapping("{url}")
    public String getPage(@PathVariable String url){
        System.out.println("restful:"+url);
        return url;
    }

文件层级

在这里插入图片描述

结果

在这里插入图片描述
我们可以看到,我们发起的是page/index.jsp的请求,根据资源放行机制应该跳转到WEB-INF/page/index.jsp资源,可是却报错/page/index.jsp未找到,说明jsp请求也没有经过静态资源放行。
根本原因:jsp请求没有经过DispatcherServlet,而不管是静态资源放行或者单元方法匹配都是基于DispatcherServlet的,所以静态资源放行也无法转发jsp请求
我们再看看访问html是否成功来验证结果。
在这里插入图片描述
不出意外,访问成功。

情景三

此时我想比较静态资源放行的转发和单元方法匹配谁优先级更高。

代码

 <!-- 3.配置静态资源放行    -->
    <mvc:resources mapping="/js/**" location="/WEB-INF/js/"></mvc:resources>
    <mvc:resources mapping="/page/**" location="/page/"></mvc:resources>
    <mvc:resources mapping="/css/**" location="WEB-INF/css/"></mvc:resources>
    <mvc:resources mapping="/images/**" location="WEB-INF/images/"></mvc:resources>

    <!--  4.配置自定义视图解析器  -->
    <bean id="resourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/page/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>
    @RequestMapping("{url}")
    public String getPage(@PathVariable String url){
        System.out.println("restful:"+url);
        return url;
    }

我们注意,此时我给自定义视图加上了后缀,我可以通过访问/index来跳转到/WEB-INF/page/index.jsp文件。

文件层级

在这里插入图片描述
按照该文件层级,当我访问/page/index时的时候,若是静态资源优先则会报错,若是单元方法优先则成功访问

结果

在这里插入图片描述
成功访问,我们再改文件层级再次验证若单元方法失败后,静态资源放行还能否执行?
在这里插入图片描述

我们将WEB-INF/page下的index.html移到了page下,并且去掉自定义视图解析器的后缀名添加,因为html可以被过静态资源放行和单元方法两者匹配到。此时请求page/html,单元方法匹配肯定失效,若是静态资源放行仍能执行则应该正确访问,若是单元方法失败后静态资源放行不再执行则报404
在这里插入图片描述
显然,单元方法和静态资源放行不能的url设置不应该冲突,若发生冲突的话静态资源放行则不再执行。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值