﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-hoojo-随笔分类-JavaEE</title><link>http://www.blogjava.net/hoojo/category/49172.html</link><description>学习在于积累：滴水可以石穿！学而不思则罔，思而不学则殆！ </description><language>zh-cn</language><lastBuildDate>Fri, 30 Aug 2013 20:55:40 GMT</lastBuildDate><pubDate>Fri, 30 Aug 2013 20:55:40 GMT</pubDate><ttl>60</ttl><item><title>在Flex （Flash）中嵌入HTML 代码或页面&amp;mdash;Flex IFrame</title><link>http://www.blogjava.net/hoojo/archive/2013/08/15/402864.html</link><dc:creator>hoojo</dc:creator><author>hoojo</author><pubDate>Thu, 15 Aug 2013 07:58:00 GMT</pubDate><guid>http://www.blogjava.net/hoojo/archive/2013/08/15/402864.html</guid><wfw:comment>http://www.blogjava.net/hoojo/comments/402864.html</wfw:comment><comments>http://www.blogjava.net/hoojo/archive/2013/08/15/402864.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/hoojo/comments/commentRss/402864.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hoojo/services/trackbacks/402864.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 在flex组件中嵌入html代码，可以利用flex iframe。这个在很多时候会用到的，有时候flex必须得这样做，如果你不这样做还真不行…… flex而且可以和html进行JavaScript交互操作，flex调用到html中的JavaScript方法以及获取调用后的返回值。 &nbsp;  1、flex iframe下载地址：https://github.com/downloads/flex...&nbsp;&nbsp;<a href='http://www.blogjava.net/hoojo/archive/2013/08/15/402864.html'>阅读全文</a><img src ="http://www.blogjava.net/hoojo/aggbug/402864.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hoojo/" target="_blank">hoojo</a> 2013-08-15 15:58 <a href="http://www.blogjava.net/hoojo/archive/2013/08/15/402864.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ActiveMQ 即时通讯服务 浅析</title><link>http://www.blogjava.net/hoojo/archive/2013/06/27/400980.html</link><dc:creator>hoojo</dc:creator><author>hoojo</author><pubDate>Thu, 27 Jun 2013 01:09:00 GMT</pubDate><guid>http://www.blogjava.net/hoojo/archive/2013/06/27/400980.html</guid><wfw:comment>http://www.blogjava.net/hoojo/comments/400980.html</wfw:comment><comments>http://www.blogjava.net/hoojo/archive/2013/06/27/400980.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/hoojo/comments/commentRss/400980.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hoojo/services/trackbacks/400980.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp; 一、 概述与介绍  ActiveMQ 是Apache出品，最流行的、功能强大的即时通讯和集成模式的开源服务器。ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规范的 JMS Provider实现。提供客户端支持跨语言和协议，带有易于在充分支持JMS 1.1和1.4使用J2EE企业集成模式和许多先进的功能。  二、 特性  1、 多种语言和协议编写客户端。语言： Java...&nbsp;&nbsp;<a href='http://www.blogjava.net/hoojo/archive/2013/06/27/400980.html'>阅读全文</a><img src ="http://www.blogjava.net/hoojo/aggbug/400980.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hoojo/" target="_blank">hoojo</a> 2013-06-27 09:09 <a href="http://www.blogjava.net/hoojo/archive/2013/06/27/400980.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ant 入门使用指南</title><link>http://www.blogjava.net/hoojo/archive/2013/06/14/400550.html</link><dc:creator>hoojo</dc:creator><author>hoojo</author><pubDate>Fri, 14 Jun 2013 05:07:00 GMT</pubDate><guid>http://www.blogjava.net/hoojo/archive/2013/06/14/400550.html</guid><wfw:comment>http://www.blogjava.net/hoojo/comments/400550.html</wfw:comment><comments>http://www.blogjava.net/hoojo/archive/2013/06/14/400550.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/hoojo/comments/commentRss/400550.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hoojo/services/trackbacks/400550.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp; 一、概述  ant 是一个将软件编译、测试、部署等步骤联系在一起加以自动化的一个工具，大多用于Java环境中的软件开发。在实际软件开发中，有很多地方可以用到ant。 &nbsp;  开发环境： System：Windows JDK：1.6+ IDE：eclipse ant：1.9.1 &nbsp; Email：hoojo_@126.com Blog：http://blog.csdn....&nbsp;&nbsp;<a href='http://www.blogjava.net/hoojo/archive/2013/06/14/400550.html'>阅读全文</a><img src ="http://www.blogjava.net/hoojo/aggbug/400550.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hoojo/" target="_blank">hoojo</a> 2013-06-14 13:07 <a href="http://www.blogjava.net/hoojo/archive/2013/06/14/400550.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>基于开源 Openfire 聊天服务器 - 开发聊天记录插件</title><link>http://www.blogjava.net/hoojo/archive/2013/03/29/397133.html</link><dc:creator>hoojo</dc:creator><author>hoojo</author><pubDate>Fri, 29 Mar 2013 03:03:00 GMT</pubDate><guid>http://www.blogjava.net/hoojo/archive/2013/03/29/397133.html</guid><wfw:comment>http://www.blogjava.net/hoojo/comments/397133.html</wfw:comment><comments>http://www.blogjava.net/hoojo/archive/2013/03/29/397133.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hoojo/comments/commentRss/397133.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hoojo/services/trackbacks/397133.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 上一篇文章介绍到怎么在自己的Java环境中搭建openfire插件开发的环境，同时介绍到怎样一步步简单的开发openfire插件。一步步很详细的介绍到简单插件开发，带Servlet的插件的开发、带JSP页面插件的开发，以及怎么样将开发好的插件打包、部署到openfire服务器。  &nbsp; 如果你没有看上一篇文章的话，请你还是看看。http://www.cnblogs.com/hoojo/ar...&nbsp;&nbsp;<a href='http://www.blogjava.net/hoojo/archive/2013/03/29/397133.html'>阅读全文</a><img src ="http://www.blogjava.net/hoojo/aggbug/397133.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hoojo/" target="_blank">hoojo</a> 2013-03-29 11:03 <a href="http://www.blogjava.net/hoojo/archive/2013/03/29/397133.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>谈谈个人关于程序开发中，&amp;ldquo;零配置&amp;rdquo;和&amp;ldquo;有配置&amp;rdquo;的看法</title><link>http://www.blogjava.net/hoojo/archive/2012/10/31/390515.html</link><dc:creator>hoojo</dc:creator><author>hoojo</author><pubDate>Wed, 31 Oct 2012 04:44:00 GMT</pubDate><guid>http://www.blogjava.net/hoojo/archive/2012/10/31/390515.html</guid><wfw:comment>http://www.blogjava.net/hoojo/comments/390515.html</wfw:comment><comments>http://www.blogjava.net/hoojo/archive/2012/10/31/390515.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/hoojo/comments/commentRss/390515.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hoojo/services/trackbacks/390515.html</trackback:ping><description><![CDATA[<blockquote> <p>本人是做Java开发的，在程序开发中会经常使用到OpenSource开源框架，这些框架大多都灵活、简单、易用、方便。而且开源框架一般会提供一些基本的配置，如我们常用的框架就有Hibernate要配置对象实体到数据库的映射；Spring要配置bean的管理及其对象、属性的注入；Struts要配置Action对象和返回的资源路径；MyBatis要配置CRUD（增删改查）的相关SQL语句。这些配置你不能省略，必须得有，没有程序也不会自动添加。我们也是极可能的简化这些配置，不管怎么样简化但这些配置是不能省略，虽然这些框架给我们开发程序都提供了很大方面上的便利。</p></blockquote> <blockquote> <p><strong><font color="#ff0000">但有时候你是否有纠结这么样的一个问题：到底是用XML配置？还是用Annotation注解配置？或是用XML和Annotation混合配置？</font></strong> </p></blockquote> <p>&nbsp; <blockquote> <p><strong><u>首先看看两种配置的优缺点比较</u></strong></p></blockquote> <blockquote> <p><em><strong>XML它是无可代替的超文本标记语言，可读性、传输性好，它还具有一下优点：<br></strong></em>1、可读性、传输性好：XML可扩展标记语言，最大的优势在于开发者能够为软件量身定制适用的标记，使代码可读性大大提升。<br>2、灵活性、易用性、扩展性、移植性好：利用XML配置能使软件更具扩展性。如Spring将class间的依赖配置在XML中，最大限度地提升应用的可扩展性。同样，如果是基于接口注入方式，可以随便切换接口实现类进行注入即可。<br>3、验证机制：具有成熟的验证机制确保程序正确性。利用Schema或DTD可以对XML的正确性进行验证，避免了非法的配置导致应用程序出错。<br>4、修改配置而无需变动现有程序、无需重新编译。 </p></blockquote> <blockquote> <p><strike><strong>虽然XML有如此多的好处，但它也不是万能的，XML也有自身的缺点：<br></strong></strike>1、开发友好性支持：需要解析工具或类库的支持。如果你的XML配置需要用到XML的提示或是解析编译，需要用到Schema或DTD进行验证。<br>2、性能影响：解析XML势必会影响应用程序性能，占用系统资源。至少你会用到一些解析XML的技术去解析节点元素内容。<br>3、维护性高：配置文件过多导致管理变得困难。<br>4、编译期无法对其配置项的正确性进行验证，或要查错只能在运行期。如Spring Bean配置了一个错误的类路径class。<br>5、IDE 无法验证配置项的正确性无能为力。如Spring注入一个错误的对象或属性。<br>6、查错变得困难。往往配置的一个手误导致莫名其妙的错误。<br>7、开发人员不得不同时维护代码和配置文件，开发效率变得低下。<br>8、配置项与代码间存在潜规则，改变了任何一方都有可能影响另外一方。 </p></blockquote> <p>&nbsp;</p> <blockquote> <p><strong><em>让我们来看看Annotation的优点<br></em></strong>1、保存在class文件中，降低维护成本。<br>2、无需工具支持，无需解析。<br>3、编译期即可验证正确性，查错变得容易，虽然有部分错误需要在运行期间才能看到。<br>4、配置简单、简约，提升开发效率。 </p></blockquote> <blockquote> <p><strike><strong>同样Annotation也不是万能的，它也有很多缺点<br></strong></strike>1、若要对配置项进行修改，不得不修改Java文件，重新编译打包应用。<br>2、配置项编码在Java文件中，可扩展性差、移植性性低。 </p></blockquote> <p>&nbsp;</p> <blockquote> <p><strong>那到底用什么样的配置呢，在这里我谈谈我个人的看法：<br></strong>1、在开发期间我们用Annotation注解，这样在一定程度上不仅可以省去对XML配置文件的维护，而且大大的提高了开发效率，缩短了开发周期。<br>2、开发后期，项目功能完成，我们可以将Annotation配置转换为XML配置，禁用Annotation即可。这样做的理由是如果项目上线，我们需要修改相关代码的配置，直接改XML、properties配置文件即可。这样就不需要开发人员找到相应的代码修改源代码、重新编译打包发布。而xml的配置是可以直接修改的，不需要重新编译，只需重启下你的服务器即可。 </p> <p>如果这样是不是即利用到框架给我们提供的Annotation注解，也利用到了XML配置。充分的发挥了开源框架给我们提供的技术应用。  <p><u>3、混合模式，Annotation和XML相互运用。需要动态配置、后期经常性修改的就用XML配置，如果是不怎么修改的就用Annotation。或许这种混合模式更适合我们，你觉得呢？O(∩_∩)O~</u></p></blockquote><img src ="http://www.blogjava.net/hoojo/aggbug/390515.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hoojo/" target="_blank">hoojo</a> 2012-10-31 12:44 <a href="http://www.blogjava.net/hoojo/archive/2012/10/31/390515.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Lucene 基础理论</title><link>http://www.blogjava.net/hoojo/archive/2012/09/06/387140.html</link><dc:creator>hoojo</dc:creator><author>hoojo</author><pubDate>Thu, 06 Sep 2012 01:34:00 GMT</pubDate><guid>http://www.blogjava.net/hoojo/archive/2012/09/06/387140.html</guid><wfw:comment>http://www.blogjava.net/hoojo/comments/387140.html</wfw:comment><comments>http://www.blogjava.net/hoojo/archive/2012/09/06/387140.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hoojo/comments/commentRss/387140.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hoojo/services/trackbacks/387140.html</trackback:ping><description><![CDATA[<h3>1. 全文检索系统与Lucene简介</h3> <h4>1.1 什么是全文检索与全文检索系统</h4> <blockquote> <p>全文检索是指计算机索引程序通过扫描文章中的每一个词，对每一个词建立一个索引，指明该词在文章中出现的次数和位置，当用户查询时，检索程序就根据事先建立的索引进行查找，并将查找的结果反馈给用户的检索方式。这个过程类似于通过字典中的检索字表查字的过程。  <p>全文检索的方法主要分为按字检索和按词检索两种。按字检索是指对于文章中的每一个字都建立索引，检索时将词分解为字的组合。对于各种不同的语言而言，字有不同的含义，比如英文中字与词实际上是合一的，而中文中字与词有很大分别。按词检索指对文章中的词，即语义单位建立索引，检索时按词检索，并且可以处理同义项等。英文等西方文字由于按照空白切分词，因此实现上与按字处理类似，添加同义处理也很容易。中文等东方文字则需要切分字词，以达到按词索引的目的，关于这方面的问题，是当前全文检索技术尤其是中文全文检索技术中的难点，在此不做详述。  <p>全文检索系统是按照全文检索理论建立起来的用于提供全文检索服务的软件系统。一般来说，全文检索需要具备建立索引和提供查询的基本功能，此外现代的全文检索系统还需要具有方便的用户接口、面向WWW[1]的开发接口、二次应用开发接口等等。功能上，全文检索系统核心具有建立索引、处理查询返回结果集、增加索引、优化索引结构等等功能，外围则由各种不同应用具有的功能组成。结构上，全文检索系统核心具有索引引擎、查询引擎、文本分析引擎、对外接口等等，加上各种外围应用系统等等共同构成了全文检索系统。图1.1展示了上述全文检索系统的结构与功能。  <p><b><a href="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image002_2.gif"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image002" border="0" alt="clip_image002" src="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image002_thumb.gif" width="552" height="385"></a></b>  <p>在上图中，我们看到：全文检索系统中最为关键的部分是全文检索引擎，各种应用程序都需要建立在这个引擎之上。一个全文检索应用的优异程度，根本上由全文检索引擎来决定。因此提升全文检索引擎的效率即是我们提升全文检索应用的根本。另一个方面，一个优异的全文检索引擎，在做到效率优化的同时，还需要具有开放的体系结构，以方便程序员对整个系统进行优化改造，或者是添加原有系统没有的功能。比如在当今多语言处理的环境下，有时需要给全文检索系统添加处理某种语言或者文本格式的功能，比如在英文系统中添加中文处理功能，在纯文本系统中添加XML或者HTML格式的文本处理功能，系统的开放性和扩充性就十分的重要。 </p></blockquote> <h4>1.2 什么是Lucene</h4> <blockquote> <p>Lucene是apache软件基金会jakarta项目组的一个子项目，是一个开放源代码的全文检索引擎工具包，即它不是一个完整的全文检索引擎，而是一个全文检索引擎的架构，提供了完整的查询引擎和索引引擎，部分文本分析引擎（英文与德文两种西方语言）。Lucene的目的是为软件开发人员提供一个简单易用的工具包，以方便的在目标系统中实现全文检索的功能，或者是以此为基础建立起完整的全文检索引擎。  <p>Lucene的原作者是Doug Cutting，他是一位资深全文索引/检索专家，曾经是V-Twin搜索引擎的主要开发者，后在Excite担任高级系统架构设计师，目前从事于一些Internet底层架构的研究。早先发布在作者自己的http://www.lucene.com/，后来发布在SourceForge，2001年年底成为apache软件基金会jakarta的一个子项目：<a href="http://jakarta.apache.org/lucene/">http://jakarta.apache.org/lucene/</a>。 </p></blockquote> <h4>1.3 Lucene的应用、特点及优势</h4> <blockquote> <p>作为一个开放源代码项目，Lucene从问世之后，引发了开放源代码社群的巨大反响，程序员们不仅使用它构建具体的全文检索应用，而且将之集成到各种系统软件中去，以及构建Web应用，甚至某些商业软件也采用了Lucene作为其内部全文检索子系统的核心。apache软件基金会的网站使用了Lucene作为全文检索的引擎，IBM的开源软件eclipse的2.1版本中也采用了Lucene作为帮助子系统的全文索引引擎，相应的IBM的商业软件Web Sphere中也采用了Lucene。Lucene以其开放源代码的特性、优异的索引结构、良好的系统架构获得了越来越多的应用。  <p>Lucene作为一个全文检索引擎，其具有如下突出的优点：  <p>（1）索引文件格式独立于应用平台。Lucene定义了一套以8位字节为基础的索引文件格式，使得兼容系统或者不同平台的应用能够共享建立的索引文件。  <p>（2）在传统全文检索引擎的倒排索引的基础上，实现了分块索引，能够针对新的文件建立小文件索引，提升索引速度。然后通过与原有索引的合并，达到优化的目的。  <p>（3）优秀的面向对象的系统架构，使得对于Lucene扩展的学习难度降低，方便扩充新功能。  <p>（4）设计了独立于语言和文件格式的文本分析接口，索引器通过接受Token流完成索引文件的创立，用户扩展新的语言和文件格式，只需要实现文本分析的接口。  <p>（5）已经默认实现了一套强大的查询引擎，用户无需自己编写代码即使系统可获得强大的查询能力，Lucene的查询实现中默认实现了布尔操作、模糊查询（Fuzzy Search）、分组查询等等。  <p>面对已经存在的商业全文检索引擎，Lucene也具有相当的优势：  <p>首先，它的开发源代码发行方式（遵守Apache Software License），在此基础上程序员不仅仅可以充分的利用Lucene所提供的强大功能，而且可以深入细致的学习到全文检索引擎制作技术和面相对象编程的实践，进而在此基础上根据应用的实际情况编写出更好的更适合当前应用的全文检索引擎。在这一点上，商业软件的灵活性远远不及Lucene。其次，Lucene秉承了开放源代码一贯的架构优良的优势，设计了一个合理而极具扩充能力的面向对象架构，程序员可以在Lucene的基础上扩充各种功能，比如扩充中文处理能力，从文本扩充到HTML、PDF等等文本格式的处理，编写这些扩展的功能不仅仅不复杂，而且由于Lucene恰当合理的对系统设备做了程序上的抽象，扩展的功能也能轻易的达到跨平台的能力。最后，转移到apache软件基金会后，借助于apache软件基金会的网络平台，程序员可以方便的和开发者、其它程序员交流，促成资源的共享，甚至直接获得已经编写完备的扩充功能。最后，虽然Lucene使用Java语言写成，但是开放源代码社区的程序员正在不懈的将之使用各种传统语言实现（例如.net framework），在遵守Lucene索引文件格式的基础上，使得Lucene能够运行在各种各样的平台上，系统管理员可以根据当前的平台适合的语言来合理的选。 </p></blockquote> <h4>&nbsp;</h4> <h4>2. Lucene系统结构分析</h4> <h4>2.1 系统结构组织</h4> <blockquote> <p>Lucene作为一个优秀的全文检索引擎，其系统结构具有强烈的面向对象特征。首先是定义了一个与平台无关的索引文件格式，其次通过抽象将系统的核心组成部分设计为抽象类，具体的平台实现部分设计为抽象类的实现，此外与具体平台相关的部分比如文件存储也封装为类，经过层层的面向对象式的处理，最终达成了一个低耦合高效率，容易二次开发的检索引擎系统。  <p>以下将讨论Lucene系统的结构组织，并给出系统结构与源码组织图：  <p><b><a href="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image004_2.gif"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image004" border="0" alt="clip_image004" src="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image004_thumb.gif" width="577" height="336"></a></b>  <p>从图中我们清楚的看到，Lucene的系统由基础结构封装、索引核心、对外接口三大部分组成。其中直接操作索引文件的索引核心又是系统的重点。Lucene的将所有源码分为了7个模块（在java语言中以包即package来表示），各个模块所属的系统部分也如上图所示。需要说明的是org.apache.lucene.queryPaser是做为org.apache.lucene.search的语法解析器存在，不被系统之外实际调用，因此这里没有当作对外接口看待，而是将之独立出来。  <p>从面象对象的观点来考察，Lucene应用了最基本的一条程序设计准则：引入额外的抽象层以降低耦合性。首先，引入对索引文件的操作org.apache.lucene.store的封装，然后将索引部分的实现建立在（org.apache.lucene.index）其之上，完成对索引核心的抽象。在索引核心的基础上开始设计对外的接口org.apache.lucene.search与org.apache.lucene.analysis。在每一个局部细节上，比如某些常用的数据结构与算法上，Lucene也充分的应用了这一条准则。在高度的面向对象理论的支撑下，使得Lucene的实现容易理解，易于扩展。  <p>Lucene在系统结构上的另一个特点表现为其引入了传统的客户端服务器结构以外的的应用结构。Lucene可以作为一个运行库被包含进入应用本身中去，而不是做为一个单独的索引服务器存在。这自然和Lucene开放源代码的特征分不开，但是也体现了Lucene在编写上的本来意图：提供一个全文索引引擎的架构，而不是实现。 </p></blockquote> <h4>2.2 数据流分析</h4> <blockquote> <p>了解数据流分析的重要性：  <p>理解Lucene系统结构的另一个方式是去探讨其中数据流的走向，并以此摸清楚Lucene系统内部的调用时序。在此基础上，我们能够更加深入的理解Lucene的系统结构组织，以方便以后在Lucene系统上的开发工作。这部分的分析，是深入Lucene系统的钥匙，也是进行重写的基础。  <p>Lucene系统中的主要的数据流以及它们之间的关系图：  <p><a href="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image006_2.jpg"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image006" border="0" alt="clip_image006" src="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image006_thumb.jpg" width="557" height="413"></a>  <p>图2.2很好的表明了Lucene在内部的数据流组织情况，并且沿着数据流的方向我们也可以对与Lucene内部的执行时序有一个清楚的了解。现在将图中的涉及到的流的类型与各个逻辑对应系统的相关部分的关系说明一下。  <p>图中共存在4种数据流，分别是文本流、token流、字节流与查询语句对象流。文本流表示了对于索引目标和交互控制的抽象，即用文本流表示了将要索引的文件，用文本流向用户输出信息；在实际的实现中，Lucene中的文本流采用了UCS-2作为编码，以达到适应多种语言文字的处理的目的。Token流是Lucene内部所使用的概念，是对传统文字中的词的概念的抽象，也是Lucene在建立索引时直接处理的最小单位；简单的讲Token就是一个词和所在域值的组合，后面在叙述文件格式时也将继续涉及到token，这里不详细展开。字节流则是对文件抽象的直接操作的体现，通过固定长度的字节（Lucene定义为8比特位长，后面文件格式将详细叙述）流的处理，将文件操作解脱出来，也做到了与平台文件系统的无关性。查询语句对象流则是仅仅在查询语句解析时用到的概念，它对查询语句抽象，通过类的继承结构反映查询语句的结构，将之传送到查找逻辑来进行查找的操作。  <p>图中的涉及到了多种逻辑，基本上直接对应于系统某一模块，但是也有跨模块调用的问题发生，这是因为Lucene的重用程度非常好，因此很多实现直接调用了以前的工作成果，这在某种程度上其实是加强了模块耦合性，但是也是为了避免系统的过于庞大和不必要的重复设计的一种折衷体现。词法分析逻辑对应于org.apache.lucene.analysis部分。查询语句语法分析逻辑对应于org.apache.lucene.queryParser部分，并且调用了org.apache.lucene.analysis的代码。查询结束之后向评分排序逻辑输出token流，继而由评分排序逻辑处理之后给出文本流的结果，这一部分的实现也包含在了org.apache.lucene.search中。索引构建逻辑对应于org.apache.lucene.index部分。索引查找逻辑则主要是org.apache.lucene.search，但是也大量的使用了org.apache.lucene.index部分的代码和接口定义。存储抽象对应于org.apache.lucene.store。没有提到的模块则是做为系统公共基础设施存在。 </p></blockquote> <h4>2.3 基于Lucene的应用开发</h4> <blockquote> <p>首先，我们需要的是按照目标语言的词法结构来构建相应的词法分析逻辑，实现Lucene在org.apache.lucene.analysis中定义的接口，为Lucene提供目标系统所使用的语言处理能力。Lucene默认的已经实现了英文和德文的简单词法分析逻辑（按照空格分词，并去除常用的语法词，如英语中的is，am，are等等）。在这里，主要需要参考实现的接口在org.apache.lucene.analysis中的Analyzer.java和Tokenizer.java中定义，Lucene提供了很多英文规范的实现样本，也可以做为实现时候的参考资料。其次，需要按照被索引的文件的格式来提供相应的文本分析逻辑，这里是指除开词法分析之外的部分，比如HTML文件，通常需要把其中的内容按照所属于域分门别类加入索引，这就需要从org.apache.lucene.document中定义的类document继承，定义自己的HTMLDocument类，然后就可以将之交给org.apache.lucene.index模块来写入索引文件。完成了这两步之后，Lucene全文检索引擎就基本上完备了。这个过程可以用下图表示：  <p><b><a href="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image008_2.gif"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image008" border="0" alt="clip_image008" src="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image008_thumb.gif" width="629" height="334"></a></b>  <p>下面是使用java语言开发，Lucene系统能够方便的嵌入到整个系统中去，作为一个API集来调用。这个过程十分简单，以下便是一个示例程序，配合注释理解起来很容易。  <p><b><a href="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image009_2.gif"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image009" border="0" alt="clip_image009" src="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image009_thumb.gif" width="664" height="602"></a></b> </p></blockquote> <h4>2.4 Lucene索引文件格式</h4> <blockquote> <p>首先在Lucene的文件格式中，以字节为基础，定义了如下的数据类型：  <p><b>表</b><b> 3.1 Lucene</b><b>文件格式中定义的数据类型</b><b></b>  <table border="0" cellspacing="0" cellpadding="0"> <tbody> <tr> <td valign="top" width="92"> <p><b>数据类型</b></p></td> <td valign="top" width="123"> <p><b>所占字节长度（字节）</b></p></td> <td valign="top" width="353"> <p><b>说明</b></p></td></tr> <tr> <td valign="top" width="92"> <p>Byte</p></td> <td valign="top" width="123"> <p>1</p></td> <td valign="top" width="353"> <p>基本数据类型，其他数据类型以此为基础定义</p></td></tr> <tr> <td valign="top" width="92"> <p>UInt32</p></td> <td valign="top" width="123"> <p>4</p></td> <td valign="top" width="353"> <p>32位无符号整数，高位优先</p></td></tr> <tr> <td valign="top" width="92"> <p>UInt64</p></td> <td valign="top" width="123"> <p>8</p></td> <td valign="top" width="353"> <p>64位无符号整数，高位优先</p></td></tr> <tr> <td valign="top" width="92"> <p>VInt</p></td> <td valign="top" width="123"> <p>不定，最少1字节</p></td> <td valign="top" width="353"> <p>动态长度整数，每字节的最高位表明还剩多少字节，每字节的低七位表明整数的值，高位优先。可以认为值可以为无限大。其示例如下  <table border="0" cellspacing="0" cellpadding="0"> <tbody> <tr> <td valign="top" width="82"> <p>值</p></td> <td valign="top" width="84"> <p>字节1</p></td> <td valign="top" width="84"> <p>字节2</p></td> <td valign="top" width="78"> <p>字节3</p></td></tr> <tr> <td valign="top" width="82"> <p>0</p></td> <td valign="top" width="84"> <p>00000000</p></td> <td valign="top" width="84">&nbsp;</td> <td valign="top" width="78">&nbsp;</td></tr> <tr> <td valign="top" width="82"> <p>1</p></td> <td valign="top" width="84"> <p>00000001</p></td> <td valign="top" width="84">&nbsp;</td> <td valign="top" width="78">&nbsp;</td></tr> <tr> <td valign="top" width="82"> <p>2</p></td> <td valign="top" width="84"> <p>00000010</p></td> <td valign="top" width="84">&nbsp;</td> <td valign="top" width="78">&nbsp;</td></tr> <tr> <td valign="top" width="82"> <p>127</p></td> <td valign="top" width="84"> <p>01111111</p></td> <td valign="top" width="84">&nbsp;</td> <td valign="top" width="78">&nbsp;</td></tr> <tr> <td valign="top" width="82"> <p>128</p></td> <td valign="top" width="84"> <p>10000000</p></td> <td valign="top" width="84"> <p>00000001</p></td> <td valign="top" width="78">&nbsp;</td></tr> <tr> <td valign="top" width="82"> <p>129</p></td> <td valign="top" width="84"> <p>10000001</p></td> <td valign="top" width="84"> <p>00000001</p></td> <td valign="top" width="78">&nbsp;</td></tr> <tr> <td valign="top" width="82"> <p>130</p></td> <td valign="top" width="84"> <p>10000010</p></td> <td valign="top" width="84"> <p>00000001</p></td> <td valign="top" width="78">&nbsp;</td></tr> <tr> <td valign="top" width="82"> <p>16383</p></td> <td valign="top" width="84"> <p>10000000</p></td> <td valign="top" width="84"> <p>10000000</p></td> <td valign="top" width="78"> <p>00000001</p></td></tr> <tr> <td valign="top" width="82"> <p>16384</p></td> <td valign="top" width="84"> <p>10000001</p></td> <td valign="top" width="84"> <p>10000000</p></td> <td valign="top" width="78"> <p>00000001</p></td></tr> <tr> <td valign="top" width="82"> <p>16385</p></td> <td valign="top" width="84"> <p>10000010</p></td> <td valign="top" width="84"> <p>10000000</p></td> <td valign="top" width="78"> <p>00000001</p></td></tr></tbody></table></p></td></tr> <tr> <td valign="top" width="92"> <p>Chars</p></td> <td valign="top" width="123"> <p>不定，最少1字节</p></td> <td valign="top" width="353"> <p>采用UTF-8编码<sup>[20]</sup>的Unicode字符序列</p></td></tr> <tr> <td valign="top" width="92"> <p>String</p></td> <td valign="top" width="123"> <p>不定，最少2字节</p></td> <td valign="top" width="353"> <p>由VInt和Chars组成的字符串类型，VInt表示Chars的长度，Chars则表示了String的值</p></td></tr></tbody></table> <p>以上的数据类型就是Lucene索引文件格式中用到的全部数据类型，由于它们都以字节为基础定义而来，因此保证了是平台无关，这也是Lucene索引文件格式平台无关的主要原因。接下来我们看看Lucene索引文件的概念组成和结构组成。  <p><b><a href="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image010_2.gif"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image010" border="0" alt="clip_image010" src="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image010_thumb.gif" width="664" height="306"></a></b>  <p>以上就是Lucene的索引文件的概念结构。Lucene索引index由若干段(segment)组成，每一段由若干的文档（document）组成，每一个文档由若干的域（field）组成，每一个域由若干的项（term）组成。项是最小的索引概念单位，它直接代表了一个字符串以及其在文件中的位置、出现次数等信息。域是一个关联的元组，由一个域名和一个域值组成，域名是一个字串，域值是一个项，比如将“标题”和实际标题的项组成的域。文档是提取了某个文件中的所有信息之后的结果，这些组成了段，或者称为一个子索引。子索引可以组合为索引，也可以合并为一个新的包含了所有合并项内部元素的子索引。我们可以清楚的看出，Lucene的索引结构在概念上即为传统的倒排索引结构。  <p>从概念上映射到结构中，索引被处理为一个目录（文件夹），其中含有的所有文件即为其内容，这些文件按照所属的段不同分组存放，同组的文件拥有相同的文件名，不同的扩展名。此外还有三个文件，分别用来保存所有的段的记录、保存已删除文件的记录和控制读写的同步，它们分别是segments，deletable和lock文件，都没有扩展名。每个段包含一组文件，它们的文件扩展名不同，但是文件名均为记录在文件segments中段的名字。让我们看如下的结构图3.2：  <p><a href="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image012_2.jpg"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image012" border="0" alt="clip_image012" src="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image012_thumb.jpg" width="593" height="342"></a>  <p>每个段的文件中，主要记录了两大类的信息：域集合与项集合。这两个集合中所含有的文件在图3.2中均有表明。由于索引信息是静态存储的，域集合与项集合中的文件组采用了一种类似的存储办法：一个小型的索引文件，运行时载入内存；一个对应于索引文件的实际信息文件，可以按照索引中指示的偏移量随机访问；索引文件与信息文件在记录的排列顺序上存在隐式的对应关系，即索引文件中按照“索引项1、索引项2…”排列，则信息文件则也按照“信息项1、信息项2…”排列。比如在图3.2所示文件中，segment1.fdx与segment1.fdt之间，segment1.tii与segment1.tis、segment1.prx、segment1.frq之间，都存在这样的组织关系。而域集合与项集合之间则通过域的在域记录文件（比如segment1.fnm）中所记录的域记录号维持对应关系，在图3.2中segment1.fdx与segment1.tii中就是通过这种方式保持联系。这样，域集合和项集合不仅仅联系起来，而且其中的文件之间也相互联系起来。此外，标准化因子文件和被删除文档文件则提供了一些程序内部的辅助设施（标准化因子用在评分排序机制中，被删除文档是一种伪删除手段）。这样，整个段的索引信息就通过这些文档有机的组成。 </p></blockquote><b> <p><br></p></b> <h4>2.5 一些公用的基础类</h4> <blockquote> <p>基础结构封装，或者基础类，由org.apache.lucene.util和org.apache.lucene.document两个包组成，前者定义了一些常量和优化过的常用的数据结构和算法，后者则是对于文档（document）和域（field）概念的一个类定义。以下我们用列表的方式来分析这些封装类，指出其要点；  <p><b></b> <p><b>表</b><b> 3.2 </b><b>基础类包</b><b>org.apache.lucene.util</b>  <p><b></b> <table border="0" cellspacing="0" cellpadding="0"> <tbody> <tr> <td valign="top" width="123"> <p><b>类</b></p></td> <td valign="top" width="445"> <p><b>说明</b></p></td></tr> <tr> <td valign="top" width="123"> <p>Arrays</p></td> <td valign="top" width="445"> <p>一个关于数组的排序方法的静态类，提供了优化的基于快排序的排序方法sort</p></td></tr> <tr> <td valign="top" width="123"> <p>BitVector</p></td> <td valign="top" width="445"> <p>C/C++语言中位域的java实现品，但是加入了序列化能力</p></td></tr> <tr> <td valign="top" width="123"> <p>Constants</p></td> <td valign="top" width="445"> <p>常量静态类，定义了一些常量</p></td></tr> <tr> <td valign="top" width="123"> <p>PriorityQueue</p></td> <td valign="top" width="445"> <p>一个优先队列的抽象类，用于后面实现各种具体的优先队列，提供常数时间内的最小元素访问能力，内部实现机制是哈析表和堆排序算法</p></td></tr></tbody></table> <p><b></b> <p><b>表</b><b> 3.3 </b><b>基础类包</b><b>org.apache.lucene.document</b>  <p><b></b> <table border="0" cellspacing="0" cellpadding="0"> <tbody> <tr> <td valign="top" width="129"> <p><b>类</b></p></td> <td valign="top" width="502"> <p><b>说明</b></p></td></tr> <tr> <td valign="top" width="129"> <p>Document</p></td> <td valign="top" width="502"> <p>是文档概念的一个实现类，每个文档包含了一个域表（fieldList），并提供了一些实用的方法，比如多种添加域的方法、返回域表的迭代器的方法</p></td></tr> <tr> <td valign="top" width="129"> <p>Field</p></td> <td valign="top" width="502"> <p>是域概念的一个实现类，每个域包含了一个域名和一个值，以及一些相关的属性</p></td></tr> <tr> <td valign="top" width="129"> <p>DateField</p></td> <td valign="top" width="502"> <p>提供了一些辅助方法的静态类，这些方法将java中Date和Time数据类型和String相互转化</p></td></tr></tbody></table></p></blockquote> <h4><a name="_Toc43005326">2.6 存储抽象</a></h4> <blockquote> <p>org.apache.lucene.store包：存储抽象是唯一能够直接对索引文件存取的包，因此其主要目的是抽象出和平台文件系统无关的存储抽象，提供诸如目录服务（增、删文件）、输入流和输出流。在分析其实现之前，首先我们看一下UML图；  <p><b><a href="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image013_2.gif"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image013" border="0" alt="clip_image013" src="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image013_thumb.gif" width="495" height="361"></a></b>  <p><b>图</b><b> 3.3 </b><b>存储抽象实现</b><b>UML</b><b>图（一）</b><b></b>  <p><b><a href="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image014_2.gif"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image014" border="0" alt="clip_image014" src="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image014_thumb.gif" width="363" height="329"></a></b>  <p><b>图</b><b> 3.4 </b><b>存储抽象实现</b><b>UML</b><b>图（二）</b>  <p><b><a href="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image015_2.gif"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image015" border="0" alt="clip_image015" src="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image015_thumb.gif" width="347" height="308"></a></b>  <p><b>图</b><b> 3.4 </b><b>存储抽象实现</b><b>UML</b><b>图（三）</b>  <p>图3.2到3.4展示了整个org.apache.lucene.store中主要的继承体系。共有三个抽象类定义：Directory、InputStream和OutputStrem，构成了一个完整的基于抽象文件系统的存取体系结构，在此基础上，实作出了两个实现品：（FSDirectory，FSInputStream，FSOutputStream）和（RAMDirectory，RAMInputStream和RAMOutputStream）。前者是以实际的文件系统做为基础实现的，后者则是建立在内存中的虚拟文件系统。前者主要用来永久的保存索引文件，后者的作用则在于索引操作时是在内存中建立小的索引，然后一次性的输出合并到文件中去，这一点我们在后面的索引逻辑部分能够看到。此外，还定以了org.apache.lucene.store.lock和org.apache.lucene.store.with两个辅助内部实现的类用在实现Directory方法的makeLock的时候，以在锁定索引读写之前来让客户程序做一些准备工作。  <p>（FSDirectory，FSInputStream，FSOutputStream）的内部实现依托于java语言中的io类库，只是简单的做了一个外部逻辑的包装。这当然要归功于java语言所提供的跨平台特性，同时也带了一些隐患：文件存取的效率提升需要依耐于文件类库的优化。如果需要继续优化文件存取的效率，应该还提供一个文件与目录的抽象，以根据各种文件系统或者文件类型来提供一个优化的机会。当然，这是应用开发者所不需要关系的问题。  <p>（RAMDirectory，RAMInputStream和RAMOutputStream）的内部实现就比较直接了，直接采用了虚拟的文件RAMFile类（定义于文件RAMDirectory.java中）来表示文件，目录则看作一个String与RAMFile对应的关联数组。RAMFile中采用数组来表示文件的存储空间。在此的基础上，完成各项操作的实现，就形成了基于内存的虚拟文件系统。因为在实际使用时，并不会牵涉到很大字节数量的文件，因此这种设计是简单直接的，也是高效率的。 </p></blockquote><b> <p><br></p></b> <h4>&nbsp;</h4> <h4>3. Lucene索引构建逻辑模块分析</h4> <h4>3.1对象体系与UML图</h4> <blockquote> <p><b>1</b><b>． </b><b>项（Term</b><b>）</b>  <p><b></b>项（Term）：包括概念所实际涉及的类、永久化类。项（Term）所表示的是一个字符串，它拥有域、频数和位置信息等等属性。因此，Lucene中设计了两个类来表示这个概念，如下图  <p><b><a href="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image016_2.gif"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image016" border="0" alt="clip_image016" src="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image016_thumb.gif" width="545" height="533"></a></b>  <p><b>图</b><b> 4.1 UML</b><b>图（－）</b>  <p><b></b> <p>上图中，有意的突出了类Term和TermInfo中的数据成员，因为它反映了对于项（Term）这个概念的具体表示。同时上图中也同时列出了用于永久化项（Term）的代理类TermInfosWriter和TermInfosReader，它们完成永久化的功能，需要注意的是，TermInfosReader内部使用了数组indexTerms和indexInfos来存储一系列项；而TermInfosWriter则是一个类似于链表的结构，通过一个other指向下一个TermInfosWriter，每一个TermInfosWriter只负责本身那个lastTerm和lastTi的永久化工作。这是一个设计上的技巧，通过批量读取（或者称为缓冲的方式）来获得读入时候的效率优化；而通过一个链表式的、各负其责的方式，来获得写出时候的设计简化。  <p>项（term）这部分的设计中，还有一些重要的接口和类：  <p><b><a href="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image017_2.gif"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image017" border="0" alt="clip_image017" src="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image017_thumb.gif" width="379" height="205"></a></b>  <p><b>图 4.2 UML图（二）</b>  <p><b></b> <p>图4.2中，我们看到三个类：TermEnum、TermDocs与TermPositions，第一个是抽象类，后两个都是接口。TermEnum的设计主要用在后面Segment和Document等等的实现中，以提供枚举其中每一个项（Term）的能力。TermDocs是一个接口，用来继承以提供返回&lt;document, frequency&gt;值对的能力，通过这个接口就可以获得某个项（Term）在某个文档中出现的频数。TermPositions则是在TermDocs上的扩展，将项（Term）在文档中的位置信息也表示出来。TermDocs（TermPositions）接口的使用方式类似于java中的Enumration接口，即通过next方法跳转，通过doc，freq等方法获得当前的属性值。  <p><a name="_Toc43005332"><b>2． </b><b>域（</b></a><b>Field</b><b>）</b>  <p>由于Field的基本概念在org.apache.lucene.document中已经做了定义，因此在这部分主要是针对项文件（.fnm文件、.fdx文件、.fdt文件）所需要的信息再来设计一些类。  <p><b><a href="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image018_2.gif"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image018" border="0" alt="clip_image018" src="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image018_thumb.gif" width="149" height="118"></a></b>  <p><b>图 4.3 UML图（三）</b>  <p><b><br></b> <p>图 4.3中展示的，就是表示与域（Field）所关联的属性信息的类。其中isIndexed表示的这个域的值是否被索引过，即值是否被分词然后索引；另外两个属性所表示的意思则很明显：一个是域的名字，一个是域的编号。  <p>关于域表和存取逻辑的UML图：  <p><b><a href="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image019_2.gif"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image019" border="0" alt="clip_image019" src="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image019_thumb.gif" width="549" height="329"></a></b>  <p>FieldInfos即为域表的概念表示，内部采用了冗余的方式以获取在通过域的编号访问或者通过域的名字来访问时候的高效率。FieldsReader与FieldsWriter则分别是写出和读入的代理类。在功能和实现上，这两个类都比较简单。  <p><b>3． </b><b>文档（document）</b>  <p>文档（document）同样也是在org.apache.lucene.document中定义过的结构。由于对于这部分比较重要，我们也来看看其UML图：  <p><b><a href="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image020_2.gif"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image020" border="0" alt="clip_image020" src="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image020_thumb.gif" width="643" height="355"></a></b>  <p><b>图 4.5 UML图（五）</b>  <p>在图4.5中我们看到，Document的设计基本上沿用了链表的处理方法。左边的Document类作为一个数据外包类，用来提供对于内部结构DocumentFieldList的增加删除访问操作等等。DocumentFieldList才是实际上的数据存储单位，它用了链表的处理方法，直接指向一个当前的Field对象和下一个DocumentFieldList对象，这个与前面的类似。为了能够逐个访问链表中的节点，还设计了DocumentFieldEnumeration枚举类。  <p><b><a href="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image021_2.gif"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image021" border="0" alt="clip_image021" src="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image021_thumb.gif" width="361" height="241"></a></b>  <p><b>图 4.6 UML图（六）</b>  <p><b><br></b> <p><b></b> <p>实际上定义于org.apache.lucene.index中的有关于Document的就是永久化的代理类。在图4.6中给出了其UML图。需要说明的是为什么没有出现读入的方法：这个方法已经隐含在图4.5中Document类中的add方法中了，结合图2.4中的程序代码段，我们就能够清楚的理解这种设计。  <p><a name="_Toc43005334"><b>4． </b><b>段（</b></a><b>segment</b><b>）</b>  <p>段（Segment）这一部分设计的比较特殊，在实现简单的对象结构之上，还特意的设计了用于段之间合并的类。接下来，我们仍然采取对照UML分析的方式逐个叙述。接下来我们看Lucene中如何表示段这个概念。  <p><b><a href="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image022_2.gif"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image022" border="0" alt="clip_image022" src="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image022_thumb.gif" width="262" height="230"></a></b>  <p><b>图 4.7 UML图（七）</b>  <p>Lucene定义了一个类SegmentInfo用来表示每一个段（Segment）的信息，包括名字（name）、含有的文档的数目（docCount）和段所位于的目录的位置（dir）。根据索引文件中的段的意义，有了这三点，就能唯一确定一个段了。SegmentInfos这个类则是用来表示一个段的链表（从标准的java.util.Vector继承而来），实际上，也就是索引（index）的意思了。需要注意的是，这里并没有在SegmentInfo中安插一个文档（document）的链表。这样做的原因牵涉到Lucene内部对于文档（相当于一个被索引文件）的处理；Lucene内部采用了赋予文档编号，给域赋值的方式来处理文档，即加入的文档顺次编号，以后用文档号表示文档，而路径信息，文件名字等等在以后索引查找需要的属性，都作为域存储下来；因此SegmentInfo中并没有另外存储一个文档（document）的链表，对于这些的写出和读入，则交给了永久化的代理类来做。  <p><b><a href="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image023_2.gif"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image023" border="0" alt="clip_image023" src="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image023_thumb.gif" width="661" height="415"></a></b>  <p><b>图 4.8 UML图（八）</b>  <p>图4.8给出了负责段（segment）的读入操作的代理类，而负责段（segment）的写出操作也同样没有定义，这些操作都直接实现在了类IndexWriter类中。段的操作同样采用了之前的数组或者说是缓冲的处理方式。  <p>针对前面项（term）那部分定义的几个接口，段（segment）这部分也需要做相应的接口实现，因为提供直接遍历访问段中的各个项的能力对于检索来说，无疑是十分重要的。即这部分的设计，实际上都是在为了检索在服务。  <p><b><a href="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image024_2.gif"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image024" border="0" alt="clip_image024" src="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image024_thumb.gif" width="351" height="346"></a></b>  <p><b>图 4.9 UML图（九）</b>  <p><b><a href="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image025_2.gif"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image025" border="0" alt="clip_image025" src="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image025_thumb.gif" width="533" height="680"></a></b>  <p><b>图 4.10 UML图（十）</b>  <p>图4.9和图4.10分别展示了前面项（term）那里定义的接口是如何在这里通过继承实现的。Lucene在处理这部分的时候，也是分成两部分（Segment与Segments开头的类）来实现，而且很合理的运用了数组的技法，以及注意了继承重用。但是细化到局部，终归是比较简单的按照语义来获得结果而已了。  <p>Lucene为了兼顾建立索引时的效率和读取索引查找的速度，引入了分小段建立索引的方式，即每一次批量建立索引时，先在内存中的虚拟文件系统中为每一个文档单独建立一个段，然后在输出的时候将这些段合并之后输出成为索引文件，这时仅仅存在一个段。多次建立的索引后，如果想优化索引文件，也可采取合并段的方法，将索引中的段合并成为一个段。我们来看一下在IndexWriter类中相应的方法的实现，来了解一下这中建立索引的实现。  <p><b><a href="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image026_2.gif"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image026" border="0" alt="clip_image026" src="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image026_thumb.gif" width="664" height="774"></a></b>  <p><b><br></b> <p>在mergeSegments函数中，将用到几个重要的类结构，它们记录了合并时候的一些重要信息，完成合并时候的工作。接下来，我们来看这几个类的UML图：  <p><b><a href="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image027_2.gif"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image027" border="0" alt="clip_image027" src="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image027_thumb.gif" width="509" height="458"></a></b>  <p><b>图 4.12 UML图（十一）</b>  <p><b></b> <p>从图4.12中，我们看到Lucene设计一个类SegmentMergeInfo用来保存每一个被合并的段的信息，也保存能够访问其内部的接口句柄，也就是说合并时的操作使用这个类作为对被合并的段的操作代理。类SegmentMergeQueue则设计为org.apache.lucene.util.PriorityQueue的子类，做为SegmentMergeInfo的容器类，而且附带能够自动排序。SegmentMerger是主要进行操作的类，主要完成合并各个数据项的问题。  <p><a name="_Toc43005335"><b>5． </b><b>IndexReader</b></a><b>类与IndexWirter类</b>  <p>最后剩下的，就是整个索引逻辑部分的使用接口类了。外界通过这两个类以及文档（document）类的构造函数调用之，比如图2.4中的代码示例所示。下面我们来看一下这部分最后两个类的UML图：  <p><b><a href="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image028_2.gif"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image028" border="0" alt="clip_image028" src="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image028_thumb.gif" width="471" height="552"></a></b>  <p><b>图 4.13 UML图（十二）</b>  <p><b></b> <p>IndexWriter的设计与IndexReader的设计很不相同，前者是一个实现类，而后者是一个抽象类，带有没有实现的接口。IndexWriter的主要作用就是接收新加入的文档（document），然后在内部为之生成相应的小段，最后再合并并向索引文件中输出，图4.11中已经给出了一些实现的代码。由于Lucene在面向对象上封装的努力，通过各个构造函数就已经完成了对于各个概念的构造过程，剩下部分的代码主要是依据各个数组或者是链表中的信息，逐个逐个的将信息写出到相应的文件中去了。IndexReader部分则只是做了接口设计，没有具体的实现，这个和本部分所完成的主要功能有关：索引构建逻辑。设计这个抽象类的目的是，预先完成一些函数，为以后的检索（search）部分的各种形式的IndexReader铺平道路，也是利用了在同一个包内可以方便访问其它类的保护变量这个java语言的限制。<a name="_Toc43005336"></a>  <p><b>3.2 </b><b>数据流逻辑</b><b></b>  <p>从宏观上明白一个系统的设计，理清楚其中的运行规律，最好的方式应该是通过数据流图。在分析了各个位于索引构建逻辑部分的类的设计之后，我们接下来就通过分析数据流图的方式来总结一下。但是由于之前提到的原因：索引读入部分在这一部分并没有完全实现，所以我们在数据流图中主要给出的是索引构建的数据流图。  <p><a href="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image030_2.jpg"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image030" border="0" alt="clip_image030" src="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_85F5/clip_image030_thumb.jpg" width="557" height="382"></a>  <p>对于图4.14中所描述的内容，结合Lucene源代码中的一些文件看，能够加深理解。准备阶段可以参考demo文件夹中的org.apache.lucene.demo.IndexFiles类和java文件夹中的org.apache.lucene.document文件包。索引构建阶段的主要源码位于java文件夹中org.apache.lucene.index.IndexWriter类，因此这部分可以结合这个类的实现来看。至于内存文件系统，比较复杂，但是这时的逻辑相对简单，因此也不难理解。  <p>上面的数据流图十分清楚的勾画除了整个索引构建逻辑这部分的设计：通过层层嵌套的类结构，在构建时候即分步骤有计划的生成了索引结构，将之存储到内存中的文件系统中，然后通过对内存中的文件系统优化合并输出到实际的文件系统中。 </p></blockquote> <p>&nbsp;</p> <p>本文是在我2010年学习Lucene的时候在互联网上摘抄整理而来，当时是在一家电子商务公司做商品检索需要用到Lucene，所以就研究了下。这篇文章也是在当时在网络上阅读Lucene相关知识整理而来的。</p><img src ="http://www.blogjava.net/hoojo/aggbug/387140.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hoojo/" target="_blank">hoojo</a> 2012-09-06 09:34 <a href="http://www.blogjava.net/hoojo/archive/2012/09/06/387140.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Lucene 简单手记</title><link>http://www.blogjava.net/hoojo/archive/2012/09/05/387077.html</link><dc:creator>hoojo</dc:creator><author>hoojo</author><pubDate>Wed, 05 Sep 2012 04:21:00 GMT</pubDate><guid>http://www.blogjava.net/hoojo/archive/2012/09/05/387077.html</guid><wfw:comment>http://www.blogjava.net/hoojo/comments/387077.html</wfw:comment><comments>http://www.blogjava.net/hoojo/archive/2012/09/05/387077.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hoojo/comments/commentRss/387077.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hoojo/services/trackbacks/387077.html</trackback:ping><description><![CDATA[<p><b>什么是全文检索与全文检索系统？</b>  <blockquote> <p>全文检索是指计算机索引程序通过扫描文章中的每一个词，对每一个词建立一个索引，指明该词在文章中出现的次数和位置，当用户查询时，检索程序就根据事先建立的索引进行查找，并将查找的结果反馈给用户的检索方式。这个过程类似于通过字典中的检索字表查字的过程。  <p>&nbsp;</p></blockquote> <blockquote> <p>全文检索的方法主要分为按字检索和按词检索两种。按字检索是指对于文章中的每一个字都建立索引，检索时将词分解为字的组合。对于各种不同的语言而言，字有不同的含义，比如英文中字与词实际上是合一的，而中文中字与词有很大分别。按词检索指对文章中的词，即语义单位建立索引，检索时按词检索，并且可以处理同义项等。  <p>&nbsp;</p></blockquote> <blockquote> <p>全文检索系统是按照全文检索理论建立起来的用于提供全文检索服务的软件系统。一般来说，全文检索需要具备建立索引和提供查询的基本功能，此外现代的全文检索系统还需要具有方便的用户接口、面向WWW[1]的开发接口、二次应用开发接口等等。功能上，全文检索系统核心具有建立索引、处理查询返回结果集、增加索引、优化索引结构等等功能，外围则由各种不同应用具有的功能组成。结构上，全文检索系统核心具有索引引擎、查询引擎、文本分析引擎、对外接口等等，加上各种外围应用系统等等共同构成了全文检索系统。</p></blockquote> <p><b></b>&nbsp; <p><b>什么是Lucene？</b>  <blockquote> <p>Lucene是apache软件基金会jakarta项目组的一个子项目，是一个开放源代码的全文检索引擎工具包，即它不是一个完整的全文检索引擎，而是一个全文检索引擎的架构，提供了完整的查询引擎和索引引擎，部分文本分析引擎（英文与德文两种西方语言）。Lucene的目的是为软件开发人员提供一个简单易用的工具包，以方便的在目标系统中实现全文检索的功能，或者是以此为基础建立起完整的全文检索引擎。  <p>&nbsp; <p>Lucene的原作者是Doug Cutting，他是一位资深全文索引/检索专家，曾经是V-Twin搜索引擎的主要开发者，后在Excite担任高级系统架构设计师，目前从事于一些Internet底层架构的研究。早先发布在作者自己的http://www.lucene.com/，后来发布在SourceForge，2001年年底成为apache软件基金会jakarta的一个子项目：<a href="http://jakarta.apache.org/lucene/">http://jakarta.apache.org/lucene/</a>。</p></blockquote> <p><b></b> <p><b></b>&nbsp; <p><b>Lucene</b><b>作为一个全文检索引擎，其具有如下突出的优点：</b>  <blockquote> <p>（1）索引文件格式独立于应用平台。Lucene定义了一套以8位字节为基础的索引文件格式，使得兼容系统或者不同平台的应用能够共享建立的索引文件。  <p>（2）在传统全文检索引擎的倒排索引的基础上，实现了分块索引，能够针对新的文件建立小文件索引，提升索引速度。然后通过与原有索引的合并，达到优化的目的。  <p>（3）优秀的面向对象的系统架构，使得对于Lucene扩展的学习难度降低，方便扩充新功能。  <p>（4）设计了独立于语言和文件格式的文本分析接口，索引器通过接受Token流完成索引文件的创立，用户扩展新的语言和文件格式，只需要实现文本分析的接口。  <p>（5）已经默认实现了一套强大的查询引擎，用户无需自己编写代码即使系统可获得强大的查询能力，Lucene的查询实现中默认实现了布尔操作、模糊查询（Fuzzy Search）、分组查询等等。</p></blockquote> <p><b></b>&nbsp; <p><b>面对已经存在的商业全文检索引擎，Lucene</b><b>也具有相当的优势：</b>  <blockquote> <p>首先，它的开发源代码发行方式（遵守Apache Software License），在此基础上程序员不仅仅可以充分的利用Lucene所提供的强大功能，而且可以深入细致的学习到全文检索引擎制作技术和面相对象编程的实践，进而在此基础上根据应用的实际情况编写出更好的更适合当前应用的全文检索引擎。在这一点上，商业软件的灵活性远远不及Lucene。  <p>其次，Lucene秉承了开放源代码一贯的架构优良的优势，设计了一个合理而极具扩充能力的面向对象架构，程序员可以在Lucene的基础上扩充各种功能，比如扩充中文处理能力，从文本扩充到HTML、PDF等等文本格式的处理，编写这些扩展的功能不仅仅不复杂，而且由于Lucene恰当合理的对系统设备做了程序上的抽象，扩展的功能也能轻易的达到跨平台的能力。  <p>最后，转移到apache软件基金会后，借助于apache软件基金会的网络平台，程序员可以方便的和开发者、其它程序员交流，促成资源的共享，甚至直接获得已经编写完备的扩充功能。最后，虽然Lucene使用Java语言写成，但是开放源代码社区的程序员正在不懈的将之使用各种传统语言实现（例如.net framework），在遵守Lucene索引文件格式的基础上，使得Lucene能够运行在各种各样的平台上，系统管理员可以根据当前的平台适合的语言来合理的选。</p></blockquote> <p><b></b> <p><b></b>&nbsp; <p><b>索引和搜索的关系</b>  <blockquote> <p>索引是现代搜索引擎的核心，建立索引的过程就是把源数据处理成非常方便查询的索引文件的过程。为什么索引这么重要呢，试想你现在要在大量的文档中搜索含有某个关键词的文档，那么如果不建立索引的话你就需要把这些文档顺序的读入内存，然后检查这个文章中是不是含有要查找的关键词，这样的话就会耗费非常多的时间，想想搜索引擎可是在毫秒级的时间内查找出要搜索的结果的。这就是由于建立了索引的原因，你可以把索引想象成这样一种数据结构，他能够使你快速的随机访问存储在索引中的关键词，进而找到该关键词所关联的文档。Lucene 采用的是一种称为反向索引（inverted index）的机制。反向索引就是说我们维护了一个词/短语表，对于这个表中的每个词/短语，都有一个链表描述了有哪些文档包含了这个词/短语。这样在用户输入查询条件的时候，就能非常快的得到搜索结果。我们将在本系列文章的第二部分详细介绍 Lucene 的索引机制，由于 Lucene 提供了简单易用的 API，所以即使读者刚开始对全文本进行索引的机制并不太了解，也可以非常容易的使用 Lucene 对你的文档实现索引。  <p>对文档建立好索引后，就可以在这些索引上面进行搜索了。搜索引擎首先会对搜索的关键词进行解析，然后再在建立好的索引上面进行查找，最终返回和用户输入的关键词相关联的文档。</p></blockquote> <p><b></b>&nbsp; <p><b>Lucene </b><b>软件包分析</b>  <blockquote> <p>Package: org.apache.lucene.document  <p>这个包提供了一些为封装要索引的文档所需要的类，比如 Document, Field。这样，每一个文档最终被封装成了一个 Document 对象。  <p>Package: org.apache.lucene.analysis  <p>这个包主要功能是对文档进行分词，因为文档在建立索引之前必须要进行分词，所以这个包的作用可以看成是为建立索引做准备工作。  <p>Package: org.apache.lucene.index  <p>这个包提供了一些类来协助创建索引以及对创建好的索引进行更新。这里面有两个基础的类：IndexWriter 和 IndexReader，其中 IndexWriter 是用来创建索引并添加文档到索引中的，IndexReader 是用来删除索引中的文档的。  <p>Package: org.apache.lucene.search  <p>这个包提供了对在建立好的索引上进行搜索所需要的类。比如 IndexSearcher 和 Hits, IndexSearcher 定义了在指定的索引上进行搜索的方法，Hits 用来保存搜索得到的结果</p></blockquote> <p> <table border="1" cellspacing="0" cellpadding="0"> <tbody> <tr> <td valign="top" width="561"> <p><b>Lucene</b><b>包结构功能表</b></p></td></tr> <tr> <td valign="top" width="186"> <p>包名</p></td> <td valign="top" width="375"> <p>功能</p></td></tr> <tr> <td valign="top" width="186"> <p>org.apache.lucene.analysis</p></td> <td valign="top" width="375"> <p>语言分析器，主要用于的切词，支持中文主要是扩展此类</p></td></tr> <tr> <td valign="top" width="186"> <p>org.apache.lucene.document</p></td> <td valign="top" width="375"> <p>索引存储时的文档结构管理，类似于关系型数据库的表结构</p></td></tr> <tr> <td valign="top" width="186"> <p>org.apache.lucene.index</p></td> <td valign="top" width="375"> <p>索引管理，包括索引建立、删除等</p></td></tr> <tr> <td valign="top" width="186"> <p>org.apache.lucene.queryParser</p></td> <td valign="top" width="375"> <p>查询分析器，实现查询关键词间的运算，如与、或、非等</p></td></tr> <tr> <td valign="top" width="186"> <p>org.apache.lucene.search</p></td> <td valign="top" width="375"> <p>检索管理，根据查询条件，检索得到结果</p></td></tr> <tr> <td valign="top" width="186"> <p>org.apache.lucene.store</p></td> <td valign="top" width="375"> <p>数据存储管理，主要包括一些底层的I/O操作</p></td></tr> <tr> <td valign="top" width="186"> <p>org.apache.lucene.util</p></td> <td valign="top" width="375"> <p>一些公用类</p></td></tr></tbody></table></p> <p><b></b>&nbsp; <p><b>一个简单的搜索应用程序</b>  <blockquote> <p>假设我们的电脑的目录中含有很多文本文档，我们需要查找哪些文档含有某个关键词。为了实现这种功能，我们首先利用  <p>Lucene 对这个目录中的文档建立索引，然后在建立好的索引中搜索我们所要查找的文档。通过这个例子读者会对如何利用  <p>Lucene 构建自己的搜索应用程序有个比较清楚的认识。</p></blockquote> <p><u></u>&nbsp; <blockquote> <p><u>建立索引</u>  <p>为了对文档进行索引，Lucene 提供了五个基础的类，他们分别是 Document, Field, IndexWriter, Analyzer, Directory。下面我们分别介绍一下这五个类的用途：  <p><u></u>&nbsp; <p>Document  <p>Document 是用来描述文档的，这里的文档可以指一个 HTML 页面，一封电子邮件，或者是一个文本文件。一个 Document 对象由多个 Field 对象组成的。可以把一个 Document 对象想象成数据库中的一个记录，而每个 Field 对象就是记录的一个字段。  <table border="1" cellspacing="0" cellpadding="0"> <tbody> <tr> <td valign="top" width="223"> <p>接口名</p></td> <td valign="top" width="324"> <p>备注</p></td></tr> <tr> <td valign="top" width="223"> <p>add(Field field)</p></td> <td valign="top" width="324"> <p>添加一个字段（Field）到Document中</p></td></tr> <tr> <td valign="top" width="223"> <p>String get(String name)</p></td> <td valign="top" width="324"> <p>从文档中获得一个字段对应的文本</p></td></tr> <tr> <td valign="top" width="223"> <p>Field getField(String name)</p></td> <td valign="top" width="324"> <p>由字段名获得字段值</p></td></tr> <tr> <td valign="top" width="223"> <p>Field[] getFields(String name)</p></td> <td valign="top" width="324"> <p>由字段名获得字段值的集</p></td></tr></tbody></table> <p>&nbsp; <p>Field  <p>Field 对象是用来描述一个文档的某个属性的，比如一封电子邮件的标题和内容可以用两个 Field 对象分别描述。  <p>即上文所说的“字段”，它是Document的片段section。  <p>Field的构造函数：  <p>Field(String name, String string, boolean store, boolean index, boolean token)。  <p>Indexed：如果字段是Indexed的，表示这个字段是可检索的。  <p>Stored：如果字段是Stored的，表示这个字段的值可以从检索结果中得到。  <p>Tokenized：如果一个字段是Tokenized的，表示它是有经过Analyzer转变后成为一个tokens序列，在这个转变过程tokenization中，Analyzer提取出需要进行索引的文本，而剔除一些冗余的词句（例如：a，the,they等，详见org.apache.lucene.analysis.StopAnalyzer.ENGLISH_STOP_WORDS和org.apache.lucene.analysis.standard.StandardAnalyzer(String[] stopWords)的API）。Token是索引时候的基本单元，代表一个被索引的词，例如一个英文单词，或者一个汉字。因此，所有包含中文的文本都必须是Tokenized的。  <p>&nbsp; <p>Analyzer  <p>在一个文档被索引之前，首先需要对文档内容进行分词处理，这部分工作就是由 Analyzer 来做的。Analyzer 类是一个抽象类，它有多个实现。针对不同的语言和应用需要选择适合的 Analyzer。Analyzer 把分词后的内容交给 IndexWriter 来建立索引。  <table border="1" cellspacing="0" cellpadding="0"> <tbody> <tr> <td valign="top" width="223"> <p>接口名</p></td> <td valign="top" width="324"> <p>备注</p></td></tr> <tr> <td valign="top" width="223"> <p>addDocument(Document doc)</p></td> <td valign="top" width="324"> <p>索引添加一个文档</p></td></tr> <tr> <td valign="top" width="223"> <p>addIndexes(Directory[] dirs)</p></td> <td valign="top" width="324"> <p>将目录中已存在索引添加到这个索引</p></td></tr> <tr> <td valign="top" width="223"> <p>addIndexes(IndexReader[] readers)</p></td> <td valign="top" width="324"> <p>将提供的索引添加到这个索引</p></td></tr> <tr> <td valign="top" width="223"> <p>optimize()</p></td> <td valign="top" width="324"> <p>合并索引并优化</p></td></tr> <tr> <td valign="top" width="223"> <p>close()</p></td> <td valign="top" width="324"> <p>关闭</p></td></tr></tbody></table> <p>IndexWriter  <p>IndexWriter 是 Lucene 用来创建索引的一个核心的类，他的作用是把一个个的 Document 对象加到索引中来。  <p>&nbsp; <p>Directory  <p>这个类代表了 Lucene 的索引的存储的位置，这是一个抽象类，它目前有两个实现，第一个是 FSDirectory，它表示一个存储在文件系统中的索引的位置。第二个是 RAMDirectory，它表示一个存储在内存当中的索引的位置。</p></blockquote> <blockquote> <p>熟悉了建立索引所需要的这些类后，我们就开始对某个目录下面的文本文件建立索引了，给出了对某个目录下的文本文件建立索引的源代码。  <div id="codeSnippetWrapper"> <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> TextFileIndexer {</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> void main(String[] args) throws <span style="color: #0000ff">Exception</span> {</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        <span style="color: #008000">// fileDir is the directory that contains the text files to be indexed</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        <span style="color: #0000ff">File</span> fileDir = <span style="color: #0000ff">new</span> <span style="color: #0000ff">File</span>("C:\\<span style="color: #0000ff">index</span>");</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">&nbsp;</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        <span style="color: #008000">// indexDir is the directory that hosts Lucene's index files</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        <span style="color: #0000ff">File</span> indexDir = <span style="color: #0000ff">new</span> <span style="color: #0000ff">File</span>("C:\\luceneIndex");</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        Analyzer luceneAnalyzer = <span style="color: #0000ff">new</span> StandardAnalyzer(Version.LUCENE_30);</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        IndexWriter indexWriter = <span style="color: #0000ff">new</span> IndexWriter(FSDirectory.<span style="color: #0000ff">open</span>(indexDir), luceneAnalyzer, <span style="color: #0000ff">true</span>, IndexWriter.MaxFieldLength.LIMITED);</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        <span style="color: #0000ff">File</span>[] textFiles = fileDir.listFiles();</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        long startTime = <span style="color: #0000ff">new</span> <span style="color: #0000ff">Date</span>().getTime();</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">&nbsp;</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        <span style="color: #008000">// Add documents to the index</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        <span style="color: #0000ff">for</span> (<span style="color: #0000ff">int</span> i = 0; i &lt; textFiles.length; i++) {</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">            <span style="color: #0000ff">if</span> (textFiles[i].isFile() &amp;&amp; textFiles[i].getName().endsWith(".txt")) {</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">                System.<span style="color: #0000ff">out</span>.println("<span style="color: #0000ff">File</span> " + textFiles[i].getCanonicalPath() + " <span style="color: #0000ff">is</span> being indexed");</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">                Reader textReader = <span style="color: #0000ff">new</span> FileReader(textFiles[i]);</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">                Document document = <span style="color: #0000ff">new</span> Document();</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">&nbsp;</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">                document.<span style="color: #0000ff">add</span>(<span style="color: #0000ff">new</span> Field("content", textReader));</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">                document.<span style="color: #0000ff">add</span>(<span style="color: #0000ff">new</span> Field("<span style="color: #0000ff">path</span>", textFiles[i].getPath(), Field.Store.YES, Field.<span style="color: #0000ff">Index</span>.ANALYZED_NO_NORMS));</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">                indexWriter.addDocument(document);</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">            }</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        }</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">&nbsp;</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        indexWriter.optimize();</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        indexWriter.<span style="color: #0000ff">close</span>();</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        long endTime = <span style="color: #0000ff">new</span> <span style="color: #0000ff">Date</span>().getTime();</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">&nbsp;</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        System.<span style="color: #0000ff">out</span>.println("It took " + (endTime - startTime) + " milliseconds <span style="color: #0000ff">to</span> <span style="color: #0000ff">create</span> an <span style="color: #0000ff">index</span> <span style="color: #0000ff">for</span> the files <span style="color: #0000ff">in</span> the directory " + fileDir.getPath());</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    }</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">}</pre><!--CRLF--></div></div>
<p>&nbsp; <p>我们注意到类 IndexWriter 的构造函数需要三个参数，第一个参数指定了所创建的索引要存放的位置，他可以是一个 File 对象，也可以是一个 FSDirectory 对象或者 RAMDirectory 对象。第二个参数指定了 Analyzer 类的一个实现，也就是指定这个索引是用哪个分词器对文挡内容进行分词。第三个参数是一个布尔型的变量，如果为 true 的话就代表创建一个新的索引，为 false 的话就代表在原来索引的基础上进行操作。接着程序遍历了目录下面的所有文本文档，并为每一个文本文档创建了一个 Document 对象。然后把文本文档的两个属性：路径和内容加入到了两个 Field 对象中，接着在把这两个 Field 对象加入到 Document 对象中，最后把这个文档用 IndexWriter 类的 add 方法加入到索引中去。这样我们便完成了索引的创建。接下来我们进入在建立好的索引上进行搜索的部分。</p></blockquote>
<p><b></b>&nbsp; <blockquote>
<p><b>搜索文档</b><b></b> 
<p><b></b>&nbsp; <p><b>Query</b> 
<p>这是一个抽象类，他有多个实现，比如TermQuery, BooleanQuery, PrefixQuery. 这个类的目的是把用户输入的查询字符串封装成Lucene能够识别的Query。 
<p><b>Term</b> 
<p>Term是搜索的基本单位，一个Term对象有两个String类型的域组成。生成一个Term对象可以有如下一条语句来完成：Term term = new Term(“fieldName”,”queryWord”); 其中第一个参数代表了要在文档的哪一个Field上进行查找，第二个参数代表了要查询的关键词。 
<p><b>TermQuery</b> 
<p>TermQuery是抽象类Query的一个子类，它同时也是Lucene支持的最为基本的一个查询类。生成一个TermQuery对象由如下语句完成： TermQuery termQuery = new TermQuery(new Term(“fieldName”,”queryWord”)); 它的构造函数只接受一个参数，那就是一个Term对象。 
<p><b>IndexSearcher</b> 
<p>IndexSearcher是用来在建立好的索引上进行搜索的。它只能以只读的方式打开一个索引，所以可以有多个IndexSearcher的实例在一个索引上进行操作。 
<p><b>Hits</b> 
<p>Hits是用来保存搜索的结果的。</p></blockquote>
<p>&nbsp; <p>介绍完这些搜索所必须的类之后，我们就开始在之前所建立的索引上进行搜索了，清单2给出了完成搜索功能所需要的代码。 
<blockquote>
<p><b>如何添加一个文档到索引文</b><b></b></p>
<p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="568">
<p>Document document = <b>new</b> Document(); 
<p>document.add(<b>new</b> Field("content",textReader)); 
<p>document.add(<b>new</b> Field("path",textFiles[i].getPath(), Field.Store.<i>YES</i>, Field.Index.<i>ANALYZED_NO_NORMS</i>)); 
<p><b></b>indexWriter.addDocument(document); 
<p>//最后不要忘记了关闭 
<p>indexWriter.close();</p></td></tr></tbody></table></p>
<p><b></b>
<p>首先第一行创建了类 Document 的一个实例，它由一个或者多个的域(Field)组成。你可以把这个类想象成代表了一个实际的文档，比如一个 HTML 页面，一个 PDF 文档，或者一个文本文件。而类 Document 中的域一般就是实际文档的一些属性。比如对于一个 HTML 页面，它的域可能包括标题，内容，URL 等。我们可以用不同类型的 Field 来控制文档的哪些内容应该索引，哪些内容应该存储。如果想获取更多的关于 Lucene 的域的信息，可以参考 Lucene 的帮助文档。代码的第二行和第三行为文档添加了两个域，每个域包含两个属性，分别是域的名字和域的内容。在我们的例子中两个域的名字分别是"content"和"path"。分别存储了我们需要索引的文本文件的内容和路径。最后一行把准备好的文档添加到了索引当中。</p></blockquote>
<p><b></b>&nbsp; <blockquote>
<p><b>从索引中删除文档</b><b></b> 
<p>类IndexReader负责从一个已经存在的索引中删除文档。 
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="568">
<p>File indexDir = new File("C:\\luceneIndex"); 
<p>IndexReader ir = IndexReader.open(indexDir); 
<p>ir.delete(1); 
<p>ir.delete(new Term("path","C:\\file_to_index\lucene.txt")); 
<p>ir.close();</p></td></tr></tbody></table>
<p>第二行用静态方法 IndexReader.open(indexDir) 初始化了类 IndexReader 的一个实例，这个方法的参数指定了索引的存储路径。类 IndexReader 提供了两种方法去删除一个文档，如程序中的第三行和第四行所示。第三行利用文档的编号来删除文档。每个文档都有一个系统自动生成的编号。第四行删除了路径为"C:\\file_to_index\lucene.txt"的文档。你可以通过指定文件路径来方便的删除一个文档。值得注意的是虽然利用上述代码删除文档使得该文档不能被检索到，但是并没有物理上删除该文档。Lucene 只是通过一个后缀名为 .delete 的文件来标记哪些文档已经被删除。既然没有物理上删除，我们可以方便的把这些标记为删除的文档恢复过来，如清单 3 所示，首先打开一个索引，然后调用方法 ir.undeleteAll() 来完成恢复工作。</p></blockquote>
<p><b></b>&nbsp;</p>
<blockquote>
<p><b>恢复已删除文档</b><b></b></p>
<p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="568">
<p>File indexDir = new File("C:\\luceneIndex"); 
<p>IndexReader ir = IndexReader.open(indexDir); 
<p>ir.undeleteAll(); 
<p>ir.close();<b></b></p></td></tr></tbody></table></p></blockquote>
<p><b></b>
<p><b></b>&nbsp;</p>
<blockquote>
<p><b>如何物理上删除文档</b><b></b></p>
<p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="568">
<p>File indexDir = new File("C:\\luceneIndex"); 
<p>Analyzer luceneAnalyzer = new StandardAnalyzer(); 
<p>IndexWriter indexWriter = new IndexWriter(indexDir,luceneAnalyzer,false); 
<p>indexWriter.optimize(); 
<p>indexWriter.close();<b></b></p></td></tr></tbody></table></p>
<p>第三行创建了类 IndexWriter 的一个实例，并且打开了一个已经存在的索引。第 4 行对索引进行清理，清理过程中将把所有标记为删除的文档物理删除。</p></blockquote>
<p><b></b>&nbsp; <blockquote>
<p><b>提高索引性能</b><b></b> 
<p>利用 Lucene，在创建索引的工程中你可以充分利用机器的硬件资源来提高索引的效率。当你需要索引大量的文件时，你会注意到索引过程的瓶颈是在往磁盘上写索引文件的过程中。为了解决这个问题, Lucene 在内存中持有一块缓冲区。但我们如何控制 Lucene 的缓冲区呢？幸运的是，Lucene 的类 IndexWriter 提供了三个参数用来调整缓冲区的大小以及往磁盘上写索引文件的频率。 
<p>1．合并因子（mergeFactor） 
<p>这个参数决定了在 Lucene 的一个索引块中可以存放多少文档以及把磁盘上的索引块合并成一个大的索引块的频率。比如，如果合并因子的值是 10，那么当内存中的文档数达到 10 的时候所有的文档都必须写到磁盘上的一个新的索引块中。并且，如果磁盘上的索引块的隔数达到 10 的话，这 10 个索引块会被合并成一个新的索引块。这个参数的默认值是 10，如果需要索引的文档数非常多的话这个值将是非常不合适的。对批处理的索引来讲，为这个参数赋一个比较大的值会得到比较好的索引效果。 
<p>2．最小合并文档数 
<p>这个参数也会影响索引的性能。它决定了内存中的文档数至少达到多少才能将它们写回磁盘。这个参数的默认值是10，如果你有足够的内存，那么将这个值尽量设的比较大一些将会显著的提高索引性能。 
<p>3．最大合并文档数 
<p>这个参数决定了一个索引块中的最大的文档数。它的默认值是 Integer.MAX_VALUE，将这个参数设置为比较大的值可以提高索引效率和检索速度，由于该参数的默认值是整型的最大值，所以我们一般不需要改动这个参数。 
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="568">
<p>int mergeFactor = 10; 
<p>int minMergeDocs = 10; 
<p>int maxMergeDocs = Integer.MAX_VALUE; 
<p>IndexWriter indexWriter = new IndexWriter(indexDir,luceneAnalyzer,true); 
<p>indexWriter.mergeFactor = mergeFactor; 
<p>indexWriter.minMergeDocs = minMergeDocs; 
<p>indexWriter.maxMergeDocs = maxMergeDocs;</p></td></tr></tbody></table>
<p>下面我们来看一下这三个参数取不同的值对索引时间的影响，注意参数值的不同和索引之间的关系。我们为这个实验准备了 10000 个测试文档。表 1 显示了测试结果。 
<p><a name="N1012D"><b>表</b></a><b>1</b><b>：测试结果</b><br><a href="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_A83B/clip_image001_2.gif"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image001" border="0" alt="clip_image001" src="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Lucene_A83B/clip_image001_thumb.gif" width="506" height="203"></a> 
<p>通过表 1，你可以清楚地看到三个参数对索引时间的影响。在实践中，你会经常的改变合并因子和最小合并文档数的值来提高索引性能。只要你有足够大的内存，你可以为合并因子和最小合并文档数这两个参数赋尽量大的值以提高索引效率，另外我们一般无需更改最大合并文档数这个参数的值，因为系统已经默认将它设置成了最大。</p></blockquote><img src ="http://www.blogjava.net/hoojo/aggbug/387077.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hoojo/" target="_blank">hoojo</a> 2012-09-05 12:21 <a href="http://www.blogjava.net/hoojo/archive/2012/09/05/387077.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>处理 Oracle SQL in 超过1000 的解决方案</title><link>http://www.blogjava.net/hoojo/archive/2012/08/31/386692.html</link><dc:creator>hoojo</dc:creator><author>hoojo</author><pubDate>Fri, 31 Aug 2012 06:51:00 GMT</pubDate><guid>http://www.blogjava.net/hoojo/archive/2012/08/31/386692.html</guid><wfw:comment>http://www.blogjava.net/hoojo/comments/386692.html</wfw:comment><comments>http://www.blogjava.net/hoojo/archive/2012/08/31/386692.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hoojo/comments/commentRss/386692.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hoojo/services/trackbacks/386692.html</trackback:ping><description><![CDATA[<blockquote> <p>处理oracle sql 语句in子句中（where id in (1, 2, ..., 1000, 1001)），如果子句中超过1000项就会报错。<br>这主要是oracle考虑性能问题做的限制。如果要解决次问题，可以用 where id (1, 2, ..., 1000) or id (1001, ...)</p></blockquote> <div id="codeSnippetWrapper"> <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #008000">/**</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #008000"> * &lt;b&gt;function:&lt;/b&gt; 处理oracle sql 语句in子句中（where id in (1, 2, ..., 1000, 1001)），如果子句中超过1000项就会报错。</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #008000"> * 这主要是oracle考虑性能问题做的限制。如果要解决次问题，可以用 where id (1, 2, ..., 1000) or id (1001, ...)</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #008000"> * @author hoojo</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #008000"> * @createDate 2012-8-31 下午02:36:03</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #008000"> * @param ids in语句中的集合对象</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #008000"> * @param count in语句中出现的条件个数</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #008000"> * @param field in语句对应的数据库查询字段</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #008000"> * @return 返回 field in (...) or field in (...) 字符串</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #008000"> */</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">private</span> String getOracleSQLIn(List&lt;?&gt; ids, <span style="color: #0000ff">int</span> count, String field) {</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    count = Math.min(count, 1000);</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #0000ff">int</span> len = ids.size();</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #0000ff">int</span> size = len % count;</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #0000ff">if</span> (size == 0) {</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        size = len / count;</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    } <span style="color: #0000ff">else</span> {</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        size = (len / count) + 1;</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    }</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    StringBuilder builder = <span style="color: #0000ff">new</span> StringBuilder();</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #0000ff">for</span> (<span style="color: #0000ff">int</span> i = 0; i &lt; size; i++) {</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        <span style="color: #0000ff">int</span> fromIndex = i * count;</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        <span style="color: #0000ff">int</span> toIndex = Math.min(fromIndex + count, len);</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        <span style="color: #008000">//System.out.println(ids.subList(fromIndex, toIndex));</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        String productId = StringUtils.defaultIfEmpty(StringUtils.join(ids.subList(fromIndex, toIndex), <span style="color: #006080">"','"</span>), <span style="color: #006080">""</span>);</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        <span style="color: #0000ff">if</span> (i != 0) {</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">            builder.append(<span style="color: #006080">" or "</span>);</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        }</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        builder.append(field).append(<span style="color: #006080">" in ('"</span>).append(productId).append(<span style="color: #006080">"')"</span>);</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    }</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    </pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #0000ff">return</span> StringUtils.defaultIfEmpty(builder.toString(), field + <span style="color: #006080">" in ('')"</span>);</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">}</pre><!--CRLF--></div></div><img src ="http://www.blogjava.net/hoojo/aggbug/386692.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hoojo/" target="_blank">hoojo</a> 2012-08-31 14:51 <a href="http://www.blogjava.net/hoojo/archive/2012/08/31/386692.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JavaScript/jQuery、HTML、CSS 构建 Web IM 远程及时聊天通信程序</title><link>http://www.blogjava.net/hoojo/archive/2012/08/13/385360.html</link><dc:creator>hoojo</dc:creator><author>hoojo</author><pubDate>Mon, 13 Aug 2012 01:39:00 GMT</pubDate><guid>http://www.blogjava.net/hoojo/archive/2012/08/13/385360.html</guid><wfw:comment>http://www.blogjava.net/hoojo/comments/385360.html</wfw:comment><comments>http://www.blogjava.net/hoojo/archive/2012/08/13/385360.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hoojo/comments/commentRss/385360.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hoojo/services/trackbacks/385360.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 这篇文章主要介绍用JavaScript和jQuery、HTML、CSS以及用第三方聊天JavaScript（jsjac）框架构建一个BS Web的聊天应用程序。此程序可以和所有连接到Openfire服务器的应用进行通信、发送消息。如果要运行本程序还需要一个聊天服务器Openfire， 以及需要用到Http方式和Openfire通信的第三方库（JabberHTTPBind）。 JabberHTTPB...&nbsp;&nbsp;<a href='http://www.blogjava.net/hoojo/archive/2012/08/13/385360.html'>阅读全文</a><img src ="http://www.blogjava.net/hoojo/aggbug/385360.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hoojo/" target="_blank">hoojo</a> 2012-08-13 09:39 <a href="http://www.blogjava.net/hoojo/archive/2012/08/13/385360.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Apache MiNa 实现多人聊天室</title><link>http://www.blogjava.net/hoojo/archive/2012/08/01/384490.html</link><dc:creator>hoojo</dc:creator><author>hoojo</author><pubDate>Wed, 01 Aug 2012 02:23:00 GMT</pubDate><guid>http://www.blogjava.net/hoojo/archive/2012/08/01/384490.html</guid><wfw:comment>http://www.blogjava.net/hoojo/comments/384490.html</wfw:comment><comments>http://www.blogjava.net/hoojo/archive/2012/08/01/384490.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/hoojo/comments/commentRss/384490.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hoojo/services/trackbacks/384490.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 开发环境：  System：Windows  JavaSDK：1.6  IDE：eclipse、MyEclipse 6.6  开发依赖库：  Jdk1.4+、mina-core-2.0.4.jar、slf4j-api-1.5.11.jar、slf4j-log4j12-1.5.11.jar  Email：hoojo_@126.com  Blog：http://blog.csdn.net/IBM_ho...&nbsp;&nbsp;<a href='http://www.blogjava.net/hoojo/archive/2012/08/01/384490.html'>阅读全文</a><img src ="http://www.blogjava.net/hoojo/aggbug/384490.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hoojo/" target="_blank">hoojo</a> 2012-08-01 10:23 <a href="http://www.blogjava.net/hoojo/archive/2012/08/01/384490.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>移动应用（手机应用）开发IM聊天程序解决方案</title><link>http://www.blogjava.net/hoojo/archive/2012/07/31/384441.html</link><dc:creator>hoojo</dc:creator><author>hoojo</author><pubDate>Tue, 31 Jul 2012 07:16:00 GMT</pubDate><guid>http://www.blogjava.net/hoojo/archive/2012/07/31/384441.html</guid><wfw:comment>http://www.blogjava.net/hoojo/comments/384441.html</wfw:comment><comments>http://www.blogjava.net/hoojo/archive/2012/07/31/384441.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hoojo/comments/commentRss/384441.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hoojo/services/trackbacks/384441.html</trackback:ping><description><![CDATA[<p>这个解决方法已经定制下来很久了，上一段时间比较忙，没有时间整这些东西。最近稍微好些，不怎么加班。所以抽空总结下，同时也分享给大家，也算是给大家一个借鉴吧！或许这并不是最好的解决方案，但只要能满足当前需求的最好方案也算是最好的解决方案，谁说不是呢！O(&#8745;_&#8745;)O~</p> <p>&nbsp;</p> <p>我们采用的方案如下：</p> <blockquote> <p>先看图</p> <p><a href="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/IM_D61B/xmpp-server-client.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="xmpp-server-client" alt="xmpp-server-client" src="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/IM_D61B/xmpp-server-client_thumb.png" border="0" height="417" width="640" /></a></p></blockquote> <p>上图的流程大致上是这样的：  </p><blockquote> <p>手机端向PC端发送聊天内容  </p><p>1、手机端程序通过Socket连接服务器端的ServerSocket  </p><p>2、然后服务器端根据手机Mobile客户端发送过来统一规范的报文或聊天内容，进行解析  </p><p>3、然后将解析的内容，再用smack框架转发到openfire服务器  </p><p>4、最后由openfire服务器向客户端（BS、CS、PhoneClient）程序发送聊天信息。这里的客户端可以是pc上的浏览器，pc上的桌面应用，手机应用等  </p><p>5、PC客户端BS程序（用http bind方式监听）的长连接监听到openfire服务器发送过来的数据，直接在页面中显示</p></blockquote> <p>&nbsp; </p><blockquote> <p>同样，PC客户端向手机端发送聊天内容  </p><p>1、PC客户端（BS）可以直接用http bind（xmpp 提供的http请求的长连接方式）直接向openfire服务器发送聊天数据；  </p><p>2、然后openfire服务器接收到聊天内容的时候，这时候socket服务器中的smack框架中有一个聊天内容的监听器  </p><p>3、监听到PC端向openfire发送的内容后，会用socket的流向手机端发送我们定义好的报文或是聊天内容  </p><p>4、手机端的socket会不停的轮询（可以模拟心跳式长连接的方式），判断是否有消息到达，如果有则显示</p></blockquote> <p>&nbsp; </p><p>而普通的聊天程序的流程则是客户端发送信息到openfire服务器，openfire服务器再将消息转发给其他客户端。他们省去了socket服务器这部分，那我们为什么要加上socket服务器这部分呢？  </p><blockquote> <p>我们这样做也是有自己的道理的：  </p><p>首先，如果让手机端自己实现向openfire服务器发送程序的代码，那工作量是相当大的。因为每个手机平台使用的语言都不同，每个平台都需要实现向openfire服务器发送聊天信息的报文。这其实就是在做重复的工作，而且每个平台实现向手机端发送报文信息的技术会让每个手机端的开发人员都要学会一套和openfire交互的代码。这势必会重复工作、重复相同业务的代码。所以，把这些代码放在一个tcp/ip的socket中转服务器进行统一发送，这也是有好处的。  </p><p>其次，把所以发送消息在报文在socket服务器完成，可以对业务进行一个统一的处理、消息过滤。</p></blockquote> <p>&nbsp;</p> <p><strong><strike><font color="#ff0000" size="2">手机端被否决的解决方案，供参考</font></strike></strong></p> <blockquote> <p>手机端用http长连接的方式，这个是不行的</p> <p>其一、手机的移动网络不稳定，长连接会经常断掉，当然你可以自动进行重连</p> <p>其二、长连接一直连接在服务器上，占用服务器资源。当然你可以使用心跳式长连接或是轮询方式</p> <p>其三、手机端一直连接服务器会使用手机端用户的网络带宽流量（流量不是免费的，客户会怎么想）</p> <p>其四、手机端一直连着服务器，对手机的电量也有消耗（现在智能机解决电量也是一个问题）</p></blockquote><img src ="http://www.blogjava.net/hoojo/aggbug/384441.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hoojo/" target="_blank">hoojo</a> 2012-07-31 15:16 <a href="http://www.blogjava.net/hoojo/archive/2012/07/31/384441.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring整合CXF，发布RSETful 风格WebService</title><link>http://www.blogjava.net/hoojo/archive/2012/07/23/383780.html</link><dc:creator>hoojo</dc:creator><author>hoojo</author><pubDate>Mon, 23 Jul 2012 08:58:00 GMT</pubDate><guid>http://www.blogjava.net/hoojo/archive/2012/07/23/383780.html</guid><wfw:comment>http://www.blogjava.net/hoojo/comments/383780.html</wfw:comment><comments>http://www.blogjava.net/hoojo/archive/2012/07/23/383780.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hoojo/comments/commentRss/383780.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hoojo/services/trackbacks/383780.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 这篇文章是承接之前CXF整合Spring的这个项目示例的延伸，所以有很大一部分都是一样的。关于发布CXF WebServer和Spring整合CXF这里就不再多加赘述了。如果你对Spring整合CXF WebService不了解，具体你可以参看这两篇文章： http://www.cnblogs.com/hoojo/archive/2011/03/30/1999563.html http://www...&nbsp;&nbsp;<a href='http://www.blogjava.net/hoojo/archive/2012/07/23/383780.html'>阅读全文</a><img src ="http://www.blogjava.net/hoojo/aggbug/383780.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hoojo/" target="_blank">hoojo</a> 2012-07-23 16:58 <a href="http://www.blogjava.net/hoojo/archive/2012/07/23/383780.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>EhCache 分布式缓存/缓存集群</title><link>http://www.blogjava.net/hoojo/archive/2012/07/19/383518.html</link><dc:creator>hoojo</dc:creator><author>hoojo</author><pubDate>Thu, 19 Jul 2012 08:33:00 GMT</pubDate><guid>http://www.blogjava.net/hoojo/archive/2012/07/19/383518.html</guid><wfw:comment>http://www.blogjava.net/hoojo/comments/383518.html</wfw:comment><comments>http://www.blogjava.net/hoojo/archive/2012/07/19/383518.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hoojo/comments/commentRss/383518.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hoojo/services/trackbacks/383518.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 开发环境：  System：Windows  JavaEE Server：tomcat5.0.2.8、tomcat6  JavaSDK： jdk6+  IDE：eclipse、MyEclipse 6.6  &nbsp; 开发依赖库：  JDK6、 JavaEE5、ehcache-core-2.5.2.jar  Email：hoojo_@126.com  Blog：http://blog.csdn....&nbsp;&nbsp;<a href='http://www.blogjava.net/hoojo/archive/2012/07/19/383518.html'>阅读全文</a><img src ="http://www.blogjava.net/hoojo/aggbug/383518.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hoojo/" target="_blank">hoojo</a> 2012-07-19 16:33 <a href="http://www.blogjava.net/hoojo/archive/2012/07/19/383518.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring 3 整合Apache CXF WebService</title><link>http://www.blogjava.net/hoojo/archive/2012/07/13/383042.html</link><dc:creator>hoojo</dc:creator><author>hoojo</author><pubDate>Fri, 13 Jul 2012 09:47:00 GMT</pubDate><guid>http://www.blogjava.net/hoojo/archive/2012/07/13/383042.html</guid><wfw:comment>http://www.blogjava.net/hoojo/comments/383042.html</wfw:comment><comments>http://www.blogjava.net/hoojo/archive/2012/07/13/383042.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hoojo/comments/commentRss/383042.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hoojo/services/trackbacks/383042.html</trackback:ping><description><![CDATA[<p>在CXF2版本中，整合Spring3发布CXF WebService就更加简单了。因为Spring 3提供了annotation注解，而CXF2发布WebService已经不像之前版本的配置那样（参考老版本发布WebService系列文章：<a title="http://www.cnblogs.com/hoojo/archive/2011/03/30/1999563.html" href="http://www.cnblogs.com/hoojo/archive/2011/03/30/1999563.html">http://www.cnblogs.com/hoojo/archive/2011/03/30/1999563.html</a>），现在发布一个WebService可以直接从Spring的IoC容器中拿到一个对象，发布成WebService服务。当然发布WebService的配置有了些小小的变动，具体请往下看。</p> <p>&nbsp;</p> <p>在老版本中发布一个WebService，配置applicationContext-server.xml文件中添加如下配置如下：</p> <p>jaxws:server的发布方式</p> <div id="codeSnippetWrapper"> <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">&lt;</span><span style="color: #800000">bean</span> <span style="color: #ff0000">id</span><span style="color: #0000ff">="userServiceBean"</span> <span style="color: #ff0000">class</span><span style="color: #0000ff">="com.hoo.service.ComplexUserService"</span><span style="color: #0000ff">/&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">&nbsp;</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">&lt;</span><span style="color: #800000">bean</span> <span style="color: #ff0000">id</span><span style="color: #0000ff">="inMessageInterceptor"</span> <span style="color: #ff0000">class</span><span style="color: #0000ff">="com.hoo.interceptor.MessageInterceptor"</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #0000ff">&lt;</span><span style="color: #800000">constructor-arg</span>  <span style="color: #ff0000">value</span><span style="color: #0000ff">="receive"</span><span style="color: #0000ff">/&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">&lt;/</span><span style="color: #800000">bean</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">&nbsp;</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">&lt;</span><span style="color: #800000">bean</span> <span style="color: #ff0000">id</span><span style="color: #0000ff">="outLoggingInterceptor"</span> <span style="color: #ff0000">class</span><span style="color: #0000ff">="org.apache.cxf.interceptor.LoggingOutInterceptor"</span><span style="color: #0000ff">/&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #008000">&lt;!-- 注意下面的address，这里的address的名称就是访问的WebService的name --&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">&lt;</span><span style="color: #800000">jaxws:server</span> <span style="color: #ff0000">id</span><span style="color: #0000ff">="userService"</span> <span style="color: #ff0000">serviceClass</span><span style="color: #0000ff">="com.hoo.service.IComplexUserService"</span> <span style="color: #ff0000">address</span><span style="color: #0000ff">="/Users"</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #0000ff">&lt;</span><span style="color: #800000">jaxws:serviceBean</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        <span style="color: #008000">&lt;!-- 要暴露的 bean 的引用 --&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        <span style="color: #0000ff">&lt;</span><span style="color: #800000">ref</span> <span style="color: #ff0000">bean</span><span style="color: #0000ff">="userServiceBean"</span><span style="color: #0000ff">/&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #0000ff">&lt;/</span><span style="color: #800000">jaxws:serviceBean</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #0000ff">&lt;</span><span style="color: #800000">jaxws:inInterceptors</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        <span style="color: #0000ff">&lt;</span><span style="color: #800000">ref</span> <span style="color: #ff0000">bean</span><span style="color: #0000ff">="inMessageInterceptor"</span><span style="color: #0000ff">/&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #0000ff">&lt;/</span><span style="color: #800000">jaxws:inInterceptors</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #0000ff">&lt;</span><span style="color: #800000">jaxws:outInterceptors</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        <span style="color: #0000ff">&lt;</span><span style="color: #800000">ref</span> <span style="color: #ff0000">bean</span><span style="color: #0000ff">="outLoggingInterceptor"</span><span style="color: #0000ff">/&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #0000ff">&lt;/</span><span style="color: #800000">jaxws:outInterceptors</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">&lt;/</span><span style="color: #800000">jaxws:server</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--></div></div>
<p>jaxws:endpoint的发布方式</p>
<div id="codeSnippetWrapper">
<div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #008000">&lt;!-- com.hoo.service.ComplexUserService是com.hoo.service.IComplexUserService接口的实现， 这种方法应该不能从Ioc中引用对象 --&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">&lt;</span><span style="color: #800000">jaxws:endpoint</span> <span style="color: #ff0000">id</span><span style="color: #0000ff">="userService2"</span> <span style="color: #ff0000">implementor</span><span style="color: #0000ff">="com.hoo.service.ComplexUserService"</span> <span style="color: #ff0000">address</span><span style="color: #0000ff">="/Users"</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #0000ff">&lt;</span><span style="color: #800000">jaxws:inInterceptors</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        <span style="color: #0000ff">&lt;</span><span style="color: #800000">ref</span> <span style="color: #ff0000">bean</span><span style="color: #0000ff">="inMessageInterceptor"</span><span style="color: #0000ff">/&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #0000ff">&lt;/</span><span style="color: #800000">jaxws:inInterceptors</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #0000ff">&lt;</span><span style="color: #800000">jaxws:outInterceptors</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        <span style="color: #0000ff">&lt;</span><span style="color: #800000">ref</span> <span style="color: #ff0000">bean</span><span style="color: #0000ff">="outLoggingInterceptor"</span><span style="color: #0000ff">/&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #0000ff">&lt;/</span><span style="color: #800000">jaxws:outInterceptors</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">&lt;/</span><span style="color: #800000">jaxws:endpoint</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--></div></div>
<p>而在2.x新版本中，发布Ioc容器中的对象为一个WebService的方法</p>
<div id="codeSnippetWrapper">
<div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">&lt;</span><span style="color: #800000">bean</span> <span style="color: #ff0000">id</span><span style="color: #0000ff">="userServiceBean"</span> <span style="color: #ff0000">class</span><span style="color: #0000ff">="com.hoo.service.ComplexUserService"</span><span style="color: #0000ff">/&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">&nbsp;</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">&lt;</span><span style="color: #800000">bean</span> <span style="color: #ff0000">id</span><span style="color: #0000ff">="inMessageInterceptor"</span> <span style="color: #ff0000">class</span><span style="color: #0000ff">="com.hoo.interceptor.MessageInterceptor"</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #0000ff">&lt;</span><span style="color: #800000">constructor-arg</span>  <span style="color: #ff0000">value</span><span style="color: #0000ff">="receive"</span><span style="color: #0000ff">/&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">&lt;/</span><span style="color: #800000">bean</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">&nbsp;</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">&lt;</span><span style="color: #800000">bean</span> <span style="color: #ff0000">id</span><span style="color: #0000ff">="outLoggingInterceptor"</span> <span style="color: #ff0000">class</span><span style="color: #0000ff">="org.apache.cxf.interceptor.LoggingOutInterceptor"</span><span style="color: #0000ff">/&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #008000">&lt;!-- 注意下面的address，这里的address的名称就是访问的WebService的name；#userServiceBean是直接引用Ioc容器中的Bean对象 --&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">&lt;</span><span style="color: #800000">jaxws:server</span> <span style="color: #ff0000">id</span><span style="color: #0000ff">="userService"</span> <span style="color: #ff0000">serviceBean</span><span style="color: #0000ff">="#userServiceBean"</span> <span style="color: #ff0000">address</span><span style="color: #0000ff">="/Users"</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #0000ff">&lt;</span><span style="color: #800000">jaxws:inInterceptors</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        <span style="color: #0000ff">&lt;</span><span style="color: #800000">ref</span> <span style="color: #ff0000">bean</span><span style="color: #0000ff">="inMessageInterceptor"</span><span style="color: #0000ff">/&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #0000ff">&lt;/</span><span style="color: #800000">jaxws:inInterceptors</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #0000ff">&lt;</span><span style="color: #800000">jaxws:outInterceptors</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        <span style="color: #0000ff">&lt;</span><span style="color: #800000">ref</span> <span style="color: #ff0000">bean</span><span style="color: #0000ff">="outLoggingInterceptor"</span><span style="color: #0000ff">/&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #0000ff">&lt;/</span><span style="color: #800000">jaxws:outInterceptors</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">&lt;/</span><span style="color: #800000">jaxws:server</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #008000">&lt;!-- 或者这种方式，在老版本中这个是不能引用Ioc容器中的对象，但在2.x中可以直接用#id或#name的方式发布服务 --&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">&lt;</span><span style="color: #800000">jaxws:endpoint</span> <span style="color: #ff0000">id</span><span style="color: #0000ff">="userService2"</span> <span style="color: #ff0000">implementor</span><span style="color: #0000ff">="#userServiceBean"</span> <span style="color: #ff0000">address</span><span style="color: #0000ff">="/Users"</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #0000ff">&lt;</span><span style="color: #800000">jaxws:inInterceptors</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        <span style="color: #0000ff">&lt;</span><span style="color: #800000">ref</span> <span style="color: #ff0000">bean</span><span style="color: #0000ff">="inMessageInterceptor"</span><span style="color: #0000ff">/&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #0000ff">&lt;/</span><span style="color: #800000">jaxws:inInterceptors</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #0000ff">&lt;</span><span style="color: #800000">jaxws:outInterceptors</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        <span style="color: #0000ff">&lt;</span><span style="color: #800000">ref</span> <span style="color: #ff0000">bean</span><span style="color: #0000ff">="outLoggingInterceptor"</span><span style="color: #0000ff">/&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #0000ff">&lt;/</span><span style="color: #800000">jaxws:outInterceptors</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">&lt;/</span><span style="color: #800000">jaxws:endpoint</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--></div></div>
<p>CXF发布WebService官方参考：<a title="http://cxf.apache.org/docs/writing-a-service-with-spring.html" href="http://cxf.apache.org/docs/writing-a-service-with-spring.html">http://cxf.apache.org/docs/writing-a-service-with-spring.html</a></p><img src ="http://www.blogjava.net/hoojo/aggbug/383042.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hoojo/" target="_blank">hoojo</a> 2012-07-13 17:47 <a href="http://www.blogjava.net/hoojo/archive/2012/07/13/383042.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>XMPP/Smack/Openfire javax.net.ssl.SSLException: Received fatal alert: internal_error</title><link>http://www.blogjava.net/hoojo/archive/2012/07/12/382901.html</link><dc:creator>hoojo</dc:creator><author>hoojo</author><pubDate>Thu, 12 Jul 2012 08:49:00 GMT</pubDate><guid>http://www.blogjava.net/hoojo/archive/2012/07/12/382901.html</guid><wfw:comment>http://www.blogjava.net/hoojo/comments/382901.html</wfw:comment><comments>http://www.blogjava.net/hoojo/archive/2012/07/12/382901.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hoojo/comments/commentRss/382901.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hoojo/services/trackbacks/382901.html</trackback:ping><description><![CDATA[<p>在xmpp协议通信中，用smack框架登录非本地openfire服务器的时候，出现javax.net.ssl.SSLException: Received fatal alert: internal_error异常信息。原因是登录他网openfire服务器出现登录延时（在没有成功链接到openfire服务器），然后就进行登录login操作的时候，就会出现这个异常。</p> <p>&nbsp;</p> <p>解决办法</p> <blockquote> <p>1、在链接openfire服务器后，线程休眠一段时间，再进行登录login操作。</p> <p>……</p> <p>connection.connect();<br>Thread.sleep(3000);  <p>connection.login(user, pass);  <p>……  <p>&nbsp; <p>2、设置setPacketReplyTimeout参数  <p>......  <p>SmackConfiguration.setPacketReplyTimeout(PACKET_REPLY_TIMEOUT);<br>config = new ConnectionConfiguration(SERVER, PORT);  <p>......  <p>注意：如果设置了休眠时间或setPacketReplyTimeout参数后还是出现错误，请讲时间设置再大些看看</p></blockquote> <p>参考官方解答：<a title="http://community.igniterealtime.org/message/206443#206443" href="http://community.igniterealtime.org/message/206443#206443">http://community.igniterealtime.org/message/206443#206443</a></p><img src ="http://www.blogjava.net/hoojo/aggbug/382901.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hoojo/" target="_blank">hoojo</a> 2012-07-12 16:49 <a href="http://www.blogjava.net/hoojo/archive/2012/07/12/382901.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在Spring、Hibernate中使用Ehcache缓存</title><link>http://www.blogjava.net/hoojo/archive/2012/07/12/382860.html</link><dc:creator>hoojo</dc:creator><author>hoojo</author><pubDate>Thu, 12 Jul 2012 02:48:00 GMT</pubDate><guid>http://www.blogjava.net/hoojo/archive/2012/07/12/382860.html</guid><wfw:comment>http://www.blogjava.net/hoojo/comments/382860.html</wfw:comment><comments>http://www.blogjava.net/hoojo/archive/2012/07/12/382860.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hoojo/comments/commentRss/382860.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hoojo/services/trackbacks/382860.html</trackback:ping><description><![CDATA[<blockquote> <p>前一篇<a title="http://www.blogjava.net/hoojo/archive/2012/07/12/382852.html" href="http://www.blogjava.net/hoojo/archive/2012/07/12/382852.html">http://www.blogjava.net/hoojo/archive/2012/07/12/382852.html</a>介绍了Ehcache整合Spring缓存，使用页面、对象缓存；这里将介绍在Hibernate中使用查询缓存、一级缓存、二级缓存，整合Spring在HibernateTemplate中使用查询缓存。</p></blockquote> <blockquote> <p>EhCache是Hibernate的二级缓存技术之一，可以把查询出来的数据存储在内存或者磁盘，节省下次同样查询语句再次查询数据库，大幅减轻数据库压力；</p></blockquote> <p>EhCache的使用注意点  <blockquote> <p>当用Hibernate的方式修改表数据(save,update,delete等等)，这时EhCache会自动把缓存中关于此表的所有缓存全部删除掉(这样能达到同步)。但对于数据经常修改的表来说，可能就失去缓存的意义了(不能减轻数据库压力)；  <p>在比较少更新表数据的情况下，EhCache一般要使用在比较少执行write操作的表(包括update,insert,delete等)[Hibernate的二级缓存也都是这样]；对并发要求不是很严格的情况下，两台机子中的缓存是不能实时同步的；</p></blockquote> <p>&nbsp;</p> <p>首先要在hibernate.cfg.xml配置文件中添加配置，在hibernate.cfg.xml中的mapping标签上面加以下内容：</p> <div id="codeSnippetWrapper"> <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #008000">&lt;!--  Hibernate 3.3 and higher --&gt;</span>  </pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #008000">&lt;!--   </span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #008000">&lt;property name="hibernate.cache.region.factory_class"&gt;net.sf.ehcache.hibernate.EhCacheRegionFactory&lt;/property&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #008000">&lt;property name="hibernate.cache.region.factory_class"&gt;net.sf.ehcache.hibernate.SingletonEhCacheRegionFactory&lt;/property&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #008000">--&gt;</span>  </pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #008000">&lt;!-- hibernate3.0-3.2 cache config--&gt;</span>  </pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #008000">&lt;!--    </span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #008000">&lt;property name="hibernate.cache.region.factory_class"&gt;net.sf.ehcache.hibernate.EhCacheProvider&lt;/property&gt;  </span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #008000">--&gt;</span>  </pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">&lt;</span><span style="color: #800000">property</span> <span style="color: #ff0000">name</span><span style="color: #0000ff">="hibernate.cache.provider_class"</span><span style="color: #0000ff">&gt;</span>net.sf.ehcache.hibernate.SingletonEhCacheProvider<span style="color: #0000ff">&lt;/</span><span style="color: #800000">property</span><span style="color: #0000ff">&gt;</span>  </pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">           </pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #008000">&lt;!-- Enable Second-Level Cache and Query Cache Settings --&gt;</span>  </pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">&lt;</span><span style="color: #800000">property</span> <span style="color: #ff0000">name</span><span style="color: #0000ff">="hibernate.cache.use_second_level_cache"</span><span style="color: #0000ff">&gt;</span>true<span style="color: #0000ff">&lt;/</span><span style="color: #800000">property</span><span style="color: #0000ff">&gt;</span>  </pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">&lt;</span><span style="color: #800000">property</span> <span style="color: #ff0000">name</span><span style="color: #0000ff">="hibernate.cache.use_query_cache"</span><span style="color: #0000ff">&gt;</span>true<span style="color: #0000ff">&lt;/</span><span style="color: #800000">property</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--></div></div>
<p>&nbsp; <p>如果你是整合在spring配置文件中，那么你得配置你的applicationContext.xml中相关SessionFactory的配置 
<div id="codeSnippetWrapper">
<div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">&lt;</span><span style="color: #800000">prop</span> <span style="color: #ff0000">key</span><span style="color: #0000ff">="hibernate.cache.use_query_cache"</span><span style="color: #0000ff">&gt;</span>true<span style="color: #0000ff">&lt;/</span><span style="color: #800000">prop</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">&lt;</span><span style="color: #800000">prop</span> <span style="color: #ff0000">key</span><span style="color: #0000ff">="hibernate.cache.use_second_level_cache"</span><span style="color: #0000ff">&gt;</span>true<span style="color: #0000ff">&lt;/</span><span style="color: #800000">prop</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">&lt;</span><span style="color: #800000">prop</span> <span style="color: #ff0000">key</span><span style="color: #0000ff">="hibernate.cache.provider_class"</span><span style="color: #0000ff">&gt;</span>org.hibernate.cache.EhCacheProvider<span style="color: #0000ff">&lt;/</span><span style="color: #800000">prop</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--></div></div>
<p>&nbsp; <p>然后在hibernate.cfg.xml配置文件中加入使用缓存的属性 
<div id="codeSnippetWrapper">
<div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #008000">&lt;!-- class-cache config --&gt;</span>  </pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">&lt;</span><span style="color: #800000">class-cache</span> <span style="color: #ff0000">class</span><span style="color: #0000ff">="com.hoo.hibernate.entity.User"</span> <span style="color: #ff0000">usage</span><span style="color: #0000ff">="read-write"</span> <span style="color: #0000ff">/&gt;</span></pre><!--CRLF--></div></div>
<p>&nbsp; <p>当然你也可以在User.hbm.xml映射文件需要Cache的配置class节点下，加入类似如下格式信息： 
<div id="codeSnippetWrapper">
<div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">&lt;</span><span style="color: #800000">class</span> <span style="color: #ff0000">name</span><span style="color: #0000ff">="com.hoo.hibernate.entity.User"</span> <span style="color: #ff0000">table</span><span style="color: #0000ff">="USER"</span> <span style="color: #ff0000">lazy</span><span style="color: #0000ff">="false"</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">&lt;</span><span style="color: #800000">cache</span> <span style="color: #ff0000">usage</span><span style="color: #0000ff">="transactional|read-write|nonstrict-read-write|read-only"</span> <span style="color: #0000ff">/&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">注意：cache节点元素应紧跟class元素</pre><!--CRLF--></div></div>
<p>&nbsp; <p>关于选择缓存策略依据： 
<blockquote>
<p><strong>ehcache不支持transactional，其他三种可以支持。</strong> 
<p><strong>read- only</strong>：无需修改， 可以对其进行只读缓存，注意：在此策略下，如果直接修改数据库，即使能够看到前台显示效果，但是将对象修改至cache中会报error，cache不会发生作用。另：删除记录会报错，因为不能在read-only模式的对象从cache中删除。 
<p><strong>read-write</strong>：需要更新数据，那么使用读/写缓存比较合适，前提：<em>数据库不可以为serializable transaction isolation level（序列化事务隔离级别）</em> 
<p><strong>nonstrict-read-write</strong>：只偶尔需要更新数据（也就是说，两个事务同时更新同一记录的情况很不常见），也不需要十分严格的事务隔离，那么比较适合使用非严格读/写缓存策略。</p></blockquote>
<p>&nbsp;</p>
<p>如果你使用的注解方式，没有User.hbm.xml，那么你也可以用注解方式配置缓存</p>
<div id="codeSnippetWrapper">
<div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)   </pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> User <span style="color: #0000ff">implements</span> Serializable {</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">}</pre><!--CRLF--></div></div>
<p>&nbsp; <p>在Dao层使用cache，代码如下 
<div id="codeSnippetWrapper">
<div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">Session s = HibernateSessionFactory.getSession();</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">Criteria c = s.createCriteria(User.<span style="color: #0000ff">class</span>);</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">c.setCacheable(true);<span style="color: #008000">//这句必须要有</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">System.out.println(<span style="color: #006080">"第一次读取"</span>);</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">List&lt;User&gt; users = c.list();</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">System.out.println(users.size());</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">HibernateSessionFactory.closeSession();</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">&nbsp;</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">s = HibernateSessionFactory.getSession();</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">c = s.createCriteria(User.<span style="color: #0000ff">class</span>);</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">c.setCacheable(true);<span style="color: #008000">//这句必须要有</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">System.out.println(<span style="color: #006080">"第二次读取"</span>);</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">users = c.list();</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">System.out.println(users.size());</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">HibernateSessionFactory.closeSession();</pre><!--CRLF--></div></div>
<p>你会发现第二次查询没有打印sql语句，而是直接使用缓存中的对象。 
<p>如果你的Hibernate和Spring整合在一起，那么你可以用HibernateTemplate来设置cache 
<div id="codeSnippetWrapper">
<div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">getHibernateTemplate().setCacheQueries(true);</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">return</span> getHibernateTemplate().find(<span style="color: #006080">"from User"</span>);</pre><!--CRLF--></div></div>
<p>当你整合Spring时，如果你的HibernateTemplate模板配置在Spring的Ioc容器中，那么你可以这样启用query cache 
<div id="codeSnippetWrapper">
<div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">&lt;</span><span style="color: #800000">bean</span> <span style="color: #ff0000">id</span><span style="color: #0000ff">="hibernateTemplate"</span> <span style="color: #ff0000">class</span><span style="color: #0000ff">="org.springframework.orm.hibernate3.HibernateTemplate"</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #0000ff">&lt;</span><span style="color: #800000">property</span> <span style="color: #ff0000">name</span><span style="color: #0000ff">="sessionFactory"</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">       <span style="color: #0000ff">&lt;</span><span style="color: #800000">ref</span> <span style="color: #ff0000">bean</span><span style="color: #0000ff">="sessionFactory"</span> <span style="color: #0000ff">/&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #0000ff">&lt;/</span><span style="color: #800000">property</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #0000ff">&lt;</span><span style="color: #800000">property</span> <span style="color: #ff0000">name</span><span style="color: #0000ff">="cacheQueries"</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">       <span style="color: #0000ff">&lt;</span><span style="color: #800000">value</span><span style="color: #0000ff">&gt;</span>true<span style="color: #0000ff">&lt;/</span><span style="color: #800000">value</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #0000ff">&lt;/</span><span style="color: #800000">property</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">&lt;/</span><span style="color: #800000">bean</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--></div></div>
<p>此后，你在dao模块中注入sessionFactory的地方都注入hibernateTemplate即可。 
<p>&nbsp; <p>以上讲到的都是Spring和Hibernate的配置，下面主要结合上面使用的ehcache，来完成ehcache.xml的配置。如果你没有配置ehcache，默认情况下使用defaultCache的配置。 
<div id="codeSnippetWrapper">
<div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">&lt;</span><span style="color: #800000">cache</span> <span style="color: #ff0000">name</span><span style="color: #0000ff">="com.hoo.hibernate.entity.User"</span> <span style="color: #ff0000">maxElementsInMemory</span><span style="color: #0000ff">="10000"</span> <span style="color: #ff0000">eternal</span><span style="color: #0000ff">="false"</span> <span style="color: #ff0000">timeToIdleSeconds</span><span style="color: #0000ff">="300"</span> <span style="color: #ff0000">timeToLiveSeconds</span><span style="color: #0000ff">="600"</span> <span style="color: #ff0000">overflowToDisk</span><span style="color: #0000ff">="true"</span> <span style="color: #0000ff">/&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #008000">&lt;!--</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #008000">hbm文件查找cache方法名的策略：如果不指定hbm文件中的region="ehcache.xml中的name的属性值"，则使用name名为com.hoo.hibernate.entity.User的cache，如果不存在与类名匹配的cache名称，则用 defaultCache。</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #008000">如果User包含set集合，则需要另行指定其cache</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #008000">例如User包含citySet集合，则需要</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #008000">添加如下配置到ehcache.xml中</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #008000">--&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">&lt;</span><span style="color: #800000">cache</span> <span style="color: #ff0000">name</span><span style="color: #0000ff">="com.hoo.hibernate.entity.citySet"</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #ff0000">maxElementsInMemory</span><span style="color: #0000ff">="10000"</span> <span style="color: #ff0000">eternal</span><span style="color: #0000ff">="false"</span> <span style="color: #ff0000">timeToIdleSeconds</span><span style="color: #0000ff">="300"</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #ff0000">timeToLiveSeconds</span><span style="color: #0000ff">="600"</span> <span style="color: #ff0000">overflowToDisk</span><span style="color: #0000ff">="true"</span> <span style="color: #0000ff">/&gt;</span></pre><!--CRLF--></div></div>
<p>&nbsp; <p>如果你使用了Hibernate的查询缓存，需要在ehcache.xml中加入下面的配置 
<div id="codeSnippetWrapper">
<div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">&lt;</span><span style="color: #800000">cache</span> <span style="color: #ff0000">name</span><span style="color: #0000ff">="org.hibernate.cache.UpdateTimestampsCache"</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #ff0000">maxElementsInMemory</span><span style="color: #0000ff">="5000"</span> </pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #ff0000">eternal</span><span style="color: #0000ff">="true"</span> </pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #ff0000">overflowToDisk</span><span style="color: #0000ff">="true"</span> <span style="color: #0000ff">/&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">&lt;</span><span style="color: #800000">cache</span> <span style="color: #ff0000">name</span><span style="color: #0000ff">="org.hibernate.cache.StandardQueryCache"</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #ff0000">maxElementsInMemory</span><span style="color: #0000ff">="10000"</span> </pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #ff0000">eternal</span><span style="color: #0000ff">="false"</span> </pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #ff0000">timeToLiveSeconds</span><span style="color: #0000ff">="120"</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #ff0000">overflowToDisk</span><span style="color: #0000ff">="true"</span> <span style="color: #0000ff">/&gt;</span></pre><!--CRLF--></div></div>
<blockquote>
<p>调试时候使用log4j的<strong>log4j.logger.org.hibernate.cache=debug</strong>，更方便看到ehcache的操作过程，主要用于调试过程,实际应用发布时候，请注释掉，以免影响性能。</p></blockquote>
<blockquote>
<p>使用ehcache，打印sql语句是正常的，因为query cache设置为true将会创建两个缓存区域：一个用于保存查询结果集 (org.hibernate.cache.StandardQueryCache)； 另一个则用于保存最近查询的一系列表的时间戳(org.hibernate.cache.UpdateTimestampsCache)。请注意：在查询缓存中，它并不缓存结果集中所包含的实体的确切状态；它只缓存这些实体的标识符属性的值、以及各值类型的结果。<strong>需要将打印sql语句与最近的cache内 容相比较，将不同之处修改到cache中，所以查询缓存通常会和二级缓存一起使用。</strong></p></blockquote><img src ="http://www.blogjava.net/hoojo/aggbug/382860.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hoojo/" target="_blank">hoojo</a> 2012-07-12 10:48 <a href="http://www.blogjava.net/hoojo/archive/2012/07/12/382860.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Ehcache 整合Spring 使用页面、对象缓存</title><link>http://www.blogjava.net/hoojo/archive/2012/07/12/382852.html</link><dc:creator>hoojo</dc:creator><author>hoojo</author><pubDate>Thu, 12 Jul 2012 02:15:00 GMT</pubDate><guid>http://www.blogjava.net/hoojo/archive/2012/07/12/382852.html</guid><wfw:comment>http://www.blogjava.net/hoojo/comments/382852.html</wfw:comment><comments>http://www.blogjava.net/hoojo/archive/2012/07/12/382852.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hoojo/comments/commentRss/382852.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hoojo/services/trackbacks/382852.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Ehcache在很多项目中都出现过，用法也比较简单。一般的加些配置就可以了，而且Ehcache可以对页面、对象、数据进行缓存，同时支持集群/分布式缓存。如果整合Spring、Hibernate也非常的简单，Spring对Ehcache的支持也非常好。EHCache支持内存和磁盘的缓存，支持LRU、LFU和FIFO多种淘汰算法，支持分布式的Cache，可以作为Hibernate的缓存插件。同时它也能...&nbsp;&nbsp;<a href='http://www.blogjava.net/hoojo/archive/2012/07/12/382852.html'>阅读全文</a><img src ="http://www.blogjava.net/hoojo/aggbug/382852.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hoojo/" target="_blank">hoojo</a> 2012-07-12 10:15 <a href="http://www.blogjava.net/hoojo/archive/2012/07/12/382852.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Openfire 的安装和配置</title><link>http://www.blogjava.net/hoojo/archive/2012/05/17/378440.html</link><dc:creator>hoojo</dc:creator><author>hoojo</author><pubDate>Thu, 17 May 2012 12:03:00 GMT</pubDate><guid>http://www.blogjava.net/hoojo/archive/2012/05/17/378440.html</guid><wfw:comment>http://www.blogjava.net/hoojo/comments/378440.html</wfw:comment><comments>http://www.blogjava.net/hoojo/archive/2012/05/17/378440.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hoojo/comments/commentRss/378440.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hoojo/services/trackbacks/378440.html</trackback:ping><description><![CDATA[<p>1、 下载最新的openfire安装文件  <p>官方下载站点：<a href="http://www.igniterealtime.org/downloads/index.jsp#openfire">http://www.igniterealtime.org/downloads/index.jsp#openfire</a>  <p>下载地址：  <p>Exe：<a href="http://www.igniterealtime.org/downloads/download-landing.jsp?file=openfire/openfire_3_7_1.exe">http://www.igniterealtime.org/downloads/download-landing.jsp?file=openfire/openfire_3_7_1.exe</a>  <p>ZIP: <a href="http://www.igniterealtime.org/downloads/download-landing.jsp?file=openfire/openfire_3_7_1.zip">http://www.igniterealtime.org/downloads/download-landing.jsp?file=openfire/openfire_3_7_1.zip</a>  <p>我使用的是zip解压版的安装文件。  <p>其中openfire是服务器，下面还有一个spark，这个是一个XMPP协议通信聊天的CS的IM软件，它可以通过openfire进行聊天对话。  <p>&nbsp; <p>2、 下载完成后，如果你下载的是exe文件，执行你的安装文件，进行安装。这里我是zip的文件。解压后，复制openfire目录到C:\Program Files\目录下；一定要在C:\Program Files\目录下的；这样openfire就安装完成了。  <p>&nbsp; <p>3、 下面我们启动openfire服务器，并配置它。在C:\Program Files\openfire\bin目录下有一个电灯泡的openfire.exe文件，双击执行，启动完成后可以看到  <p><a href="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Openfire_1186E/image_2.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Openfire_1186E/image_thumb.png" width="360" height="271"></a>  <p>4、 点击Launch Admin按钮进入<a href="http://127.0.0.1:9090/setup/index.jsp">http://127.0.0.1:9090/setup/index.jsp</a>页面，配置openfire服务器  <p>&nbsp; <p>5、 选择语言 中文简体  <p><a href="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Openfire_1186E/image_4.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Openfire_1186E/image_thumb_1.png" width="289" height="348"></a>  <p>点击continue进入  <p>&nbsp; <p>6、 配置服务器域名  <p><a href="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Openfire_1186E/image_6.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Openfire_1186E/image_thumb_2.png" width="396" height="175"></a>  <p>如果你是本地访问，那么你可以不修改或是使用localhost、127.0.0.1的方式  <p>如果你用于外网或局域网访问，那么你的地址配置成外网或局域网地址  <p>&nbsp; <p>7、 选择数据库  <p><a href="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Openfire_1186E/image_8.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Openfire_1186E/image_thumb_3.png" width="273" height="183"></a>  <p>选择openfire自带的，当然你也可以选择你的数据库类型。如Oracle、SQLServer、MySQL等。如果openfire没有带jdbc的连接驱动，你需要添加连接数据库的jdbc驱动；驱动放在C:\Program Files\openfire\lib目录下  <p>&nbsp; <p>8、 选择特性配置，默认即可  <p><a href="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Openfire_1186E/image_10.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Openfire_1186E/image_thumb_4.png" width="351" height="202"></a>  <p>&nbsp; <p>9、 管理员邮件，可以跳过这步  <p><a href="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Openfire_1186E/image_12.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Openfire_1186E/image_thumb_5.png" width="385" height="188"></a>  <p>&nbsp; <p>10、 安装完成  <p><a href="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Openfire_1186E/image_14.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Openfire_1186E/image_thumb_6.png" width="192" height="146"></a>  <p>进入管理员控制台页面  <p>&nbsp; <p>11、 进入<a href="http://127.0.0.1:9090/login.jsp">http://127.0.0.1:9090/login.jsp</a>页面后，输入admin、密码admin登陆进入  <p><a href="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Openfire_1186E/image_16.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Openfire_1186E/image_thumb_7.png" width="244" height="93"></a>  <p>&nbsp; <p>12、 进入后可以看到  <p><a href="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Openfire_1186E/image_18.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Openfire_1186E/image_thumb_8.png" width="493" height="351"></a>  <p>服务器名称就是jwchat的连接地址；你可以使用Spark、jwchat链接这个地址进行IM通信聊天……  <p>至此，openfire的安装和配置已经完成。下一篇文章开始完成jwchat的安装和配置。  <p>如果你需要更换服务器名称ip，请看下一篇文章！  <img src ="http://www.blogjava.net/hoojo/aggbug/378440.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hoojo/" target="_blank">hoojo</a> 2012-05-17 20:03 <a href="http://www.blogjava.net/hoojo/archive/2012/05/17/378440.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java 利用SWFUpload多文件上传 session 为空失效，不能验证的问题</title><link>http://www.blogjava.net/hoojo/archive/2012/05/11/377897.html</link><dc:creator>hoojo</dc:creator><author>hoojo</author><pubDate>Fri, 11 May 2012 06:14:00 GMT</pubDate><guid>http://www.blogjava.net/hoojo/archive/2012/05/11/377897.html</guid><wfw:comment>http://www.blogjava.net/hoojo/comments/377897.html</wfw:comment><comments>http://www.blogjava.net/hoojo/archive/2012/05/11/377897.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hoojo/comments/commentRss/377897.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hoojo/services/trackbacks/377897.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp;&nbsp; 我们都知道普通的文件上传是通过表单进行文件上传的，还不能达到异步上传的目的。通过使用某些技术手段，比如jquery form.js可以达到异步上传的目的，但最重要的问题在于，它不能够进行多个文件的上传。如果你要上传多个文件，必须一个一个地上传，同时还要在界面上处理当上传完一个文件之后，下一个文件上传框的问题。<br>&nbsp;&nbsp;&nbsp; 现在我们有了一个更多的运行，即使用swfupload进行多文件异步上传。顾名思义，它是一个flash的上传工具，但在界面上的表现形式使它和普通的html元素一样，没有复杂的展现，就一个普通的上传框，即可达到想要目的。  <p>&nbsp;&nbsp;&nbsp; 关于swfupload的使用这里自不必多，这里主要介绍的是解决在java web开发过程中经常碰到的验证失败的问题。这是因为flash在上传的时候使用的是和浏览器不同的会话，flash的SWFUpload上传利用socket套接字进行通信，所以导致session和原来上一次的会话不同，导致session丢失。这样就导致服务器在验证时自然被认为是新会话，从而验证不能通过，导致上传不能成功了。<br>&nbsp;&nbsp;&nbsp; 解决问题的方法，就是让flash在上传文件的时候带上同在一个界面的session标识，这通常是修改其中的upload_url来达到我们的目的，修改如下所示：  <div id="codeSnippetWrapper"> <div id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"><pre style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none">upload_url: <span style="color: #006080">"/admin/infobuild/image/upload.action;jsessionid=${pageContext.session.id }"</span></pre><!--CRLF--></div></div>
<p></p>上面这句话，必须放到jsp界面上，因为里面使用到了JavaWeb的语法，当然这可以修改，通过将&lt;%=session.getId()%&gt; 或 ${pageContext.session.id } 放到特殊的js变量中，可以达到隐藏变量的目的。比如如下的代码： 
<div id="codeSnippetWrapper">
<div id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"><pre style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none">&lt;!-- 这句要房子jsp页面中的script脚本中，或是放在servlet的response.getWriter()流中的script脚本中；总之要在swfupload 的js引入之前执行 --&gt;</pre><!--CRLF--><pre style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none">window[<span style="color: #006080">"sessionId"</span>]=<span style="color: #006080">"${pageContext.session.id}"</span>; </pre><!--CRLF--><pre style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none">&lt;!-- 这句话就可以在引入的js中使用 --&gt;</pre><!--CRLF--><pre style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none">upload_url: Gtip.util.addContextPath(<span style="color: #006080">"/admin/infobuild/image/upload.action;jsessionId"</span>  + <span style="color: #006080">"="</span> + window[<span style="color: #006080">"sessionId"</span>]),</pre><!--CRLF--></div></div>
<p>以上方案是解决在jsp页面中解决的取值java的变量值；</p>
<p>如上代码的第一句放到jsp文件中，如jsp的公共include文件中。下面一句就放到js文件中，如引入的upload.js文件当中。<br>&nbsp;&nbsp;&nbsp; 但以上代码还存在一个问题，就是默认的sessionName问题。在tomcat或者其它j2ee容器，默认的sessionName也是 jsessionId。如果我们修改了sessionName如通过tomcat的server.xml修改session_cookie_name，这样默认的sessionName就是我们修改之后的了。解决此问题，需要再加一个参数设置才可，如下所示： 
<p>&nbsp;</p>
<div id="codeSnippetWrapper">
<div id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"><pre style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none">&lt;!-- 这三行放在include 导入的那个jsp的页面中 --&gt;</pre><!--CRLF--><pre style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none">window[<span style="color: #006080">"contextPath"</span>] = <span style="color: #006080">"${pageContext.request.contextPath}"</span>;</pre><!--CRLF--><pre style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none">window[<span style="color: #006080">"sessionId"</span>] = <span style="color: #006080">"${pageContext.session.id}"</span>;</pre><!--CRLF--><pre style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none">window[<span style="color: #006080">"sessionName"</span>] = <span style="color: #006080">"jsessionId"</span>;</pre><!--CRLF--><pre style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none">&nbsp;</pre><!--CRLF--><pre style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"><span style="color: #008000">// js中使用jsp中设置的window的变量值</span></pre><!--CRLF--><pre style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none">upload_url: addContextPath(<span style="color: #006080">"/admin/infobuild/image/upload.action;"</span> + window[<span style="color: #006080">"sessionName"</span>] + <span style="color: #006080">"="</span> + window[<span style="color: #006080">"sessionId"</span>])</pre><!--CRLF--></div></div>
<p></p>
<p>以上代码的前三行放到公共的include.jsp中，最后一行放到公共的upload.js中。这样即可满足最终要求了。<br>不过有一点不好的即是，在部署环境中时，如果部署环境修改了sessionName，则必须在此include.jsp中修改一个具体的sessionName才可。 
<p>转载请标明出处:<a href="http://www.iflym.com">i flym</a><br>本文地址:<a href="http://www.iflym.com/index.php/code/201108190001.html">http://www.iflym.com/index.php/code/201108190001.html</a></p><img src ="http://www.blogjava.net/hoojo/aggbug/377897.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hoojo/" target="_blank">hoojo</a> 2012-05-11 14:14 <a href="http://www.blogjava.net/hoojo/archive/2012/05/11/377897.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ExtJS Form扩展组件[ColorFiled, DateTimeFiled, IconCombo, MultiComboBox, DynamicTreeCombox]</title><link>http://www.blogjava.net/hoojo/archive/2012/02/27/370835.html</link><dc:creator>hoojo</dc:creator><author>hoojo</author><pubDate>Mon, 27 Feb 2012 05:56:00 GMT</pubDate><guid>http://www.blogjava.net/hoojo/archive/2012/02/27/370835.html</guid><wfw:comment>http://www.blogjava.net/hoojo/comments/370835.html</wfw:comment><comments>http://www.blogjava.net/hoojo/archive/2012/02/27/370835.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hoojo/comments/commentRss/370835.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hoojo/services/trackbacks/370835.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 支持Form颜色选择组件、日期时间选择组件、带图标的下拉列表、多选下来列表、动态下拉列表树等组件 开发环境： System：Windows WebBrowser：IE6+、Firefox3+ JavaEE Server：tomcat5.0.2.8、tomcat6 IDE：eclipse、MyEclipse 8 开发依赖库： JavaEE5、ext 2.2.2 Email：hoojo_@126.co...&nbsp;&nbsp;<a href='http://www.blogjava.net/hoojo/archive/2012/02/27/370835.html'>阅读全文</a><img src ="http://www.blogjava.net/hoojo/aggbug/370835.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hoojo/" target="_blank">hoojo</a> 2012-02-27 13:56 <a href="http://www.blogjava.net/hoojo/archive/2012/02/27/370835.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>NoSQL 之 Morphia 操作 MongoDB</title><link>http://www.blogjava.net/hoojo/archive/2012/02/17/370169.html</link><dc:creator>hoojo</dc:creator><author>hoojo</author><pubDate>Fri, 17 Feb 2012 02:34:00 GMT</pubDate><guid>http://www.blogjava.net/hoojo/archive/2012/02/17/370169.html</guid><wfw:comment>http://www.blogjava.net/hoojo/comments/370169.html</wfw:comment><comments>http://www.blogjava.net/hoojo/archive/2012/02/17/370169.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/hoojo/comments/commentRss/370169.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hoojo/services/trackbacks/370169.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp; 上两篇文章:http://www.cnblogs.com/hoojo/archive/2011/06/01/2066426.html  http://www.cnblogs.com/hoojo/archive/2011/06/02/2068665.html  介绍到了在MongoDB的控制台完成MongoDB的数据操作、以及通过Java MongoDB 的驱动完成在Java中对Mon...&nbsp;&nbsp;<a href='http://www.blogjava.net/hoojo/archive/2012/02/17/370169.html'>阅读全文</a><img src ="http://www.blogjava.net/hoojo/aggbug/370169.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hoojo/" target="_blank">hoojo</a> 2012-02-17 10:34 <a href="http://www.blogjava.net/hoojo/archive/2012/02/17/370169.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>分享文件一个上传工具类</title><link>http://www.blogjava.net/hoojo/archive/2012/02/10/369732.html</link><dc:creator>hoojo</dc:creator><author>hoojo</author><pubDate>Fri, 10 Feb 2012 06:04:00 GMT</pubDate><guid>http://www.blogjava.net/hoojo/archive/2012/02/10/369732.html</guid><wfw:comment>http://www.blogjava.net/hoojo/comments/369732.html</wfw:comment><comments>http://www.blogjava.net/hoojo/archive/2012/02/10/369732.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.blogjava.net/hoojo/comments/commentRss/369732.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hoojo/services/trackbacks/369732.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 最近在搭建一个项目，需要用到很多通用的工具类，自己也写了几个。现在分享一下，也方便自己以后使用。如果你觉得不错的话，也欢迎转载。blog http://blog.csdn.net/IBM_hoojohttp://hoojo.cnblogs.comhttp://hoojo.blogjava.netemail hoojo_@126.com  &nbsp; 文件上传状态枚举类：  package com...&nbsp;&nbsp;<a href='http://www.blogjava.net/hoojo/archive/2012/02/10/369732.html'>阅读全文</a><img src ="http://www.blogjava.net/hoojo/aggbug/369732.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hoojo/" target="_blank">hoojo</a> 2012-02-10 14:04 <a href="http://www.blogjava.net/hoojo/archive/2012/02/10/369732.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>缩放图片工具类，创建缩略图、伸缩图片比例</title><link>http://www.blogjava.net/hoojo/archive/2012/02/08/369590.html</link><dc:creator>hoojo</dc:creator><author>hoojo</author><pubDate>Wed, 08 Feb 2012 05:48:00 GMT</pubDate><guid>http://www.blogjava.net/hoojo/archive/2012/02/08/369590.html</guid><wfw:comment>http://www.blogjava.net/hoojo/comments/369590.html</wfw:comment><comments>http://www.blogjava.net/hoojo/archive/2012/02/08/369590.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hoojo/comments/commentRss/369590.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hoojo/services/trackbacks/369590.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 支持将Image的宽度、高度缩放到指定width、height，并保存在指定目录通过目标对象的大小和标准（指定）大小计算出图片缩小的比例可以设置图片缩放质量，并且可以根据指定的宽高缩放图片 源码：  package com.hoo.util;&nbsp;import java.awt.Image;import java.awt.image.BufferedImage;import java.io....&nbsp;&nbsp;<a href='http://www.blogjava.net/hoojo/archive/2012/02/08/369590.html'>阅读全文</a><img src ="http://www.blogjava.net/hoojo/aggbug/369590.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hoojo/" target="_blank">hoojo</a> 2012-02-08 13:48 <a href="http://www.blogjava.net/hoojo/archive/2012/02/08/369590.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts 笔记</title><link>http://www.blogjava.net/hoojo/archive/2012/01/29/368972.html</link><dc:creator>hoojo</dc:creator><author>hoojo</author><pubDate>Sun, 29 Jan 2012 08:48:00 GMT</pubDate><guid>http://www.blogjava.net/hoojo/archive/2012/01/29/368972.html</guid><wfw:comment>http://www.blogjava.net/hoojo/comments/368972.html</wfw:comment><comments>http://www.blogjava.net/hoojo/archive/2012/01/29/368972.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/hoojo/comments/commentRss/368972.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hoojo/services/trackbacks/368972.html</trackback:ping><description><![CDATA[<p><b>Struts </b><b>概述</b>  <blockquote> <p>随着MVC 模式的广泛使用，催生了MVC 框架的产生。在所有的MVC 框架中，出现最早，应用最广的就是Struts 框架。</p></blockquote> <p><b>Struts </b><b>的起源</b>  <blockquote> <p>Struts 是Apache 软件基金组织Jakarta 项目的一个子项目， Struts 的前身是CraigR. McClanahan 编写的JSP Model2 架构。  <p>Struts 在英文中是"支架、支撑"的意思，这表明了Struts 在Web 应用开发中的巨大作用，采用Struts 可以更好地遵循MVC 模式。此外， Struts 提供了一套完备的规范，以基础类库，可以充分利用JSP/Servlet 的优点，减轻程序员的工作量，具有很强的可扩展性。</p></blockquote> <p><b>Struts</b><b>优点</b>  <blockquote> <p>提高开发效率，减轻了程序员的工作量，降低了重复代码（降低代码冗余），文件不再臃肿。  <p>可以规范软件开发的行为。ActionForm为我们封装请求数据  <p>增加代码的扩展性、移植性  <p>提高代码的可重用性、可读性，无需多个Servlet多个方法  <p>Action转发页面只须配置跳转资源即可，无效全路径、硬编码。降低代码的耦合性</p></blockquote> <p><b>Struts </b><b>架构的工作原理</b>  <blockquote> <p><u>1. Model 部分</u>  <p>Struts 的Model 部分由ActionForm和JavaBean 组成。其中ActionForm用于封装用户请求参数，所有的用户请求参数由系统自动封装成ActionForm 对象:该对象被ActionServlet转发给Action; 然后Action 根据ActionForm里的请求参数处理用户请求。JavaBean 则封装了底层的业务逻辑，包括数据库访问等。在更复杂的应用中，JavaBean所代表的绝非一个简单的JavaBean，可能是EJB 组件或者其他的业务逻辑组件。该Model 对应图3 .4的Model 部分。  <p><u>2. View 部分</u>  <p>Struts 的View 部分采用JSP 实现。Struts 提供了丰富的标签库，通过这些标签库可以最大限度地减少脚本的使用。这些自定义的标签库可以实现与Model 的有效交互，并增加了显示功能。对应图的JSP 部分。  <p>整个应用由客户端请求驱动，当客户端请求被ActionServlet 拦截时， ActionServlet根据请求决定是否需要调用Model 处理用户请求，当用户请求处理完成后，其处理结果通过JSP 呈现给用户。  <p><u>3. Controller部分</u>  <p>Struts 的Controller 由两个部分组成。  <p>·系统核心控制器—拦截用户请求ActionServlet 派发请求  <p>·业务逻辑控制器—处理用户请求的Action，处理业务逻辑  <p>其中，系统核心控制器是一个ActionServlet。该控制器由Struts 框架提供，继承HttpServlet类，因此可以配置成一个标准的Servlet。该控制器负责拦截所有Http请求，然后根据用户请求决定是否需要调用业务逻辑控制器，如果需要调用业务逻辑控制器，则将请求转发给Action 处理，否则直接转向请求的JSP 页面。业务逻辑控制器负责处理用户请求，但业务逻辑控制器本身并不具有处理能力，而是调用Model 来完成处理。业务逻辑控制器对应图3 .4中的Action 部分。  <p><a href="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Struts_EB6B/clip_image002_2.jpg"><img title="clip_image002" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="297" alt="clip_image002" src="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/Struts_EB6B/clip_image002_thumb.jpg" width="558" border="0"></a>  <p><b>下面结合图3.7 </b><b>对Struts </b><b>的工作流程作详细的讲解。</b>  <p>Web 应用都是请求一响应的程序结构。程序是由客户端Client 发出Http 请求开始的，客户端请求被ActionServlet 拦截。在ActionServlet 处，有两种情况:  <p>·要求逻辑控制器处理的请求:  <p>·简单转发的请求。  <p>对于第一种的请求，ActionServlet 需要调用对应的Action。因此ActionServlet 将请求转发到Action ，如果请求还配置了对应的FormBean，则ActionServlet 还负责用请求参数填充ActionForm，此时如果ActionForm还没有创建。ActionServlet会帮我们创建一个可以用的ActionForm，如果ActionForm已经创建就直接给我们用， ActionForm 的实质就是JavaBean，专门用于封装请求参数。并且在次期间，如果ActionForm如果有验证方法，会去执行验证方法，如果验证通过会进入Action中。验证失败，会跳转到Action配置的input资源页面。  <p>此时的Action 将无须从HTTP Request 中获取请求参数，而是从ActionForm 中获得请求参数。Action 获得请求参数后，调用Model 对象由JavaBean 处理用户请求。Action处理完用户请求之后，将处理结果包装成ActionForward，回送给ActionServlet。  <p>由于ActionForward 对象封装了JSP 资源的映射。因此， ActionServlet 知道调用合适的JSP 资源表现给客户端。  <p>对于第二种请求， HTTP 请求无须Action 处理，只是对普通资源的请求，作为超级链接的替代。因为ActionServlet 直接将该请求转发给JSP 资源，既不会填充ActionForm，也无须调用Action 处理。  <p>JSP 页面在表现之前，还需要调用对应的JavaBean，此处的JavaBean 不再是包含业务逻辑的JavaBean，而是封装了处理结果的普通vo (值对象)。JSP 页面根据vo 的值，可能利用JSTL 或者Struts 的标签库来生成HTTP 响应给客户端。总之JSP 应尽量避免使用Java 脚本。</p></blockquote> <p><b>Action</b><b>配置</b>  <blockquote> <p>path是我们请求访问的路径，如果用struts标签，会默认加上.do的后缀。ActionServlet拦截到*.do的请求后，就进行相应的业务处理，然后派发到path对应的Action；  <p>name是Action对象的ActionForm，ActionForm是封装请求的信息，如表单  <p>attribute和name一样，可以省略，在省略的情况下用name。都是对应ActionForm  <p>type是Action对象对应的文件路径，含包名  <p>scope是ActionForm的作用域，默认request  <p>parameter后带方法名称，即请求所执行的方法  <p>forward是转发后的资源页面</p></blockquote> <p><b>ActionForward</b><b>配置</b>  <blockquote> <p>name逻辑名称和Action中的mapping.forward参数对应  <p>path对应映射的JSP页面  <p>redirect是否重定向请求  <p>forward有全局和局部的2种，如果当前Action配置的forward资源在当前配置的Action中没有找到，然后回到全局的forward资源中查找。局部优先全局</p></blockquote> <p><b>ActonForm</b><b>配置</b>  <blockquote> <p>name是form的名称  <p>type是form的包名+文件名  <p>ActionForm还有动态ActionForm、验证ActionForm</p></blockquote> <p><b>国际化I18N</b><b>（Internationalization</b><b>）</b>  <blockquote> <p>目的：是适应更多的、更好的用户界面  <p>Java 程序的国际化主要通过如下三个类完成。  <p>&nbsp;&nbsp; java.util. ResourceBundle: 对应用于加载一个资源包。  <p>&nbsp;&nbsp; java.util.Locale: 对应一个特定的国家/区域及语言环境。  <p>&nbsp;&nbsp; java.text.MessageFormat: 用于将消息格式化。  <p>为了实现程序的国际化，必须先提供程序所需要的资源文件。资源文件的内容是和很多key-value 对。其中key 是程序使用的部分，而value 则是程序界面的显示。  <p>资源文件的命名可以有如下三种形式。  <p>&nbsp;&nbsp; baseName _language_country.properties。  <p>&nbsp;&nbsp; baseName _language.properties。  <p>&nbsp;&nbsp; baseNarne.properties 。  <p>其中baseName 是资源文件的基本名，用户可以自由定义。而language 和count可都不可随意变化，必须是Java 所支持的语言和国家。  <p><u>1.国际化支持的语言和国家</u>  <p>事实上， Java 也不可能支持所有国家和语言，如需要获取Java 所支持的语言和国家，可调用Locale 类的getAvailableLocale 方法来获取。该方法返回一个Locale 数组，该数组里包含了Java 所支持的语言和国家。  <p><u>2. 编写国际化所需的资源</u>  <p>国际化所需的资源文件内容是key-value 对，下面提供了两个资源文件，这两个资源文件很简单，只包含一个key-value 对。  <p>下面是MyResource.properties 的文件的内容:  <p>资源文件的内容: key-value 对。  <p>msg=Hello , {O} Today is {1}.  <p>下面是MyResource_zh_CN.properties 文件的内容:  <p>资源文件的内容: key-value 对  <p>msg=你好. {O} 今天是{l}。  <p>所有资源文件的key 都是相同的，只是value 会随国家和语言的不同而变化。  <p><u><b>3.</b><b>程序从哪里获取资源呢?</b></u>  <p>在ResourceBundle 加载资源时按如下顺序搜索。  <p>搜索所有国家和语言都匹配的资源文件，例如，对于简体中文的环境，先搜索如下文件:  <p>MyResource_zh_CN.properties  <p>如果没有找到国家和语言都匹配的资源文件，则再搜索语言匹配的文件，即搜索如下文件:  <p>MyResource_zh.properties  <p>如果上面的文件依然无法搜索到，则搜索baseNarne 匹配的文件，即搜索如下文件:  <p>MyResource.properties  <p><u>4. 使用类文件代替资源文件</u>  <p>Java 也允许使用类文件代替资源文件，即将所有的key-value对存入class 文件，而不是属性文件。  <p>用来代替资源文件的Java 文件必须满足如下条件。  <p>·类的名字必须为baseNarne_language_country，这与属性文件的命名相似。  <p>·该类必须继承ListResourceBundle，并重写getContents 方法，该方法返回Object数组，该数组的每一个项都是key=value 对。  <p>eg:下面的类文件可以代替上面的属性文件:  <p>public class MyResource_zh_CN extends ListResourceBundle {  <p>&nbsp;&nbsp;&nbsp; // 定义资源  <p>&nbsp;&nbsp;&nbsp; private final Object myData[][] = { "msg" , " {0}您好!今天是{l} "};  <p>&nbsp;&nbsp;&nbsp; //重写方法getContents()  <p>&nbsp;&nbsp;&nbsp; public Object[] [] getContents() {  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //该方法返回资源的key-value对  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return myData;  <p>&nbsp;&nbsp;&nbsp; }  <p>}  <p>如果系统同时存在资源文件及类文件，则系统将以类文件为主，而不会调用资源文件。对于简体中文的Locale， ResourceBundle 搜索资源的顺序是:  <p>(1) baseName zh CN.class 。  <p>(2) baseNarne_zh_CN.properties。  <p>(3) baseNarne zh.class 。  <p>(4) baseNarne_zh.properties。  <p>(5) baseNarne.class。  <p>(6) baseNarne.properties。  <p>当系统按上面的顺序搜索资源文件时，如果前面的文件不存在，则会使用下一个:如果一直找不到对应的文件，系统将抛出异常。</p></blockquote> <p>struts加载资源文件  <blockquote> <p>资源文件的加载通过struts-config.xml文件来配置，加载资源文件应从Web 应用的WEB-INF/classes路径开始加载。因此，资源文件必须放在WEB-INF/classes路径或该路径的子路径下。如果直接放在WEB-INF/classes 路径下，在配置资源文件时，直接指定资源文件的baseName 即可。但如果放在子路径下，则必须以包的形式配置。</p></blockquote> <p><b>动态ActionForm</b>  <blockquote> <p><b>Why</b><b>？</b>当一个form表单的属性、字段非常多的情况下，需要我们不断的修改、添加ActionForm中的属性，并提供getter、setter方法。虽然这个类比较简单，但是大量重复的getter、setter方法也是比较繁琐的。这个时候struts的动态ActionForm就派上用场了。使用动态ActionForm 的目的是为了减少代码的书写量，但是相对在配置方面要复杂些。  <p><u>配置动态ActionForm</u>  <p>所有的动态ActionForm 的实现类都必须是org.apache.struts.action.DynaActionForm类，或者是它的子类。使用动态ActionForm 与前面不同的是:因为系统不清楚动态ActionForm 的属性，所以必须在配置文件中配置对应的属性。可以使用form-property 元素来配置动态ActionForm 的属性。  <p>&lt;!一配置动态ActionForm，动态Aciton 必须使用乌rnaActionForm 一〉  <p>&lt;form-bean name="loginForm" type="org.apache.struts.action.DynaActionForm"&gt;  <p>&nbsp;&nbsp;&nbsp;&nbsp; &lt;!一配置ActionForm的属性: username--&gt;  <p>&nbsp;&nbsp;&nbsp;&nbsp; &lt;form-property name="username" type="java.lang.String"/&gt;  <p>&nbsp;&nbsp;&nbsp;&nbsp; &lt;! 配置ActionForm的属性: pass--&gt;  <p>&nbsp;&nbsp;&nbsp;&nbsp; &lt;form-property name="pass"type="java.lang.String"/&gt;  <p>&lt;/form-bean&gt;  <p>&nbsp; <p>&lt;!-- 配置Action中的path ， type ， name 属性&gt;  <p>&lt;action path="/login" type="com.hoo.LoginAction" name="loginForm"&gt;  <p>&nbsp;&nbsp;&nbsp;&nbsp; &lt;!一配置两个局部Forward--&gt;  <p>&nbsp;&nbsp;&nbsp;&nbsp; &lt;forward name="welcome" path="/WEB-INF/jsp/welcome.jsp"/&gt;  <p>&nbsp;&nbsp;&nbsp;&nbsp; &lt;forward name="input" path="/login.jsp"/&gt;  <p>&lt;/action&gt;  <p>从上面的配置文件可看出，动态ActionForm 的配置必须增加form-property 元素，每个属性必须对应一个form-property元素。  <p>form-property元素包含两个属性。  <p>name: 属性的名字，必须与JSP 页面的表单域的名字相同。  <p>type: 属性的类型。  <p>&nbsp; <p><u>使用动态ActionForm</u>  <p>//必须重写该核心方法，该方法actionForm 将表单的请求参数封装成值对象  <p>public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {  <p>&nbsp;&nbsp;&nbsp;&nbsp; //将ActionForm强制类型转换为DynaActionForm  <p>&nbsp;&nbsp;&nbsp;&nbsp; DynaActionForm loginForm = (DynaActionForm)form;  <p>&nbsp;&nbsp;&nbsp;&nbsp; //从ActionForm中解析出请求参数: username  <p>&nbsp;&nbsp;&nbsp;&nbsp; String username = (String)loginForm.get("username");  <p>&nbsp;&nbsp;&nbsp;&nbsp; //从ActionForm中解析出请求参数: password  <p>&nbsp;&nbsp;&nbsp;&nbsp; String pass = (String)loginForm.get("pass");  <p>&nbsp;&nbsp;&nbsp;&nbsp; //后面的处理与前一个示例的Action 相同。  <p>&nbsp;&nbsp;&nbsp;&nbsp; …………  <p>}  <p>使用动态ActionForm 时，请求参数必须使用DynaActionForm的getter 方法获取。  <p>DynaActionForm 的getter 方法主要有如下三个。  <p>Object get(java.lang.String name): 根据属性名返回对应的值。  <p>Object get(java.lang.String name, int index): 对于有多个重名表单域的情况， Struts将其当成数组处理，此处根据表面域名和索引获取对应值。  <p>Object get(java.lang.String name, java.lang.String key): 对于使用Map 属性的情况，根据属性名及对应key. 获取对应的值。  <p>&nbsp;</p></blockquote> <p><b>Struts </b><b>的标签库</b>  <blockquote> <p>Struts 提供了大量的标签库，用于完成表现层的输出。借助于Struts 的标签库，可避免在JSP 中嵌入大量的Java 脚本，从而提高代码的可读性。  <p>Struts 主要提供了如下三个标签库。  <p>A、 html: 用于生成HTML 的基本标签。  <p>B、 bean: 用于完成程序国际化，输出Struts 的ActionForm 的属性值等。  <p>C、 logic: 用于完成循环、选择等流程控制。  <p>&nbsp; <p><u>使用html 标签库</u>  <p>Struts 为htrnl 的大部分标签提供了对应的htrnl 标签， htrnl 所支持的标签大致有如下。  <p>* base: 表现成一个HTML 的&lt;base&gt;标签。  <p>* button: 表现成一个按钮，该按钮默认没有任何动作。  <p>* cancel: 表现成一个取消按钮。  <p>* checkbox: 表现成一个Checkbox 的输入框。  <p>* error: 用于输出数据校验的出错提示。  <p>* file: 表现成一个文件浏览输入框。  <p>* form: 表现成一个form 域。  <p>* frame: 表现成一个HTML&lt;frame&gt;标签。  <p>* hidde: 表现成一个隐藏域。  <p>* htrnl: 表现成HTML 的&lt;htrnl&gt;标签。  <p>* image: 表现成表单域的image 域。  <p>* img: 表现成一个HTML 的img 标签。  <p>* javascrit: 表现成JavaScript 的校验代码，这些校验代码根据ValidatorPlugIn 生成。  <p>* link: 表现成HTML 的超级链接。  <p>* messages: 用于输出Struts 的各种提示信息，包括校验提示。  <p>* multibox: 表现成一个Checkbox 输入框。  <p>* option: 表现成选择框的一个选项。  <p>* password: 表现成一个密码输入框。  <p>* radio: 表现成一个单选输入框。  <p>* reset: 表现成一个重设按钮。  <p>* rewrite: 表现成一个URL 。  <p>* select: 表现成一个列表选择框。  <p>* submit: 表现成一个提交按钮。  <p>* text: 表现成一个单行文本输入框。  <p>* textarea: 表现成一个多行文本框。  <p>&nbsp; <p><u>使用bean 标签库</u>  <p>bean 标签库主要用于输出属性值、提示消息及定义请求参数等。下面是bean 标签库的常用标签。  <p>* cookie: 将请求的cookie 的值定义成脚本可以访问的JavaBean 实例。  <p>* define: 将某个bean 的属性值定义成脚本可以访问的变量。  <p>* header: 将请求头的值定义成脚本可以访问的变量。  <p>* include: 将某个JSP 资源完整定义成一个bean 实例。  <p>* message: 用于输出国际化信息。  <p>* page: 将page Context 中的特定项定义成一个bean 。  <p>* parameter: 将请求参数定义成脚本可以访问的变量。  <p>* resource: 加载Web 应用的资源，并将其变成JavaB eano  <p>* struts: 用于将某个Struts 的内部配置成一个bean 。  <p>* write: 用于输出某个bean 的属性值。  <p>&nbsp; <p><u>使用logic 标签库</u>  <p>logic 标签库是使用最频繁，相对复杂的标签库。logic 标签库主要用于完成基本的流程控制，比如循环及选择等。  <p>logic 标签库主要有如下标签。  <p>* empty: 如果给定的变量为空或者为空字符串，则就计算并输出标签体的内容。  <p>* equal: 如果给定变量与特定的值相等，则会计算并输出该标签体的内容。  <p>* forward: 将某个页面的控制权forward 确定的ActionForward 项。  <p>* greaterEqual: 如果给定变量大于或等于特定的值，则会计算并输出标签体的内容。  <p>* greaterThan: 如果给定变量大于特定的值，则会计算井输出标签体的内容。  <p>* iterate: 通过遍历给定集合的元素，对标签体的内容进行循环。  <p>* lessEqual: 如果给定变量小于或等于特定的值，则会计算并输出标签体的内容。  <p>* lessThan: 如果给定变量小于特定的值，则会计算并输出标签体的内容。  <p>* match: 如果特定字符串是给定消息合适的子字符串，则会计算并输出标签体的内容。  <p>* messagesNotPresent: 如果请求中不包含特定的消息内容，将计算并输出标签体的内容。  <p>* messagesPresent: 如果请求中包含特定的消息内容，则计算并输出标签体的内容。  <p>* notEmpty: 如果给定的变量既不为空，也不是空字符串，则计算并输出标签体的内容。  <p>* notEqual: 如果给定变量不等于特定的值，则会计算并输出标签体的内容。  <p>* notMatch: 如果特定宇符串不是给定消息合适的子字符串，则会计算并输出标签体的内容。  <p>* notPresent: 如果特定的值没有出现在请求中，则计算并输出标签体的内容。  <p>* present: 如果特定的值出现在请求中，则计算并输出标签体的内容。  <p>* redirect: 重定向页面。  <p>&nbsp;</p></blockquote> <p><b>Struts </b><b>的数据校验</b>  <blockquote> <p>数据校验也称为输入校验，指导对用户的输入进行基本过滤，包括必填宇段，宇段必须为数字及两次输入的密码必须相匹配等。这些是每个MVC 框架都应该完成的任务，Struts 提供了基本的数据校验，如果结合commons-validator， Struts 则拥有强大的校验框架，包括进行客户端的JavaScript 校验等。  <p>Struts 的数据校验大致有如下几种方式:  <p>ActionForm 的代码校验。  <p>Action 里的代码校验。  <p>结合commons-validator.jar 的校验。  <p>&nbsp; <p><u>ActionForm 的代码校验</u>  <p>ActionForm 的代码校验是最基本的校验方式。这种校验方式是重写ActionForm 的validate 方法，在该方法内对所有的宇段进行基本校验。如果出现不符合要求的输出，则将出错提示封装在ActionError 对象里，最后将多个ActionError 组合成ActionErrors 对象，该对象里封装了全部的出错提示。并将错误信息用&lt;html:error/&gt;展现在配置的input的失败页面上。  <p>&nbsp; <p><u>Action 的代码校验</u>  <p>在Action 里通过代码完成输入校验，是最基本，也最容易使用的方法。与最初的MVC 设计相似，在调用业务逻辑组件之前，先对数据进行基本校验。这是最传统也是最原始的方法。  <p>这种校验方式非常容易理解，所有的代码都需要程序员自己控制，相当灵活。  <p>但有如下几个不方便之处。  <p>·用户需要书写大量的校验代码，使程序变得烦琐。  <p>· 数据校验应该在填充ActionForm里完成，最好能在客户端完成校验，而不是推迟到Action 里才完成数据校验。  <p>注意:在实际的使用中，这种校验方式不仅程序开发复杂，且性能也不高。  <p>&nbsp; <p><u>结合commons-validator.jar 的校验</u>  <p>借助于commons-validator.jar 的支持， Struts的校验功能非常强大，几乎不需书写任何代码。不仅可以完成服务器端校验，同时还可完成客户端校验，即弹出Javascript 提示。  <p>使用commons-validator.jar 校验框架时，有如下几个通用配置。  <p>·增加校验资源。  <p>·利用ValidatorPlugIn 加载校验资源。  <p>·ActionForm 使用ValidatorForm 的于类。  <p>下面分别通过三个示例讲解这三种校验:基本的校验、对动态ActionForm 执行校验及弹出JavaScript 校验提示。  <p>&nbsp; <p><u>1. 继承ValidatorForm 的校验</u>  <p>如果需要使用commons-validator 框架，请按如下步骤进行。  <p>(1) Struts 的ActionForm必须是ValidatorForm的子类，提供验证属性字段的getter、setter方法  <p>(2) 编写表单域时必须满足校验规则。校验规则都由规则文件控制，规则文件有以下两个。  <p>* validator-rules.xml 文件  <p>* validation.xml 文件  <p>第一个文件可在Struts 的解压缩后的文件夹的lib 下找到，将该文件复制到WEB-INF  <p><u>2. common-validator支持的校验规则</u>  <p>common-validator支持的校验规则非常丰富，特别是mask 和validwhen 两个规则，  <p>极大地丰富了该校验框架的功能。  <p>常用的校验规则有如下几种。  <p>* required: 必填。  <p>* va1idwhen: 必须满足某个有效条件。  <p>* minlength: 输入必须大于最小长度。  <p>* maxlength: 输入必须小于最大长度。  <p>* mask: 输入匹配正确的表达式。  <p>* byte: 输入只能是一个byte 类型变量。  <p>* short: 输入只能是一个short 类型变量。  <p>* integer: 输入只能是一个integer 变量。  <p>* long: 输入只能是一个long 变量。  <p>* float: 输入只能是一个float 变量。  <p>* double: 输入只能是一个double 变量。  <p>* date: 输入必须是一个日期。  <p>* intRange: 输入的数字必须在整数范围内。  <p>* floatRange: 输入的数字必须在单精度浮点数范围内。  <p>* doubleRange: 输入的数字必须在双精度浮点数范围内。  <p>* email: 输入必须是有效的E-mail 地址。  <p>* uri: 输入必须是有效的uri 地址。  <p><u>3.使用DynaValidatorForm 的校验</u>  <p>即使不书写ActionForm，也可以利用cornmon-validator 校验框架。此时使用的ActionForm 的实现类，必须既是动态Form ，也是验证Form，DynaValidatorForm 就是满足这两个条件的Form。  <p><u>4. 弹出客户端JavaScript提示</u>  <p>如需要弹出客户端JavaScript 校验非常简单，无须修改其他配置文件，只需修改登录使用的JSP 页面的两个地方。  <p>(1) 为form 元素增加onsubmit="return validateXxxForm(this);"属性，其中的XxxForm就是需要校验的form 名，与struts-config.xrnl中配置的form-bean 的name 属性一致，也与validation.xrnl文件中需要校验的form 的name 属性一致。  <p>(2) 增加&lt;html:javascript formName="xxxForm"/&gt; ，其中xxxForm 是需要校验的form 名。  <p>注意:即使使用了客户端技验规则，也不要删除页面的htm1 :rnessages 标签。因为该标签会在客户端技验通过，而在服务器端技验并未通过时弹出提示。  <p>&nbsp;</p></blockquote> <p><b>Struts </b><b>的异常框架</b>  <blockquote> <p>Struts 1.1 版本中加入了对异常的处理，称之为Exception Handling，标志着作为一个整体的框架， Struts 越来越趋于成熟。  <p>在以前的Struts 开发过程中，对于异常的处理，主要是采用手动处理的方式:如通过try/catch 等捕获异常:然后将定制个性化的，比较详细的错误信息放进ActionMessage中:最后在返回页面中把这些错误信息反馈给用户。  <p>对于异常的原始信息，不管是最终用户还是开发员都不希望看到。  <p>借助于Struts 的异常框架，异常处理只需通过struts-config.xm1文件定义即可。根据异常定义的位置不同，异常可分为局部异常和全局异常两种。  <p>·局部异常作为action 的子元素中定义。  <p>·全局异常在globa1-excetpions 元素中定义。  <p>异常定义的格式如下:  <p>&lt;exception key="keyNarne" type="ExceptionNarne" scope="scope" path="uri"/&gt;: 当Struts 出现ExceptionNarne 的异常时，页面自动转向uri 指向的资源，并在该页面输出keyName 对应的国际化中的出错提示。</p></blockquote> <p><b>几种常用的Action</b>  <blockquote> <p>除了基本的Action 之外， Struts 还提供了几个其他类型的Action ，这些Action 大大丰富了Struts 的功能。下面介绍如下儿个常用的Action 。  <p>* DispatchAction: 能同时完成多个Action 功能的Action 。  <p>* ForwardActon: 该类用来整合Struts 和其他业务逻辑组件，通常只对请求作有效性检查。  <p>* IncludeAction: 用于引入其他的资源和页面。  <p>* LookupDispatchAction: DispatchAction 的子类，根据按钮的key ，控制转发给action的方法。  <p>* MappingDispatchAction: DispatchAction 的子类，一个action 可映射出多个Action地址。  <p>* SwitchAction: 用于从一个模块转换至另一个模块，如果应用分成多个模块时，就可以使用SwitchAction 完成模块之间的切换。  <p><u></u>&nbsp; <p><u>DispatchAction</u>  <p>在该action 的配置中，增加了parameter属性，该属性用于指定参数名，即Struts 将根据该参数的值调用对应的方法。为了让请求增加method 的参数，method参数对应的是要请求执行的方法。  <p>&lt;action path="/login" type="com.hoo.LoginAction" name="loginForm" scope="request" validate="true" input="login.jsp" parameter="method"&gt;  <p>&nbsp;&nbsp;&nbsp;&nbsp; &lt;forward name="success" path="/welcome.jsp"/&gt;  <p>&lt;/action&gt;  <p>Login.do?method=login  <p>&nbsp; <p><u>MappingDispatchAction</u>  <p>可将同一个Action 的不同方法映射成多个Action URI ，这种Action 的写法与DispatchAction 非常相似，同样不需要重写execute 方法，而是将书写多个自定义的方法。这些方法除了方法名与execute 方法不同外，其他的参数列表及异常处理完全一样。  <p>&lt;!-- 配置第一个Action. 实现类是com.hoo.LoginAction , parameter 为add--&gt;  <p>&lt;action path="/add" type="com.hoo.LoginAction" name="loginForm" scope="request" validate="true" input="login.jsp" parameter="add"&gt;  <p>&nbsp;&nbsp;&nbsp;&nbsp; &lt;forward name="success" path="/welcome.jsp"/&gt;  <p>&lt;/action&gt;  <p>&lt;! 配置第二个Action. 实现类是com.hoo.LoginAction , parameter 为modify--&gt;  <p>&lt;action path="/modify" type="com.hoo.LoginAction" name="loginForm" scope="request" validate="true" input="login.jsp" parameter="modify"&gt;  <p>&nbsp;&nbsp;&nbsp;&nbsp; &lt;forward name="success" path="/welcome.jsp"/&gt;  <p>&lt;/action&gt;  <p>其中，path对应的是请求的地址uri，而parameter是对于当前请求所执行的方法;  <p>注意:使用MappingDispatchAction 并没有带来太大的优势，系统完全可以书写两个Action，分别定义两个不同的action 映射，而其他部分没有区别。  <p><u>LookupDispatchAction</u>  <p>LookupDispatchAction也是DispatchAction 的一种，但它的处理更加简单。该Action也可包含多个处理方法，它可让处理方法与按钮直接关联，无须使用任何的JavaScript脚本。因此可通过重写getKeyMethodMap方法完成按钮与Action 中方法的关联。  <p>//用于关联按钮和方法  <p>protected Map getKeyMethodMap() {  <p>&nbsp;&nbsp;&nbsp;&nbsp; Map map = new HashMap();  <p>&nbsp;&nbsp;&nbsp;&nbsp; //如果按钮标题的key 为button.add. 则提交该按钮时对应add 方法  <p>&nbsp;&nbsp;&nbsp;&nbsp; map .put ("button. add" , "add");  <p>&nbsp;&nbsp;&nbsp;&nbsp; //如果按钮标题的key 为button.modify. 则提交该按钮时对应modify 方法  <p>&nbsp;&nbsp;&nbsp;&nbsp; map.put ("button.modify" , "modify") ;  <p>&nbsp;&nbsp;&nbsp;&nbsp; return map;  <p>}  <p>&nbsp; <p><u>ForwardAction</u>  <p>如果需要从一个页面或资源转换到另一个资源时，直接使用页面或资源路径的超级链接定位并不是好的做法，这使得控制器没有机会处理相关的请求事直。  <p>使用ForwardAction可以完成请求的转发，当控制器调用ForwardAction的perform()方法时，它会使用属性parameter 所设定的路径进行forward 的动作。下面是一个设定ForwardAction的例子:  <p>&lt;actlon-mapplngs&gt;  <p>&nbsp;&nbsp;&nbsp;&nbsp; &lt;action path="/welcome" type="org.apache.struts.actions.ForwardAction" parameter="/welcome.jsp"/&gt;  <p>&lt;/action-mappings&gt;  <p>该action 仅仅完成转发，并没有执行其他的额外动作。页面控制转发的代码如下:  <p>&lt;a href="welcome.do"&gt;转入&lt;/a&gt;  <p>当单击转入超级链接时，将可以转向ForwardAction中parameter指向的资源。  <p>&nbsp; <p><u>IncludeAction</u>  <p>IncludeAction的用法与ForwardAction的用法比较相似，区别在于ForwardAction将跳转到action 定义的资源，而IncludeAction用于引入该action 对应的资源。  <p>下面是IncludeAction定义的源代码:  <p>&lt;action-mapplngs&gt;  <p>&nbsp;&nbsp;&nbsp;&nbsp; &lt;action path="/welcome" type="org.apache. struts.actions.IncludeAction" parameter="/welcome.jsp"/&gt;  <p>&lt;/action-mappings&gt;  <p>该action 用于经welcome.jsp 作为资源导入。  <p>页面中负责加载该action 所导入资源的代码如下:  <p>&lt;jsp:include page="welcome.do"/&gt;&lt;br&gt;  <p>上面的代码将会把welcome action 定义的资源导入该页面。  <p><u></u>&nbsp; <p><u>SwitchAction</u>  <p>SwitchAction 主要用于模块之间的切换。当一个应用之中存在多个模块时，使用SwitchAction在不同模块之间的action 之间切换还是相当方便的。  <p>&nbsp;</p></blockquote> <p><b>Struts </b><b>的常见扩展方法</b>  <blockquote> <p>Struts 的强大吸引力还来自于它的可扩展性，其扩展性通常有如下三种方式。  <p>·实现PlugIn: 如果需要在应用启动或关闭时完成某些操作，可以创建自己的PlugIn类。  <p>·继承RequestProcessor: 如果想在请求被处理中的某个时刻做一些业务逻辑时，可以考虑实现自己的RequestProcessor 类。  <p>·继承ActionServlet: 如果需要在每次开始处理请求之前，或者处理请求结束之后完成某些操作，可以实现自己的ActionServlet 来完成扩展。  <p>&nbsp; <p>下面分别从三个方面来介绍Struts 的扩展。  <p><u><strong>实现PlugIn 接口</strong></u>  <p>Struts 已经演示了PlugIn 的扩展方法:与common- validation 的整合。后面还将介绍Spring 与Struts 的整合，也利用了PlugIn 的扩展。  <p>在下面的应用中，系统使用Hibernate 作为持久层，在启动时创建SessionFactory 实例，并将该SessionFactory 存入application ，在应用关闭时销毁SessionFactory 。只需如下两步即可完成此功能。  <p><strike>(1) 实现自己的PlugIn 类。</strike>  <p>&nbsp;&nbsp;&nbsp;&nbsp; 实现PlugIn 接口必须实现如下两个方法。  <p>&nbsp;&nbsp;&nbsp;&nbsp; 1 void destroy()。  <p>&nbsp;&nbsp;&nbsp;&nbsp; 2 void init(ActionServlet serlet， ModuleConfig config) 。  <p>&nbsp;&nbsp;&nbsp;&nbsp; 应用启动时调用init 方法，而应用关闭时则调用destroy 方法。  <p>&nbsp;&nbsp;&nbsp;&nbsp; 下面是SessionFactoryLoaderPlugIn 的实现类:  <p>&nbsp;&nbsp;&nbsp;&nbsp; public class SessionFactoryLoaderPlugin implements PlugIn {  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //Hibernate 的配置文件  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private String configFile;  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //应用关闭时，销毁资源  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void destroy()  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("系统销毁SessionFactory");  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //应用启动时，完成SessionFactory 的初始化  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void init(ActionServlet actionServlet , ModuleConfig config) throws ServletException  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("系统以" + getConfigFile() + "为配置文件初始化SessionFactory") ;  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //获取Plugln 配置文件的方法  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public String getConfigFile() {  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return configFile;  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 负责加载Plugln 配置属性的方法  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void setConfigFile(String configFile) {  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.configFile = configFile;  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  <p>&nbsp;&nbsp;&nbsp;&nbsp; }  <p>在上面的PlugIn 中，并没有真正初始化SessionFactory ，仅在控制台打印出字符串来标识创建动作。另外，还提供了configFile 属性的setter 和getter 方法，这两个方法负责访问plugin 元素的configFile 属性。  <p>&nbsp; <p><strike>( 2 ) 将SessionFactoryLoaderPlugIn 配置在struts-config.xml 文件中。方法与ValidatorPlugIn 的配置并没有区别，下面是配置SessionFactoryLoaderPlugIn 的代码:</strike>  <p>&lt;plug-in className="hoo.SessionFactoryLoaderPluging"&gt;  <p>&nbsp;&nbsp;&nbsp;&nbsp; &lt;set-property property="conf工gFile" value=" WEB-INF/hibernate.cfg.xml"I&gt;  <p>&lt;/plug-in&gt;  <p>在配置SessionFactoryLoaderPlugIn 时，配置了configFile 属性，该属性用于确定Hibernate 配置文件的文件名。  <p>&nbsp; <p><u><strong>继承RequestProcessor</strong></u>  <p>RequestProcessor 是Struts 的核心类，而Struts 的核心控制器是ActionServlet 。但ActionServlet 并未完成真正的处理，只是调用RequestProcessor ， RequestProcessor 才是Struts 的核心类。  <p>扩展RequestProcessor 的实例在Spring 中有个示范， Spring 提供的Delegating RequestProcessor 是一个很好的示例。下面示例对RequestProcessor 进行简单的扩展。  <p>RequestProcessor 包含了如下常见的方法。  <p>* ActionForm processActionForm: RequestProcessor填充ActionForm 时执行该方法。  <p>* Action processActionCreate: RequestProcessor 调用Action 时调用该方法。  <p>* boolean processPreprocess: 预处理用户请求时执行该方法。  <p>* boolean processValidate: 处理输入校验时调用该方法。  <p>扩展RequestProcessor 只需两步即可。  <p>(2)在struts-config.xml 文件中配置MyRequestProcessor。用户重写了RequestProcessor，但Struts 并不知道，必须在struts-config且nl 中配置才可以。  <p>下面是配置MyRequestProcessor 的代码:  <p>&lt;controller processorClass="lee.MyRequestProcessor" /&gt;  <p>该属性的配置应该放在action-mappings元素之后。  <p>注意:重写RequestProccessor的方法时，别忘了使用super 来调用父类的动作。如果没有调用该方法，意味着开发者必须完成Struts 框架所完成的动作。这是不应该的，因为程序员只是在框架中加入额外的处理，并不是要替代Struts。  <p>&nbsp; <p><strike><strong>继承ActionServlet</strong></strike>  <p>如果需要在开始处理请求，或者处理结束之后加入自己的处理时，可对ActionServlet进行扩展。例如解决中文的编码问题。  <p>ActionServlet 接收处理请求参数时，并不是按GBK 的解码方式处理请求，因此容易形成乱码。为了解决该问题，可以强制指定ActionServlet 使用GBK 的解码方式。  <p>继承ActionServlet重写process方法，设置request、response编码为gbk，然后配置在web.xml中。</p></blockquote><img src ="http://www.blogjava.net/hoojo/aggbug/368972.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hoojo/" target="_blank">hoojo</a> 2012-01-29 16:48 <a href="http://www.blogjava.net/hoojo/archive/2012/01/29/368972.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Servlet 手记</title><link>http://www.blogjava.net/hoojo/archive/2012/01/29/368965.html</link><dc:creator>hoojo</dc:creator><author>hoojo</author><pubDate>Sun, 29 Jan 2012 07:50:00 GMT</pubDate><guid>http://www.blogjava.net/hoojo/archive/2012/01/29/368965.html</guid><wfw:comment>http://www.blogjava.net/hoojo/comments/368965.html</wfw:comment><comments>http://www.blogjava.net/hoojo/archive/2012/01/29/368965.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.blogjava.net/hoojo/comments/commentRss/368965.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hoojo/services/trackbacks/368965.html</trackback:ping><description><![CDATA[<blockquote> <p>Servlet 是一种比JSP 更早的动态网页编程技术。在没有JSP 之前， Servlet 也是同时充当视图层、业务逻辑层及持久层角色。  <p>Servlet 的开发效率非常低，特别是当使用Servlet 生成表现层页面时，页面中所有的HTML 标签，都需采用Servlet 的输出流来输出，因此极其烦琐。由于Servlet 是个标准的Java 类，因此必须由程序员开发，其修改难度大，美工人员根本无法参与Servlet 页面的开发。这一系列的问题，都阻碍了Servlet 作为表现层的使用。  <p>自MVC 规范出现后， Servlet 的责任开始明确下来，仅仅作为控制器使用，不再需要生成页面标签，也不再作为视图层角色使用。  <p>&nbsp;</p></blockquote> <blockquote> <p>Servlet ，通常称为服务器端小程序，是运行在服务器端的程序，用于处理及响应客户端请求。  <p>Servlet 是个特殊的Java 类，这个Java 类必须继承HttpServlet 。每个Servlet 可以响应户端的请求。Servlet 提供不同的方法用于响应客户端请求。  <p>doGet: 用于响应客户端的get 请求。  <p>doPost: 用于响应客户端的post 请求。  <p>doPut: 用于响应客户端的put 请求。  <p>doDelete: 用于响应客户端的delete 请求。  <p>事实上，客户端的请求通常只有get 和post 两种; Servlet 为了响应这两种请求，必须重写doGet 和doPost 两个方法。如果Servlet 为了响应四个方法，则需要同时重写上面的四个方法。  <p>&nbsp;</p></blockquote> <blockquote> <p>大部分时候， Servlet 对于所有请求的响应都是完全一样的。此时，可以采用重写一个方法来代替上面的几个方法， Servlet 只需重写service 方法即可响应客户端的所有请求。另外， HttpServlet 还包含两个方法。  <p>init(ServletConfig config): 创建Servlet 实例时，调用的初始化方法。  <p>destroy: 销毁Servlet 实例时，自动调用的资源回收方法。  <p>通常无须重写init和destroy两个方法，除非需要在初始化Servlet 时，完成某些资源初始化的方法，才考虑重写init 方法。如果需要在销毁Servlet 之前，先完成某些资源的回收，比如关闭数据库连接等，才需要重写destroy 方法。  <p>注意:如果重写了init(ServletConfig config)方法，则应在重写该方法的第一行调用super.init(config) 。该方法将调用HttpServlet 的init 方法。  <p>&nbsp;</p></blockquote> <p>Servlet 和JSP 的区别在于:  <blockquote> <p>Servlet 中没有内置对象，原来JSP 中的内置对象都必须通过HttpServletRequest对象，或由HttpServletResponse 对象生成:  <p>对于静态的HTML 标签， Servlet 都必须使用页面输出流逐行输出。  <p>这也正是笔者在前面介绍的: JSP 是Servlet 的一种简化，使用JSP 只需要完成程序员需要输出到客户端的内容，至于JSP 中的Java 脚本如何镶嵌到一个类中，由JSP 容器完成。而Servlet 则是个完整的Java 类，这个类的service 方法用于生成对客户端的响应。  <p>&nbsp;</p></blockquote> <p><strong>Servlet 的配置</strong>  <blockquote> <p>编辑好的Servlet 源文件并不能响应用户请求，还必须将其编译成class 文件。将编译后的HelloServlet. class 文件放在WEB-INF/classes 路径下，如果Servlet 有包，则还应该将class 文件放在对应的包路径下。  <p>为了让Servlet 能响应用户请求，还必须将Servlet 配置在Web 应用中。配置Servlet时，需要修改web.xrnl 文件。  <p>配置Servlet 需要配置两个部分。&lt;servlet&gt;/&lt;servlet-mapping&gt;  <p>&nbsp;</p></blockquote> <p><strong>Servlet的生命周期</strong>  <blockquote> <p>Servlet 在容器中运行，其实例的创建及销毁等都不是由程序员决定的，而是由容器进行控制。  <p>Servlet 的创建有两个选择。  <p>客户端请求对应的Servlet 时，创建Servlet 实例:大部分的Servlet 都是这种Servlet。 Web 应用启动时，立即创建Servlet 实例:即load-on-startup Servlet。  <p>每个Servlet 的运行都遵循如下生命周期。  <p>(1)创建Servlet 实例。  <p>(2) Web 容器调用Servlet 的init 方法，对Servlet 进行初始化。  <p>(3) Servlet 初始化后，将一直存在于容器中，用于响应客户端请求。如果客户端有get 请求，容器调用Servlet 的doGet 方法处理并响应请求。对于不同的请求，有不同的处理方法，或者统一使用service 方法处理来响应用户请求。  <p>(4) Web 容器角色销毁Servlet 时，调用Servlet 的destroy 方法，通常在关闭Web容器之时销毁Servlet。  <p>&nbsp;</p></blockquote> <p><strong>使用Servlet创作为控制器</strong>  <blockquote> <p>正如前面见到，使用Servlet 作为表现层的工作量太大，所有的HTML 标签都需要使用页面输出流生成。因此，使用Servlet 作为表现层有如下三个劣势。  <p>开发效率低，所有的HTML 标签都需使用页面输出流完成。  <p>不利于团队协作开发，美工人员无法参与Servlet 界面的开发。  <p>程序可维护性差，即使修改一个按钮的标题，都必须重新编辑Java 代码，并重新编译。  <p>&nbsp; <p>整个结构非常清晰，下面是MVC 中各个角色的对应组件。  <p>M: Model，即模型，对应JavaBean 。  <p>V: View ，即视图，对应JSP 页面。  <p>C: Controller，即控制器，对应Servlet。</p></blockquote> <p>&nbsp; <p>load-on-startup Servlet  <blockquote> <p>Servlet 的实例化有两个时机:用户请求之时，或应用启动之时。应用启动时就启动的Servlet 通常是用于某些后台服务的Servlet ，或者拦截很多请求的Servlet; 这种Servlet 通常作为应用的基础Servlet 使用，提供重要的后台服务。如果需要Web 应用启动时，可使用load-on-startup 元素完成Servlet 的初始化。load-on-startup 元素只接收一个整型值，这个整型值越小， Servlet 就越优先初始化。</p></blockquote> <p>访问Servlet 的配置参数  <blockquote> <p>配置Servlet 时，还可以增加附加的配置参数。通过使用配置参数，可以实现更好地解耦，避免将所有的参数以硬编码方式写在程序中。  <p>访问Servlet 配置参数要通过ServletConfig 类的实例完成， ServletConfig提供如下方法。  <p>java.lang.String getInitParameter(java.lang.String name): 用于获取初始化参数。  <p>注意: JSP 的内直对象config 就是此处的ServletConfig</p></blockquote> <p>自定义标签类  <blockquote> <p>使用标签类，可以使用简单的标签来封装复杂的功能，从而使团队更好地协作开发(能让美工人员更好地参与JSP 页面的开发)。  <p>自定义标签类都必须继承一个父类: java.Servlet.jsp.tagext.TagSupport 。除此之外，自定义标签类还有如下要求。  <p>·如果标签类包含属性，每个属性都有对应的getter 和setter 方法。  <p>·重写doStartTag或doEndTag方法，这两个方法生成页面内容。  <p>·如果需要在销毁标签之前完成资源回收，则重写re1ease方法。</p></blockquote> <p><strong>TLD 文件</strong>  <blockquote> <p>TLD 是Tag Library Definition 的缩写，即标签库定义，文件的后缀是tld ，每个TLD文件对应一个标签库，一个标签库中可包含多个标签。TLD 文件也称为标签库定义文件。标签库定义文件的根元素是taglib，它可以有多个tag 子元素，每个tag 子元素都对应一个标签。  <p>编辑了标签库定义文件还不够， Web 容器还无法加载标签库定义文件。还必须在web.xml 文件中增加标签库的定义。在web.xml 文件中定义标签库时使用taglib 元素，该元素包含两个子元素: taglib-uri和taglib-location，前者确定标签库的URI; 后者确定标签库定义文件的位置。</p></blockquote> <p>使用标签库  <blockquote> <p>使用标签库分成以下两步。  <p>(1) 导入标签库:使用taglib 编译指令导入标签。  <p>(2) 使用标签:在JSP 页面中使用自定义标签。  <p>taglib 的语法格式如下:  <p>〈%@ taglib uri="tagliburi" prefix="tagPrefix" %〉  <p>其中uri 属性确定标签库定义文件的URI，这个URI 就是在web.xml 文件中为标签  <p>库定义的URI。而prefix 属性确定的是标签前缀，即在JSP 页面中使用标签时，该标签  <p>库负责处理的标签前缀。  <p>使用标签的语法格式如下:  <p>&lt;tagPrefix : tagName tagAttribute=ntagValue n ...&gt;  <p>&lt;tagBody/&gt;  <p>&lt;/tagPrefix&gt;  <p>如果该标签没有标签体，则可以使用如下语法格式:  <p>&lt;tagPrefix : tagName tagAttribute=ntagValue n …/&gt;</p></blockquote> <p>带标签体的标签  <blockquote> <p>带标签体的标签，就是允许在标签内嵌套标签，通常可用于完成一些逻辑运算例如判断和循环等。  <p>带标签体的标签需要继承BodyTagSupport，该类包含一个bodyContent 属性，该属性代表标签体。  <p>BodyTagSupport 还包含两个方法。  <p>doAfterBody: 每次处理完标签体后调用该方法。  <p>void doInitBody: 开始调用标签体时调用该方法。  <p>如果有必要，可以重写这两个方法。  <p>在处理标签类的各个方法中，不同的返回值对应不同的含义，常用的返回值有如下几个。  <p>SKIP_BODY: 不处理标签体，直接调用doEndTag方法。  <p>SKIP_PAGE: 忽略标签后面的JSP 页面。  <p>EVAL_PAGE: 处理标签结束，直接处理页面内容。  <p>EVAL_BODY_BUFFERED: 处理标签体。  <p>EVAL_BODY_INCLUDE: 处理标签体，但忽略setBodyContent和doInitBody方法。  <p>EVAL_BODY_AGAIN: 对标签体循环处理。  <p>&nbsp;</p></blockquote> <p><strong>Filter</strong>  <blockquote> <p>Filter 并不是一个标准的Servlet ，它不能处理用户请求，也不能对客户端生成响应。主要用于对HttpServletRequest 进行预处理，也可以对HttpServletResponse 进行后处理，是个典型的处理链。  <p><u>Filter 有如下几个用处。</u>  <p>·在HttpServletRequest 到达Servlet 之前，拦截客户的HttpServletRequest 。  <p>·根据需要检查HttpServletRequest ，也可以修改HttpServletRequest 头和数据。  <p>·在HttpServletResponse 到达客户端之前，拦截HttpServletResponse 。  <p>·根据需要检查HttpServletResponse ，也可以修改HttpServletResponse 头和数据。  <p><u><em>Filter 有如下几个种类。</em></u>  <p>·用户授权的Filter: Filter 负责检查用户请求，根据请求过滤用户非法请求。  <p>·日志Filter: 详细记录某些特殊的用户请求。  <p>·负责解码的Filter: 包括对非标准编码的请求解码。  <p>.能改变XML 内容的XSLTFilter 等。  <p>一个Filter 可负责拦截多个请求或响应:一个请求或响应也可被多个请求拦截。  <p><u><em>创建一个Filter 只需两个步骤:</em></u>  <p>(1)创建Filter 处理类:  <p>(2) 在web.xml 文件中配置Filter。  <p><u>创建Filter 类</u>  <p>创建Filter 必须实现javax.servle t. Filter 接口，在该接口中定义了三个方法。  <p>void init(FilterConfig config): 用于完成Filter 的初始化。  <p>void destroy: 用于Filter 销毁前，完成某些资源的回收。  <p>void doFilter(ServletRequest request, ServletResponse response,FilterChain chain): 实现过滤功能，该方法就是对每个请求及响应增加的额外处理。  <p>执行chain.doFilter(request，reponse)方法，当Filter 对请求过滤后，依然将请求发送到目的地址。如果检查权限，可以在Filter 中根据用户请求的HttpSession，判断用户权限是否足够。  <p>如果权限不够，则调用重定向即可，无须调用chain.doFilter(request，reponse)方法。  <p><u>配置Filter</u>  <p>Filter 的配置和Servlet 的配置非常相似，都需要配置两个部分:  <p>·配置Filter 名。  <p>·配置Filter 拦截URL 模式。  <p>区别在于， Servlet 通常只配置一个URL ，而Filter 可以同时拦截多个请求的URL。  <p>因此，可以配置多个Filter 拦截模式。  <p>&nbsp;</p></blockquote> <p><strong>Listener </strong> <blockquote> <p>Listener 的作用非常类似于load-on-startup Servlet。用于在Web 应用启动时，启动某些后台程序，这些后台程序负责为系统运行提供支持。  <p>Listener 与load-on-startup Servlet 的区别在于: Listener 的启动时机比load-on-startup Servlet 早，只是Listener 是Servlet 2.3 规范之后才出现的。  <p>使用Listener 只需要两个步骤:  <p>(1) 创建Listener 实现类。  <p>(2) 在web.xml 文件中配置Listener。  <p><u><em>创建Listener 类</em></u>  <p>创建Li stener 类必须实现ServletContex tListener 接口，该接口包含两个方法。  <p>eontextInitialized(ServletContextEvent see): 启动Web 应用时，系统调用该Filter的方法。  <p>eontextDestroyed(ServletContextEvent see): 关闭Web 应用时候，系统调用Filter  <p>的方法。  <p><u><em>配置Listener</em></u>  <p>正如load-an-startup Servlet 一样， Listener 用于启动Web 应用的后台服务程序，但不负责处理及响应用户请求，因此无须配置URL。  <p>若将Listener 配置在Web 容器中(如果Web 容器支持Listener)，则Listener 将随Web 应用的启动而启动。  <p>配置Listener 时使用&lt;listener/&gt;元素，下面是配置Listener 的片段:  <p>&lt;!-- 配置Listener--&gt;  <p>&lt;listener&gt;  <p>&lt;!- 指定Listener 的实现类→  <p>&lt;listener-class&gt;lee.ScheduleListener&lt;/listener-class&gt;  <p>&lt;/listener&gt;  <p>在上面的配置中，既无须配置Listener 的名字，也无须配置Listener 的URL 只需配置它的实现类即可。此时容器将自动检测部署在容器中的Listener，并在应用启动时，自动加载所有的Listener。</p></blockquote><img src ="http://www.blogjava.net/hoojo/aggbug/368965.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hoojo/" target="_blank">hoojo</a> 2012-01-29 15:50 <a href="http://www.blogjava.net/hoojo/archive/2012/01/29/368965.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JSP 手记</title><link>http://www.blogjava.net/hoojo/archive/2012/01/29/368960.html</link><dc:creator>hoojo</dc:creator><author>hoojo</author><pubDate>Sun, 29 Jan 2012 06:49:00 GMT</pubDate><guid>http://www.blogjava.net/hoojo/archive/2012/01/29/368960.html</guid><wfw:comment>http://www.blogjava.net/hoojo/comments/368960.html</wfw:comment><comments>http://www.blogjava.net/hoojo/archive/2012/01/29/368960.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/hoojo/comments/commentRss/368960.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hoojo/services/trackbacks/368960.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: UML的组成 <br><br>UML由视图(View)、图(Diagram)、模型元素(Model Element)和通用机制(General Mechanism)等几个部分组成。 <br><br>a) 视图(View)： 是表达系统的某一方面的特征的UML建模元素的子集，由多个图构成，是在某一个抽象层上，对系统的抽象表示。 <br><br>b) 图(Diagram)： 是模型元素集的图形表示，通常是由弧（关系）和顶点（其他模型元素）相互连接构成的。 <br><br>c) 模型元素(Model Element)：代表面向对象中的类、对象、消息和关系等概念，是构成图的最基本的常用概念。 <br><br>d) 通用机制(General Mechanism)：用于表示其他信息，比如注释、模型元素的语义等。另外，UML还提供扩展机制，使UML语言能够适应一个特殊的方法（或过程），或扩充至一个组织或用户。 <br><br>&nbsp;&nbsp;<a href='http://www.blogjava.net/hoojo/archive/2012/01/29/368960.html'>阅读全文</a><img src ="http://www.blogjava.net/hoojo/aggbug/368960.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hoojo/" target="_blank">hoojo</a> 2012-01-29 14:49 <a href="http://www.blogjava.net/hoojo/archive/2012/01/29/368960.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Solr开发文档</title><link>http://www.blogjava.net/hoojo/archive/2011/10/21/361747.html</link><dc:creator>hoojo</dc:creator><author>hoojo</author><pubDate>Fri, 21 Oct 2011 08:41:00 GMT</pubDate><guid>http://www.blogjava.net/hoojo/archive/2011/10/21/361747.html</guid><wfw:comment>http://www.blogjava.net/hoojo/comments/361747.html</wfw:comment><comments>http://www.blogjava.net/hoojo/archive/2011/10/21/361747.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/hoojo/comments/commentRss/361747.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hoojo/services/trackbacks/361747.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Solr 是一种可供企业使用的、基于 Lucene 的搜索服务器，它支持层面搜索、命中醒目显示和多种输出格式。在这篇文章中，将介绍 Solr 并展示如何轻松地将其表现优异的全文本搜索功能加入到 Web 应用程序中。  开发环境：  System：Windows  WebBrowser：IE6+、Firefox3+  JDK：1.6+  JavaEE Server：tomcat5.0.2.8、tom...&nbsp;&nbsp;<a href='http://www.blogjava.net/hoojo/archive/2011/10/21/361747.html'>阅读全文</a><img src ="http://www.blogjava.net/hoojo/aggbug/361747.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hoojo/" target="_blank">hoojo</a> 2011-10-21 16:41 <a href="http://www.blogjava.net/hoojo/archive/2011/10/21/361747.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java 多线程断点下载文件</title><link>http://www.blogjava.net/hoojo/archive/2011/09/30/359875.html</link><dc:creator>hoojo</dc:creator><author>hoojo</author><pubDate>Fri, 30 Sep 2011 10:29:00 GMT</pubDate><guid>http://www.blogjava.net/hoojo/archive/2011/09/30/359875.html</guid><wfw:comment>http://www.blogjava.net/hoojo/comments/359875.html</wfw:comment><comments>http://www.blogjava.net/hoojo/archive/2011/09/30/359875.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hoojo/comments/commentRss/359875.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hoojo/services/trackbacks/359875.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 基本原理：利用URLConnection获取要下载文件的长度、头部等相关信息，并设置响应的头部信息。并且通过URLConnection获取输入流，将文件分成指定的块，每一块单独开辟一个线程完成数据的读取、写入。通过输入流读取下载文件的信息，然后将读取的信息用RandomAccessFile随机写入到本地文件中。同时，每个线程写入的数据都文件指针也就是写入数据的长度，需要保存在一个临时文件中。这样当...&nbsp;&nbsp;<a href='http://www.blogjava.net/hoojo/archive/2011/09/30/359875.html'>阅读全文</a><img src ="http://www.blogjava.net/hoojo/aggbug/359875.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hoojo/" target="_blank">hoojo</a> 2011-09-30 18:29 <a href="http://www.blogjava.net/hoojo/archive/2011/09/30/359875.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>BlazeDS 整合 Flex HelloWorld 示例</title><link>http://www.blogjava.net/hoojo/archive/2011/09/16/358798.html</link><dc:creator>hoojo</dc:creator><author>hoojo</author><pubDate>Fri, 16 Sep 2011 07:24:00 GMT</pubDate><guid>http://www.blogjava.net/hoojo/archive/2011/09/16/358798.html</guid><wfw:comment>http://www.blogjava.net/hoojo/comments/358798.html</wfw:comment><comments>http://www.blogjava.net/hoojo/archive/2011/09/16/358798.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/hoojo/comments/commentRss/358798.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hoojo/services/trackbacks/358798.html</trackback:ping><description><![CDATA[<p>开发环境：  <p>System：Windows  <p>WebBrowser：IE6+、Firefox3+  <p>JavaEE Server：tomcat5.0.2.8、tomcat6  <p>IDE：eclipse、MyEclipse 8  <p>Flex IDE：Flash Builder 4  <p>BlazeDS：4.5  <p>开发依赖库：  <p>JavaEE5、blazeDS 4.5  <p>Email：hoojo_@126.com  <p>Blog：<a href="http://blog.csdn.net/IBM_hoojo">http://blog.csdn.net/IBM_hoojo</a>  <p><a href="http://hoojo.cnblogs.com/">http://hoojo.cnblogs.com/</a>  <p>&nbsp; <h4>一、准备工作</h4> <p>1、 首先要提供相关的jar包  <p>Java服务器端需要提供BlazeDS相关的配置和jar包  <p>下载地址：<a href="http://opensource.adobe.com/wiki/display/blazeds/download+blazeds+trunk">http://opensource.adobe.com/wiki/display/blazeds/download+blazeds+trunk</a>  <p>下载后，解压你可以看到这样的一个目录  <p><a href="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/BlazeDSFlexHelloWorld_D786/clip_image002_2.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image002" border="0" alt="clip_image002" src="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/BlazeDSFlexHelloWorld_D786/clip_image002_thumb.jpg" width="185" height="194"></a>  <p>Docs就是文档  <p>Resource是源码  <p>SampleDB是示例用的数据库，可以运行startdb.bat来启动数据库  <p>Tomcat是内置的tomcat，如果你没有tomcat的话可以使用它，在tomcat的webapps目录中有samples示例  <p>blazeds.war就是blazeDS的核心文件、库，你可以把这个war放到tomcat的webapps目录下，就会自动解压。当然你也可以自己手动解压。  <p>Blazeds-spring.war是和spring整合的配置  <p>Ds-console.war是blazeDS的控制台程序  <p>Samples.war是官方提供的示例  <p>Samples-spring.war是spring和blazeDS的整合示例  <h5>二、部署服务器端程序</h5> <p>1、新建一个JavaWeb Project工程，然后在WEB-INF/lib目录中添加如下jar包  <p><a href="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/BlazeDSFlexHelloWorld_D786/clip_image004_2.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image004" border="0" alt="clip_image004" src="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/BlazeDSFlexHelloWorld_D786/clip_image004_thumb.jpg" width="201" height="242"></a>  <p>这些jar包可以在blazeds.war包中的lib目录中可以找到  <p>2、 然后你需要将blazeds.war包中的WEB-INF目录下的flex目录复制到当前工程的WEB-INF下  <p>3、 将blazeds.war包中的WEB-INF目录下的web.xml的配置，添加到当前工程的web.xml文件中  <p>4、 最后基本的样式如下  <p><a href="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/BlazeDSFlexHelloWorld_D786/clip_image006_2.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image006" border="0" alt="clip_image006" src="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/BlazeDSFlexHelloWorld_D786/clip_image006_thumb.jpg" width="152" height="244"></a>  <p>5、 最后你发布当前工程，如果没有错误就表明你服务器端部署成功了。  <p>6、 编写一个HelloWorld的java程序。代码如下  <div id="codeSnippetWrapper"> <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">package</span> com.hoo.flex;</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">&nbsp;</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #008000">/**</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #008000"> * &lt;b&gt;function:&lt;/b&gt; HelloWorld Example</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #008000"> * @author hoojo</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #008000"> * @createDate 2011-8-31 下午06:11:27</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #008000"> * @file HelloWorld.java</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #008000"> * @package com.hoo.flex</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #008000"> * @project BlazeDSServer</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #008000"> * @blog http://blog.csdn.net/IBM_hoojo</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #008000"> * @email hoojo_@126.com</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #008000"> * @version 1.0</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #008000"> */</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> HelloWorld {</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    </pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #0000ff">public</span> HelloWorld() {</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    }</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    </pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #0000ff">public</span> String sayHello(String name) {</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        <span style="color: #0000ff">return</span> <span style="color: #006080">"["</span> + name + <span style="color: #006080">"] say hello!"</span>;</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    }</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">}</pre><!--CRLF--></div></div>
<p>就一个sayHello方法，接收一个参数。 
<h5>三、Flex客户端程序</h5>
<p>1、创建一个Flex工程，在选择服务器技术的时候，你需要选择J2EE。然后勾上使用J2EE技术，然后选择BlazeDS。点击Next下一步 
<p><a href="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/BlazeDSFlexHelloWorld_D786/clip_image008_2.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image008" border="0" alt="clip_image008" src="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/BlazeDSFlexHelloWorld_D786/clip_image008_thumb.jpg" width="244" height="118"></a> 
<p>2、配置根文件夹，也就是JavaEE服务器端发布程序在tomcat中的位置。我这里是在tomcat的webapps的BlazeDSServer中，BlazeDSServer是我的服务器端程序。根URL是访问服务器端程序的url；上下文目录对应工程名称；最后就是输出文件夹目录，这个是Flex的文件最后在tomcat中保存的目录。 
<p><a href="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/BlazeDSFlexHelloWorld_D786/clip_image010_2.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image010" border="0" alt="clip_image010" src="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/BlazeDSFlexHelloWorld_D786/clip_image010_thumb.jpg" width="244" height="89"></a> 
<p>3、最后你需要设置服务器端的services-config.xml的路径到编译参数中，这个很重要！如果你不设置的话，那么你在后面用RemoteObject调用BlazeDS的时候，就需要设置endpoint。设置如下： 
<p><a href="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/BlazeDSFlexHelloWorld_D786/clip_image012_2.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image012" border="0" alt="clip_image012" src="http://www.blogjava.net/images/blogjava_net/hoojo/WindowsLiveWriter/BlazeDSFlexHelloWorld_D786/clip_image012_thumb.jpg" width="244" height="20"></a> 
<p>-services是参数键，后面的字符串是值。我这里是设置BlazeDSServer发布到tomcat目录中的services-config.xml的路径。 
<p>4、编译Flex前端代码，代码如下： 
<div id="codeSnippetWrapper">
<div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">&lt;?</span><span style="color: #800000">xml</span> <span style="color: #ff0000">version</span><span style="color: #0000ff">="1.0"</span> <span style="color: #ff0000">encoding</span><span style="color: #0000ff">="utf-8"</span>?<span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">&lt;</span><span style="color: #800000">mx:Application</span> <span style="color: #ff0000">xmlns:mx</span><span style="color: #0000ff">="http://www.adobe.com/2006/mxml"</span> <span style="color: #ff0000">viewSourceURL</span><span style="color: #0000ff">="BlazeDSHelloWorld.mxml"</span> <span style="color: #ff0000">layout</span><span style="color: #0000ff">="absolute"</span> <span style="color: #ff0000">minWidth</span><span style="color: #0000ff">="955"</span> <span style="color: #ff0000">minHeight</span><span style="color: #0000ff">="600"</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #0000ff">&lt;</span><span style="color: #800000">mx:Script</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        <span style="color: #0000ff">&lt;!</span>[CDATA[</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">            import mx.controls.Alert;</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">            import mx.rpc.AsyncToken;</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">            import mx.rpc.events.ResultEvent;</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">            </pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">            private function faultHandler(event: Event): void {</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">                Alert.show(event.toString(), event.type);</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">            }</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">            </pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">            private function resultHandler(event: ResultEvent): void {</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">                //event.result是服务器端返回对象</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">                result.text = "Message：" + event.result.toString();</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">            }</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">            </pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">            private function sendHandler(): void {</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">                helloRemoteObject.sayHello(userName.text);</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">            }        </pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        ]]<span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #0000ff">&lt;/</span><span style="color: #800000">mx:Script</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    </pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #008000">&lt;!-- 当工程没有设置编译器-service参数 或是-context-root等参数，就需要手动设置endpoint参数 --&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #0000ff">&lt;</span><span style="color: #800000">mx:RemoteObject</span> </pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        <span style="color: #ff0000">id</span><span style="color: #0000ff">="helloRemoteObject"</span> </pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        <span style="color: #ff0000">destination</span><span style="color: #0000ff">="helloWorld"</span> </pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        <span style="color: #ff0000">fault</span><span style="color: #0000ff">="faultHandler(event)"</span> </pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        <span style="color: #ff0000">result</span><span style="color: #0000ff">="resultHandler(event)"</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        <span style="color: #ff0000">showBusyCursor</span><span style="color: #0000ff">="true"</span><span style="color: #0000ff">/&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #0000ff">&lt;</span><span style="color: #800000">mx:Panel</span> <span style="color: #ff0000">x</span><span style="color: #0000ff">="10"</span> <span style="color: #ff0000">y</span><span style="color: #0000ff">="10"</span> <span style="color: #ff0000">width</span><span style="color: #0000ff">="272"</span> <span style="color: #ff0000">height</span><span style="color: #0000ff">="148"</span> <span style="color: #ff0000">layout</span><span style="color: #0000ff">="absolute"</span> <span style="color: #ff0000">title</span><span style="color: #0000ff">="BlazeDS Remote HelloWorld Sample"</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        <span style="color: #0000ff">&lt;</span><span style="color: #800000">mx:Label</span> <span style="color: #ff0000">x</span><span style="color: #0000ff">="10"</span> <span style="color: #ff0000">y</span><span style="color: #0000ff">="22"</span> <span style="color: #ff0000">text</span><span style="color: #0000ff">="请输入名称"</span><span style="color: #0000ff">/&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        <span style="color: #0000ff">&lt;</span><span style="color: #800000">mx:TextInput</span> <span style="color: #ff0000">x</span><span style="color: #0000ff">="70"</span> <span style="color: #ff0000">y</span><span style="color: #0000ff">="19"</span> <span style="color: #ff0000">id</span><span style="color: #0000ff">="userName"</span><span style="color: #0000ff">/&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        <span style="color: #0000ff">&lt;</span><span style="color: #800000">mx:Button</span> <span style="color: #ff0000">x</span><span style="color: #0000ff">="184"</span> <span style="color: #ff0000">y</span><span style="color: #0000ff">="45"</span> <span style="color: #ff0000">label</span><span style="color: #0000ff">="发送"</span> <span style="color: #ff0000">click</span><span style="color: #0000ff">="sendHandler()"</span><span style="color: #0000ff">/&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        <span style="color: #0000ff">&lt;</span><span style="color: #800000">mx:Text</span> <span style="color: #ff0000">x</span><span style="color: #0000ff">="10"</span> <span style="color: #ff0000">y</span><span style="color: #0000ff">="79"</span> <span style="color: #ff0000">id</span><span style="color: #0000ff">="result"</span><span style="color: #0000ff">/&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #0000ff">&lt;/</span><span style="color: #800000">mx:Panel</span><span style="color: #0000ff">&gt;</span>    </pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">&lt;/</span><span style="color: #800000">mx:Application</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--></div></div>
<p>首先你需要将Java服务器端的HelloWorld程序配置在flex的remoting-config.xml中，配置如下： 
<div id="codeSnippetWrapper">
<div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">&lt;?</span><span style="color: #800000">xml</span> <span style="color: #ff0000">version</span><span style="color: #0000ff">="1.0"</span> <span style="color: #ff0000">encoding</span><span style="color: #0000ff">="UTF-8"</span>?<span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">&lt;</span><span style="color: #800000">service</span> <span style="color: #ff0000">id</span><span style="color: #0000ff">="remoting-service"</span> </pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #ff0000">class</span><span style="color: #0000ff">="flex.messaging.services.RemotingService"</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">&nbsp;</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #0000ff">&lt;</span><span style="color: #800000">adapters</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        <span style="color: #0000ff">&lt;</span><span style="color: #800000">adapter-definition</span> <span style="color: #ff0000">id</span><span style="color: #0000ff">="java-object"</span> <span style="color: #ff0000">class</span><span style="color: #0000ff">="flex.messaging.services.remoting.adapters.JavaAdapter"</span> <span style="color: #ff0000">default</span><span style="color: #0000ff">="true"</span><span style="color: #0000ff">/&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #0000ff">&lt;/</span><span style="color: #800000">adapters</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    </pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #0000ff">&lt;</span><span style="color: #800000">default-channels</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        <span style="color: #0000ff">&lt;</span><span style="color: #800000">channel</span> <span style="color: #ff0000">ref</span><span style="color: #0000ff">="my-amf"</span><span style="color: #0000ff">/&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #0000ff">&lt;/</span><span style="color: #800000">default-channels</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    </pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #0000ff">&lt;</span><span style="color: #800000">destination</span> <span style="color: #ff0000">id</span><span style="color: #0000ff">="helloWorld"</span><span style="color: #0000ff">&gt;</span>    </pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        <span style="color: #0000ff">&lt;</span><span style="color: #800000">properties</span><span style="color: #0000ff">&gt;</span>    </pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">            <span style="color: #0000ff">&lt;</span><span style="color: #800000">source</span><span style="color: #0000ff">&gt;</span>com.hoo.flex.HelloWorld<span style="color: #0000ff">&lt;/</span><span style="color: #800000">source</span><span style="color: #0000ff">&gt;</span>    </pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">        <span style="color: #0000ff">&lt;/</span><span style="color: #800000">properties</span><span style="color: #0000ff">&gt;</span>    </pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px">    <span style="color: #0000ff">&lt;/</span><span style="color: #800000">destination</span><span style="color: #0000ff">&gt;</span> </pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 10pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">&lt;/</span><span style="color: #800000">service</span><span style="color: #0000ff">&gt;</span></pre><!--CRLF--></div></div>
<p>上面mxml代码中的RemoteObject的destination对应的就是remoting-config.xml配置文件中的destination的id。这个是一一对应的，然后在sendHandler方法中，helloRemoteObject对应的就是RemoteObject的id，而sayHello方法对应的就是配置在remoting-config.xml中的destination的source的Java服务器端代码的公有方法。添加完配置后，需要重启tomcat。 
<p>运行上面的flex程序后，如果输入参数后，点击发送，可以看到服务器端返回的消息就说明BlazeDS整合Flex成功了。 
<img src ="http://www.blogjava.net/hoojo/aggbug/358798.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hoojo/" target="_blank">hoojo</a> 2011-09-16 15:24 <a href="http://www.blogjava.net/hoojo/archive/2011/09/16/358798.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用Dom4j操作XML</title><link>http://www.blogjava.net/hoojo/archive/2011/08/11/356310.html</link><dc:creator>hoojo</dc:creator><author>hoojo</author><pubDate>Thu, 11 Aug 2011 07:52:00 GMT</pubDate><guid>http://www.blogjava.net/hoojo/archive/2011/08/11/356310.html</guid><wfw:comment>http://www.blogjava.net/hoojo/comments/356310.html</wfw:comment><comments>http://www.blogjava.net/hoojo/archive/2011/08/11/356310.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hoojo/comments/commentRss/356310.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hoojo/services/trackbacks/356310.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Dom4j也可以很方便完成XML文档的创建、元素的修改、文档的查询遍历等，但dom4j稍比jdom复杂一点，不过在大片文档的情况下dom4j的性能要不jdom好。  # 准备 首先，提供相关的jar包 Dom4j jar包下载： http://sourceforge.net/projects/dom4j/files/dom4j-2.0.0-ALPHA-2/ jaxen jar下载： http://...&nbsp;&nbsp;<a href='http://www.blogjava.net/hoojo/archive/2011/08/11/356310.html'>阅读全文</a><img src ="http://www.blogjava.net/hoojo/aggbug/356310.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hoojo/" target="_blank">hoojo</a> 2011-08-11 15:52 <a href="http://www.blogjava.net/hoojo/archive/2011/08/11/356310.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>