分享
 
 
 

基于 J2EE 体系实现多层结构 Blog 平台(3)

王朝java/jsp·作者佚名  2008-05-31
窄屏简体版  字體: |||超大  

十二、生成缩略图

当用户上传了图片后,必须生成缩略图以便用户能快速浏览。我们不需借助第三方软件,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( nhIMAGE_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/下,确保用户不能访问,并且在配置文件中初始化目录:

<bean id="luceneSearcher" class="org.crystalblog.search.LuceneSearcher"

<property name="Directory"

<value/WEB-INF/search/</value

</property

</bean

十五、发送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:

<filter

<filter-nameencodingFilter</filter-name

<filter-classorg.crystalblog.web.filter.EncodingFilter</filter-class

<init-param

<param-nameencoding</param-name

<param-valuegb2312</param-value

</init-param

</filter

<filter-mapping

<filter-nameencodingFilter</filter-name

<url-pattern/*</url-pattern

</filter-mapping

然后用文本工具搜索所有的.htm,.html,.properties文件,将“iso-8859-1”替换为“gb2312”,现在页面中文已经能正常显示,但是Lucene仍不能正常解析中文,原因是标准的StandardA?nalyzer只能解析英文,可以从网上下载一个支持中文的Analyzer。

十八、总结

Spring的确是一个优秀的J2EE框架,通过Spring强大的集成和配置能力,我们能轻松设计出灵活的多层J2EE应用而无需复杂的EJB组件支持。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有