SpringMVC整合Freemaker


更多信息:http://baike.baidu.com/view/1278430.htm http://freemarker.org 

[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]

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

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


step3.在DispatcherServlet上下文配置文件spring-servlet.xml中添加Freemarker所需的配置,代碼如下:


<!-- 配置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>



step3.1在DispatcherServlet上下文配置文件spring-servlet.xml中添加FreeMaker自定义标签需要的配置 代碼如下:


      <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>


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

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

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


纠正指令存在的BUG



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>

猜你喜欢

转载自liweichao.iteye.com/blog/2214530