程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 基於 J2EE 體系實現多層結構 Blog 平台(3)

基於 J2EE 體系實現多層結構 Blog 平台(3)

編輯:關於JAVA

十二、生成縮略圖

當用戶上傳了圖片後,必須生成縮略圖以便用戶能快速浏覽。我們不需借助第三方軟件,JDK標准庫就包含了圖像處理的API。我們把一張圖片按比例縮放到120X120大小,以下是關鍵代碼:

public static void createPrevIEwImage(String srcFile, String destFile) {

try {

File fi = new File(srcFile); // src

File fo = new File(destFile); // dest

BufferedImage bis = ImageIO.read(fi);

int w = bis.getWidth();

int h = bis.getHeight();

double scale = (double)w/h;

int nw = IMAGE_SIZE; // final int IMAGE_SIZE = 120;

int nh = (nw * h) / w;

if( nh>IMAGE_SIZE ) {

nh = IMAGE_SIZE;

nw = (nh * w) / h;

}

double sx = (double)nw / w;

double sy = (double)nh / h;

transform.setToScale(sx,sy);

AffineTransformOp ato = new AffineTransformOp(transform, null);

BufferedImage bid = new BufferedImage(nw, nh, BufferedImage.TYPE_3BYTE_BGR);

ato.filter(bis,bid);

ImageIO.write(bid, "jpeg", fo);

} catch(Exception e) {

e.printStackTrace();

throw new RuntimeException("Failed in create prevIEw image. Error: " + e.getMessage());

}

}

十三、實現RSS

RSS是一個標准的XML文件,Rss閱讀器可以讀取這個XML文件獲得文章的信息,使用戶可以通過Rss閱讀器而非浏覽器閱讀Blog,我們只要動態生成這個XML文件便可以了。RSSLibJ是一個專門讀取和生成RSS的小巧實用的Java庫,大小僅25k,可以從http://sourceforge.Net/projects/rsslibj/下載rsslibj-1_0RC2.jar和它需要的EXMLjar兩個文件,然後復制到web/WEB-INF/lib/下。

使用RSSLibJ異常簡單,我們先設置好HttpServletResponse的Header,然後通過RSSLibJ輸出XML即可:

Channel channel = new Channel();

channel.setDescription(account.getDescription());

baseUrl = baseUrl.substring(0, n);

channel.setLink("http://server-name/home.c?accountId=" + accountId);

channel.setTitle(account.getTitle());

List articles = facade.getArticles(accountId, account.getMaxPerPage(), 1);

Iterator it = articles.iterator();

while(it.hasNext()) {

Article article = (Article)it.next();

channel.addItem("http://server-name/article.c?articleId=" + article.getArticleId(),

article.getSummary(), article.getTitle()

);

}

// 輸出XML:

response.setContentType("text/XML");

PrintWriter pw = response.getWriter();

pw.print(channel.getFeed("rss"));

pw.close();

十四、實現全文搜索

全文搜索能大大方便用戶快速找到他們希望的文章,為blog增加一個全文搜索功能是非常必要的。然而,全文搜索不等於SQL的LIKE語句,因為關系數據庫的設計並不是為全文搜索設計的,數據庫索引對全文搜索無效,在一個幾百萬條記錄中檢索LIKE '%A%'可能會耗時幾分鐘,這是不可接受的。幸運的是,我們能使用免費並且開源的純Java實現的Lucene全文搜索引擎,Lucene可以非常容易地集成到我們的blog中。

Lucene不提供直接對文件,數據庫的索引,只提供一個高性能的引擎,但接口卻出人意料地簡單。我們只需要關心以下幾個簡單的接口:

Document:代表Lucene數據庫的一條記錄,也代表搜索的一條結果。

Field:一個Document包含一個或多個FIEld,類似關系數據庫的字段。

IndexWriter:用於創建新的索引,也就是向數據庫添加新的可搜索的大段字符串。

Analyzer:將字符串拆分成單詞(Token),不同的文本對應不同的Analyzer,如HtmlAnalyzer,PDFAnalyzer。

Query:封裝一個查詢,用於解析用戶輸入。例如,將“bea blog”解析為“同時包含bea和blog的文章”。

Searcher:搜索一個Query,結果將以Hits返回。

Hits:封裝一個搜索結果,包含Document集合,能非常容易地輸出結果。

下一步,我們需要為Article表的content字段建立全文索引。首先為Lucene新建一個數據庫,請注意這個數據庫是Lucene專用的,我們不能也不必知道它的內部結構。Lucene的每個數據庫對應一個目錄,只需要指定目錄即可:

String indexDir = "C:/search/blog";

IndexWriter indexWriter = new IndexWriter(indexDir, new StandardAnalyzer(), true);

indexWriter.close();

然後添加文章,讓Lucene對其索引:

String title = "文章標題"

// 從數據庫讀取

String content = "文章內容"

// 從數據庫讀取

// 打開索引:

IndexWriter indexWriter = new IndexWriter(indexDir, new StandardAnalyzer(), false);

// 添加一個新記錄:

Document doc = new Document();

doc.add(FIEld.KeyWord("title", title));

doc.add(FIEld.Text("content", content));

// 建立索引:

indexWriter.addDocument(doc);

// 關閉:

indexWriter.close();

要搜索文章非常簡單,然後添加文章,讓對其索引:

String title = "文章標題" // 從數據庫讀取

String content = "文章內容" // 從數據庫讀取

// 打開索引:

IndexWriter indexWriter = new IndexWriter(indexDir, new StandardAnalyzer(), false);

// 添加一個新記錄:

Document doc = new Document();

doc.add(FIEld.KeyWord("title", title));

doc.add(FIEld.Text("content", content));

// 建立索引:

indexWriter.addDocument(doc);

// 關閉:

indexWriter.close();

要搜索文章:

Searcher searcher = new IndexSearcher(dir);

Query query = QueryParser.parse(keyWord, "content", new StandardAnalyzer());

Hits hits = searcher.search(query);

if(hits != null){

for(int i = 0;i < hits.length(); i++){

Document doc = hits.doc(i);

System.out.println("found in " + doc.get("title"));

System.out.println(doc.get("content"));

}

}

searcher.close();

我們設計一個LuceneSearcher類封裝全文搜索功能,由於必須鎖定數據庫所在目錄,我們把數據庫設定在/WEB-INF/search/下,確保用戶不能訪問,並且在配置文件中初始化目錄:

  /WEB-INF/search/

十五、發送Email

Blog用戶可以讓系統將來訪用戶的留言發送到注冊的Email地址,為了避免使用SMTP發信服務器,我們自己手動編寫一個SendMail組件,直接通過SMTP協議將Email發送到用戶信箱。

SendMail組件只需配置好DNS服務器的IP地址,即可向指定的Email信箱發送郵件。並且,SendMail使用緩沖隊列和多線程在後台發送Email,不會中斷正常的Web服務。具體代碼請看SendMail.Java。

十六、測試

服務器配置為:P4 1.4G,512M DDR,100M Ethernet,Windows XP Professional SP2。

測試服務器分別為WebLogic Server 8.1,Tomcat 4.1/5.0,Resin 2.1.1。

測試數據庫為MS SQL Server 2000 SP3。

十七、中文支持

測試發現,中文不能在頁面中正常顯示,為了支持中文,首先在web.XML加入Filter,用於將輸入編碼設置為gb2312:

encodingFilter

org.crystalblog.web.filter.EncodingFilter

encoding

gb2312

encodingFilter

/*

然後用文本工具搜索所有的.htm,.Html,.propertIEs文件,將“iso-8859-1”替換為“gb2312”,現在頁面中文已經能正常顯示,但是Lucene仍不能正常解析中文,原因是標准的StandardA?nalyzer只能解析英文,可以從網上下載一個支持中文的Analyzer。

十八、總結

Spring的確是一個優秀的J2EE(J2EE培訓 )框架,通過Spring強大的集成和配置能力,我們能輕松設計出靈活的多層J2EE應用而無需復雜的EJB組件支持。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved