﻿<?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-金家寶-随笔分类-其他辅助基础</title><link>http://www.blogjava.net/jiabao/category/20482.html</link><description>機會只會給垂青有准備的人，運氣不是每個人都有的.</description><language>zh-cn</language><lastBuildDate>Sat, 21 Apr 2007 12:03:42 GMT</lastBuildDate><pubDate>Sat, 21 Apr 2007 12:03:42 GMT</pubDate><ttl>60</ttl><item><title>php＋mysql扎实个人基本功</title><link>http://www.blogjava.net/jiabao/archive/2007/04/21/112478.html</link><dc:creator>金家寶</dc:creator><author>金家寶</author><pubDate>Sat, 21 Apr 2007 11:45:00 GMT</pubDate><guid>http://www.blogjava.net/jiabao/archive/2007/04/21/112478.html</guid><wfw:comment>http://www.blogjava.net/jiabao/comments/112478.html</wfw:comment><comments>http://www.blogjava.net/jiabao/archive/2007/04/21/112478.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jiabao/comments/commentRss/112478.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jiabao/services/trackbacks/112478.html</trackback:ping><description><![CDATA[
		<p>一. 10句话<br />1.不要依赖register_global=ON的环境，从你刚懂得配置php运行环境甚至尚不明白register_global的ON/OFF会对自己有什么影响的那天起，就应该勇敢地把它设为OFF.<br />2.写程序前看看怎么用error_reporting.<br />3.不懂就问本身没错，但你需要在那之前查查手册。<br />4.当然，你需要懂得使用手册。手册上找不到答案的时候，应该考虑下网络上的搜索引擎。<br />5.刚学会php+mysql之后，不要叫嚷着要写论坛，要写XXX。要明白，刚学会写汉字并不表示你有能力写诗。<br />6.在学web编程的时候，你应该先去认识html这个朋友。<br />7.有点能力后，试着回答新手的问题，不要看到自己懂的而别人不懂就沾沾自喜，扔下一名“简单，那是基本的东西”就走更要不得。<br />8.思考是一个好习惯，不动手去写就等于空想，什么也没有。<br />9.写好一段程序，如果觉得很满意，一周后再看一遍，也许你会认为它应该有所改变<br />10.有空多看看别人的程序，找出他人的不足或优点，自己掂量。<br /><br />二. 各取所需<br /><br />1.善于使用“引用”,它能直接影响到程序的效率。<br /><br />2.善于用三元运算子,可以让程式较精简有效率。<br />比如:<br /></p>
		<blockquote>
				<pre>PHP代码:<hr /><br />if ($data[$i]['nickname'])
<br />{
<br />    $nickname =  $data[$i]['nickname'];
<br />}
<br />else
<br />{
<br />    $nickname =  $data[$i]['ip'];
<br />}<br /><hr /></pre>
		</blockquote>
		<p>
				<br />可以写成:<br /></p>
		<blockquote>
				<pre>PHP代码:<hr /><br />$nickname =  $data[$i]['nickname'] ? $data[$i]['nickname'] : $data[$i]['ip'];<br /><hr /></pre>
		</blockquote>
		<p>
				<br />
				<br />3.善于组织if...else...回圈<br />比如:<br /></p>
		<blockquote>
				<pre>PHP代码:<hr /><br />$ext_name = strtolower(str_replace(".", "", strrchr($upfilename, ".")));
<br />if (!empty($type))
<br />{
<br />    if (!strpos($type, $ext_name))
<br />    {
<br />        echo "Please upload the file of $type form.";
<br />        exit();
<br />    }
<br />}<br /><hr /></pre>
		</blockquote>
		<p>
				<br />上面的代码你应该写成这样:<br /></p>
		<blockquote>
				<pre>PHP代码:<hr /><br />$ext_name = strtolower(str_replace(".", "", strrchr($upfilename, ".")));
<br />if (!($type==='') &amp;&amp; strpos($type, $ext_name)===false)
<br />{
<br />    echo "Please upload the file of $type form.";
<br />    exit();
<br />}<br /><hr /></pre>
		</blockquote>
		<p>
				<br />
				<br />4.尽量让你的代码清淅些<br />如果写成这样，是比较让人头痛的:<br /></p>
		<blockquote>
				<pre>PHP代码:<hr /><br />$foo=$_post["foo"];
<br />   $username=$_post["user"]; 
<br />$group=$_POST["group"];
<br />if ($group=="wheel"){
<br />$username=$username."wheel";
<br />}<br /><hr /></pre>
		</blockquote>
		<p>
				<br />同样的代码，这样就比较让人看得舒服了:<br /></p>
		<blockquote>
				<pre>PHP代码:<hr /><br />$foo      = $_post["foo"];
<br />$username = $_post["username"];
<br />$group    = $_POST["group"];
<br />if ($group=="wheel")
<br />{
<br />    $username = $username."wheel";
<br />}<br /><hr /></pre>
		</blockquote>
		<p>
				<br />当然，有一定基础后，你应该要写成这样:<br /></p>
		<blockquote>
				<pre>PHP代码:<hr /><br />$foo      = &amp;$_POST['foo'];
<br />$username =  $_POST["group"]!='wheel' ? $_POST["username"] : $_POST["username"].'wheel';<br /><hr /></pre>
		</blockquote>
		<p>
				<br />5.编写规范的mysql 语句。<br />字段和表名用"`"引起来，避免保留字的影响。<br />如果看到下面这样的一个sql query，会让人比较头痛:<br /></p>
		<blockquote>
				<pre>PHP代码:<hr /><br />$query="select `flash_comment`.`content` , `flash_comment`.`nickname` , `flash_comment`.`date` , `flash_comment`.`ip` , `product`.`p_name` , `sgflash`.`fid` from `flash_comment` left join `product` on ( `flash_comment`.`p_no` = `product`.`p_no` ) left join `sgflash` on ( `product`.`p_name` = `sgflash`.`f_name` ) where `flash_comment`.`p_no` != '' order by `flash_comment`.`date`";<br /><hr /></pre>
		</blockquote>
		<p>
				<br />同样的一个query,写成这样就令人看得明白得多了:<br /></p>
		<blockquote>
				<pre>PHP代码:<hr /><br />$query = "SELECT `flash_comment`.`content` , `flash_comment`.`nickname` , `flash_comment`.`date` , `flash_comment`.`ip` , `product`.`p_name` , `sgflash`.`fid` 
<br />          FROM `flash_comment` 
<br />          LEFT JOIN `product` ON ( `flash_comment`.`p_no` = `product`.`p_no` ) 
<br />          LEFT JOIN `sgflash` ON ( `product`.`p_name` = `sgflash`.`f_name` ) 
<br />          WHERE `flash_comment`.`p_no` != ''
<br />          ORDER BY `flash_comment`.`date`";<br /></pre>
		</blockquote>
<img src ="http://www.blogjava.net/jiabao/aggbug/112478.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jiabao/" target="_blank">金家寶</a> 2007-04-21 19:45 <a href="http://www.blogjava.net/jiabao/archive/2007/04/21/112478.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>深入剖析Java编程中的中文问题及建议最优解决方法</title><link>http://www.blogjava.net/jiabao/archive/2007/04/10/109661.html</link><dc:creator>金家寶</dc:creator><author>金家寶</author><pubDate>Tue, 10 Apr 2007 07:55:00 GMT</pubDate><guid>http://www.blogjava.net/jiabao/archive/2007/04/10/109661.html</guid><wfw:comment>http://www.blogjava.net/jiabao/comments/109661.html</wfw:comment><comments>http://www.blogjava.net/jiabao/archive/2007/04/10/109661.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jiabao/comments/commentRss/109661.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jiabao/services/trackbacks/109661.html</trackback:ping><description><![CDATA[
		<p>
				<b>1、中文问题的来源 </b>
				<br />    计算机最初的操作系统支持的编码是单字节的字符编码，于是，在计算机中一切处理程序最初都是以单字节编码的英文为准进行处理。随着计算机的发展，为了适应世界其它民族的语言（当然包括我们的汉字），人们提出了UNICODE编码，它采用双字节编码，兼容英文字符和其它民族的双字节字符编码，所以，目前，大多数国际性的软件内部均采用UNICODE编码，在软件运行时，它获得本地支持系统（多数时间是操作系统）默认支持的编码格式，然后再将软件内部的UNICODE转化为本地系统默认支持的格式显示出来。Java的JDK和JVM即是如此，我这里说的JDK是指国际版的JDK，我们大多数程序员使用的是国际化的JDK版本，以下所有的JDK均指国际化的JDK版本。我们的汉字是双字节编码语言，为了能让计算机处理中文，我们自己制定的gb2312、GBK、GBK2K等标准以适应计算机处理的需求。所以，大部分的操作系统为了适应我们处理中文的需求，均定制有中文操作系统，它们采用的是GBK,GB2312编码格式以正确显示我们的汉字。如：中文Win2K默认采用的是GBK编码显示，在中文WIN2k中保存文件时默认采用的保存文件的编码格式也是GBK的，即，所有在中文WIN2K中保存的文件它的内部编码默认均采用GBK编码，注意：GBK是在GB2312基础上扩充来的。<br />    由于Java语言内部采用UNICODE编码，所以在JAVA程序运行时，就存在着一个从UNICODE编码和对应的操作系统及浏览器支持的编码格式转换输入、输出的问题，这个转换过程有着一系列的步骤，如果其中任何一步出错，则显示出来的汉字就会出是乱码，这就是我们常见的JAVA中文问题。<br />    同时，Java是一个跨平台的编程语言，也即我们编写的程序不仅能在中文windows上运行，也能在中文Linux等系统上运行，同时也要求能在英文等系统上运行（我们经常看到有人把在中文win2k上编写的JAVA程序，移植到英文Linux上运行）。这种移植操作也会带来中文问题。<br />    还有，有人使用英文的操作系统和英文的IE等浏览器，来运行带中文字符的程序和浏览中文网页，它们本身就不支持中文，也会带来中文问题。<br />    有，几乎所有的浏览器默认在传递参数时都是以UTF-8编码格式来传递，而不是按中文编码传递，所以，传递中文参数时也会有问题，从而带来乱码现象。<br />    总之，以上几个方面是JAVA中的中文问题的主要来源，我们把以上原因造成的程序不能正确运行而产生的问题称作：JAVA中文问题。<br /><b>2、JAVA编码转换的详细过程 </b><br />    我们常见的JAVA程序包括以下类别：<br />     *直接在console上运行的类(包括可视化界面的类)<br />     *JSP代码类（注：JSP是Servlets类的变型）<br />     *Servelets类<br />     *EJB类<br />     *其它不可以直接运行的支持类<br />    这些类文件中，都有可能含有中文字符串，并且我们常用前三类JAVA程序和用户直接交互，用于输出和输入字符，如：我们在JSP和Servlet中得到客户端送来的字符，这些字符也包括中文字符。无论这些JAVA类的作用如何，这些JAVA程序的生命周期都是这样的：<br />    *编程人员在一定的操作系统上选择一个合适的编辑软件来实现源程序代码并以.java扩展名保存在操作系统中，例如我们在中文win2k中用记事本编辑一个java源程序；<br />     *编程人员用JDK中的javac.exe来编译这些源代码，形成.class类(JSP文件是由容器调用JDK来编译的)；<br />     *直接运行这些类或将这些类布署到WEB容器中去运行，并输出结果。<br />    那么，在这些过程中，JDK和JVM是如何将这些文件如何编码和解码并运行的呢？<br />    这里，我们以中文win2k操作系统为例说明JAVA类是如何来编码和被解码的。<br />    第一步，我们在中文win2k中用编辑软件如记事本编写一个Java源程序文件(包括以上五类JAVA程序)，程序文件在保存时默认采用了操作系统默认支持GBK编码格式(操作系统默认支持的格式为file.encoding格式)形成了一个.java文件，也即，java程序在被编译前，我们的JAVA源程序文件是采用操作系统默认支持的file.encoding编码格式保存的，java源程序中含有中文信息字符和英文程序代码；要查看系统的file.encoding参数，可以用以下代码：<br />public class ShowSystemDefaultEncoding {<br />public static void main(String[] args) {<br />String encoding = System.getProperty("file.encoding");<br />System.out.println(encoding);<br />}}<br />    第二步，我们用JDK的javac.exe文件编译我们的Java源程序，由于JDK是国际版的，在编译的时候，如果我们没有用-encoding参数指定我们的JAVA源程序的编码格式，则javac.exe首先获得我们操作系统默认采用的编码格式，也即在编译java程序时，若我们不指定源程序文件的编码格式，JDK首先获得操作系统的file.encoding参数(它保存的就是操作系统默认的编码格式，如WIN2k，它的值为GBK)，然后JDK就把我们的java源程序从file.encoding编码格式转化为JAVA内部默认的UNICODE格式放入内存中。然后，javac把转换后的unicode格式的文件进行编译成.class类文件，此时.class文件是UNICODE编码的，它暂放在内存中，紧接着，JDK将此以UNICODE编码的编译后的class文件保存到我们的操作系统中形成我们见到的.class文件。对我们来说，我们最终获得的.class文件是内容以UNICODE编码格式保存的类文件，它内部包含我们源程序中的中文字符串，只不过此时它己经由file.encoding格式转化为UNICODE格式了。<br />    这一步中，对于JSP源程序文件是不同的，对于JSP，这个过程是这样的：即WEB容器调用JSP编译器，JSP编译器先查看JSP文件中是否设置有文件编码格式，如果JSP文件中没有设置JSP文件的编码格式，则JSP编译器调用JDK先把JSP文件用JVM默认的字符编码格式(也即WEB容器所在的操作系统的默认的file.encoding)转化为临时的Servlet类，然后再把它编译成UNICODE格式的class类，并保存在临时文件夹中。如：在中文win2k上，WEB容器就把JSP文件从GBK编码格式转化为UNICODE格式，然后编译成临时保存的Servlet类，以响应用户的请求。<br />    第三步，运行第二步编译出来的类，分为三种情况：<br />    A、 直接在console上运行的类<br />    B、 EJB类和不可以直接运行的支持类(如JavaBean类)<br />    C、 JSP代码和Servlet类<br />    D、 JAVA程序和数据库之间<br />    下面我们分这四种情况来看。<br />    A、直接在console上运行的类<br />    这种情况，运行该类首先需要JVM支持，即操作系统中必须安装有JRE。运行过程是这样的：首先java启动JVM，此时JVM读出操作系统中保存的class文件并把内容读入内存中，此时内存中为UNICODE格式的class类，然后JVM运行它，如果此时此类需要接收用户输入，则类会默认用file.encoding编码格式对用户输入的串进行编码并转化为unicode保存入内存（用户可以设置输入流的编码格式）。程序运行后，产生的字符串（UNICODE编码的）再回交给JVM，最后JRE把此字符串再转化为file.encoding格式(用户可以设置输出流的编码格式)传递给操作系统显示接口并输出到界面上。<br />    对于这种直接在console上运行的类，它的转化过程可用图1更加明确的表示出来：</p>
		<p>
				<img style="BORDER-RIGHT: black 1px solid; BORDER-TOP: black 1px solid; BORDER-LEFT: black 1px solid; BORDER-BOTTOM: black 1px solid" src="http://java.ccidnet.com/col/attachment/2006/6/713009.gif" />
		</p>
		<p>图1<br />    以上每一步的转化都需要正确的编码格式转化，才能最终不出现乱码现象。<br />    B、EJB类和不可以直接运行的支持类(如JavaBean类)<br />    由于EJB类和不可以直接运行的支持类，它们一般不与用户直接交互输入和输出，它们常常与其它的类进行交互输入和输出，所以它们在第二步被编译后，就形成了内容是UNICODE编码的类保存在操作系统中了，以后只要它与其它的类之间的交互在参数传递过程中没有丢失，则它就会正确的运行。<br />这种EJB类和不可以直接运行的支持类, 它的转化过程可用图2更加明确的表示出来：</p>
		<p>
				<img style="BORDER-RIGHT: black 1px solid; BORDER-TOP: black 1px solid; BORDER-LEFT: black 1px solid; BORDER-BOTTOM: black 1px solid" src="http://java.ccidnet.com/col/attachment/2006/6/713011.gif" />
		</p>
		<p>图2<br />    C、JSP代码和Servlet类<br />    经过第二步后，JSP文件也被转化为Servlets类文件，只不过它不像标准的Servlets一校存在于classes目录中，它存在于WEB容器的临时目录中，故这一步中我们也把它做为Servlets来看。<br />    对于Servlets，客户端请求它时，WEB容器调用它的JVM来运行Servlet，首先，JVM把Servlet的class类从系统中读出并装入内存中，内存中是以UNICODE编码的Servlet类的代码，然后JVM在内存中运行该Servlet类，如果Servlet在运行的过程中，需要接受从客户端传来的字符如：表单输入的值和URL中传入的值，此时如果程序中没有设定接受参数时采用的编码格式，则WEB容器会默认采用ISO-8859-1编码格式来接受传入的值并在JVM中转化为UNICODE格式的保存在WEB容器的内存中。Servlet运行后生成输出，输出的字符串是UNICODE格式的，紧接着，容器将Servlet运行产生的UNICODE格式的串（如html语法，用户输出的串等）直接发送到客户端浏览器上并输出给用户，如果此时指定了发送时输出的编码格式，则按指定的编码格式输出到浏览器上，如果没有指定，则默认按ISO-8859-1编码发送到客户的浏览器上。这种JSP代码和Servlet类，它的转化过程可用图3更加明确地表示出来：</p>
		<p>
				<img style="BORDER-RIGHT: black 1px solid; BORDER-TOP: black 1px solid; BORDER-LEFT: black 1px solid; BORDER-BOTTOM: black 1px solid" src="http://java.ccidnet.com/col/attachment/2006/6/713013.gif" />
		</p>
		<p>图3<br />    D、Java程序和数据库之间<br />    对于几乎所有数据库的JDBC驱动程序，默认的在JAVA程序和数据库之间传递数据都是以ISO-8859-1为默认编码格式的，所以，我们的程序在向数据库内存储包含中文的数据时，JDBC首先是把程序内部的UNICODE编码格式的数据转化为ISO-8859-1的格式，然后传递到数据库中，在数据库保存数据时，它默认即以ISO-8859-1保存，所以，这是为什么我们常常在数据库中读出的中文数据是乱码。<br />    对于JAVA程序和数据库之间的数据传递，我们可以用图4清晰地表示出来</p>
		<p>
				<img style="BORDER-RIGHT: black 1px solid; BORDER-TOP: black 1px solid; BORDER-LEFT: black 1px solid; BORDER-BOTTOM: black 1px solid" src="http://java.ccidnet.com/col/attachment/2006/6/713015.gif" />
		</p>
		<p>图4<br />    <b>3、分析常见的JAVA中文问题几个必须清楚的原则</b><br />    首先，经过上面的详细分析，我们可以清晰地看到，任何JAVA程序的生命期中，其编码转换的关键过程是在于：最初编译成class文件的转码和最终向用户输出的转码过程。<br />    其次，我们必须了解JAVA在编译时支持的、常用的编码格式有以下几种：<br />    *ISO-8859-1，8-bit, 同8859_1,ISO-8859-1,ISO_8859_1等编码<br />    *Cp1252，美国英语编码，同ANSI标准编码<br />    *UTF-8，同unicode编码<br />    *GB2312，同gb2312-80,gb2312-1980等编码<br />    *GBK , 同MS936，它是gb2312的扩充<br />    及其它的编码，如韩文、日文、繁体中文等。同时，我们要注意这些编码间的兼容关体系如下：<br />    unicode和UTF-8编码是一一对应的关系。GB2312可以认为是GBK的子集，即GBK编码是在gb2312上扩展来的。同时，GBK编码包含了20902个汉字，编码范围为：0x8140-0xfefe，所有的字符可以一一对应到UNICODE2.0中来。<br />    再次，对于放在操作系统中的.java源程序文件，在编译时，我们可以指定它内容的编码格式，具体来说用-encoding来指定。注意：如果源程序中含有中文字符，而你用-encoding指定为其它的编码字符，显然是要出错的。用-encoding指定源文件的编码方式为GBK或gb2312，无论我们在什么系统上编译含有中文字符的JAVA源程序都不会有问题，它都会正确地将中文转化为UNICODE存储在class文件中。<br />    <br />然后，我们必须清楚，几乎所有的WEB容器在其内部默认的字符编码格式都是以ISO-8859-1为默认值的，同时，几乎所有的浏览器在传递参数时都是默认以UTF-8的方式来传递参数的。所以，虽然我们的Java源文件在出入口的地方指定了正确的编码方式，但其在容器内部运行时还是以ISO-8859-1来处理的。<br /></p>
		<p> </p>
		<p align="center">
				<br />
		</p>
		<br />
		<br />
		<p>   <b>4、中文问题的分类及其建议最优解决办法</b><br />    了解以上JAVA处理文件的原理之后，我们就可以提出了一套建议最优的解决汉字问题的办法。<br />    我们的目标是：我们在中文系统中编辑的含有中文字符串或进行中文处理的JAVA源程序经编译后可以移值到任何其它的操作系统中正确运行，或拿到其它操作系统中编译后能正确运行，能正确地传递中文和英文参数，能正确地和数据库交流中英文字符串。<br />    我们的具体思路是：在JAVA程序转码的入口和出口及JAVA程序同用户有输入输出转换的地方限制编码方法使之正确即可。<br />    具体解决办法如下：<br />    1、 针对直接在console上运行的类<br />    对于这种情况，我们建议在程序编写时，如果需要从用户端接收用户的可能含有中文的输入或含有中文的输出，程序中应该采用字符流来处理输入和输出，具体来说，应用以下面向字符型节点流类型：<br />    对文件：FileReader，FileWrieter <br />        其字节型节点流类型为：FileInputStream，FileOutputStream<br />    对内存（数组）：CharArrayReader，CharArrayWriter<br />        其字节型节点流类型为：ByteArrayInputStream，ByteArrayOutputStream<br />    对内存（字符串）：StringReader，StringWriter<br />    对管道：PipedReader，PipedWriter<br />        其字节型节点流类型为：PipedInputStream，PipedOutputStream<br />    同时，应该用以下面向字符型处理流来处理输入和输出：<br />    BufferedWriter，BufferedReader<br />        其字节型的处理流为：BufferedInputeStream，BufferedOutputStream<br />    InputStreamReader，OutputStreamWriter<br />    其字节型的处理流为：DataInputStream，DataOutputStream<br />    其中InputStreamReader和InputStreamWriter用于将字节流按照指定的字符编码集转换到字符流，如：<br />    InputStreamReader in = new InputStreamReader(System.in，"GB2312")；<br />    OutputStreamWriter out = new OutputStreamWriter (System.out，"GB2312")；<br />    例如：采用如下的示例JAVA编码就达到了要求：<br />//Read.java<br />import java.io.*;<br />public class Read {<br />public static void main(String[] args) throws IOException {<br />String str = "\n中文测试，这是内部硬编码的串"+"\ntest english character";<br />String strin= "";<br />BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in,"gb2312")); //设置输入接口按中文编码<br />BufferedWriter stdout = new BufferedWriter(new OutputStreamWriter(System.out,"gb2312")); //设置输出接口按中文编码<br />stdout.write("请输入:");<br />stdout.flush();<br />strin = stdin.readLine();<br />stdout.write("这是从用户输入的串："+strin);<br />stdout.write(str);<br />stdout.flush();<br />}}<br />    同时，在编译程序时，我们用以下方式来进行：<br />    javac -encoding gb2312 Read.java<br />    其运行结果如图5所示：<br /><br />    图5<br />    2、 针对EJB类和不可以直接运行的支持类(如JavaBean类)<br />    由于这种类它们本身被其它的类调用，不直接与用户交互，故对这种类来说，我们的建议的处理方式是内部程序中应该采用字符流来处理程序内部的中文字符串（具体如上面一节中一样），同时，在编译类时用-encoding gb2312参数指示源文件是中文格式编码的即可。<br />    3、 针对Servlet类<br />    针对Servlet，我们建议用以下方法：<br />    在编译Servlet类的源程序时，用-encoding指定编码为GBK或GB2312，且在向用户输出时的编码部分用response对象的setContentType("text/html;charset=GBK");或gb2312来设置输出编码格式，同样在接收用户输入时，我们用request.setCharacterEncoding("GB2312")；这样无论我们的servlet类移植到什么操作系统中，只有客户端的浏览器支持中文显示，就可以正确显示。如下是一个正确的示例：<br /><font face="Times New Roman" size="3">//HelloWorld.java<br />package hello;<br />import java.io.*;<br />import javax.servlet.*;<br />import javax.servlet.http.*;<br />public class HelloWorld extends HttpServlet<br />{<br />public void init() throws ServletException { }<br />public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException<br />{<br />request.setCharacterEncoding("GB2312"); //设置输入编码格式<br />response.setContentType("text/html;charset=GB2312"); //设置输出编码格式<br />PrintWriter out = response.getWriter(); //建议使用PrintWriter输出<br />out.println("&amp;lt hr &amp;gt");<br />out.println("Hello World! This is created by Servlet!测试中文!");<br />out.println("&amp;lt hr &amp;gt");<br />}<br />public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException<br />{<br />request.setCharacterEncoding("GB2312"); //设置输入编码格式<br />response.setContentType("text/html;charset=GB2312"); //设置输出编码格式<br />String name = request.getParameter("name");<br />String id = request.getParameter("id");<br />if(name==null) name="";<br />if(id==null) id="";<br />PrintWriter out = response.getWriter(); //建议使用PrintWriter输出<br />out.println("&amp;lt hr &amp;gt");<br />out.println("你传入的中文字串是：" + name);<br />out.println("&amp;lt hr &amp;gt你输入的id是：" + id);<br />out.println("&amp;lt hr &amp;gt");<br />}<br />public void destroy() { }<br />}<br />    请用javac -encoding gb2312 HelloWorld.java来编译此程序。<br />    测试此Servlet的程序如下所示：<br />&amp;lt %@page contentType="text/html; charset=gb2312"% &amp;gt<br />&amp;lt %request.setCharacterEncoding("GB2312");% &amp;gt<br />&amp;lt html &amp;gt&amp;lt head &amp;gt&amp;lt title &amp;gt&amp;lt /title &amp;gt<br />&amp;lt Script language="JavaScript" &amp;gt<br />function Submit() {<br />//通过URL传递中文字符串值给Servlet<br />document.base.action = "./HelloWorld?name=中文";<br />document.base.method = "POST";<br />document.base.submit();<br />}<br />&amp;lt /Script &amp;gt<br />&amp;lt /head &amp;gt<br />&amp;lt body bgcolor="#FFFFFF" text="#000000" topmargin="5" &amp;gt<br />&amp;lt form name="base" method = "POST" target="_self" &amp;gt<br />&amp;lt input name="id" type="text" value="" size="30" &amp;gt<br />&amp;lt a href = "JavaScript:Submit()" &amp;gt传给Servlet&amp;lt /a &amp;gt<br />&amp;lt /form &amp;gt&amp;lt /body &amp;gt&amp;lt /html &amp;gt<br />    其运行结果如图6所示：<br /><br />    图6<br />    4、 JAVA程序和数据库之间<br />    为避免JAVA程序和数据库之间数据传递出现乱码现象，我们建议采用以下最优方法来处理：<br />    1、 对于JAVA程序的处理方法按我们指定的方法处理。<br />    2、 把数据库默认支持的编码格式改为GBK或GB2312的。<br />    如：在mysql中，我们可以在配置文件my.ini中加入以下语句实现：<br />    在[mysqld]区增加：<br />    default-character-set=gbk<br />    并增加：<br />    [client]<br />    default-character-set=gbk<br />    在SQL Server2K中，我们可以将数据库默认的语言设置为Simplified Chinese来达到目的。<br />    5、 针对JSP代码<br />    由于JSP是在运行时，由WEB容器进行动态编译的，如果我们没有指定JSP源文件的编码格式，则JSP编译器会获得服务器操作系统的file.encoding值来对JSP文件编译的，它在移植时最容易出问题，如在中文win2k中可以很好运行的jsp文件拿到英文linux中就不行，尽管客户端都是一样的，那是因为容器在编译JSP文件时获取的操作系统的编码不同造成的（在中文wink中的file.encoding和在英文Linux中file.encoding是不同的，且英文Linux的file.encoding对中文不支持，所以编译出来的JSP类就会有问题）。网络上讨论的大多数是此类问题，多是因为JSP文件移植平台时不能正确显示的问题，对于这类问题，我们了解了JAVA中程序编码转换的原理，解决起来就容易多了。我们建议的解决办法如下：<br />    1、我们要保证JSP向客户端输出时是采用中文编码方式输出的，即无论如何我们首先在我们的JSP源代编中加入以下一行：<br /></font></p>
		<p>
				<font face="Times New Roman" size="3">  &amp;lt %@page contentType="text/html; charset=gb2312"% &amp;gt<br />    2、为了让JSP能正确获得传入的参数，我们在JSP源文件头加入下面一句：<br />    &amp;lt %request.setCharacterEncoding("GB2312");% &amp;gt<br />    3、为了让JSP编译器能正确地解码我们的含有中文字符的JSP文件，我们需要在JSP源文件中指定我们的JSP源文件的编码格式，具体来说，我们在JSP源文件头上加入下面的一句即可：<br />    &amp;lt %@page pageEncoding="GB2312"% &amp;gt或&amp;lt %@page pageEncoding="GBK"% &amp;gt<br />    这是JSP规范2.0新增加的指令。<br />    我们建议使用此方法来解JSP文件中的中文问题，下面的代码是一个正确做法的JSP文件的测试程序：<br />//testchinese.jsp<br />&amp;lt %@page pageEncoding="GB2312"% &amp;gt<br />&amp;lt %@page contentType="text/html; charset=gb2312"% &amp;gt<br />&amp;lt %request.setCharacterEncoding("GB2312");% &amp;gt<br />&amp;lt %<br />String action = request.getParameter("ACTION");<br />String name = "";<br />String str = "";<br />if(action!=null &amp;&amp; action.equals("SENT"))<br />{<br />name = request.getParameter("name");<br />str = request.getParameter("str");<br />}<br />% &amp;gt<br />&amp;lt html &amp;gt<br />&amp;lt head &amp;gt<br />&amp;lt title &amp;gt&amp;lt /title &amp;gt<br />&amp;lt Script language="JavaScript" &amp;gt<br />function Submit()<br />{<br />document.base.action = "?ACTION=SENT&amp;str=传入的中文";<br />document.base.method = "POST";<br />document.base.submit();<br />}<br />&amp;lt /Script &amp;gt<br />&amp;lt /head &amp;gt<br />&amp;lt body bgcolor="#FFFFFF" text="#000000" topmargin="5" &amp;gt<br />&amp;lt form name="base" method = "POST" target="_self" &amp;gt<br />&amp;lt input type="text" name="name" value="" size="30" &amp;gt<br />&amp;lt a href = "JavaScript:Submit()" &amp;gt提交&amp;lt /a &amp;gt<br />&amp;lt /form &amp;gt<br />&amp;lt %<br />if(action!=null &amp;&amp; action.equals("SENT"))<br />{<br />out.println("&amp;lt br &amp;gt你输入的字符为："+name);<br />out.println("&amp;lt br &amp;gt你通过URL传入的字符为："+str);<br />}<br />% &amp;gt<br />&amp;lt /body &amp;gt<br />&amp;lt /html &amp;gt<br />    如图7是此程序运行的结果示意图：<br /><br />    图7<br />    <b>5、总结</b><br />    在上面的详细分析中，我们清晰地给出了JAVA在处理源程序过程中的详细转换过程，为我们正确解决JAVA编程中的中文问题提供了基础。同时，我们给出了认为是最优的解决JAVA中文问题的办法。<br />    <b>6、参考资料</b><br />    1、段明辉.Java 编程技术中汉字问题的分析及解决.<br />        http://www-900.ibm.com/developerWorks/cn/java/java_chinese/index.shtml<br />    2、 周竞涛.关于Java中文问题的几条分析原则<br />        http://www-900.ibm.com/developerWorks/cn/java/l-javachinese/index.shtml<br />    <b>7、作者介绍</b><br />        作者：abnerchai，高级程序员，作者联系方法：<a href="mailto:josserchai@yahoo.com">josserchai@yahoo.com</a><br /></font>
		</p>
		<p>
				<font face="Times New Roman" size="3">   </font>
				<br />
		</p>
<img src ="http://www.blogjava.net/jiabao/aggbug/109661.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jiabao/" target="_blank">金家寶</a> 2007-04-10 15:55 <a href="http://www.blogjava.net/jiabao/archive/2007/04/10/109661.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>表现层、持久层、业务层</title><link>http://www.blogjava.net/jiabao/archive/2007/04/08/109189.html</link><dc:creator>金家寶</dc:creator><author>金家寶</author><pubDate>Sat, 07 Apr 2007 19:17:00 GMT</pubDate><guid>http://www.blogjava.net/jiabao/archive/2007/04/08/109189.html</guid><wfw:comment>http://www.blogjava.net/jiabao/comments/109189.html</wfw:comment><comments>http://www.blogjava.net/jiabao/archive/2007/04/08/109189.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jiabao/comments/commentRss/109189.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jiabao/services/trackbacks/109189.html</trackback:ping><description><![CDATA[
		<div class="postText">
				<p>
						<font size="4">为了实现web层（struts）和持久层（Hibernate）之间的松散耦合，我们采用业务代表（Business Delegate）和DAO（Data Access Object）两种模式。DAO模式为了减少业务逻辑和数据访问逻辑之间的耦合，当一个持久曾框架被应用时，该模式将会减少业务对象和该框架之间的耦合，这样我们可以不修改业务对象而选择不同的持久层框架的实现。实际上在DAO模式中包含两种结构模式：桥（Bridge）模式和适配器（Adaptor）模式。 </font>
				</p>
				<p>
						<font size="4">对表现层，我们使用</font>
						<a style="COLOR: rgb(0,0,128)" href="http://jakarta.apache.org/struts">
								<font size="4">Struts</font>
						</a>
						<font size="4">；业务层使用</font>
						<a style="COLOR: rgb(0,0,128)" href="http://www.springframework.org/">
								<font size="4">Spring</font>
						</a>
						<font size="4">；对于持久层我们使用的是</font>
						<a style="COLOR: rgb(0,0,255)" href="http://www.hibernate.org/">
								<font size="4">Hibernate</font>
						</a>
						<font size="4">。你尽可以取代这里的某个框架而使用你喜欢的框架已达到同样的效果。下图显示了框架被整合起来时，从最高层次看到的视图。<br /><br /><img height="193" alt="clip_image001_0007.gif" src="http://www.blogjava.net/images/blogjava_net/steelhand/clip_image001_0007.gif" width="450" border="0" /></font>
				</p>
				<p align="left">
						<font size="4">
								<strong>应用层</strong>
								<strong>
								</strong>
						</font>
				</p>
				<p>
						<font size="4">    许多设计良好的web应用，可以被按职责分为四层。这些层次是表现层、持久层、业务层、和领域模型层。每一个层次都有其独特的职责，不能把各自的功能与其它层次相混合。每一个应用层都应该和其它层隔离开来，但允许使用接口在层间进行通信。我们开始来看看每个层，并讨论一下它们各自都应该提供什么和不应该提供什么。</font>
				</p>
				<p align="left">
						<font size="4">
								<strong>表现层</strong>
								<strong>
								</strong>
						</font>
				</p>
				<p>
						<font size="4">    一个典型的web 应用的末端是表现层。许多Java 开发者都知道Struts提供了什么东西。然而，太多时候，耦合代码比如业务逻辑被放进org.apache.struts.Action中。所以，我们先总结一下Struts之类的框架应该提供什么。下面就是Struts 的职责所在：</font>
				</p>
				<ol>
						<li>
								<font size="4">管理用户的请求和响应 </font>
						</li>
						<li>
								<font size="4">提供一个控制起来将调用委托到业务逻辑和其他上游处理 </font>
						</li>
						<li>
								<font size="4">将来自于抛出例外的其他层的例外处理到Struts Action 中 </font>
						</li>
						<li>
								<font size="4">组装可以在视图中表现的模型对象 </font>
						</li>
						<li>
								<font size="4">执行UI 校验</font>
						</li>
				</ol>
				<p>
						<font size="4">下面是一些经常可以使用Struts进行编码但是不应该和表现层关联的事情：</font>
				</p>
				<ol>
						<li>
								<font size="4">直接和数据库交互，比如JDBC 调用 </font>
						</li>
						<li>
								<font size="4">与应用相关的业务逻辑和校验 </font>
						</li>
						<li>
								<font size="4">事务管理</font>
						</li>
				</ol>
				<p>
						<font size="4">在表现层中引入这些类型的代码将导致类型耦合和维护负担。</font>
				</p>
				<p align="left">
						<font size="4">
								<strong>持久层</strong>
								<strong>
								</strong>
						</font>
				</p>
				<p>
						<font size="4">    一个典型Web应用的另一端是持久层。这也是应用中最容易很快失控的地方。开发者通常低估了自己构建自己的持久层框架的挑战。一个定制的，内部开发的持久层不仅需要大量的开发时间，并且通常缺乏功能和难以管理。目前有许多解决这些问题的开源对象关系映射 (ORM) 框架。特别地，Hibernate 框架就允许Java中的对象-关系的持久性和查询服务。Hibernate 对已经熟悉了SQL 和JDBC API的Java开发者来或具有中度的学习曲线。Hibernate 的持久对象基于POJO和Java群集（collections）。此外，使用Hibernate 不和你的IDE接口。下面列出了你需要在持久性框架中编写的代码类型：</font>
				</p>
				<ol>
						<li>
								<font size="4">查询关系信息到对象中。Hibernate是通过称为HQL的OO查询语言，或者使用更有表现能力的规则API，来完成这个工作的。除了使用对象而不是表，使用字段而不是列的方式，HQL非常类似于 SQL。也有一些新的特定的HQL 语言特征需要学习；但是，它们是很容易理解和良好编写的。HQL是一种用于查询对象的自然语言，而对象，只需要很少的学习曲线吧。. </font>
						</li>
						<li>
								<font size="4">存储、更新和删除存储在数据库中的信息 </font>
						</li>
						<li>
								<font size="4">高级的对象关系映射框架比如Hibernate支持大部分主流SQL数据库，它们支持父/子关系，事务，继承和多态。</font>
						</li>
				</ol>
				<p>
						<font size="4">下面是应该在持久层避免的一些事情：</font>
				</p>
				<ol>
						<li>
								<font size="4">业务逻辑应该置于应用的更高层中。这里只允许数据访问方法。 </font>
						</li>
						<li>
								<font size="4">不应该使持久逻辑和表现逻辑耦合。避免表现组件如JSP或者基于servlet的类中的逻辑直接和数据访问进行通信。通过将持久性逻辑隔离在其自己的层中，应用将具有更加灵活的修改性而不影响到其他层的代码。例如， Hibernate可以使用其他持久框架和API代替，而不需要修改其它层中的代码。</font>
						</li>
				</ol>
				<p>
						<font size="4">业务层应该负责下面的问题：</font>
				</p>
				<ol>
						<li>
								<font size="4">处理应用的业务逻辑和业务校验 </font>
						</li>
						<li>
								<font size="4">管理事务 </font>
						</li>
						<li>
								<font size="4">允许与其他层进行交互的接口 </font>
						</li>
						<li>
								<font size="4">管理业务级对象之间的依赖性 </font>
						</li>
						<li>
								<font size="4">加入了表现和持久层之间的灵活性，以便它们不需要彼此进行直接通信 </font>
						</li>
						<li>
								<font size="4">从表现层暴露上下文给业务层以获得业务服务 </font>
						</li>
						<li>
								<font size="4">管理从业务层到表现层的实现</font>
						</li>
				</ol>
		</div>
<img src ="http://www.blogjava.net/jiabao/aggbug/109189.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jiabao/" target="_blank">金家寶</a> 2007-04-08 03:17 <a href="http://www.blogjava.net/jiabao/archive/2007/04/08/109189.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于POJO及DAO- -</title><link>http://www.blogjava.net/jiabao/archive/2007/04/06/109033.html</link><dc:creator>金家寶</dc:creator><author>金家寶</author><pubDate>Fri, 06 Apr 2007 14:11:00 GMT</pubDate><guid>http://www.blogjava.net/jiabao/archive/2007/04/06/109033.html</guid><wfw:comment>http://www.blogjava.net/jiabao/comments/109033.html</wfw:comment><comments>http://www.blogjava.net/jiabao/archive/2007/04/06/109033.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jiabao/comments/commentRss/109033.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jiabao/services/trackbacks/109033.html</trackback:ping><description><![CDATA[
		<p>POJO = pure old Java object POJO有一些private的参数作为对象的属性。然后针对每个参数定义了get和set方法作为访问的接口。例如： public class User { </p>
		<p>private long id; </p>
		<p>private String name; </p>
		<p>public void setId(long id) { </p>
		<p>this.id = id; </p>
		<p>} </p>
		<p>public void setName(String name) { </p>
		<p>this.name=name; </p>
		<p>} </p>
		<p>public long getId() { </p>
		<p>return id; </p>
		<p>} </p>
		<p>public String getName() { </p>
		<p>return name; </p>
		<p>} </p>
		<p>} </p>
		<p>POJO对象有时也被称为Data对象，大量应用于表现现实中的对象。 </p>
		<!-- Saved in parser cache with key wikidb:pcache:idhash:9963-0!1!0!0!!zh-cn!2 and timestamp 20070406133935 -->
		<div class="printfooter">取自"<a href="http://wiki.ccw.com.cn/POJO">http://wiki.ccw.com.cn/POJO</a>"</div>
		<!-- end content -->
		<div class="visualClear">
		</div>
		<h2 class="diaryTitle"> </h2>                                       
<p></p><p>POJO = pure old java object or plain ordinary java object or what ever.</p><p>PO = persisent object 持久对象</p><p>就是说在一些Object/Relation Mapping工具中，能够做到维护数据库表记录的persisent object完全是一个符合Java Bean规范的纯Java对象，没有增加别的属性和方法。全都是这样子的：</p><pre class="code">public class User { 
  private long id; 
  private String name;
  public void setId(long id) {
 this.id = id;
}  
public void setName(String name) {
this.name=name;
} 
 public long getId() {
 return id;
}  
public String getName() { 
return name;
}
}  
</pre><hr /><p>首先要区别持久对象和POJO。</p><p>持久对象实际上必须对应数据库中的entity，所以和POJO有所区别。比如说POJO是由new创建，由GC回收。但是持久对象是insert数据库创建，由数据库delete删除的。基本上持久对象生命周期和数据库密切相关。另外持久对象往往只能存在一个数据库Connection之中，Connnection关闭以后，持久对象就不存在了，而POJO只要不被GC回收，总是存在的。</p><p>由于存在诸多差别，因此持久对象PO(Persistent Object)在代码上肯定和POJO不同，起码PO相对于POJO会增加一些用来管理数据库entity状态的属性和方法。而ORM追求的目标就是要PO在使用上尽量和POJO一致，对于程序员来说，他们可以把PO当做POJO来用，而感觉不到PO的存在。</p><p>JDO的实现方法是这样的：</p><p>1、编写POJO</p><p>2、编译POJO</p><p>3、使用JDO的一个专门工具，叫做Enhancer，一般是一个命令行程序，手工运行，或者在ant脚本里面运行，对POJO的class文件处理一下，把POJO替换成同名的PO。</p><p>4、在运行期运行的实际上是PO，而不是POJO。</p><p>该方法有点类似于JSP，JSP也是在编译期被转换成Servlet来运行的，在运行期实际上运行的是Servlet，而不是JSP。</p><p>Hibernate的实现方法比较先进：</p><p>1、编写POJO</p><p>2、编译POJO</p><p>3、直接运行，在运行期，由Hibernate的CGLIB动态把POJO转换为PO。</p><p>由此可以看出Hibernate是在运行期把POJO的字节码转换为PO的，而JDO是在编译期转换的。一般认为JDO的方式效率会稍高，毕竟是编译期转换嘛。但是Hibernate的作者Gavin King说CGLIB的效率非常之高，运行期的PO的字节码生成速度非常之快，效率损失几乎可以忽略不计。</p><p>实际上运行期生成PO的好处非常大，这样对于程序员来说，是无法接触到PO的，PO对他们来说完全透明。可以更加自由的以POJO的概念操纵PO。另外由于是运行期生成PO，所以可以支持增量编译，增量调试。而JDO则无法做到这一点。实际上已经有很多人在抱怨JDO的编译期Enhancer问题了，而据说JBossDO将采用运行期生成PO字节码，而不采用编译期生成PO字节码。</p><p>另外一个相关的问题是，不同的JDO产品的Enhancer生成的PO字节码可能会有所不同，可能会影响在JDO产品之间的可移植性，这一点有点类似EJB的可移植性难题。</p><hr /><p>由这个问题另外引出一个JDO的缺陷。</p><p>由于JDO的PO状态管理方式，所以当你在程序里面get/set的时候，实际上不是从PO的实例中取values，而是从JDO <a href="http://www.hibernate.org.cn/index.php?cmd=newdoc&amp;newdocname=State+Manager&amp;node=48&amp;refnode=84"><font color="#006699">State Manager</font></a><strong class="missing"><font color="#880000">?</font></strong>中取出来，所以一旦PM关闭，PO就不能进行存取了。</p><p>在JDO中，也可以通过一些办法使得PO可以在PM外面使用，比如说定义PO是transient的，但是该PO在PM关闭后就没有PO identity了。无法进行跨PM的状态管理。</p><p>而Hibernate是从PO实例中取values的，所以即使Session关闭，也一样可以get/set，可以进行跨Session的状态管理。</p><p>在分多层的应用中，由于持久层和业务层和web层都是分开的，此时Hibernate的PO完全可以当做一个POJO来用，也就是当做一个VO，在各层间自由传递，而不用去管Session是开还是关。如果你把这个POJO序列化的话，甚至可以用在分布式环境中。（不适合lazy loading的情况）</p><p>但是JDO的PO在PM关闭后就不能再用了，所以必须在PM关闭前把PO拷贝一份VO，把VO传递给业务层和web层使用。在非分布式环境中，也可以使用ThreadLocal模式确保PM始终是打开状态，来避免每次必须进行PO到VO的拷贝操作。但是不管怎么说，这总是权宜之计，不如Hibernate的功能强。</p><p>辨别一些名词： <br />1。VO：实际上很模糊，通常指ValueObject和ViewObject <br />2. ViewObject，界面展现需要的对象，如Struts的FormBean <br />3。Value Object，早期被作为ValueObject和Transfer Object的总称。实际上Value Object的真正意义在于它的内容，而不是身份 <br />4。Transfer Object：数据传输对象，在应用程序不同层次之间传书对象，在一个分布式应用程序中，通常可以提高整体的性能 <br />5。PO：也许就是Persistent Object，基本上就是Entity了 <br />在不同的体系结构和实现方式里面，这些对象有可能重复，也有可能不重叠。如果你要做一个对所有的体系都能够方便移植的框架，那么每一种对象都需要严格区分。例如JDO的PO不能作为TO，应为它不能脱离PM，譬如你可以选择用ViewObject（如Struts的FOrmBean)直接作为TO，但在tapestry和Webwork里面就不合适了。但在很多时候，能够方便实用是最重要的，不要过度设计就是了。 </p><p>POJO是这样一个对象，它是一个普通的Java对象，它不同于EJB这样的带有繁重的容器控制功能的对象，它也不是那种被Enhanced过的对象，例如JDO的静态Enhance，也不是类似Hibernate那样被动态的byte code generation过。 <br /><br />也就是说POJO的概念是相对于其他那种被人动过手脚的class而言的，它是没有被动过手脚的。 <br /><br />其实，为什么要做DAO?无非是： <br />1， 管理connection/transaction (hibernate的话就是session/transaction) <br />2, 便于进行统计/log操作； <br />3， 便于进行权限控制； <br /><br />DAO模式中，有两类对象，一种是DAO，一种是valueObject。 在我们讨论的这个情况中，value object是hibernate对应的POJO. <br /><br />那么，按照我的理解，DAO就是一个Transaction包装器，其逻辑结构就是商业的具体事务。此处，数据库的transaction和商业的事务是统一的。</p><img src ="http://www.blogjava.net/jiabao/aggbug/109033.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jiabao/" target="_blank">金家寶</a> 2007-04-06 22:11 <a href="http://www.blogjava.net/jiabao/archive/2007/04/06/109033.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>搭建TOMCAT+JPETSTORE出现的错误</title><link>http://www.blogjava.net/jiabao/archive/2007/04/01/107751.html</link><dc:creator>金家寶</dc:creator><author>金家寶</author><pubDate>Sun, 01 Apr 2007 06:15:00 GMT</pubDate><guid>http://www.blogjava.net/jiabao/archive/2007/04/01/107751.html</guid><wfw:comment>http://www.blogjava.net/jiabao/comments/107751.html</wfw:comment><comments>http://www.blogjava.net/jiabao/archive/2007/04/01/107751.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/jiabao/comments/commentRss/107751.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jiabao/services/trackbacks/107751.html</trackback:ping><description><![CDATA[ool.java:684)<br />        at java.lang.Thread.run(Thread.java:595)<br />2007-04-01 13:52:17,234 [http-8080-Processor20] DEBUG org.apache.struts.action.R<br />equestProcessor - processForwardConfig(ForwardConfig[name=null,path=/common/Erro<br />r.jsp,redirect=false,contextRelative=false,module=null])<br />2007-04-01 13:52:17,968 [http-8080-Processor20] DEBUG org.apache.struts.util.Mod<br />uleUtils - Get module name for path /shop/viewCategory.shtml<br />2007-04-01 13:52:17,968 [http-8080-Processor20] DEBUG org.apache.struts.util.Mod<br />uleUtils - Module name found: default<br />2007-04-01 13:52:17,968 [http-8080-Processor20] DEBUG org.apache.struts.action.R<br />equestProcessor - Processing a 'GET' for path '/shop/viewCategory'<br />2007-04-01 13:52:17,968 [http-8080-Processor20] DEBUG org.apache.struts.util.Req<br />uestUtils -  Looking for ActionForm bean instance in scope 'request' under attri<br />bute key 'productListForm'<br />2007-04-01 13:52:17,968 [http-8080-Processor20] DEBUG org.apache.struts.util.Req<br />uestUtils -  Creating new ActionForm instance of type 'com.jdon.strutsutil.Model<br />ListForm'<br />2007-04-01 13:52:17,968 [http-8080-Processor20] DEBUG org.apache.struts.util.Req<br />uestUtils -  --&gt; <a href="mailto:com.jdon.strutsutil.ModelListForm@1ff2e1b">com.jdon.strutsutil.ModelListForm@1ff2e1b</a><br />2007-04-01 13:52:17,968 [http-8080-Processor20] DEBUG org.apache.struts.action.R<br />equestProcessor -  Storing ActionForm bean instance in scope 'request' under att<br />ribute key 'productListForm'<br />2007-04-01 13:52:17,968 [http-8080-Processor20] DEBUG org.apache.struts.action.R<br />equestProcessor -  Populating bean properties from this request<br />2007-04-01 13:52:17,968 [http-8080-Processor20] DEBUG org.apache.struts.action.R<br />equestProcessor -  Looking for Action instance for class com.jdon.framework.samp<br />les.jpetstore.presentation.action.ProductListAction<br />2007-04-01 13:52:17,968 [http-8080-Processor20] DEBUG org.apache.struts.action.R<br />equestProcessor -   Returning existing Action instance<br />2007-04-01 13:52:17,984 [http-8080-Processor20] DEBUG com.jdon.bussinessproxy.co<br />nfig.TargetMetaDefXmlLoader - [JdonFramework]metaDefs size:12<br />2007-04-01 13:52:17,984 [http-8080-Processor20] DEBUG com.jdon.controller.servic<br />e.WebServiceFactory - [JdonFramework] getService was found in:productManager<br />2007-04-01 13:52:17,984 [http-8080-Processor20] DEBUG com.jdon.security.web.Http<br />RequestUserSetup - [JdonFramework] setArrtibute:REMOTE_ADDRESS=127.0.0.1<br />2007-04-01 13:52:17,984 [http-8080-Processor20] DEBUG com.jdon.container.access.<br />ServiceAccessorImp - [JdonFramework] enter getService: proxyInstanceFactoryVisit<br />able in action<br />2007-04-01 13:52:17,984 [http-8080-Processor20] DEBUG com.jdon.container.visitor<br />.HttpSessionProxyVisitor - [JdonFramework] get the optimized instance for the ke<br />y com.jdon.framework.samples.jpetstore.service.bo.ProductManagerImpproxyInstance<br />FactoryVisitable<br />2007-04-01 13:52:17,984 [http-8080-Processor20] DEBUG com.jdon.bussinessproxy.dy<br />ncproxy.DynamicProxyWeaving - [JdonFramework]call method:com.jdon.framework.samp<br />les.jpetstore.service.ProductManager.getProductIDsListByCategory<br />2007-04-01 13:52:17,984 [http-8080-Processor20] DEBUG com.jdon.aop.AopClient - [<br />JdonFramework] enter AOP invoker2 for:com.jdon.framework.samples.jpetstore.servi<br />ce.bo.ProductManagerImp method:getProductIDsListByCategory<br />2007-04-01 13:52:17,984 [http-8080-Processor20] DEBUG com.jdon.aop.joinpoint.Adv<br />isorChainFactory - [JdonFramework] enter  create PointcutAdvisor<br />2007-04-01 13:52:17,984 [http-8080-Processor20] DEBUG com.jdon.aop.joinpoint.Adv<br />isorChainFactory - [JdonFramework] find all service's interceptos size=1<br />2007-04-01 13:52:17,984 [http-8080-Processor20] DEBUG com.jdon.aop.joinpoint.Adv<br />isorChainFactory - [JdonFramework] find pojoService's interceptos size=4<br />2007-04-01 13:52:17,984 [http-8080-Processor20] DEBUG com.jdon.aop.reflection.Pr<br />oxyMethodInvocation - [JdonFramework] method.getName() :getProductIDsListByCateg<br />ory<br />2007-04-01 13:52:17,984 [http-8080-Processor20] DEBUG com.jdon.aop.AopClient - [<br />JdonFramework] MethodInvocation will proceed ...<br />2007-04-01 13:52:17,984 [http-8080-Processor20] DEBUG com.jdon.aop.interceptor.C<br />acheInterceptor - [JdonFramework]methodMatchsModelGET: returnClassName = com.jdo<br />n.controller.model.PageIterator<br />2007-04-01 13:52:17,984 [http-8080-Processor20] DEBUG com.jdon.aop.interceptor.P<br />oolInterceptor - [JdonFramework] enter PoolInterceptor<br />2007-04-01 13:52:17,984 [http-8080-Processor20] DEBUG com.jdon.aop.interceptor.P<br />oolInterceptor - [JdonFramework] borrow a object:com.jdon.framework.samples.jpet<br />store.service.bo.ProductManagerImp id:17427094 from pool<br />2007-04-01 13:52:17,984 [http-8080-Processor20] DEBUG com.jdon.aop.interceptor.P<br />oolInterceptor - [JdonFramework]pool state: active=1 free=0<br />2007-04-01 13:52:17,984 [http-8080-Processor20] DEBUG com.jdon.aop.reflection.Pr<br />oxyMethodInvocation - [JdonFramework] finish call all inteceptors<br />2007-04-01 13:52:17,984 [http-8080-Processor20] DEBUG com.jdon.aop.reflection.Pr<br />oxyMethodInvocation - [JdonFramework]enter method reflection<br />2007-04-01 13:52:17,984 [http-8080-Processor20] DEBUG com.jdon.aop.reflection.Pr<br />oxyMethodInvocation - [JdonFramework] target:com.jdon.framework.samples.jpetstor<br />e.service.bo.ProductManagerImp service's method:getProductIDsListByCategory runn<br />ing..<br />2007-04-01 13:52:17,984 [http-8080-Processor20] DEBUG com.jdon.aop.reflection.Pr<br />oxyMethodInvocation - [JdonFramework] it is pojo target service<br />2007-04-01 13:52:17,984 [http-8080-Processor20] DEBUG com.jdon.aop.reflection.Me<br />thodInvokerUtil - [JdonFramework] method invoke: com.jdon.framework.samples.jpet<br />store.service.bo.ProductManagerImp method=getProductIDsListByCategory<br />2007-04-01 13:52:17,984 [http-8080-Processor20] DEBUG com.jdon.framework.samples<br />.jpetstore.service.bo.ProductManagerImp -  getProductIDsListByCategory<br />2007-04-01 13:52:17,984 [http-8080-Processor20] ERROR com.jdon.framework.samples<br />.jpetstore.service.bo.ProductManagerImp -  Dao error : com.ibatis.dao.client.Dao<br />Exception: Error starting SQL Map transaction.  Cause: java.sql.SQLException: In<br />valid authorization specification,  message from server: "Access denied for user<br /> <a href="mailto:'banq'@'localhost'">'banq'@'localhost'</a> (using password: YES)"<br />Caused by: java.sql.SQLException: Invalid authorization specification,  message<br />from server: "Access denied for user <a href="mailto:'banq'@'localhost'">'banq'@'localhost'</a> (using password: YES)"<br />2007-04-01 13:52:17,984 [http-8080-Processor20] DEBUG com.jdon.aop.reflection.Me<br />thodInvokerUtil - [JdonFramework] method invoke successfully<br />2007-04-01 13:52:17,984 [http-8080-Processor20] DEBUG com.jdon.aop.interceptor.P<br />oolInterceptor - [JdonFramework] realease a object:com.jdon.framework.samples.jp<br />etstore.service.bo.ProductManagerImp to pool<br />2007-04-01 13:52:17,984 [http-8080-Processor20] DEBUG com.jdon.bussinessproxy.dy<br />ncproxy.DynamicProxyWeaving - [JdonFramework]call method:getProductIDsListByCate<br />gory finish!<br />2007-04-01 13:52:17,984 [http-8080-Processor20] DEBUG org.apache.struts.action.E<br />xceptionHandler - ExceptionHandler caught this exception:<br />java.lang.Exception: getPageIterator's result is null, check your ModelListActio<br />n subclass<br />        at com.jdon.strutsutil.ModelListAction.execute(ModelListAction.java:67)<br />        at org.apache.struts.action.RequestProcessor.processActionPerform(Reques<br />tProcessor.java:421)<br />        at org.apache.struts.action.RequestProcessor.process(RequestProcessor.ja<br />va:226)<br />        at org.apache.struts.action.ActionServlet.process(ActionServlet.java:116<br />4)<br />        at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:397)<br />        at javax.servlet.http.HttpServlet.service(HttpServlet.java:689)<br />        at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)<br />        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appl<br />icationFilterChain.java:252)<br />        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationF<br />ilterChain.java:173)<br />        at com.jdon.util.SetCharacterEncodingFilter.doFilter(SetCharacterEncodin<br />gFilter.java:92)<br />        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appl<br />icationFilterChain.java:202)<br />        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationF<br />ilterChain.java:173)<br />        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperV<br />alve.java:214)<br />        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextV<br />alve.java:178)<br />        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.j<br />ava:126)<br />        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.j<br />ava:105)<br />        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineVal<br />ve.java:107)<br />        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.jav<br />a:148)<br />        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java<br />:825)<br />        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.proce<br />ssConnection(Http11Protocol.java:738)<br />        at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpo<br />int.java:526)<br />        at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFol<br />lowerWorkerThread.java:80)<br />        at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadP<br />ool.java:684)<br />        at java.lang.Thread.run(Thread.java:595)<br />2007-04-01 13:52:17,984 [http-8080-Processor20] DEBUG org.apache.struts.action.R<br />equestProcessor - processForwardConfig(ForwardConfig[name=null,path=/common/Erro<br />r.jsp,redirect=false,contextRelative=false,module=null])<br />2007-04-01 13:52:18,531 [http-8080-Processor20] DEBUG org.apache.struts.util.Mod<br />uleUtils - Get module name for path /shop/viewCategory.shtml<br />2007-04-01 13:52:18,531 [http-8080-Processor20] DEBUG org.apache.struts.util.Mod<br />uleUtils - Module name found: default<br />2007-04-01 13:52:18,531 [http-8080-Processor20] DEBUG org.apache.struts.action.R<br />equestProcessor - Processing a 'GET' for path '/shop/viewCategory'<br />2007-04-01 13:52:18,531 [http-8080-Processor20] DEBUG org.apache.struts.util.Req<br />uestUtils -  Looking for ActionForm bean instance in scope 'request' under attri<br />bute key 'productListForm'<br />2007-04-01 13:52:18,531 [http-8080-Processor20] DEBUG org.apache.struts.util.Req<br />uestUtils -  Creating new ActionForm instance of type 'com.jdon.strutsutil.Model<br />ListForm'<br />2007-04-01 13:52:18,531 [http-8080-Processor20] DEBUG org.apache.struts.util.Req<br />uestUtils -  --&gt; <a href="mailto:com.jdon.strutsutil.ModelListForm@2bfdff">com.jdon.strutsutil.ModelListForm@2bfdff</a><br />2007-04-01 13:52:18,531 [http-8080-Processor20] DEBUG org.apache.struts.action.R<br />equestProcessor -  Storing ActionForm bean instance in scope 'request' under att<br />ribute key 'productListForm'<br />2007-04-01 13:52:18,531 [http-8080-Processor20] DEBUG org.apache.struts.action.R<br />equestProcessor -  Populating bean properties from this request<br />2007-04-01 13:52:18,531 [http-8080-Processor20] DEBUG org.apache.struts.action.R<br />equestProcessor -  Looking for Action instance for class com.jdon.framework.samp<br />les.jpetstore.presentation.action.ProductListAction<br />2007-04-01 13:52:18,531 [http-8080-Processor20] DEBUG org.apache.struts.action.R<br />equestProcessor -   Returning existing Action instance<br />2007-04-01 13:52:18,531 [http-8080-Processor20] DEBUG com.jdon.bussinessproxy.co<br />nfig.TargetMetaDefXmlLoader - [JdonFramework]metaDefs size:12<br />2007-04-01 13:52:18,531 [http-8080-Processor20] DEBUG com.jdon.controller.servic<br />e.WebServiceFactory - [JdonFramework] getService was found in:productManager<br />2007-04-01 13:52:18,531 [http-8080-Processor20] DEBUG com.jdon.security.web.Http<br />RequestUserSetup - [JdonFramework] setArrtibute:REMOTE_ADDRESS=127.0.0.1<br />2007-04-01 13:52:18,531 [http-8080-Processor20] DEBUG com.jdon.container.access.<br />ServiceAccessorImp - [JdonFramework] enter getService: proxyInstanceFactoryVisit<br />able in action<br />2007-04-01 13:52:18,531 [http-8080-Processor20] DEBUG com.jdon.container.visitor<br />.HttpSessionProxyVisitor - [JdonFramework] get the optimized instance for the ke<br />y com.jdon.framework.samples.jpetstore.service.bo.ProductManagerImpproxyInstance<br />FactoryVisitable<br />2007-04-01 13:52:18,531 [http-8080-Processor20] DEBUG com.jdon.bussinessproxy.dy<br />ncproxy.DynamicProxyWeaving - [JdonFramework]call method:com.jdon.framework.samp<br />les.jpetstore.service.ProductManager.getProductIDsListByCategory<br />2007-04-01 13:52:18,531 [http-8080-Processor20] DEBUG com.jdon.aop.AopClient - [<br />JdonFramework] enter AOP invoker2 for:com.jdon.framework.samples.jpetstore.servi<br />ce.bo.ProductManagerImp method:getProductIDsListByCategory<br />2007-04-01 13:52:18,531 [http-8080-Processor20] DEBUG com.jdon.aop.joinpoint.Adv<br />isorChainFactory - [JdonFramework] enter  create PointcutAdvisor<br />2007-04-01 13:52:18,531 [http-8080-Processor20] DEBUG com.jdon.aop.joinpoint.Adv<br />isorChainFactory - [JdonFramework] find all service's interceptos size=1<br />2007-04-01 13:52:18,531 [http-8080-Processor20] DEBUG com.jdon.aop.joinpoint.Adv<br />isorChainFactory - [JdonFramework] find pojoService's interceptos size=4<br />2007-04-01 13:52:18,531 [http-8080-Processor20] DEBUG com.jdon.aop.reflection.Pr<br />oxyMethodInvocation - [JdonFramework] method.getName() :getProductIDsListByCateg<br />ory<br />2007-04-01 13:52:18,531 [http-8080-Processor20] DEBUG com.jdon.aop.AopClient - [<br />JdonFramework] MethodInvocation will proceed ...<br />2007-04-01 13:52:18,531 [http-8080-Processor20] DEBUG com.jdon.aop.interceptor.C<br />acheInterceptor - [JdonFramework]methodMatchsModelGET: returnClassName = com.jdo<br />n.controller.model.PageIterator<br />2007-04-01 13:52:18,531 [http-8080-Processor20] DEBUG com.jdon.aop.interceptor.P<br />oolInterceptor - [JdonFramework] enter PoolInterceptor<br />2007-04-01 13:52:18,531 [http-8080-Processor20] DEBUG com.jdon.aop.interceptor.P<br />oolInterceptor - [JdonFramework] borrow a object:com.jdon.framework.samples.jpet<br />store.service.bo.ProductManagerImp id:17427094 from pool<br />2007-04-01 13:52:18,531 [http-8080-Processor20] DEBUG com.jdon.aop.interceptor.P<br />oolInterceptor - [JdonFramework]pool state: active=1 free=0<br />2007-04-01 13:52:18,531 [http-8080-Processor20] DEBUG com.jdon.aop.reflection.Pr<br />oxyMethodInvocation - [JdonFramework] finish call all inteceptors<br />2007-04-01 13:52:18,531 [http-8080-Processor20] DEBUG com.jdon.aop.reflection.Pr<br />oxyMethodInvocation - [JdonFramework]enter method reflection<br />2007-04-01 13:52:18,531 [http-8080-Processor20] DEBUG com.jdon.aop.reflection.Pr<br />oxyMethodInvocation - [JdonFramework] target:com.jdon.framework.samples.jpetstor<br />e.service.bo.ProductManagerImp service's method:getProductIDsListByCategory runn<br />ing..<br />2007-04-01 13:52:18,531 [http-8080-Processor20] DEBUG com.jdon.aop.reflection.Pr<br />oxyMethodInvocation - [JdonFramework] it is pojo target service<br />2007-04-01 13:52:18,531 [http-8080-Processor20] DEBUG com.jdon.aop.reflection.Me<br />thodInvokerUtil - [JdonFramework] method invoke: com.jdon.framework.samples.jpet<br />store.service.bo.ProductManagerImp method=getProductIDsListByCategory<br />2007-04-01 13:52:18,531 [http-8080-Processor20] DEBUG com.jdon.framework.samples<br />.jpetstore.service.bo.ProductManagerImp -  getProductIDsListByCategory<br />2007-04-01 13:52:18,546 [http-8080-Processor20] ERROR com.jdon.framework.samples<br />.jpetstore.service.bo.ProductManagerImp -  Dao error : com.ibatis.dao.client.Dao<br />Exception: Error starting SQL Map transaction.  Cause: java.sql.SQLException: In<br />valid authorization specification,  message from server: "Access denied for user<br /> <a href="mailto:'banq'@'localhost'">'banq'@'localhost'</a> (using password: YES)"<br />Caused by: java.sql.SQLException: Invalid authorization specification,  message<br />from server: "Access denied for user <a href="mailto:'banq'@'localhost'">'banq'@'localhost'</a> (using password: YES)"<br />2007-04-01 13:52:18,546 [http-8080-Processor20] DEBUG com.jdon.aop.reflection.Me<br />thodInvokerUtil - [JdonFramework] method invoke successfully<br />2007-04-01 13:52:18,546 [http-8080-Processor20] DEBUG com.jdon.aop.interceptor.P<br />oolInterceptor - [JdonFramework] realease a object:com.jdon.framework.samples.jp<br />etstore.service.bo.ProductManagerImp to pool<br />2007-04-01 13:52:18,546 [http-8080-Processor20] DEBUG com.jdon.bussinessproxy.dy<br />ncproxy.DynamicProxyWeaving - [JdonFramework]call method:getProductIDsListByCate<br />gory finish!<br />2007-04-01 13:52:18,546 [http-8080-Processor20] DEBUG org.apache.struts.action.E<br />xceptionHandler - ExceptionHandler caught this exception:<br />java.lang.Exception: getPageIterator's result is null, check your ModelListActio<br />n subclass<br />        at com.jdon.strutsutil.ModelListAction.execute(ModelListAction.java:67)<br />        at org.apache.struts.action.RequestProcessor.processActionPerform(Reques<br />tProcessor.java:421)<br />        at org.apache.struts.action.RequestProcessor.process(RequestProcessor.ja<br />va:226)<br />        at org.apache.struts.action.ActionServlet.process(ActionServlet.java:116<br />4)<br />        at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:397)<br />        at javax.servlet.http.HttpServlet.service(HttpServlet.java:689)<br />        at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)<br />        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appl<br />icationFilterChain.java:252)<br />        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationF<br />ilterChain.java:173)<br />        at com.jdon.util.SetCharacterEncodingFilter.doFilter(SetCharacterEncodin<br />gFilter.java:92)<br />        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appl<br />icationFilterChain.java:202)<br />        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationF<br />ilterChain.java:173)<br />        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperV<br />alve.java:214)<br />        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextV<br />alve.java:178)<br />        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.j<br />ava:126)<br />        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.j<br />ava:105)<br />        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineVal<br />ve.java:107)<br />        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.jav<br />a:148)<br />        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java<br />:825)<br />        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.proce<br />ssConnection(Http11Protocol.java:738)<br />        at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpo<br />int.java:526)<br />        at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFol<br />lowerWorkerThread.java:80)<br />        at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadP<br />ool.java:684)<br />        at java.lang.Thread.run(Thread.java:595)<br />2007-04-01 13:52:18,546 [http-8080-Processor20] DEBUG org.apache.struts.action.R<br />equestProcessor - processForwardConfig(ForwardConfig[name=null,path=/common/Erro<br />r.jsp,redirect=false,contextRelative=false,module=null])<br />2007-04-01 14:02:02,593 [ContainerBackgroundProcessor[StandardEngine[Catalina]]]<br /> DEBUG com.jdon.container.visitor.HttpSessionProxyVisitor - [JdonFramework] unva<br />lueBound active, sessionId :3523A004637D3D889596DC8076494139<br />2007-04-01 14:02:02,593 [ContainerBackgroundProcessor[StandardEngine[Catalina]]]<br /> DEBUG com.jdon.container.visitor.HttpSessionProxyVisitor - [JdonFramework] unva<br />lueUnbound active, componentsboxs size2<br /><img src ="http://www.blogjava.net/jiabao/aggbug/107751.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jiabao/" target="_blank">金家寶</a> 2007-04-01 14:15 <a href="http://www.blogjava.net/jiabao/archive/2007/04/01/107751.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>如何从开发人员走向架构师</title><link>http://www.blogjava.net/jiabao/archive/2007/03/16/104379.html</link><dc:creator>金家寶</dc:creator><author>金家寶</author><pubDate>Fri, 16 Mar 2007 15:23:00 GMT</pubDate><guid>http://www.blogjava.net/jiabao/archive/2007/03/16/104379.html</guid><wfw:comment>http://www.blogjava.net/jiabao/comments/104379.html</wfw:comment><comments>http://www.blogjava.net/jiabao/archive/2007/03/16/104379.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jiabao/comments/commentRss/104379.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jiabao/services/trackbacks/104379.html</trackback:ping><description><![CDATA[很多架构师都是从好的开发人员逐步过渡而来的，但并非每个好的开发人员都希望成为架构师，而且他们并不是都适合做架构师。无论您是打算进行职业转型的开发人员，还是寻找能承担体系结构设计责任的合适人选的经理，都务必对此转型过程有个清楚的了解。本文将讨论从实现专家到架构师的过渡过程。 
<p></p><p>　　在寻找优秀的指挥的时候，您首先要找的是一名优秀的音乐演奏家。但并非每个音乐演奏家都能成为优秀的指挥。架构师的专业发展方面也与此类似。越来越多的 IT 组织开始认识到良好软件体系结构的重要性，架构师职业正迅速发展为 IT 内一个独立的门类。由于要从相当小的候选范围内招募架构师，因此这就给管理带来了一些新挑战。即使人力资源部门找到了候选者，针对经验进行的筛选也比其他门类更为严格。跨越这些障碍的最快方式是要认识到，大部分好的架构师同时也是好的开发人员，因此寻找架构师人才时可能首先应该从普通开发人员中找起。招聘人员在对候选者(内部或外部)进行详细审查时，应该考虑这个观点。不过，对此资源进行挑选可能比较麻烦，因为只有极少的优秀开发人员具有成为架构师的特征或愿望。</p><p>　　本文列出了开发人员成为架构师要进行的工作。我将从可能考虑进行此转型的开发人员和评估进行此转型的开发人员的经理这两个方面来探讨这一问题。我还将提供一系列在做出这些决策时要考虑的因素。</p><p>　　<strong>个人特征</strong></p><p>　　软件开发团队和管理层之间的联系始终是 IT 中的一个关键所在。二者都倾向于以完全不同的方式考虑给定的问题。大部分相关<b onmouseover="isShowAds = true;isShowAds2 = true;ads.Move(this,&quot;http://rad.17luntan.com/UploadImage/17/633058554832006250.gif&quot;,&quot;%u201C%u593A%u5B9D%u5947%u5175%uFF0C%u9510%u4E0D%u53EF%u5F53%21%20%u8D2DLG%u9510%u6BD4%u6DB2%u6676%uFF0C%u60CA%u559C%u597D%u793C%u7B49%u4F60%u62FF%21%u201D%20%20%20%20&quot;,&quot;19250&quot;,&quot;技术&quot;,&quot;%u6280%u672F&quot;,&quot;http%3A//210.192.100.35/11725683872830http%3A//www.lgemonitor.com.cn/mnt/sale0703/index.html%3F11725683872830&quot;)" style="FONT-WEIGHT: normal; CURSOR: hand; COLOR: #0000ff; TEXT-DECORATION: underline" onmouseout="javascript:isShowAds = false;isShowAds2 = false;">技术</b>都是讨论<b onmouseover="isShowAds = true;isShowAds2 = true;ads.Move(this,&quot;&quot;,&quot;%u6700NB%u516C%u53F8%u7684%u9879%u76EE%u7BA1%u7406%u65B9%u6CD5%u8BBA%uFF01&quot;,&quot;21428&quot;,&quot;项目经理&quot;,&quot;%u9879%u76EE%u7ECF%u7406&quot;,&quot;http%3A//www.microsoft.com/china/technet/itsolutions/techguide/msf/default.mspx&quot;)" style="FONT-WEIGHT: normal; CURSOR: hand; COLOR: #0000ff; TEXT-DECORATION: underline" onmouseout="javascript:isShowAds = false;isShowAds2 = false;">项目经理</b>应如何跟踪和解释开发人员的进度和问题。但沟通不足的情况仍然非常普遍，而且这是项目失败的首要原因。好的架构师是解决这个问题的最有效办法。架构师的主要责任是提供开发人员和项目经理之间的共用沟通媒体。他们负责让业务规则及需求与工程实践及限制相适应，以确保成功。以下是成功架构师的一些主要特征。</p><p>　　<strong>愿意并有能力进行沟通：</strong>在开发人员中发现架构师的最有价值标准是有效的沟通。您需要技术娴熟、经验丰富的开发人员，这样的人员需要有就项目中的业务相关问题进行沟通的经历。架构师经常必须对理解方面的差距进行预计，然后才能有所贡献。他们必须愿意克服困难来确保技术和业务观点的融合。他们并不必对意见交换工作进行计划和协调;这仍然主要是项目经理的工作。他们的任务是确定表述系统<b onmouseover="isShowAds = true;isShowAds2 = true;ads.Move(this,&quot;http://rad.17luntan.com/UploadImage/17/633058554832006250.gif&quot;,&quot;%u201C%u593A%u5B9D%u5947%u5175%uFF0C%u9510%u4E0D%u53EF%u5F53%21%20%u8D2DLG%u9510%u6BD4%u6DB2%u6676%uFF0C%u60CA%u559C%u597D%u793C%u7B49%u4F60%u62FF%21%u201D%20%20%20%20&quot;,&quot;19228&quot;,&quot;设计&quot;,&quot;%u8BBE%u8BA1&quot;,&quot;http%3A//210.192.100.35/11725683872830http%3A//www.lgemonitor.com.cn/mnt/sale0703/index.html%3F11725683872830&quot;)" style="FONT-WEIGHT: normal; CURSOR: hand; COLOR: #0000ff; TEXT-DECORATION: underline" onmouseout="javascript:isShowAds = false;isShowAds2 = false;">设计</b>时的最佳工具和构件，以促进有效的意见交换。他们必须能够判断当前方法显得不足而需要采用新方法的情况。写作技能也非常重要，还需要具有制作草图的技能或使用制图软件的能力。 </p><p>　　<strong>具有处理谈判细节方面的经验：</strong>架构师经常需要负责讨论系统开发的技术折衷方案。优先级的冲突可能会带来实践限制、风险规避或可能导致在各个不同业务组之间需求不同。优秀的架构师能够有效地评估技术可能性，并能在不损失项目的主要价值的前提下制订开发计划来处理各种利害关系和限制。这与前面讨论的沟通技能紧密相关，但同时也要体现架构师的技术能力。好的架构师候选者应该是经常帮助对有争议的讨论进行引导的人，能够使讨论得出新的想法，而不会使其在一个位置停滞不前。 </p><p>　　<strong>自觉主动;积极解决设计问题：</strong>架构师的日常工作目标经常并不明确。很多开发人员直接参考功能规范来列出任务清单。架构师通常则是向这些开发人员提供所需结构的人员，以便尽可能提高工作效率。好的候选者不仅进行沟通方面的工作，而且也会预计各种设计问题并加以解决——通常在没有任何具体指示的情况下自觉进行。无论所分配的职责如何，积极参与项目的开发人员都有机会从一起工作的人员中脱颖而出。 </p><p>　　<strong>抽象思维和分析：</strong>架构师必须能够理解表述模糊的概念并将其变成相关各方能够理解的项目构件。他们必须能够理解抽象概念，并以具体的语言对其进行沟通。开发人员中好的候选者经常要求或自己主动解释开发生命周期中容易混淆的问题。他们能迅速评估各种想法并将其纳入后续工作的操作建议中。</p><p>　　开发人员经常具有很强的数学能力，而好的架构师则倾向于表现出更强的口头表达能力。管理人员经常说开发人员具有“工程意识”，而这是一个用于评估架构师的非常有意义的方面。架构师应该具有很强的解决技术问题的能力，但还必须能够准确获知更为全面的人员如何与技术交互的信息。这要求具有某种形式的抽象思维(而不再是代码的细节)，这种思维能力可能较难形成。</p><p>　　有些人认为，某种级别的正式教育是成为优秀开发人员的必备条件之一，我并不同意这种精英论。我遇到了很多高中就辍学的优秀开发人员。不过，对于体系结构设计工作，我的个人经验以及我对所需能力的认识都让我相信，好的架构师通常至少获得了一个有挑战性的学士学位。</p><p>　　<strong>跟踪生命周期</strong></p><p>　　好的架构师通常有在具备定义良好的软件开发生命周期(Software Development Life Cycle，SDLC)的组织工作的经验。架构师必须理解在其所属专业内最重要的操作过程。这并不意味着需要有其他前提，例如，并不需要高能力成熟度模型(Capability Maturity Model，CMM)级别的工作经验。好的架构师可能来自使用 SDLC 的多个小型迭代的极限编程(Extreme Programming，XP)方法的组织。务必注意各种传统软件开发操作，如 Michael A. Jackson 的方法：Jackson 结构编程(Jackson Structured Programming，JSP)和 Jackson 系统开发(Jackson System Development，JSD)。Jackson 的研究对架构师职业发展的意义就像 Donald Knuth 的研究对程序员一样重要。架构师可以偏爱任何经典的、经过时间考验的软件系统开发方法。</p><p>　　SDLC 也可以成为评估架构师合适人选的有用机制。每个 SDLC 阶段都具有能提供相关线索的特征。SDLC 包含很多小的变体，但在此部分，我将使用几乎所有方法的公共基础部分。下面的列表详细说明了 SDLC 的各个阶段，并列出了好的架构师候选者在每个阶段表现出来的特征。</p><ul><li>　　<strong>分析：</strong>在分析期间，好的架构师会考虑非技术影响，以便了解需求和将在其中进行开发的环境。架构师可为风险评估任务带来广泛的软件经验供参考。寻找具有丰富经验的开发人员，以帮助业务部门理解技术人员正确解释需求所需的信息。寻找在开发的早期阶段能够预计可能遇到的问题的开发人员。 
</li><li>　　<strong>设计：</strong>在高级设计期间，好的架构师会收集问题空间的各个抽象元素，并就其进行沟通，以便开发团队草拟将要开发的系统的相关图表。架构师负责将需求谨慎地映射到所得到的系统体系结构的功能。在详细设计期间，他们所扮演的角色并不是核心角色，但为了根据整个系统的规则对特定模块的元素进行审查，仍然需要他们。寻找善于让团队能够预计设计决策对最终系统的影响的开发人员。寻找善于确定一些最佳构件来促进与技术和非技术受众沟通设计问题的开发人员。 
</li><li>　　<strong>实现：</strong>在实现期间，架构师对项目进行引导，以确保其符合系统体系结构。他们在一线评估技术更改请求，并确定如何对设计进行调整，以最好地处理此类请求。架构师还要密切了解开发人员的进度，特别要跟踪系统中模块间的集成点的状态。寻找经常对讨论进行引导来连接多个子系统的开发人员。寻找项目经理可以依赖其快速地进行与更改和出现的问题相关的风险评估的开发人员。 
</li><li>　　<strong>测试：</strong>架构师对系统集成和用户接受度测试进行指导，并负责评估进度的正确沟通的持续测试结果。寻找理解错误模式且善于将测试复查结果转换为行动计划的开发人员。 
</li><li>　　<strong>维护：</strong>在维护期间，架构师将发起关于系统集成的讨论。无论处理 IT 基础设施问题，还是确保部门之间的技术合作，架构师都必须完全理解应用程序，必须快速学习姊妹应用程序的体系结构，而且必须就集成点和风险进行有效沟通。寻找具有系统集成经验且表现出快速掌握全貌的能力的开发人员。系统集成是一项独特的任务。 </li></ul><p>　　<strong>架构师培养建议</strong></p><p>　　有些组织能比其他组织更有效地进行架构师培养。如果充分考虑到招聘此类新专业人才的困难，努力促成能鼓励开发人员发展为架构师的环境是非常明智的策略。但务必避免对不愿意或不适合走这条路的开发人员进行处罚。组织应该为开发人员制订多条发展路线，包括那些愿意继续担任开发人员的人。对架构师而言，资深开发人员不可或缺。他们可以实现系统中最关键的模块。通过对其他开发人员进行代码检查和测试支持，他们可帮助确保总体软件质量，而如果质量不能保证，即使最好的体系结构也毫无用处。</p><p>　　组织应制订个人评估程序，以鼓励开发人员考虑其职业目标，其中要包含体系结构设计的选项。应该鼓励经理在其下属中寻找体系结构设计人才。应该实现指导计划，让架构师与希望成为架构师的开发人员协作工作。应该鼓励开发人员通过参加各种协会、撰写文章和参加会议，从而参与到专业领域中来。通过这样参与进来，可帮助开发人员从新的角度理解系统，并帮助他们更好地就其认识进行沟通。这样还能培养可提高效率的重要创新想法。</p><p>　　<strong>结束语</strong></p><p>　　开发人员一旦迈出了通向体系结构设计专业方向的第一步，就可以利用很多资源来获得帮助，其中包括很多来自 IBM 的资源。有时候，此过程的最困难的部分就是第一步，而本文提供了一些线索和提示，经理和开发人员可以利用其来评估应该鼓励哪些人努力成为架构师。</p><p></p><div id="Disclaimer"><p>声明：文章摘自CSDN</p></div><img src ="http://www.blogjava.net/jiabao/aggbug/104379.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jiabao/" target="_blank">金家寶</a> 2007-03-16 23:23 <a href="http://www.blogjava.net/jiabao/archive/2007/03/16/104379.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>