Spring4.1新特性——静态资源处理增强

编程技术  /  houtizong 发布于 3年前   150

目录

Spring4.1新特性——综述

Spring4.1新特性——Spring核心部分及其他

Spring4.1新特性——Spring缓存框架增强

Spring4.1新特性——异步调用和事件机制的异常处理

Spring4.1新特性——数据库集成测试脚本初始化

Spring4.1新特性——Spring MVC增强

Spring4.1新特性——页面自动化测试框架Spring MVC Test HtmlUnit简介

Spring4.1新特性——静态资源处理增强

 

Spring 4.1对静态资源处理进行了细化,ResourceHttpRequestHandler细分为两大部分:ResourceResolver和ResourceTransformer。

public interface ResourceResolver {  Resource resolveResource(HttpServletRequest request, String requestPath, List<? extends Resource> locations,ResourceResolverChain chain);  String resolveUrlPath(String resourcePath, List<? extends Resource> locations, ResourceResolverChain chain);}  

 

resolveResource用于把当前请求路径解析到一个在locations中存在的Resource,即相对于locations目录,这个要看实际实现,比如PathResourceResolver就是相对目录;

resolveUrlPath用于把资源路径解析为向外暴露的URL路径形式,比如VersionResourceResolver实现就是在资源路径上加上版本号。 

public interface ResourceTransformer {Resource transform(HttpServletRequest request, Resource resource, ResourceTransformerChain transformerChain)throws IOException;}

用于把资源从一种形式转换为另一种形式,比如对css文件中的url进行过滤并修改。 

 

ResourceResolver和ResourceTransformer实现和Filter机制类似,就不多阐述了。

 

ResourceHttpRequestHandler核心实现:

protected Resource getResource(HttpServletRequest request) throws IOException{String path = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);if (path == null) {throw new IllegalStateException("Required request attribute '" +HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE + "' is not set");}if (!StringUtils.hasText(path) || isInvalidPath(path)) {if (logger.isTraceEnabled()) {logger.trace("Ignoring invalid resource path [" + path + "]");}return null;}ResourceResolverChain resolveChain = new DefaultResourceResolverChain(getResourceResolvers());Resource resource = resolveChain.resolveResource(request, path, getLocations()); //先进行ResourceResolverif (resource == null || getResourceTransformers().isEmpty()) {return resource;}ResourceTransformerChain transformChain = new DefaultResourceTransformerChain(resolveChain, getResourceTransformers());//然后进行ResourceTransformerresource = transformChain.transform(request, resource);return resource;}

 

交互流程是:

request(/static/js/jquery-版本.js)

        |

       V 

GzipResourceResolver(如果需要Gzip压缩,进行Gzip压缩)

        |

       V 

CacheResolver(缓存中如果找到了,直接返回)

        |

       V 

VersionResourceResolver(去掉版本号,然后查找资源)

        |

       V 

PathResourceResolver(如直接到底层文件系统找)

        |

       V

CachingResourceTransformer(判断是否有已经转换好的缓存)

        |

       V

CssLinkResourceTransformer(CSS链接替换,如加版本号,其会调用ResourceResolver的resolveUrlPath得到新的UrlPath)

        |

       V

response

 

对应的Spring配置文件

    <mvc:resources mapping="/static/**" location="/WEB-INF/static/">        <mvc:resolvers>            <bean class="org.springframework.web.servlet.resource.GzipResourceResolver"/>            <bean class="org.springframework.web.servlet.resource.CachingResourceResolver">                <constructor-arg ref="cache"/>            </bean>            <bean class="org.springframework.web.servlet.resource.VersionResourceResolver">                <property name="strategyMap">                    <map>                        <entry key="/**">                            <bean class="org.springframework.web.servlet.resource.ContentVersionStrategy"/>                        </entry>                    </map>                </property>            </bean>            <bean class="org.springframework.web.servlet.resource.PathResourceResolver"/>        </mvc:resolvers>        <mvc:transformers>            <bean class="org.springframework.web.servlet.resource.CachingResourceTransformer">                <constructor-arg ref="cache"/>            </bean>            <bean class="org.springframework.web.servlet.resource.CssLinkResourceTransformer"/>        </mvc:transformers>    </mvc:resources>

其中版本机制是使用ContentBasedVersionStrategy,其通过MD5内容生成版本。

 

如果配置文件是如下形式,其默认会自动注册一个PathResourceResolver。

 <mvc:resources mapping="/static/**" location="/WEB-INF/static/"/>

 

如果想在页面中也完成同样的事情,可以首先注册一个拦截器:

    <mvc:interceptors>        <mvc:interceptor>            <mvc:mapping path="/**"/>            <bean class="org.springframework.web.servlet.resource.ResourceUrlProviderExposingInterceptor">                <constructor-arg>                        <bean class="org.springframework.web.servlet.resource.ResourceUrlProvider"/>                </constructor-arg>            </bean>        </mvc:interceptor>    </mvc:interceptors>

然后在页面中使用如下代码完成相应的功能:

<%=((ResourceUrlProvider)request.getAttribute("org.springframework.web.servlet.resource.ResourceUrlProvider"))        .getForLookupPath("/static/css/style.css")%>

 

另外ResourceUrlProvider目前实现是有问题的,没有考虑使用mvc:resources标签注册ResourceHttpRequestHandler的情况;我们需要修改下其源码:

                Object handler = hm.getUrlMap().get(pattern);                if(handler instanceof String) {//如果是字符串,那么接着去获取Bean才对                    handler = hm.getApplicationContext().getBean((String)handler);                }                if (handler instanceof ResourceHttpRequestHandler) {

 

上边的使用还是很麻烦,大家可以自己实现一个jstl function来简化使用。

 

也可以使用ResourceUrlEncodingFilter过滤器,其会对Response进行包装,当调用encodeURL时会对url进行resolver。 

 

 

当我们访问localhost:8080/test时会看到响应内容带着版本号:hello /static/css/style-23f8024fc04a067828dded9083ceab4f.css,而style.css中会变成:

@import url('other-a18c41dc0df32e9856c5c08914284553.css');

 

@import url('../css2/css2-ad02c833411bcdc09669b1464001c5e4.css');

 

当other-a18c41dc0df32e9856c5c08914284553.css请求到服务端后,会使用VersionStrategy去提取版本并进行版本的匹配,如果版本变了,而客户端没有感知到,那么将报404,这个是无法忍受的,即版本化不是持久化的。

 

 

 Spring4新特性

Spring4新特性——泛型限定式依赖注入

Spring4新特性——核心容器的其他改进

Spring4新特性——Web开发的增强

Spring4新特性——集成Bean Validation 1.1(JSR-349)到SpringMVC 

Spring4新特性——Groovy Bean定义DSL

Spring4新特性——更好的Java泛型操作API 

Spring4新特性——JSR310日期API的支持

Spring4新特性——注解、脚本、任务、MVC等其他特性改进 

 

源码下载

https://github.com/zhangkaitao/spring4-1-showcase/tree/master/spring4.1-resource

 

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!

留言需要登陆哦

技术博客集 - 网站简介:
前后端技术:
后端基于Hyperf2.1框架开发,前端使用Bootstrap可视化布局系统生成

网站主要作用:
1.编程技术分享及讨论交流,内置聊天系统;
2.测试交流框架问题,比如:Hyperf、Laravel、TP、beego;
3.本站数据是基于大数据采集等爬虫技术为基础助力分享知识,如有侵权请发邮件到站长邮箱,站长会尽快处理;
4.站长邮箱:[email protected];

      订阅博客周刊 去订阅

文章归档

文章标签

友情链接

Auther ·HouTiZong
侯体宗的博客
© 2020 zongscan.com
版权所有ICP证 : 粤ICP备20027696号
PHP交流群 也可以扫右边的二维码
侯体宗的博客