一.相對路徑仍是絕對路徑的問題javascript
前端頁面加載資源或者請求的時候究竟是使用相對路徑仍是絕對路徑,想必你們都很清楚,用的是固然是相對路徑,由於這樣增長了項目的靈活性,不須要常常的改動。那既然是相對路徑就須要在頁面中當心使用了,一旦使用錯誤,討厭的404就會來了,至關討人厭。css
二.相對路徑的獲取html
相對路徑的獲取辦法也有好多種前端
1. 一種是在jsp頁面利用<%%>來拼湊路徑,而後配置base路徑,代碼以下java
<% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServeName()+":"+request.getServePort()+"/"+path+"/"; %> <head> <base href="<%basePath%>"> </head>
2.這裏爲你們介紹另外一種辦法就是經過spring的Applicationlistener接口來傳遞相對路徑的參數,能夠直接在頁面中使用,同時能夠經過此方法來解決靜態文件更新後的緩存問題。框架【spring+springmvc】git
步驟:web
①.引入spring及其餘的相關jar包,此處省略spring
②.配置相關配置文件apache
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"+..