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}
来直接取值的,这个要看个人喜好了。