【spring】ApplicationListener传递参数到页面(解决静态+动态资源路径+静态文件的缓存控制)
一.相对路径还是绝对路径的问题
前端页面加载资源或者请求的时候到底是使用相对路径还是绝对路径,想必大家都很清楚,用的是当然是相对路径,因为这样增加了项目的灵活性,不需要经常的改动。那既然是相对路径就需要在页面中小心使用了,一旦使用错误,讨厌的404就会来了,相当讨人厌。
二.相对路径的获取
相对路径的获取办法也有好多种
1. 一种是在jsp页面利用<%%>来拼凑路径,然后配置base路径,代码如下
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServeName()+":"+request.getServePort()+"/"+path+"/";
%>
<head>
<base href="<%basePath%>">
</head>
2.这里为大家介绍另一种办法就是通过spring的Applicationlistener接口来传递相对路径的参数,可以直接在页面中使用,同时可以通过此方法来解决静态文件更新后的缓存问题。框架【spring+springmvc】
步骤:
①.引入spring及其他的相关jar包,此处省略
②.配置相关配置文件
spring的配置文件ApplicationContext.xml
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.1.xsd"> <context:component-scan base-package="com.raipeng.work.spring.model"/>
<context:component-scan base-package="com.raipeng.work.spring.listener"/>
<!--加载自定义的配置文件-->
<context:property-placeholder location="classpath:config.properties"/>
</beans>
config.properties
git.version =1.0.0
web.xml
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app>
<display-name>Archetype Created Web Application</display-name> <context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param> <servlet>
<servlet-name>test</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:test-servlet.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>test</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping> <listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
test.servlet.xml (spring mvc 配置文件)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd"> <context:component-scan base-package="com.xxx.work.spring.controller"/> <mvc:default-servlet-handler/> <mvc:annotation-driven/>
<!--视图解析配置-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
webConfig.java
package com.xxx.work.spring.model; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; /**
* Created by 111 on 2015/11/24.
*/
//需要加入注解并扫描该文件,用于后期的自动注入
@Component
public class WebConfig {
private String resource;//静态资源文件
private String context;//WEB应用上下文
private String revision;//CSS、js版本号,防止缓存的问题 public String getResource() {
return resource;
} public void setResource(String resource) {
this.resource = resource;
} public String getContext() {
return context;
} public void setContext(String context) {
this.context = context;
} public String getRevision() {
return revision;
}
//加载配置文件中的值
@Value("${git.version}")
public void setRevision(String revision) {
this.revision = revision;
}
}
WebApplicationContextListener.java
package com.xxx.work.spring.listener; import com.raipeng.work.spring.model.WebConfig;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
import org.springframework.web.context.WebApplicationContext; import javax.annotation.Resource;
import javax.servlet.ServletContext; /**
* Created by 111 on 2015/11/24.
*/ //需要注解,并扫描,在程序启动的时候就自动加载
@Component
public class WebApplicationListener implements ApplicationListener<ContextRefreshedEvent> { private Logger logger = LogManager.getLogger(WebApplicationListener.class); private WebConfig webConfig; //资源注入,也可以直接在变量上用autowired
@Resource
public void setWebConfig(WebConfig webConfig) {
this.webConfig = webConfig;
} //覆盖ApplicationListener的方法,重写自己的业务逻辑
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
ApplicationContext applicationContext = event.getApplicationContext();
WebApplicationContext webApplicationContext = (WebApplicationContext)applicationContext;
ServletContext servletContext = webApplicationContext.getServletContext();
webConfig.setContext(servletContext.getContextPath());
webConfig.setResource(webConfig.getContext()+"/public");
servletContext.setAttribute("context",webConfig.getContext());
servletContext.setAttribute("resource",webConfig.getResource());
servletContext.setAttribute("revision",webConfig.getRevision());
logger.debug("context:{},resource:{},revision:{}",webConfig.getContext(),webConfig.getResource(),webConfig.getRevision());
}
}
index.jsp
<%--
Created by IntelliJ IDEA.
User: 111
Date: 2015/11/24
Time: 15:51
To change this template use File | Settings | File Templates.
--%>
<!--jsp有的版本默认el表达式关闭,如果遇到el表达式没解析,可以试试加上这个-->
<%@ page isELIgnored="false"%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html> <head>
<link rel="stylesheet" href="${resource}/css/index.css?revision=${revision}">
<title></title>
</head>
<body>
<img src="${resource}/image/image.png"/>
<a href="${context}/test/home">点击</a>
</body>
</html>
目录结构
忽略boot.jsp
浏览器中的效果:

三.原理解析(暂略)
这里从spring的流程进行分析,
首先启动Tomcat服务器
——>根据web.xml中配置的contextLoaderListener初始化容器(ContextLoadListener.java 实现了ServletContextListener)
@Override
public void contextInitialized(ServletContextEvent event) {
initWebApplicationContext(event.getServletContext());
}
——>实际上是在父类ContextLoader中初始化,在ContextLoader中为容器例示一个根webApplicationContext(Instantiate the root WebApplicationContext for this loader),方法为
if (this.context == null) {
this.context = createWebApplicationContext(servletContext);
}
接着如果有父上下文加载父上下文(这里parentContext为空)
四.js页面的相对路径解决(使用tiles布局,定义在general.jsp的公共页面):
<script type="text/javascript" src="${resource}/lib/amd/require.js"
data-main="${resource}/lib/amd/config.js?revision=${revision}"
data-app="${resource}/js/general.js,<tiles:insertAttribute name="app" ignore="true"/>"
data-context="${context}" data-revision="${revision}" data-resource="${resource}" defer
async="true"></script>
在config.js(amd的配置文件)中
(function () {
var scripts = document.getElementsByTagName('script');
for (var i = 0; i < scripts.length; i++) {
if (scripts[i].getAttribute('data-main')) {
var context = scripts[i].getAttribute('data-context');
var revision = scripts[i].getAttribute('data-revision');
var resource = scripts[i].getAttribute('data-resource');
var config = {
context: context,
revision: revision,
resource: resource
};
window.config = config;
break;
}
}
})(window);
调用时使用:url:config.context 静态页面:config.resource+"/lib"+..
【spring】ApplicationListener传递参数到页面(解决静态+动态资源路径+静态文件的缓存控制)的更多相关文章
- 资料汇总--Ajax中Put和Delete请求传递参数无效的解决方法(Restful风格)【转】
开发环境:Tomcat9.0 在使用Ajax实现Restful的时候,有时候会出现无法Put.Delete请求参数无法传递到程序中的尴尬情况,此时我们可以有两种解决方案:1.使用地址重写的方法传递参数 ...
- Ajax中Put和Delete请求传递参数无效的解决方法(Restful风格)
本文装载自:http://blog.csdn.net/u012737182/article/details/52831008 感谢原文作者分享 开发环境:Tomcat9.0 在使用Ajax实现R ...
- Spring Mvc 传递参数要controller出现了400,日期参数全局处理,格式化yyyy-MM-dd 和yyyy-MM-dd HH:mm:ss
描述:今天做一个业务操作的时候,ajax传递参数要controller出现了400,前后台都没有报错. 问题:springmvc 在接收日期类型参数时,如不做特殊处理 会出现400语法格式错误 解决: ...
- router-link跳转页面传递参数及页面刷新方法
使用router-link传参: 第一种: 路径:http://localhost:8080/goodListP?id=2 跳转的页面获取参数: this.$route.query.id 第二种: 路 ...
- url传递参数带 + ,解决办法
修改客户端,将客户端带“+”的参数中的“+”全部替换为“%2B”,这样参数传到服务器端时就能得到“+”了.
- ajax 传递参数中文乱码解决办法
/********Start***********/ /*获取地址栏参数*/ function getRequest(){ var url = location.search; //获取url中&qu ...
- NodeJs学习记录(六)使用 res.locals 传递参数到页面
res.locals的生命周期是单次请求,有点类似于java servlet 里的 httpServletRequest.setAttribute("param1",1); 既然 ...
- vue - 路由传递参数
结构目录 1. 页面传值(不同之间的页面传值) 1.1 index.js配置 源码: // 引入vue框架 import Vue from 'vue' // 引入vue-router路由依赖 impo ...
- cli下的php(并传递参数)
传递参数有两种方式: 第一种使用文件操作,STDOUT作为标准输出,STDIN作为标准输入 使用fwrite($file,$string)作输出,使用fgets($file)作输入.这种应该算是继承自 ...
随机推荐
- 使用docker 部署rabbitmq 镜像
1.使用带有web管理功能 sudo docker pull rabbitmq:management 2.运行镜像文件创建容器 sudo docker run -d --name rabbitmq - ...
- Future模式衍生出来的更高级的应用
再上一个场景:我们自己写一个简单的数据库连接池,能够复用数据库连接,并且能在高并发情况下正常工作. 实现代码1: package test; import java.util.concurrent.C ...
- oracle中可能使用到的命令
借鉴他人 1.su – oracle 不是必需,适合于没有DBA密码时使用,可以不用密码来进入sqlplus界面.2.sqlplus /nolog 或sqlplus system/manager 或. ...
- Spring基础知识备案
关于@Value注解不能为静态变量赋值的问题 // eg:(xxx.ooo.value=100) 以下这种方式,来自配置文件的属性值无法注入: public class XxxUtils { @Val ...
- 我们为什么不用 Select * 吗?
应用程序慢如牛,原因多多,可能是网络的原因.可能是系统架构的原因,还有可能是数据库的原因. 那么如何提高数据库SQL语句执行速度呢?有人会说性能调优是数据库管理员(DBA)的事,然而性能调优跟程序员们 ...
- iOS 9之后Url链接的NSUTF8StringEncoding转码实现
在iOS中通过WebView加载Url或者请求HTTP时,若是链接中包含中文.特殊符号&%或是空格等都需要预先进行一下转码才可正常访问. 许久没编码,原先的方法已废弃了都,在此对应当前最新的方 ...
- Java 多文件压缩成一个文件工具类
简单修改来自博客园勇闯天涯zfc的博客 一.内容 ①使用 Java 将多个文件打包压缩成一个压缩文件: ②主要使用 java.io 下的类 二.源代码:ZIPUtil .java import jav ...
- 教你如何用勾勾街快速生成一个苹果IOS APP
现在苹果手机上的各种各样的APP,想不想也有一款属于自己的专属APP?很简单,用勾勾街可以在3分钟内快速制作一款,快来看看! 工具平台: 勾勾街 (www.gogojie.com ) 操作方法: 1. ...
- Oracle导入大数据量(百万以上)dmp文件,报错ora-12592 :包错误
进行自动化测试过程中,发现需要重新搭建一套自动化测试库,然后利用pl/sql对数据库导出: 进行导入后发现报错ora-12592 :包错误 原因分析,数据量过大,传输超时,需要在Oracle服务端以及 ...
- Android中SDK工具集锦
来源:<Android 4 高级编程> Android提供的SDK中包含有很多用于设计.实现.调试应用程序的工具:比较重要的如下所述: 1. ADB工具 Android应用程序调试桥ADB ...