SpringMVC整合Freemaker

[color=red]
更多信息:[url]http://baike.baidu.com/view/1278430.htm[/url] [url]http://freemarker.org[/url] 
[/color]

[color=green]
<!-- Freemarker Maven dependency-->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.20</version>
</dependency>
<!-- ui.freemarker -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>3.2.4.RELEASE</version>
</dependency>
[/color]

[b][color=red][table]
|step2.在src/main/resources/conf目錄下新建Freemarker屬性文件freemarker.properties,此屬性文件定義了Freemarker常用的編碼轉換,代碼如下::|
[/table][/color][/b]

tag_syntax=auto_detect
template_update_delay=2
default_encoding=UTF-8
output_encoding=UTF-8
locale=zh_CN
date_format=yyyy-MM-dd
time_format=HH:mm:ss
datetime_format=yyyy-MM-dd HH:mm:ss


[b][color=red][table]
|step3.在DispatcherServlet上下文配置文件spring-servlet.xml中添加Freemarker所需的配置,代碼如下:|
[/table][/color][/b]


<!-- 配置Freemarker属性文件路径 -->
<bean id="freemarkerConfiguration" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="location" value="classpath:conf/freemarker.properties" />
</bean>
<!-- 配置freeMarker模板加载地址 -->
<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<!-- 视图解析器会在/WEB-INF/ftl/路径下扫描视图文件-->
<property name="templateLoaderPath" value="/WEB-INF/ftl/" />
<property name="freemarkerVariables">
<map>
<entry key="xml_escape" value-ref="fmXmlEscape" />
</map>
</property>
</bean>
<bean id="fmXmlEscape" class="freemarker.template.utility.XmlEscape" />
<!-- 配置freeMarker视图解析器 -->
<bean id="freemakerViewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.freemarker.FreeMarkerView" />
<!-- 所描路径内所有的ftl結尾的文件 -->
<property name="viewNames">
<array>
<value>*.ftl</value>
</array>
</property>
<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="order" value="1" />
</bean>



[b][color=red][table]
|step3.1在DispatcherServlet上下文配置文件spring-servlet.xml中添加FreeMaker自定义标签需要的配置 代碼如下:|
[/table][/color][/b]


<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<!-- 假设你需要使用freemarker的自定义标签,这里还需要增加这一段 -->
<property name="freemarkerVariables" />
<!-- 这里配置的是自定义标签,建议命名为XXDirective,有多个就一起在这里配置
<map>
<entry key="courselist" value-ref="courselist"/>
<entry key="channellist" value-ref="channellist"/>
<entry key="upper" value ref="upper"/>
</map>
</property>
</bean>
<bean id="courselist" class="com.keweisoft.ecmp.web.label.CourseListDirecitve"/>
<bean id="channellist" class="com.keweisoft.ecmp.web.label.TopChannelDirt"/>
<bean id="childchanlist" class="com.keweisoft.ecmp.web.label.TopChannelDirt"/>
<bean id="upper" class="com.keweisoft.ecmp.web.label.PaymentDirecitive"/>



import java.io.IOException;
import java.io.Writer;
import java.util.Map;

import freemarker.core.Environment;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;
//把小写的字符转换为大写的字符
public class PaymentDirecitive implements TemplateDirectiveModel {


public void execute(Environment env, Map params, TemplateModel[] loopVars,
TemplateDirectiveBody body) throws TemplateException, IOException {
// 检查参数是否传入
if (!params.isEmpty()) {
throw new TemplateModelException(
"This directive doesn't allow parameters.");
}
if (loopVars.length != 0) {
throw new TemplateModelException(
"This directive doesn't allow loop variables.");
}
// 是否有非空的嵌入内容
//2015、6、11修改下面被注释的内用 如果以共享变量存储
//还是以环境变量存储在显示的时候都出出现BUG
//前者是一个模板中同一个标签不能用两次并且不能支持当前页面的
//再次请求;后置不支持一个模板多次使用也会报错
//去过是一些复杂的业务就是用循环变量这样就可以多次使用多次访问
//demo我会在本章的最下面带上
/*env.getConfiguration().setSharedVariable("upper", new PaymentDirecitive());
env.setVariable("upper", new PaymentDirecitive());*/
if (body != null) {
// 执行嵌入体部分,和 FTL 中的<#nested>一样,除了
// 我们使用我们自己的 writer 来代替当前的 output writer.
body.render(new UpperCaseFilterWriter(env.getOut()));
} else {
throw new RuntimeException("missing body");
}
}
private class UpperCaseFilterWriter extends Writer {
private final Writer out;
public UpperCaseFilterWriter(){out=null;};
public UpperCaseFilterWriter(Writer out) {
this.out = out;
}

public void write(char[] cbuf, int off, int len) throws IOException {
char[] transformedCbuf = new char[len];
for (int i = 0; i < len; i++) {
transformedCbuf[i] = Character.toUpperCase(cbuf[i + off]);
}
out.write(transformedCbuf);
}

public void flush() throws IOException {
out.flush();
}

public void close() throws IOException {
out.close();
}
}
}


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>
</title>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<body>
<#-- upper 《entry key="upper" value ref="upper"》这个一个标签 -->
<@upper>
bar
<#-- 这里允许使用所有的 FTL -->
<#list ["red", "green", "blue"] as color>
${color}
</#list>
baaz
</@upper>
</body>
</html>


[b][table]
|注意:freemarker里面获取HttpServletRequest没有办法获取,最后还是通过spring的一个listener解决的|
|在web.xml里面添加下面的配置:|
[/table][/b]

<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>


ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
HttpServletRequest request = attr.getRequest();


[b][color=red][table]
||
|纠正指令存在的BUG|
[/table][/color][/b]



public class PaymentDirecitive implements TemplateDirectiveModel {

@Resource
private IPaymentService paymentService;
@Resource
private IStationService stationService;
@Resource(name="freemarkerConfig")
private FreeMarkerConfigurer freemarkerConfig;
private static Queue<PaymentDirecitiveModel> queuePayment=new LinkedList<PaymentDirecitive.PaymentDirecitiveModel>();
private static String PAYMENT_CACHE="stationPayment" ;
private static BeansWrapper beansWrapper;
static{
queuePayment.add(new PaymentDirecitive().new PaymentDirecitiveModel());
beansWrapper =
new BeansWrapperBuilder(Configuration.VERSION_2_3_22).build();
}
String name = null;

public PaymentDirecitive(String name) {
this.name = name;
}

public PaymentDirecitive() {

}

public void execute(Environment env, Map params, TemplateModel[] loopVars,
TemplateDirectiveBody body) throws TemplateException, IOException {
// 检查参数是否传入
/*if (!params.isEmpty()) {
throw new TemplateModelException("This directive doesn't allow parameters.");
}
if (loopVars.length != 0) {
throw new TemplateModelException("This directivedoesn't allow loop variables.");
}*/
Writer out=env.getOut();
// 是否有非空的嵌入内容
if (body != null) {
ServletRequestAttributes requestAttr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
HttpServletRequest request = requestAttr.getRequest(); //TODO 模拟数据

request.getSession().setAttribute("station",3);

HttpSession session=request.getSession();
Integer station=(Integer)session.getAttribute("station");
Map<String,String> para=new HashMap<String, String>();
para.put("stationId",station.toString());//TODO 模拟缓存
PaymentDirecitiveModel result=(PaymentDirecitiveModel)session.getAttribute(PAYMENT_CACHE+station);
if(null!=result)
{
loopVars[0]=new DefaultObjectWrapper(Configuration.VERSION_2_3_22).wrap(result.getDataView());
}else
{
PaymentDirecitiveModel pdm=null;
List<Map<String,Object>> list=this.paymentService.getPaymentDirectiveByStationId(para);
for (int i = 0; i < list.size(); i++) {
pdm=queuePayment.peek();
Map<String,Object> tmp=list.get(i);
String stationId=tmp.get("station_id").toString();
String payId=tmp.get("pay_id").toString();
String payAccount=tmp.get("pay_account").toString();
String payStatus=tmp.get("pay_status").toString();
String platId=tmp.get("plat_id").toString();
String paymentId=tmp.get("payment_id").toString();
String partner=tmp.get("partner").toString();
String privateKey=tmp.get("private_key").toString();
String logPath=tmp.get("log_path").toString();
String platName=tmp.get("plat_name").toString();
String platDesc=tmp.get("plat_desc").toString();
String logoPath=tmp.get("logo_path").toString();
String paymentType= tmp.get("payment_type").toString();
String paymentDesc= tmp.get("payment_desc").toString();
String attrNameP=tmp.get("attr_name_p").toString();
String attrValueP=tmp.get("attr_value_p").toString();
String attrNameI=tmp.get("attr_name_i").toString();
String attrValueI=tmp.get("attr_value_i").toString();
if(i==0)
{
pdm.setStationId(stationId);

pdm.setLogoPath(logoPath);
pdm.setPlatName(platName);
pdm.setPlatDesc(platDesc);

pdm.setPayAccount(payAccount);
pdm.setPayStatus(payStatus);
pdm.setPartner(partner);
pdm.setLogPath(logPath);
pdm.setPrivateKey(privateKey);

pdm.setPaymentType(paymentType);
pdm.setPaymentDesc(paymentDesc);
}
else
{
pdm.setStationId(stationId);



if(pdm.setPlatId(platId))
{
pdm.setLogoPath(logoPath);
pdm.setPlatName(platName);
pdm.setPlatDesc(platDesc);

}
/* else
{
queuePayment.add(new PaymentDirecitiveModel());
i-=1;
continue ;
}
*/
if(!pdm.setPayId(payId))
{
pdm.setPayAccount(payAccount);
pdm.setPayStatus(payStatus);
pdm.setPartner(partner);
pdm.setLogPath(logPath);
pdm.setPrivateKey(privateKey);
}
if(!pdm.setPaymentId(paymentId))
{
pdm.setPaymentType(paymentType);
pdm.setPaymentDesc(paymentDesc);

}
pdm.setPaymentAttrs(paymentId,attrNameI, attrValueI);
pdm.setPlatAttrs(platId,attrNameP, attrValueP);
}
}
session.setAttribute(PAYMENT_CACHE+station,pdm);//TODO 模拟缓存
loopVars[0]=new DefaultObjectWrapper(Configuration.VERSION_2_3_22).wrap(pdm.getDataView());
}

body.render(env.getOut());
} else {
throw new RuntimeException("missing body");
}
}


private class PaymentDirecitiveModel
{
@SuppressWarnings("unused")
public String getStationId() {
return stationId;
}
public void setStationId(String stationId) {
this.stationId = stationId;
}
@SuppressWarnings("unused")
public List<String> getPayId() {
return payId;
}
public Boolean setPayId(String payId) {
if(!this.payId.contains(payId))
{
this.payId.add(payId);
return false;
}
else
return true;

}
@SuppressWarnings("unused")
public List<String> getPlatId() {
return platId;
}
public Boolean setPlatId(String platId) {
if(!this.platId.contains(platId))
{
this.platId.add(platId);
return true;
}
else
return false;
}
@SuppressWarnings("unused")
public List<String> getPaymentId() {
return paymentId;
}
public Boolean setPaymentId(String paymentId) {
if(!this.paymentId.contains(paymentId))
{
this.paymentId.add(paymentId);
return false;
}
else
return true;
}
@SuppressWarnings("unused")
public Map<String, String> getPlatAttrs(String key) {
return platAttrs.get(key);
}
public void setPlatAttrs(String key,String name ,String value) {
Map<String,String> attr=new HashMap<String, String>();
attr.put(name, value);
this.platAttrs.put(key,attr);
}
@SuppressWarnings("unused")
public Map<String, String> getPaymentAttrs(String key) {
return paymentAttrs.get(key);
}
public void setPaymentAttrs(String key,String name ,String value) {
Map<String,String> attr=new HashMap<String, String>();
attr.put(name, value);
this.paymentAttrs.put(key,attr);
}

private String stationId;
private List<String> payId=new ArrayList<String>();
private List<String> payStatus=new ArrayList<String>();
@SuppressWarnings("unused")
public List<String> getPayStatus() {
return payStatus;
}
public void setPayStatus(String payStatus) {
if(!this.payStatus.contains(payStatus))
this.payStatus.add(payStatus);
}

private List<String> logoPath=new ArrayList<String>();
@SuppressWarnings("unused")
public List<String> getLogoPath() {

return logoPath;
}
public void setLogoPath(String logoPath) {
if(!this.logoPath.contains(logoPath))
{
this.logoPath.add(logoPath);
}

}
@SuppressWarnings("unused")
public List<String> getPartner() {
return partner;
}
public void setPartner(String partner) {
if(!this.partner.contains(partner))
this.partner.add(partner);
}

private List<String> platName =new ArrayList<String>();
@SuppressWarnings("unused")
public List<String> getPlatName() {
return platName;
}
public void setPlatName(String platName) {
if(!this.platName.contains(platName))
this.platName.add(platName);
}
private List<String> privateKey=new ArrayList<String>();
@SuppressWarnings("unused")
public List<String> getPrivateKey() {
return privateKey;
}
public void setPrivateKey(String privateKey) {
if(!this.privateKey.contains(privateKey))
this.privateKey.add(privateKey);
}
@SuppressWarnings("unused")
public List<String> getPlatDesc() {
return platDesc;
}
public void setPlatDesc(String platDesc){
if(!this.platDesc.contains(platDesc))
this.platDesc.add(platDesc);
}

private List<String> logPath=new ArrayList<String>();
@SuppressWarnings("unused")
public List<String> getLogPath() {
return logPath;
}
public void setLogPath(String logPath) {
if(!this.logoPath.contains(logPath))
this.logPath.add(logPath);
}
private List<String> paymentType=new ArrayList<String>();
@SuppressWarnings("unused")
public List<String> getPaymentType() {
return paymentType;
}
public void setPaymentType(String paymentType) {
if(!this.paymentType.contains(paymentType));
this.paymentType.add(paymentType);
}
private List<String>paymentDesc=new ArrayList<String>();
@SuppressWarnings("unused")
public List<String> getPaymentDesc() {
return paymentDesc;
}
public void setPaymentDesc(String paymentDesc) {
if(!this.paymentDesc.contains(paymentDesc))
this.paymentDesc.add(paymentDesc);
}
private List<String> payAccount=new ArrayList<String>();
@SuppressWarnings("unused")
public List<String> getPayAccount() {
return payAccount;
}
public void setPayAccount(String payAccount) {
if(!this.payAccount.contains(payAccount))
this.payAccount.add(payAccount);
}
private List<HashMap<String, String>> dataView=new ArrayList<HashMap<String, String>>();

public List<HashMap<String, String>> getDataView() {
if(this.dataView.size()>0)
return dataView;
else
{
for(int i=0,len=platId.size();i<len;i++)
{
HashMap<String, String> subDataView=new HashMap<String, String>();
subDataView.put("platId",this.platId.get(i));
subDataView.put("paymentId",this.paymentId.get(i));
subDataView.put("payId",this.payId.get(i));
subDataView.put("src",this.logoPath.get(i));
this.dataView.add(subDataView);
}
return dataView;
}
}
public void setDataView(List<HashMap<String, String>> dataView) {
if(null==dataView)
{
this.dataView.clear();
}
else
this.dataView = dataView;
}

private List<String>platDesc=new ArrayList<String>();
private List<String> partner=new ArrayList<String>();
private List<String> platId=new ArrayList<String>();
private List<String> paymentId=new ArrayList<String>();
private Map<String,Map<String,String>> platAttrs=new HashMap<String,Map<String,String>>();
private Map<String,Map<String,String>> paymentAttrs=new HashMap<String,Map<String,String>>();
public PaymentDirecitiveModel() {

}

}

}


<#assign uriPrefix="/ecmp-web">
<@payment ;dataView >
<#list dataView as items>
<#list items?keys as item>

<#if item=='src'>
<img src="${uriPrefix}${items[item]}"/>

<#elseif item=="payId">
<input type="radio" name="${item}" value="${items[item]}"/>
<#else>
<input type="hidden" name="${item}" value="${items[item]}"/>
</#if>
</#list>
</#list>
</@payment>
<@payment ;dataView >
<#list dataView as items>
<#list items?keys as item>

<#if item=='src'>
<img src="${uriPrefix}${items[item]}"/>

<#elseif item=="payId">
<input type="radio" name="${item}" value="${items[item]}"/>
<#else>
<input type="hidden" name="${item}" value="${items[item]}"/>
</#if>
</#list>
</#list>
</@payment>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值