www.javaei.com网站建设手记——(4)实现细节

 

Javaei的发布系统的主要功能是录入、预览和发布,在实现上,其实是个很小很小的增删改查,本微不足道,但我觉得技术不是最重要的事,因为我的网站目前不需要太高深的技术。但还是要说说这个发布系统的一些实现细节,不为别的,只为给自己做个记录,给网站做个记录。

         在上一篇已经说到过,发布系统的关键在于生成html并替换动态连接为静态的html连接,我想到的实现方式有两种,在客户端用程序发起请求,第一种方式是解析响应的html,对要处理的超级链接(也就是<a href=””>)做处理,第二种方式是在开发的时候定制一个标签,把要处理的超级链接写在定制标签里,服务器在解析标签的时候对超级链接进行处理。对超级链接进行处理有两件事,一件事就是生成该链接的html文件,一件事是替换原来的连接为指向生成的html文件的静态链接。我采用的是第二种方式。第一种方式更适合对已有的网站进行静态化。不管是哪种方式,都面临着一个相同的问题,那就是在处理超级链接的时候,超级链接指向的页面同样包含着要处理的超级链接,而且还会有与正在处理超级链接相同的超级链接,这是个递归。其实这也是个简单的爬虫,已经爬过的就不能再爬。解决这个问题其实很简单,对已经处理过的超级链接做个hash缓存就可以了。

         要处理的超级链接生成的html方式可能不一样,简单来说就是生成的html文件的路径和生成的html连接的uri可能不相同,所以需要把这种不同从标签处理器里分出来,标签不能太复杂,标签的主要作用应该是接受标签的属性值作为参数和输出<a>标签和href属性的值及其他属性的值。而生成html文件和html路径(也作为uri)应该由一个独立出来的处理器来完成。下面是相关的类结构图。



 

BaseHrefTag的部分代码如下

Java代码
  1. public abstract class BaseHrefTag extends BodyTagSupport {   
  2.        
  3.     private String href;//   
  4.     private String tohtml;//是否需要处理,预览时为false   
  5.   
  6.     private String classname;//css class name   
  7.     private String target;//target   
  8.     private String root;//生成html链接时是否加上host   
  9.        
  10.   
  11.     public int doStartTag() throws JspException {   
  12.         // TODO Auto-generated method stub   
  13.         String hrefvalue = null;   
  14.            
  15. //      System.out.println("getHref() "+getHref());   
  16.            
  17.         if(getHrefCache().containsKey(getHref())){   
  18.             hrefvalue = getHrefCache().get(getHref());   
  19.         }else{   
  20.             hrefvalue = getHref();   
  21.             if(isTohtml()){   
  22.                 hrefvalue=getToHtml().getHtmlHref(hrefvalue);   
  23.                 hrefvalue = addRoot(hrefvalue);   
  24.                 getHrefCache().put(getHref(), hrefvalue);   
  25.                 try {   
  26.                     hrefvalue = getToHtml().exportToHtmlFile(getHref());   
  27.                 } catch (Exception e) {   
  28.                     // TODO Auto-generated catch block   
  29.                     e.printStackTrace();   
  30.                 }   
  31.                    
  32.                 hrefvalue = addRoot(hrefvalue);   
  33.                 getHrefCache().put(getHref(), hrefvalue);   
  34.             }   
  35.         }   
  36.            
  37.         String href ="<a href="""+hrefvalue+""" ";   
  38.         if(getTarget() != null){   
  39.             href = href + "target = """+getTarget()+""" ";   
  40.         }   
  41.         if(getClassname() != null){   
  42.             href = href + "class="""+getClassname()+"""";   
  43.         }   
  44.         href = href + ">";   
  45.         printToPage(href);   
  46.         return  (BodyTagSupport.EVAL_BODY_TAG);   
  47.     }   
  48.   
  49.   
  50. }  
public abstract class BaseHrefTag extends BodyTagSupport {
	
	private String href;//
	private String tohtml;//是否需要处理,预览时为false

	private String classname;//css class name
	private String target;//target
	private String root;//生成html链接时是否加上host
	

	public int doStartTag() throws JspException {
		// TODO Auto-generated method stub
		String hrefvalue = null;
		
//		System.out.println("getHref() "+getHref());
		
		if(getHrefCache().containsKey(getHref())){
			hrefvalue = getHrefCache().get(getHref());
		}else{
			hrefvalue = getHref();
			if(isTohtml()){
				hrefvalue=getToHtml().getHtmlHref(hrefvalue);
				hrefvalue = addRoot(hrefvalue);
				getHrefCache().put(getHref(), hrefvalue);
				try {
					hrefvalue = getToHtml().exportToHtmlFile(getHref());
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
				hrefvalue = addRoot(hrefvalue);
				getHrefCache().put(getHref(), hrefvalue);
			}
		}
		
		String href ="<a href="""+hrefvalue+""" ";
		if(getTarget() != null){
			href = href + "target = """+getTarget()+""" ";
		}
		if(getClassname() != null){
			href = href + "class="""+getClassname()+"""";
		}
		href = href + ">";
		printToPage(href);
		return  (BodyTagSupport.EVAL_BODY_TAG);
	}


}

 

 

 

 

AbstractToHtml的部分代码如下

Java代码
  1. public abstract class AbstractToHtml {   
  2.        
  3.   
  4.                //有子类实现,构造生成的html文件的名称和路径   
  5.     protected abstract String[] createDirAndFile(String href);   
  6.        
  7.        
  8.     public String exportToHtmlFile(String href)throws Exception{   
  9.                                //发起get方式请求   
  10.         URL mu = new URL(ClientParam.root+appendToHref(href));   
  11.         URLConnection conn = mu.openConnection();   
  12.         conn.connect();   
  13.            
  14.            
  15.         String[] dirfile  = createDirAndFile(href);   
  16.            
  17.         writeToFile(ClientParam.basicdir+dirfile[0],dirfile[1],conn);   
  18.            
  19.         return dirfile[0]+dirfile[1];   
  20.   
  21.     }   
  22.        
  23.   
  24.        
  25.                 //读取服务器响应的内容输出到html文件   
  26.     private void writeToFile(String dirname,String filename,URLConnection conn)throws Exception{   
  27.         deleteOldFile(dirname,filename);   
  28.         PrintStream ps=new PrintStream(dirname+filename,ClientParam.charset);   
  29.         BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(),ClientParam.charset));   
  30.         String s;   
  31.         while((s=br.readLine())!=null){   
  32.             ps.println(s);   
  33.         }   
  34.         br.close();   
  35.         ps.close();   
  36.     }   
  37.   
  38. }   
  39.       
public abstract class AbstractToHtml {
	

               //有子类实现,构造生成的html文件的名称和路径
	protected abstract String[] createDirAndFile(String href);
	
	
	public String exportToHtmlFile(String href)throws Exception{
                               //发起get方式请求
		URL mu = new URL(ClientParam.root+appendToHref(href));
		URLConnection conn = mu.openConnection();
		conn.connect();
		
		
		String[] dirfile  = createDirAndFile(href);
		
		writeToFile(ClientParam.basicdir+dirfile[0],dirfile[1],conn);
		
		return dirfile[0]+dirfile[1];

	}
	

	
                //读取服务器响应的内容输出到html文件
	private void writeToFile(String dirname,String filename,URLConnection conn)throws Exception{
		deleteOldFile(dirname,filename);
		PrintStream ps=new PrintStream(dirname+filename,ClientParam.charset);
		BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(),ClientParam.charset));
		String s;
		while((s=br.readLine())!=null){
			ps.println(s);
		}
		br.close();
		ps.close();
	}

}
	

 

 

 

 

  页面的<iframe src="">src属性又是也需要处理,采用同样的方法,定义SrcTag。

  在开发的时候,非常喜欢用jstl和自己定义的标签,其实人家的模板技术也大致如此。

文章转载自http://summeryhrb.javaeye.com/admin/blogs/415054

posted @ 2009-06-25 16:27  javaei  阅读(1669)  评论(8编辑  收藏  举报