使用velocity实现页面静态化可以提高网站的性能,但是生成的静态页面怎么做到实时更新呢?
管理员在后台的每个操作 增删改查,都进行监听,并在操作完成后去验证一下对应的文件是否存在,存在就更新,不存在就不操作
使用第三智能刷新明显科学一点,使用第三种方法我们就需要使用到 设计模式中的——观察者模式
初始化velocity的配置:
package com.wwxl.filter; import java.io.IOException; import java.util.Properties; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import org.apache.velocity.app.Velocity; import com.wwxl.servletcontext.FConfig; /** * Servlet Filter implementation class SetCodeFilter */ public class SetCodeFilter implements Filter { /** * Default constructor. */ public SetCodeFilter() { // TODO Auto-generated constructor stub } /** * @see Filter#destroy() */ public void destroy() { // TODO Auto-generated method stub } /** * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain) */ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // TODO Auto-generated method stub // place your code here // pass the request along the filter chain chain.doFilter(request, response); } /** * @see Filter#init(FilterConfig) */ @SuppressWarnings("static-access") public void init(FilterConfig fConfig) throws ServletException { //初始化velocity配置 Properties properties=new Properties(); //指定velocity日志存放位置 properties.put("runtime.log",fConfig.getServletContext().getRealPath("/WEB-INF/log/velocity_example.log")); //指定模板存放的位置 properties.put("file.resource.loader.path",fConfig.getServletContext().getRealPath("/WEB-INF/velocity/")); properties.put("input.encoding","UTF-8"); properties.put("default.contentType","text/html;charset\\=UTF-8"); properties.put("output.encoding","UTF-8 "); Velocity.init(properties); //初始化时获取servletcontext,在java 代码里面会用到这个servletcontext来获取服务器的相对路径 FConfig fc=new FConfig(); fc.setServletcontext(fConfig.getServletContext()); } }
package com.wwxl.servletcontext; import javax.servlet.ServletContext; /** * 获取servletcontext,生命周期是 从servletContext创建到服务器关闭 * @author Administrator * */ public class FConfig { public static ServletContext servletcontext; public static ServletContext getServletcontext() { return servletcontext; } public static void setServletcontext(ServletContext servletcontext) { FConfig.servletcontext = servletcontext; } }
package com.wwxl.service.impl; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Observable; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.wwxl.dao.UserDao; import com.wwxl.entity.User; import com.wwxl.observer.UserServiceimplObserver; import com.wwxl.service.UserService; //被观察对象 继承observable @Service @Transactional public class UserServiceimpl extends Observable implements UserService{ @Autowired @Qualifier("userDao") private UserDao userDao; /** * 添加用户 */ public boolean sva(User user) { boolean falg=this.userDao.sva(user); if(falg) { Map<String,Object> maps=new HashMap<String, Object>(); maps.put("falg","save"); maps.put("user",user); //标记此 Observable 对象为已改变的对象;现在 hasChanged 方法将返回 true。 this.setChanged(); //如果 hasChanged 方法指示对象已改变,则通知其所有观察者,并调用 clearChanged 方法来指示此对象不再改变,maps是更改的内容 this.notifyObservers(maps); } return falg; } /** * 查询用户 */ public List<User> findAll() { return this.userDao.findAll(); } /** * 根据id查询用户 */ public User findUserById(String id) { return this.userDao.getById(id); } //注册观察者,一个 observable 对象可以有一个或多个观察者。观察者可以是实现了 Observer 接口的任意对象 public UserServiceimpl(){ //注册观察者 this.addObserver(new UserServiceimplObserver()); } }
package com.wwxl.observer; import java.util.Map; import java.util.Observable; import java.util.Observer; import com.wwxl.entity.User; import com.wwxl.servletcontext.FConfig; import com.wwxl.util.JHtmlVelocityGenerator; //观察者,观察用户发生改变就生成静态页面 public class UserServiceimplObserver extends FConfig implements Observer{ //观察用户是否修改了数据 @SuppressWarnings("unchecked") public void update(Observable o, Object arg) { Map<String,Object> maps=(Map<String, Object>)arg; String falg=(String) maps.get("falg"); System.out.println("对用户做了什么操作:"+falg); User user=(User) maps.get("user"); boolean falgs=JHtmlVelocityGenerator.JHtmlVelocityGenerators(getServletcontext(), user, "mytemplates.html","res/template"); if(falgs) { System.out.println("生成静态页面成功"); } else { System.out.println("生成静态页面失败"); } } }
package com.wwxl.util; import java.io.File; import javax.servlet.ServletContext; import org.apache.velocity.VelocityContext; import com.wwxl.constant.ClassConstant; import com.wwxl.entity.User; public class JHtmlVelocityGenerator extends HtmlVelocityGenerator { /** * 生成静态页面 * @param servletcontext servlert上下文 * @param entity 修改的对象 * @param templateName 模板名称 * @param savePath 存放路径 */ public static boolean JHtmlVelocityGenerators(ServletContext servletcontext,User user,String templateName,String savePath) { boolean falg=false; // 获得相对路径 String realPath =servletcontext.getRealPath(savePath); File savefiles = new File(realPath); if (!savefiles.exists()) savefiles.mkdirs(); String htmlName=ClassConstant.HTML_PREFIX+user.getId(); VelocityContext context = new VelocityContext(); context.put("user",user); falg=HtmlVelocityGenerator.HtmlCreate(savefiles, templateName, htmlName, context); return falg; } }
package com.wwxl.util; import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.OutputStreamWriter; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.Velocity; /** * velocity静态页面生成通用类 * @author 邓文伟 * */ public class HtmlVelocityGenerator{ /** * 静态页面生成器 * @param savefiles 生成的html页面保存的路径 * @param templateName 模板名称 * @param htmlName 生成的html名称 * @param context velocity上下文 * @return */ public static boolean HtmlCreate(File savefiles,String templateName,String htmlName,VelocityContext context) { try { Template template = Velocity.getTemplate(templateName); File savefile = new File(savefiles,htmlName+".html"); FileOutputStream outstream = new FileOutputStream(savefile); OutputStreamWriter writer = new OutputStreamWriter(outstream,"UTF-8"); BufferedWriter bufferWriter = new BufferedWriter(writer); template.merge(context, bufferWriter); bufferWriter.flush(); outstream.close(); bufferWriter.close(); return true; }catch (Exception e) { e.printStackTrace(); return false; } } public static void main(String[] args) { //HtmlVelocityGenerator.HtmlCreate("c:/"); } }
/** * 查询静态资源 * @param request * @param response * @param id * @return */ @RequestMapping({ "/userIds.htm" }) public ModelAndView userByIds(HttpServletRequest request, HttpServletResponse response, String id) { ModelAndView mv = new JModelAndView(null, request, response); // 获得要生成的静态html文件的名字 String htmlName =HTML_PREFIX + id + ".html"; mv.setViewName(CONTEXT_RES_TEMPLATE+htmlName); return mv; }很多细节还待优化,先这样记录下来吧,花了我半天时间弄这个!