【spring】ApplicationListener傳遞參數到頁面(解決靜態+動態資源路徑+靜態文件的緩存控制)

一.相對路徑仍是絕對路徑的問題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"+..

相關文章
相關標籤/搜索