freemarker 页面如何获取绝对路径 basePath

原创 freemarker

在使用 FreeMarker 模板的时候,加载静态资源需要添加一个项目根路径的前缀,以适配浏览器地址栏中的项目名称。当然很多时候在实际上线的时候,一般是去除项目名称的,但是考虑在测试、多项目部署或其他特殊情况下需要使用,并且这也是代码健壮性的一方面,我们一般是要去取这个值的。

传统方式取相对路径

spring-mvc.xml 中配置

<!-- FreeMarker视图解析 如返回userinfo。。在这里配置后缀名ftl和视图解析器。。 -->
<bean id="viewResolverFtl"
    class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
    <property name="viewClass"
        value="org.springframework.web.servlet.view.freemarker.FreeMarkerView" />
    <property name="suffix" value=".ftl" />
    <property name="contentType" value="text/html;charset=UTF-8" />
    <property name="exposeRequestAttributes" value="true" />
    <property name="exposeSessionAttributes" value="true" />
    <property name="exposeSpringMacroHelpers" value="true" />
    <property name="requestContextAttribute" value="request" />
    <property name="cache" value="true" />
    <property name="order" value="0" />
</bean>

其中 <property name="requestContextAttribute" value="request" /> 是关键。

ftl页面中设置

<#assign base=request.contextPath />
<!DOCTYPE html>
<html lang="zh">
<head>
    <base id="base" href="${base}">
    <title>首页</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <link href="${base}/static/bootstrap-3.3.4/css/bootstrap.min.css" rel="stylesheet">
    <script src="${base}/static/bootstrap-3.3.4/js/bootstrap.min.js"></script>

js文件中获取path

var base = document.getElementById("base").href;
// 与后台交互
_send = function(async, url, value, success, error) {
    $.ajax({
        async : async,
        url : base + '/' + url,
        contentType : "application/x-www-form-urlencoded; charset=utf-8",
        data : value,
        dataType : 'json',
        type : 'post',
        success : function(data) {
            success(data);
        },
        error : function(data) {
            error(data);
        }
    });
};

即可获取带项目名的路径,但这路径是相对路径,浏览器输入 http://localhost:8080/test-web/index.html 访问,一切正常。

重写 FreeMarkerView 的 exposeHelpers 方法

通过继承freemarker视图解析类 org.springframework.web.servlet.view.freemarker.FreeMarkerView,重写 exposeHelpers 方法,在 spring 里配置自己的 freemarker 的视图解析器,在模板中就可以通过 ${base} 获取。

MyFreeMarkerView 代码

package com.liuqianfei.framework.ext;

import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.servlet.view.freemarker.FreeMarkerView;

public class MyFreeMarkerView extends FreeMarkerView
{
    private static final String CONTEXT_PATH = "base"; 
    @Override
    protected void exposeHelpers(Map<String, Object> model,
        HttpServletRequest request) throws Exception
    {
        model.put(CONTEXT_PATH, request.getContextPath());
        super.exposeHelpers(model, request);
    }

}

spring-mvc.xml配置

<bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
    <!-- 省略其他配置 -->
    <!-- 自定义FreeMarkerView,用来定义项目的全局路径 -->
    <property name="viewClass" value="com.liuqianfei.framework.ext.MyFreeMarkerView" />
</bean>

总结

总的来说,第二种方式比较好一点,使用也方便。另一种不是很推荐的方式是使用过滤器或拦截器在 request 中注入 contextPath 的方式。

当然,在 springmvc + freemarker 的环境下,不做任何配置,也是可以使用 ${request.contextPath} 来直接取值的,这个要看个人喜好了。

如果觉得这对你有用,请随意赞赏,给与作者支持
评论 0
最新评论