jfinal freemarker生成静态html完整例子!支持调用两次render效果,返回json数据。

package com.seo.tool;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;

import javax.servlet.ServletContext;

import com.jfinal.core.JFinal;
import com.jfinal.kit.PathKit;
import com.jfinal.render.FreeMarkerRender;
import com.jfinal.render.JsonRender;
import com.jfinal.render.RenderException;

import freemarker.template.Configuration;
import freemarker.template.ObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;

public class MyRender extends FreeMarkerRender {

	public MyRender(String view,String url,String jsonText) {
		super(view);
		// TODO Auto-generated constructor stub
		this.url = url;
		this.jsonText = jsonText;
	}
	
	private String url;
	private String jsonText;
	private static final String contentType = "text/html; charset=" + getEncoding();
	private static final Configuration config = new Configuration();
	private static final String contentTypeJson = "application/json; charset=" + getEncoding();
	private static final String contentTypeForIE = "text/html; charset=" + getEncoding();
	private boolean forIE = false;
	
	public MyRender forIE() {
		forIE = true;
		return this;
	}
	/**
	 * freemarker can not load freemarker.properies automatically
	 */
	public static Configuration getConfiguration() {
		return config;
	}
	
	/**
	 * Set freemarker's property.
	 * The value of template_update_delay is 5 seconds.
	 * Example: FreeMarkerRender.setProperty("template_update_delay", "1600");
	 */
	public static void setProperty(String propertyName, String propertyValue) {
		try {
			FreeMarkerRender.getConfiguration().setSetting(propertyName, propertyValue);
		} catch (TemplateException e) {
			throw new RuntimeException(e);
		}
	}
	
	public static void setProperties(Properties properties) {
		try {
			FreeMarkerRender.getConfiguration().setSettings(properties);
		} catch (TemplateException e) {
			throw new RuntimeException(e);
		}
	}
	
	/**
	 * Create public void afterJFinalStart() in YourJFinalConfig and 
	 * use this method in MyJFinalConfig.afterJFinalStart() to set
	 * ServletContext for template loading
	 */
	public static void setTemplateLoadingPath(String path) {
		config.setServletContextForTemplateLoading(JFinal.me().getServletContext(), path);
	}
	
    static void init(ServletContext servletContext, Locale locale, int template_update_delay) {
        // Initialize the FreeMarker configuration;
        // - Create a configuration instance
        // config = new Configuration();
        // - Templates are stoted in the WEB-INF/templates directory of the Web app.
        config.setServletContextForTemplateLoading(servletContext, "/");	// "WEB-INF/templates"
        // - Set update dealy to 0 for now, to ease debugging and testing.
        //   Higher value should be used in production environment.
        
        if (getDevMode()) {
        	config.setTemplateUpdateDelay(0);
       	}
        else {
        	config.setTemplateUpdateDelay(template_update_delay);
        }
        
        // - Set an error handler that prints errors so they are readable with
        //   a HTML browser.
        // config.setTemplateExceptionHandler(TemplateExceptionHandler.HTML_DEBUG_HANDLER);
        config.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
        
        // - Use beans wrapper (recommmended for most applications)
        config.setObjectWrapper(ObjectWrapper.BEANS_WRAPPER);
        // - Set the default charset of the template files
        config.setDefaultEncoding(getEncoding());		// config.setDefaultEncoding("ISO-8859-1");
        // - Set the charset of the output. This is actually just a hint, that
        //   templates may require for URL encoding and for generating META element
        //   that uses http-equiv="Content-type".
        config.setOutputEncoding(getEncoding());			// config.setOutputEncoding("UTF-8");
        // - Set the default locale
        config.setLocale(locale /* Locale.CHINA */ );		// config.setLocale(Locale.US);
        config.setLocalizedLookup(false);
        
        // 去掉int型输出时的逗号, 例如: 123,456
        // config.setNumberFormat("#");		// config.setNumberFormat("0"); 也可以
        config.setNumberFormat("#0.#####");
        config.setDateFormat("yyyy-MM-dd");
        config.setTimeFormat("HH:mm:ss");
        config.setDateTimeFormat("yyyy-MM-dd HH:mm:ss");
    }
    
	/**
	 * 继承类可通过覆盖此方法改变 contentType,从而重用 freemarker 模板功能
	 * 例如利用 freemarker 实现 FreeMarkerXmlRender 生成 Xml 内容
	 */
    public String getContentType() {
    	return contentType;
    }
    
	@SuppressWarnings({"unchecked", "rawtypes"})
	public void render() {
		//response.setContentType(getContentType());
        System.out.println("进入myrender");
		Map data = new HashMap();
		for (Enumeration<String> attrs=request.getAttributeNames(); attrs.hasMoreElements();) {
			String attrName = attrs.nextElement();
			data.put(attrName, request.getAttribute(attrName));
		}
		
		PrintWriter writerJson = null;
		Writer writer = null;
        try {
			Template template = super.getConfiguration().getTemplate(view);
			System.out.println("response.getWriter()	" + response.getWriter());
			//writerPW = response.getWriter();
			String htmlPath = JFinal.me().getServletContext().getRealPath("/") + "/jiage/" + this.getUrl(); 
			File htmlFile = new File(htmlPath);   
	        writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(htmlFile), "UTF-8"));  
			template.process(data, writer);		// Merge the data-model and the template
			//template.process(data, writer);	
	        response.setHeader("Pragma", "no-cache");	// HTTP/1.0 caches might not implement Cache-Control and might only implement Pragma: no-cache
			response.setHeader("Cache-Control", "no-cache");
			response.setDateHeader("Expires", 0);
			
			response.setContentType(forIE ? contentTypeForIE : contentTypeJson);
			writerJson = response.getWriter();
			writerJson.write(jsonText);
			writerJson.flush();
        } catch (Exception e) {
			throw new RenderException(e);
		}
		finally {
			if (writer != null)
				try {
					writer.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		}
       
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public String getJsonText() {
		return jsonText;
	}

	public void setJsonText(String jsonText) {
		this.jsonText = jsonText;
	}
	
}

 

MyRender直接拷贝了 FreeMarkerRender,继承了FreeMarkerRender,当然这样写点累赘,但这个不是关键。

整个流程来说:

String htmlPath = JFinal.me().getServletContext().getRealPath("/") + "/jiage/" + this.getUrl(); 
File htmlFile = new File(htmlPath);   
writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(htmlFile), "UTF-8"));  

用来替换原来输出response html代码输出到浏览器的方法。

template.process(data, writer);    不能删掉

通过以上步骤,即可在jfinal使用freemarker生成静态html

如果生成之后我想返回json到前端,让前端进行处理应该怎么办呢?如果调用两次render?

调用两次render,最后一次执行的方法才能生效。

解决办法:

1、如果在前端执行两次请求,获取第二次的json,感觉有点累赘。(未验证)

2、直接在myrender方法中进行扩展,应该response没有被使用,所以我们可以找到JsonRender里面的方法,进行合并。

response.setHeader("Pragma", "no-cache");	// HTTP/1.0 caches might not implement Cache-Control and might only implement Pragma: no-cache
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
			
response.setContentType(forIE ? contentTypeForIE : contentTypeJson);
writerJson = response.getWriter();
writerJson.write(jsonText);
writerJson.flush();

调用方法的时候,是需要传入json,所以自己定一个String jsonText。

MyRender myRender = new MyRender("/pages.html",keypage.getUrl(),JsonKit.toJson(Keypage.dao.findById(keywordid)));
render(myRender);

 

转载于:https://my.oschina.net/u/143998/blog/827157

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值