﻿<?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-Junky's IT Notebook-随笔分类-struts</title><link>http://www.blogjava.net/junky/category/11524.html</link><description /><language>zh-cn</language><lastBuildDate>Fri, 29 Jun 2007 20:58:12 GMT</lastBuildDate><pubDate>Fri, 29 Jun 2007 20:58:12 GMT</pubDate><ttl>60</ttl><item><title>WebWork教程- Interceptor(拦截器)</title><link>http://www.blogjava.net/junky/archive/2007/06/28/126717.html</link><dc:creator>junky</dc:creator><author>junky</author><pubDate>Thu, 28 Jun 2007 01:37:00 GMT</pubDate><guid>http://www.blogjava.net/junky/archive/2007/06/28/126717.html</guid><wfw:comment>http://www.blogjava.net/junky/comments/126717.html</wfw:comment><comments>http://www.blogjava.net/junky/archive/2007/06/28/126717.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junky/comments/commentRss/126717.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junky/services/trackbacks/126717.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: WebWork教程- Interceptor(拦截器)Interceptor（拦截器）将Action共用的行为独立出来，在Action执行前后运行。这也就是我们所说的AOP（Aspect Oriented Programming，面向切面编程），它是分散关注的编程方法，它将通用需求功能从不相关类之中分离出来；同时，能够使得很多类共享一个行为，一旦行为发生变化，不必修改很多类，只要修改这个行为就...&nbsp;&nbsp;<a href='http://www.blogjava.net/junky/archive/2007/06/28/126717.html'>阅读全文</a><img src ="http://www.blogjava.net/junky/aggbug/126717.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junky/" target="_blank">junky</a> 2007-06-28 09:37 <a href="http://www.blogjava.net/junky/archive/2007/06/28/126717.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Strust拦截器</title><link>http://www.blogjava.net/junky/archive/2007/06/28/126715.html</link><dc:creator>junky</dc:creator><author>junky</author><pubDate>Thu, 28 Jun 2007 01:35:00 GMT</pubDate><guid>http://www.blogjava.net/junky/archive/2007/06/28/126715.html</guid><wfw:comment>http://www.blogjava.net/junky/comments/126715.html</wfw:comment><comments>http://www.blogjava.net/junky/archive/2007/06/28/126715.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junky/comments/commentRss/126715.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junky/services/trackbacks/126715.html</trackback:ping><description><![CDATA[1.概述 <br><br>Strust拦截器改进了Strust对Action的操作能力,增加了拦截器特性和IoC特性. <br><br>通过分析另外的WEB框架,比如:WebWork 2/XWork,Strust拦截器的目的是把其它WEB框架最好的特性整合到STRUTS中.Strust拦截器支持struts1.1, 按照BSD许可发行. <br><br>2.特点 <br>Action 拦截 <br>WW2 操作风格 <br>支持 regular 和 Tiles <br>包括使用Strust拦截器修改过的Strust例子 <br><br><br>3.使用方法: <br><br>把Strust拦截器配置为一个struts插件,就可以在需要的任何地方调用. <br><br><br>4.配置struts插件: <br><br>把Strust拦截器配置为一个struts插件,只需要修改 Struts 配置文件就可以了,修改后的配置文件.一般看起来像这种样子: <br><br>&lt;plug-in className="net.sf.struts.saif.SAIFPlugin"&gt; <br>&lt;set-property property="interceptor-config" value="/WEB-INF/interceptor-config.xml" /&gt; <br>&lt;/plug-in&gt; <br><br><br>5.拦截器的配置 <br><br>在interceptor-config.xml文件中定义了所有拦截(当然可以是另外的任何文件名). 这个文件包含拦截定义和它们应该如何被使用. <br><br>从两个方面来定义 Struts Actions拦截: <br>globally and by Action. When the Action is requested, first any global interceptors will be applied, then Action-specific interceptors. <br><br>The following interceptors are included in SAIF: <br><br>Included interceptors Class Description <br>net.sf.struts.saif.ComponentInterceptor Performs inversion of control functionality. Sets any components the Action has defined it needs. <br><br>This is an example of an interceptor configuration file: <br><br>&lt;interceptor-config&gt; <br>&lt;interceptor name="componentInterceptor" type="net.sf.struts.saif.ComponentInterceptor"/&gt; <br>&lt;interceptor name="testInterceptor" type="net.sf.struts.saif.TestInterceptor"/&gt; <br><br>&lt;default-interceptors&gt; <br>&lt;interceptor name="componentInterceptor"/&gt; <br>&lt;/default-interceptors&gt; <br><br>&lt;action type="org.apache.struts.webapp.example.EditRegistrationAction"&gt; <br>&lt;interceptor name="testInterceptor"/&gt; <br>&lt;/action&gt; <br>&lt;/interceptor-config&gt; <br>Interceptor Implementation <br>Interceptors can perform actions before and after a Struts Action is called. To write an interceptor, simple implement the net.sf.struts.saif.ActionInterceptor interface and implement the beforeAction() and afterAction() methods. <br><br>This is an example of an interceptor implementation: <br><br>public class TestInterceptor implements ActionInterceptor <br>{ <br>public void beforeAction(Action action, ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) <br>{ <br>log.debug("beforeAction called"); <br>} <br><br>public void afterAction(Action action, ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) <br>{ <br>log.debug("afterAction called"); <br>} <br><br>private Log log = LogFactory.getLog(TestInterceptor.class); <br>} <br>Contact <br>Please contact Lars Hoss or Don Brown with comments, bug reports, and suggestions.<br>
<img src ="http://www.blogjava.net/junky/aggbug/126715.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junky/" target="_blank">junky</a> 2007-06-28 09:35 <a href="http://www.blogjava.net/junky/archive/2007/06/28/126715.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>深入剖析JSP和Servlet对中文的处理(转)</title><link>http://www.blogjava.net/junky/archive/2007/04/16/111006.html</link><dc:creator>junky</dc:creator><author>junky</author><pubDate>Mon, 16 Apr 2007 08:28:00 GMT</pubDate><guid>http://www.blogjava.net/junky/archive/2007/04/16/111006.html</guid><wfw:comment>http://www.blogjava.net/junky/comments/111006.html</wfw:comment><comments>http://www.blogjava.net/junky/archive/2007/04/16/111006.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junky/comments/commentRss/111006.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junky/services/trackbacks/111006.html</trackback:ping><description><![CDATA[<p>世界上的各地区都有本地的语言。地区差异直接导致了语言环境的差异。在开发一个国际化程序的过程中，处理语言问题就显得很重要了。</p>
<p>这是一个世界范围内都存在的问题，所以，Java提供了世界性的解决方法。本文描述的方法是用于处理中文的，但是，推而广之，对于处理世界上其它国家和地区的语言同样适用。</p>
<p>汉字是双字节的。所谓双字节是指一个双字要占用两个BYTE的位置（即16位），分别称为高位和低位。中国规定的汉字编码为GB2312，这是强制性的，目前几乎所有的能处理中文的应用程序都支持GB2312。GB2312包括了一二级汉字和9区符号，高位从0xa1到0xfe，低位也是从0xa1到0xfe，其中，汉字的编码范围为0xb0a1到0xf7fe。</p>
<p>另外有一种编码，叫做GBK，但这是一份规范，不是强制的。GBK提供了20902个汉字，它兼容GB2312，编码范围为0x8140到0xfefe。GBK中的所有字符都可以一一映射到Unicode 2.0。</p>
<p>在不久的将来，中国会颁布另一种标准：GB18030-2000（GBK2K）。它收录了藏、蒙等少数民族的字型，从根本上解决了字位不足的问题。注意：它不再是定长的。其二字节部份与GBK兼容，四字节部分是扩充的字符、字形。它的首字节和第三字节从0x81到0xfe，二字节和第四字节从0x30到0x39。</p>
<p>本文不打算介绍Unicode，有兴趣的可以浏览&#8220;http://www.unicode.org/&#8221;查看更多的信息。Unicode有一个特性：它包括了世界上所有的字符字形。所以，各个地区的语言都可以建立与Unicode的映射关系，而Java正是利用了这一点以达到异种语言之间的转换。</p>
<p>在JDK中，与中文相关的编码有：</p>
<p><strong><font color=#993300>表1 JDK中与中文相关的编码列表</font></strong></p>
<p>
<table>
    <tbody>
        <tr>
            <td>编码名称</td>
            <td>说明</td>
        </tr>
        <tr>
            <td>ASCII</td>
            <td>7位，与ascii7相同</td>
        </tr>
        <tr>
            <td>ISO8859-1</td>
            <td>8-位，与 8859_1,ISO-8859-1,ISO_8859-1,latin1...等相同</td>
        </tr>
        <tr>
            <td>GB2312-80</td>
            <td>16位，与gb2312,gb2312-1980,EUC_CN,euccn,1381,Cp1381, 1383, Cp1383, ISO2022CN,ISO2022CN_GB...等相同</td>
        </tr>
        <tr>
            <td>GBK</td>
            <td>与MS936相同，注意：区分大小写</td>
        </tr>
        <tr>
            <td>UTF8</td>
            <td>与UTF-8相同</td>
        </tr>
        <tr>
            <td>GB18030</td>
            <td>与cp1392、1392相同，目前支持的JDK很少</td>
        </tr>
    </tbody>
</table>
</p>
<p>在实际编程时，接触得比较多的是GB2312（GBK）和ISO8859-1。</p>
<p><strong>为什么会有&#8220;?&#8221;号</strong></p>
<p>上文说过，异种语言之间的转换是通过Unicode来完成的。假设有两种不同的语言A和B，转换的步骤为：先把A转化为Unicode，再把Unicode转化为B。</p>
<p>举例说明。有GB2312中有一个汉字&#8220;李&#8221;，其编码为&#8220;C0EE&#8221;，欲转化为ISO8859-1编码。步骤为：先把&#8220;李&#8221;字转化为Unicode，得到&#8220;674E&#8221;，再把&#8220;674E&#8221;转化为ISO8859-1字符。当然，这个映射不会成功，因为ISO8859-1中根本就没有与&#8220;674E&#8221;对应的字符。</p>
<p>当映射不成功时，问题就发生了！当从某语言向Unicode转化时，如果在某语言中没有该字符，得到的将是Unicode的代码&#8220;\uffffd&#8221;（&#8220;\u&#8221;表示是Unicode编码，）。而从Unicode向某语言转化时，如果某语言没有对应的字符，则得到的是&#8220;0x3f&#8221;（&#8220;?&#8221;）。这就是&#8220;?&#8221;的由来。</p>
<p>例如：把字符流buf =&#8220;0x80 0x40 0xb0 0xa1&#8221;进行new String(buf, "gb2312")操作，得到的结果是&#8220;\ufffd\u554a&#8221;，再println出来，得到的结果将是&#8220;?啊&#8221;，因为&#8220;0x80 0x40&#8221;是GBK中的字符，在GB2312中没有。</p>
<p>再如，把字符串String="\u00d6\u00ec\u00e9\u0046\u00bb\u00f9"进行new String (buf.getBytes("GBK"))操作，得到的结果是&#8220;3fa8aca8a6463fa8b4&#8221;，其中，&#8220;\u00d6&#8221;在&#8220;GBK&#8221;中没有对应的字符，得到&#8220;3f&#8221;，&#8220;\u00ec&#8221;对应着&#8220;a8ac&#8221;，&#8220;\u00e9&#8221;对应着&#8220;a8a6&#8221;，&#8220;0046&#8221;对应着&#8220;46&#8221;（因为这是ASCII字符），&#8220;\u00bb&#8221;没找到，得到&#8220;3f&#8221;，最后，&#8220;\u00f9&#8221;对应着&#8220;a8b4&#8221;。把这个字符串println一下，得到的结果是&#8220;?&#236;&#233;F?&#249;&#8221;。看到没？这里并不全是问号，因为GBK与Unicode映射的内容中除了汉字外还有字符，本例就是最好的明证。</p>
<p>所以，在汉字转码时，如果发生错乱，得到的不一定都是问号噢！不过，错了终究是错了，50步和100步并没有质的差别。</p>
<p>或者会问：如果源字符集中有，而Unicode中没有，结果会如何？回答是不知道。因为我手头没有能做这个测试的源字符集。但有一点是肯定的，那就是源字符集不够规范。在Java中，如果发生这种情况，是会抛出异常的。</p>
<p><strong>什么是UTF</strong></p>
<p>UTF，是Unicode Text Format的缩写，意为Unicode文本格式。对于UTF，是这样定义的：</p>
<p>（1）如果Unicode的16位字符的头9位是0，则用一个字节表示，这个字节的首位是&#8220;0&#8221;，剩下的7位与原字符中的后7位相同，如&#8220;\u0034&#8221;（0000 0000 0011 0100），用&#8220;34&#8221; (0011 0100)表示；（与源Unicode字符是相同的）；</p>
<p>（2）如果Unicode的16位字符的头5位是0，则用2个字节表示，首字节是&#8220;110&#8221;开头，后面的5位与源字符中除去头5个零后的最高5位相同；第二个字节以&#8220;10&#8221;开头，后面的6位与源字符中的低6位相同。如&#8220;\u025d&#8221;（0000 0010 0101 1101），转化后为&#8220;c99d&#8221;（1100 1001 1001 1101）；</p>
<p>（3）如果不符合上述两个规则，则用三个字节表示。第一个字节以&#8220;1110&#8221;开头，后四位为源字符的高四位；第二个字节以&#8220;10&#8221;开头，后六位为源字符中间的六位；第三个字节以&#8220;10&#8221;开头，后六位为源字符的低六位；如&#8220;\u9da7&#8221;（1001 1101 1010 0111），转化为&#8220;e9b6a7&#8221;（1110 1001 1011 0110 1010 0111）；</p>
<p>可以这么描述JAVA程序中Unicode与UTF的关系，虽然不绝对：字符串在内存中运行时，表现为Unicode代码，而当要保存到文件或其它介质中去时，用的是UTF。这个转化过程是由writeUTF和readUTF来完成的。</p>
<p>好了，基础性的论述差不多了，下面进入正题。</p>
<p>先把这个问题想成是一个黑匣子。先看黑匣子的一级表示：</p>
<p>input(charsetA)-＞process(Unicode)-＞output(charsetB)</p>
<p>简单，这就是一个IPO模型，即输入、处理和输出。同样的内容要经过&#8220;从charsetA到unicode再到charsetB&#8221;的转化。</p>
<p>再看二级表示：</p>
<p>SourceFile(jsp,java)-＞class-＞output</p>
<p>在这个图中，可以看出，输入的是jsp和java源文件，在处理过程中，以Class文件为载体，然后输出。再细化到三级表示：</p>
<p>jsp-＞temp file-＞class-＞browser,os console,db</p>
<p>app,servlet-＞class-＞browser,os console,db</p>
<p>这个图就更明白了。Jsp文件先生成中间的Java文件，再生成Class。而Servlet和普通App则直接编译生成Class。然后，从Class再输出到浏览器、控制台或数据库等。</p>
<p><strong>JSP：从源文件到Class的过程</strong></p>
<p>Jsp的源文件是以&#8220;.jsp&#8221;结尾的文本文件。在本节中，将阐述JSP文件的解释和编译过程，并跟踪其中的中文变化。</p>
<p>1、JSP/Servlet引擎提供的JSP转换工具（jspc）搜索JSP文件中用＜%@ page contentType ="text/html; charset=＜Jsp-charset＞"%＞中指定的charset。如果在JSP文件中未指定＜Jsp-charset＞，则取JVM中的默认设置file.encoding，一般情况下，这个值是ISO8859-1；</p>
<p>2、jspc用相当于&#8220;javac &#8211;encoding ＜Jsp-charset＞&#8221;的命令解释JSP文件中出现的所有字符，包括中文字符和ASCII字符，然后把这些字符转换成Unicode字符，再转化成UTF格式，存为JAVA文件。ASCII码字符转化为Unicode字符时只是简单地在前面加&#8220;00&#8221;，如&#8220;A&#8221;，转化为&#8220;\u0041&#8221;（不需要理由，Unicode的码表就是这么编的）。然后，经过到UTF的转换，又变回&#8220;41&#8221;了！这也就是可以使用普通文本编辑器查看由JSP生成的JAVA文件的原因；</p>
<p>3、引擎用相当于&#8220;javac &#8211;encoding UNICODE&#8221;的命令，把JAVA文件编译成CLASS文件；</p>
<p>先看一下这些过程中中文字符的转换情况。有如下源代码：</p>
<p>
<table>
    <tbody>
        <tr>
            <td>＜%@ page contentType="text/html; charset=gb2312"%＞＜html＞＜body＞＜% String a="中文"; out.println(a);%＞＜/body＞＜/html＞</td>
        </tr>
    </tbody>
</table>
</p>
<p>这段代码是在UltraEdit for Windows上编写的。保存后，&#8220;中文&#8221;两个字的16进制编码为&#8220;D6 D0 CE C4&#8221;（GB2312编码）。经查表，&#8220;中文&#8221;两字的Unicode编码为&#8220;\u4E2D\u6587&#8221;，用 UTF表示就是&#8220;E4 B8 AD E6 96 87&#8221;。打开引擎生成的由JSP文件转变而成的JAVA文件，发现其中的&#8220;中文&#8221;两个字确实被&#8220;E4 B8 AD E6 96 87&#8221;替代了，再查看由JAVA文件编译生成的CLASS文件，发现结果与JAVA文件中的完全一样。</p>
<p>再看JSP中指定的CharSet为ISO-8859-1的情况。</p>
<p>
<table>
    <tbody>
        <tr>
            <td>＜%@ page contentType="text/html; charset=ISO-8859-1"%＞<br>＜html＞<br>＜body＞<br>＜% String a="中文"; out.println(a);%＞<br>＜/body＞<br>＜/html＞</td>
        </tr>
    </tbody>
</table>
</p>
<p>同样，该文件是用UltraEdit编写的，&#8220;中文&#8221;这两个字也是存为GB2312编码&#8220;D6 D0 CE C4&#8221;。先模拟一下生成的JAVA文件和CLASS文件的过程：jspc用ISO-8859-1来解释&#8220;中文&#8221;，并把它映射到Unicode。由于ISO-8859-1是8位的，且是拉丁语系，其映射规则就是在每个字节前加&#8220;00&#8221;，所以，映射后的Unicode编码应为&#8220;\u00D6\u00D0\u00CE\u00C4&#8221;，转化成UTF后应该是&#8220;C3 96 C3 90 C3 8E C3 84&#8221;。好，打开文件看一下，JAVA文件和CLASS文件中，&#8220;中文&#8221;果然都表示为&#8220;C3 96 C3 90 C3 8E C3 84&#8221;。</p>
<p>如果上述代码中不指定＜Jsp-charset＞，即把第一行写成&#8220;＜%@ page contentType="text/html" %＞&#8221;，JSPC会使用file.encoding的设置来解释JSP文件。在RedHat 6.2上，其处理结果与指定为ISO-8859-1是完全相同的。</p>
<p>到现在为止，已经解释了从JSP文件到CLASS文件的转变过程中中文字符的映射过程。一句话：从&#8220;JspCharSet到Unicode再到UTF&#8221;。下表总结了这个过程：</p>
<p><strong><font color=#993300>表2 &#8220;中文&#8221;从JSP到CLASS的转化过程</font></strong></p>
<p>
<table>
    <tbody>
        <tr>
            <td>Jsp-CharSet</td>
            <td>JSP文件中</td>
            <td>JAVA文件中</td>
            <td>CLASS文件中</td>
        </tr>
        <tr>
            <td>GB2312</td>
            <td>D6 D0 CE C4(GB2312)</td>
            <td>从\u4E2D\u6587(Unicode)到E4 B8 AD E6 96 87 (UTF)</td>
            <td>E4 B8 AD E6 96 87 (UTF)</td>
        </tr>
        <tr>
            <td>ISO-8859-1</td>
            <td>D6 D0 CE C4(GB2312)</td>
            <td>从\u00D6\u00D0\u00CE\u00C4 (Unicode)到C3 96 C3 90 C3 8E C3 84 (UTF)</td>
            <td>C3 96 C3 90 C3 8E C3 84 (UTF)</td>
        </tr>
        <tr>
            <td>无（默认＝file.encoding）</td>
            <td>同ISO-8859-1</td>
            <td>同ISO-8859-1</td>
            <td>同ISO-8859-1</td>
        </tr>
    </tbody>
</table>
</p>
<p>下节先讨论Servlet从JAVA文件到CLASS文件的转化过程，然后再解释从CLASS文件如何输出到客户端。之所以这样安排，是因为JSP和Servlet在输出时处理方法是一样的。</p>
<p><strong>Servlet：从源文件到Class的过程</strong></p>
<p>Servlet源文件是以&#8220;.java&#8221;结尾的文本文件。本节将讨论Servlet的编译过程并跟踪其中的中文变化。</p>
<p>用&#8220;javac&#8221;编译Servlet源文件。javac可以带&#8220;-encoding ＜Compile-charset＞&#8221;参数，意思是&#8220;用＜ Compile-charset ＞中指定的编码来解释Serlvet源文件&#8221;。</p>
<p>源文件在编译时，用＜Compile-charset＞来解释所有字符，包括中文字符和ASCII字符。然后把字符常量转变成Unicode字符，最后，把Unicode转变成UTF。</p>
<p>在Servlet中，还有一个地方设置输出流的CharSet。通常在输出结果前，调用HttpServletResponse的setContentType方法来达到与在JSP中设置＜Jsp-charset＞一样的效果，称之为＜Servlet-charset＞。</p>
<p>注意，文中一共提到了三个变量：＜Jsp-charset＞、＜Compile-charset＞和＜Servlet-charset＞。其中，JSP文件只与＜Jsp-charset＞有关，而＜Compile-charset＞和＜Servlet-charset＞只与Servlet有关。</p>
<p>看下例：</p>
<p>import javax.servlet.*;</p>
<p>import javax.servlet.http.*;</p>
<p>class testServlet extends HttpServlet<br>{&nbsp;<br>　public void doGet(HttpServletRequest req,HttpServletResponse resp)<br>　throws ServletException,java.io.IOException<br>　{&nbsp;<br>　　resp.setContentType("text/html; charset=GB2312");<br>　　java.io.PrintWriter out=resp.getWriter();<br>　　out.println("＜html＞");<br>　　out.println("#中文#");<br>　　out.println("＜/html＞");<br>　}<br>} </p>
<p>该文件也是用UltraEdit for Windows编写的，其中的&#8220;中文&#8221;两个字保存为&#8220;D6 D0 CE C4&#8221;（GB2312编码）。</p>
<p>开始编译。下表是＜Compile-charset＞不同时，CLASS文件中&#8220;中文&#8221;两字的十六进制码。在编译过程中，＜Servlet-charset＞不起任何作用。＜Servlet-charset＞只对CLASS文件的输出产生影响，实际上是＜Servlet-charset＞和＜Compile-charset＞一起，达到与JSP文件中的＜Jsp-charset＞相同的效果，因为＜Jsp-charset＞对编译和CLASS文件的输出都会产生影响。</p>
<p><strong><font color=#993300>表3 &#8220;中文&#8221;从Servlet源文件到Class的转变过程</font></strong></p>
<p>
<table>
    <tbody>
        <tr>
            <td>Compile-charset</td>
            <td>Servlet源文件中</td>
            <td>Class文件中</td>
            <td>等效的Unicode码</td>
        </tr>
        <tr>
            <td>GB2312</td>
            <td>D6 D0 CE C4 (GB2312)</td>
            <td>E4 B8 AD E6 96 87 (UTF)</td>
            <td>\u4E2D\u6587 (在Unicode中＝&#8220;中文&#8221;)</td>
        </tr>
        <tr>
            <td>ISO-8859-1</td>
            <td>D6 D0 CE C4 (GB2312)</td>
            <td>C3 96 C3 90 C3 8E C3 84 (UTF)</td>
            <td>\u00D6 \u00D0 \u00CE \u00C4 (在D6 D0 CE C4前面各加了一个00)</td>
        </tr>
        <tr>
            <td>无（默认）</td>
            <td>D6 D0 CE C4 (GB2312)</td>
            <td>同ISO-8859-1</td>
            <td>同ISO-8859-1</td>
        </tr>
    </tbody>
</table>
</p>
<p>普通Java程序的编译过程与Servlet完全一样。</p>
<p>CLASS文件中的中文表示法是不是昭然若揭了？OK，接下来看看CLASS又是怎样输出中文的呢？</p>
<p><strong>Class：输出字符串</strong></p>
<p>上文说过，字符串在内存中表现为Unicode编码。至于这种Unicode编码表示了什么，那要看它是从哪种字符集映射过来的，也就是说要看它的祖先。这好比在托运行李时，外观都是纸箱子，里面装了什么就要看寄邮件的人实际邮了什么东西。</p>
<p>看看上面的例子，如果给一串Unicode编码&#8220;00D6 00D0 00CE 00C4&#8221;，如果不作转换，直接用Unicode码表来对照它时，是四个字符（而且是特殊字符）；假如把它与&#8220;ISO8859-1&#8221;进行映射，则直接去掉前面的&#8220;00&#8221;即可得到&#8220;D6 D0 CE C4&#8221;，这是ASCII码表中的四个字符；而假如把它当作GB2312来进行映射，得到的结果很可能是一大堆乱码，因为在GB2312中有可能没有（也有可能有）字符与00D6等字符对应（如果对应不上，将得到0x3f，也就是问号，如果对应上了，由于00D6等字符太靠前，估计也是一些特殊符号，真正的汉字在Unicode中的编码从4E00开始）。</p>
<p>各位看到了，同样的Unicode字符，可以解释成不同的样子。当然，这其中有一种是我们期望的结果。以上例而论，&#8220;D6 D0 CE C4&#8221;应该是我们所想要的，当把&#8220;D6 D0 CE C4&#8221;输出到IE中时，用&#8220;简体中文&#8221;方式查看，就能看到清楚的&#8220;中文&#8221;两个字了。（当然了，如果你一定要用&#8220;西欧字符&#8221;来看，那也没办法，你将得不到任何有何时何地的东西）为什么呢？因为&#8220;00D6 00D0 00CE 00C4&#8221;本来就是由ISO8859-1转化过去的。</p>
<p>给出如下结论：</p>
<p>在Class输出字符串前，会将Unicode的字符串按照某一种内码重新生成字节流，然后把字节流输入，相当于进行了一步&#8220;String.getBytes(???)&#8221;操作。???代表某一种字符集。</p>
<p>如果是Servlet，那么，这种内码就是在HttpServletResponse.setContentType()方法中指定的内码，也就是上文定义的＜Servlet-charset＞。</p>
<p>如果是JSP，那么，这种内码就是在＜%@ page contentType=""%＞中指定的内码，也就是上文定义的＜Jsp-charset＞。</p>
<p>如果是Java程序，那么，这种内码就是file.encoding中指定的内码，默认为ISO8859-1。</p>
<p>当输出对象是浏览器时</p>
<p>以流行的浏览器IE为例。IE支持多种内码。假如IE接收到了一个字节流&#8220;D6 D0 CE C4&#8221;，你可以尝试用各种内码去查看。你会发现用&#8220;简体中文&#8221;时能得到正确的结果。因为&#8220;D6 D0 CE C4&#8221;本来就是简体中文中&#8220;中文&#8221;两个字的编码。</p>
<p>OK，完整地看一遍。</p>
<p>JSP：源文件为GB2312格式的文本文件，且JSP源文件中有&#8220;中文&#8221;这两个汉字</p>
<p>如果指定了＜Jsp-charset＞为GB2312，转化过程如下表。</p>
<p><strong><font color=#993300>表4 Jsp-charset = GB2312时的变化过程</font></strong></p>
<p>
<table>
    <tbody>
        <tr>
            <td>序号</td>
            <td>步骤说明</td>
            <td>结果</td>
        </tr>
        <tr>
            <td>1</td>
            <td>编写JSP源文件，且存为GB2312格式</td>
            <td>D6 D0 CE C4（D6D0=中 CEC4=文）</td>
        </tr>
        <tr>
            <td>2</td>
            <td>jspc把JSP源文件转化为临时JAVA文件，并把字符串按照GB2312映射到Unicode，并用UTF格式写入JAVA文件中</td>
            <td>E4 B8 AD E6 96 87</td>
        </tr>
        <tr>
            <td>3</td>
            <td>把临时JAVA文件编译成CLASS文件</td>
            <td>E4 B8 AD E6 96 87</td>
        </tr>
        <tr>
            <td>4</td>
            <td>运行时，先从CLASS文件中用readUTF读出字符串，在内存中的是Unicode编码</td>
            <td>4E 2D 65 87（在Unicode中4E2D=中 6587=文）</td>
        </tr>
        <tr>
            <td>5</td>
            <td>根据Jsp-charset=GB2312把Unicode转化为字节流</td>
            <td>D6 D0 CE C4</td>
        </tr>
        <tr>
            <td>6</td>
            <td>把字节流输出到IE中，并设置IE的编码为GB2312（作者按：这个信息隐藏在HTTP头中）</td>
            <td>D6 D0 CE C4</td>
        </tr>
        <tr>
            <td>7</td>
            <td>IE用&#8220;简体中文&#8221;查看结果</td>
            <td>&#8220;中文&#8221;（正确显示）</td>
        </tr>
    </tbody>
</table>
</p>
<p>如果指定了＜Jsp-charset＞为ISO8859-1，转化过程如下表。</p>
<p><strong><font color=#993300>表5 Jsp-charset = ISO8859-1时的变化过程</font></strong></p>
<p>
<table>
    <tbody>
        <tr>
            <td>序号</td>
            <td>步骤说明</td>
            <td>结果</td>
        </tr>
        <tr>
            <td>1</td>
            <td>编写JSP源文件，且存为GB2312格式</td>
            <td>D6 D0 CE C4（D6D0=中 CEC4=文）</td>
        </tr>
        <tr>
            <td>2</td>
            <td>jspc把JSP源文件转化为临时JAVA文件，并把字符串按照ISO8859-1映射到Unicode，并用UTF格式写入JAVA文件中</td>
            <td>C3 96 C3 90 C3 8E C3 84</td>
        </tr>
        <tr>
            <td>3</td>
            <td>把临时JAVA文件编译成CLASS文件</td>
            <td>C3 96 C3 90 C3 8E C3 84</td>
        </tr>
        <tr>
            <td>4</td>
            <td>运行时，先从CLASS文件中用readUTF读出字符串，在内存中的是Unicode编码</td>
            <td>00 D6 00 D0 00 CE 00 C4（啥都不是！！！）</td>
        </tr>
        <tr>
            <td>5</td>
            <td>根据Jsp-charset=ISO8859-1把Unicode转化为字节流</td>
            <td>D6 D0 CE C4</td>
        </tr>
        <tr>
            <td>6</td>
            <td>把字节流输出到IE中，并设置IE的编码为ISO8859-1（作者按：这个信息隐藏在HTTP头中）</td>
            <td>D6 D0 CE C4</td>
        </tr>
        <tr>
            <td>7</td>
            <td>IE用&#8220;西欧字符&#8221;查看结果</td>
            <td>乱码，其实是四个ASCII字符，但由于大于128，所以显示出来的怪模怪样</td>
        </tr>
        <tr>
            <td>8</td>
            <td>改变IE的页面编码为&#8220;简体中文&#8221;</td>
            <td>&#8220;中文&#8221;（正确显示）</td>
        </tr>
    </tbody>
</table>
</p>
<p>奇怪了！为什么把＜Jsp-charset＞设成GB2312和ISO8859-1是一个样的，都能正确显示？因为表4表5中的第2步和第5步互逆，是相互&#8220;抵消&#8221;的。只不过当指定为ISO8859-1时，要增加第8步操作，殊为不便。</p>
<p>再看看不指定＜Jsp-charset＞ 时的情况。</p>
<p><strong><font color=#993300>表6 未指定Jsp-charset 时的变化过程</font></strong></p>
<p>
<table>
    <tbody>
        <tr>
            <td>序号</td>
            <td>步骤说明</td>
            <td>结果</td>
        </tr>
        <tr>
            <td>1</td>
            <td>编写JSP源文件，且存为GB2312格式</td>
            <td>D6 D0 CE C4（D6D0=中 CEC4=文）</td>
        </tr>
        <tr>
            <td>2</td>
            <td>jspc把JSP源文件转化为临时JAVA文件，并把字符串按照ISO8859-1映射到Unicode，并用UTF格式写入JAVA文件中</td>
            <td>C3 96 C3 90 C3 8E C3 84</td>
        </tr>
        <tr>
            <td>3</td>
            <td>把临时JAVA文件编译成CLASS文件</td>
            <td>C3 96 C3 90 C3 8E C3 84</td>
        </tr>
        <tr>
            <td>4</td>
            <td>运行时，先从CLASS文件中用readUTF读出字符串，在内存中的是Unicode编码</td>
            <td>00 D6 00 D0 00 CE 00 C4</td>
        </tr>
        <tr>
            <td>5</td>
            <td>根据Jsp-charset=ISO8859-1把Unicode转化为字节流</td>
            <td>D6 D0 CE C4</td>
        </tr>
        <tr>
            <td>6</td>
            <td>把字节流输出到IE中</td>
            <td>D6 D0 CE C4</td>
        </tr>
        <tr>
            <td>7</td>
            <td>IE用发出请求时的页面的编码查看结果</td>
            <td>视情况而定。如果是简体中文，则能正确显示，否则，需执行表5中的第8步</td>
        </tr>
    </tbody>
</table>
</p>
<p>Servlet：源文件为JAVA文件，格式是GB2312，源文件中含有&#8220;中文&#8221;这两个汉字</p>
<p>如果＜Compile-charset＞＝GB2312，＜Servlet-charset＞=GB2312</p>
<p><strong><font color=#993300>表7 Compile-charset=Servlet-charset=GB2312 时的变化过程</font></strong></p>
<p>
<table>
    <tbody>
        <tr>
            <td>序号</td>
            <td>步骤说明</td>
            <td>结果</td>
        </tr>
        <tr>
            <td>1</td>
            <td>编写Servlet源文件，且存为GB2312格式</td>
            <td>D6 D0 CE C4（D6D0=中 CEC4=文）</td>
        </tr>
        <tr>
            <td>2</td>
            <td>用javac &#8211;encoding GB2312把JAVA源文件编译成CLASS文件</td>
            <td>E4 B8 AD E6 96 87 （UTF）</td>
        </tr>
        <tr>
            <td>3</td>
            <td>运行时，先从CLASS文件中用readUTF读出字符串，在内存中的是Unicode编码</td>
            <td>4E 2D 65 87 (Unicode)</td>
        </tr>
        <tr>
            <td>4</td>
            <td>根据Servlet-charset=GB2312把Unicode转化为字节流</td>
            <td>D6 D0 CE C4 (GB2312)</td>
        </tr>
        <tr>
            <td>5</td>
            <td>把字节流输出到IE中并设置IE的编码属性为Servlet-charset=GB2312</td>
            <td>D6 D0 CE C4 (GB2312)</td>
        </tr>
        <tr>
            <td>6</td>
            <td>IE用&#8220;简体中文&#8221;查看结果</td>
            <td>&#8220;中文&#8221;（正确显示）</td>
        </tr>
    </tbody>
</table>
</p>
<p>如果＜Compile-charset＞＝ISO8859-1，＜Servlet-charset＞=ISO8859-1</p>
<p><strong><font color=#993300>表8 Compile-charset=Servlet-charset=ISO8859-1时的变化过程</font></strong></p>
<p>
<table>
    <tbody>
        <tr>
            <td>序号</td>
            <td>步骤说明</td>
            <td>结果</td>
        </tr>
        <tr>
            <td>1</td>
            <td>编写Servlet源文件，且存为GB2312格式</td>
            <td>D6 D0 CE C4（D6D0=中 CEC4=文）</td>
        </tr>
        <tr>
            <td>2</td>
            <td>用javac &#8211;encoding ISO8859-1把JAVA源文件编译成CLASS文件</td>
            <td>C3 96 C3 90 C3 8E C3 84 （UTF）</td>
        </tr>
        <tr>
            <td>3</td>
            <td>运行时，先从CLASS文件中用readUTF读出字符串，在内存中的是Unicode编码</td>
            <td>00 D6 00 D0 00 CE 00 C4</td>
        </tr>
        <tr>
            <td>4</td>
            <td>根据Servlet-charset=ISO8859-1把Unicode转化为字节流</td>
            <td>D6 D0 CE C4</td>
        </tr>
        <tr>
            <td>5</td>
            <td>把字节流输出到IE中并设置IE的编码属性为Servlet-charset=ISO8859-1</td>
            <td>D6 D0 CE C4 (GB2312)</td>
        </tr>
        <tr>
            <td>6</td>
            <td>IE用&#8220;西欧字符&#8221;查看结果</td>
            <td>乱码（原因同表5）</td>
        </tr>
        <tr>
            <td>7</td>
            <td>改变IE的页面编码为&#8220;简体中文&#8221;</td>
            <td>&#8220;中文&#8221;（正确显示）</td>
        </tr>
    </tbody>
</table>
</p>
<p>如果不指定Compile-charset或Servlet-charset，其默认值均为ISO8859-1。</p>
<p>当Compile-charset=Servlet-charset时，第2步和第4步能互逆，&#8220;抵消&#8221;，显示结果均能正确。读者可试着写一下Compile-charset＜＞Servlet-charset时的情况，肯定是不正确的。</p>
<p>当输出对象是数据库时</p>
<p>输出到数据库时，原理与输出到浏览器也是一样的。本节只是Servlet为例，JSP的情况请读者自行推导。</p>
<p>假设有一个Servlet，它能接收来自客户端（IE，简体中文）的汉字字符串，然后把它写入到内码为ISO8859-1的数据库中，然后再从数据库中取出这个字符串，显示到客户端。</p>
<p><strong><font color=#993300>表9 输出对象是数据库时的变化过程（1）</font></strong></p>
<p>
<table>
    <tbody>
        <tr>
            <td>序号</td>
            <td>步骤说明</td>
            <td>结果</td>
            <td>域</td>
        </tr>
        <tr>
            <td>1</td>
            <td>在IE中输入&#8220;中文&#8221;</td>
            <td>D6 D0 CE C4</td>
            <td>IE</td>
        </tr>
        <tr>
            <td>2</td>
            <td>IE把字符串转变成UTF，并送入传输流中</td>
            <td>E4 B8 AD E6 96 87</td>
        </tr>
        <tr>
            <td>3</td>
            <td>Servlet接收到输入流，用readUTF读取</td>
            <td>4E 2D 65 87(unicode)</td>
            <td>Servlet</td>
        </tr>
        <tr>
            <td>4</td>
            <td>编程者在Servlet中必须把字符串根据GB2312还原为字节流</td>
            <td>D6 D0 CE C4</td>
        </tr>
        <tr>
            <td>5</td>
            <td>编程者根据数据库内码ISO8859-1生成新的字符串</td>
            <td>00 D6 00 D0 00 CE 00 C4</td>
        </tr>
        <tr>
            <td>6</td>
            <td>把新生成的字符串提交给JDBC</td>
            <td>00 D6 00 D0 00 CE 00 C4</td>
        </tr>
        <tr>
            <td>7</td>
            <td>JDBC检测到数据库内码为ISO8859-1</td>
            <td>00 D6 00 D0 00 CE 00 C4</td>
            <td>JDBC</td>
        </tr>
        <tr>
            <td>8</td>
            <td>JDBC把接收到的字符串按照ISO8859-1生成字节流</td>
            <td>D6 D0 CE C4</td>
        </tr>
        <tr>
            <td>9</td>
            <td>JDBC把字节流写入数据库中</td>
            <td>D6 D0 CE C4</td>
        </tr>
        <tr>
            <td>10</td>
            <td>完成数据存储工作</td>
            <td>D6 D0 CE C4 数据库</td>
        </tr>
        <tr>
            <td>以下是从数据库中取出数的过程</td>
        </tr>
        <tr>
            <td>11</td>
            <td>JDBC从数据库中取出字节流</td>
            <td>D6 D0 CE C4</td>
            <td>JDBC</td>
        </tr>
        <tr>
            <td>12</td>
            <td>JDBC按照数据库的字符集ISO8859-1生成字符串，并提交给Servlet</td>
            <td>00 D6 00 D0 00 CE 00 C4 (Unicode)</td>
            <td>&nbsp;</td>
        </tr>
        <tr>
            <td>13</td>
            <td>Servlet获得字符串</td>
            <td>00 D6 00 D0 00 CE 00 C4 (Unicode)</td>
            <td>Servlet</td>
        </tr>
        <tr>
            <td>14</td>
            <td>编程者必须根据数据库的内码ISO8859-1还原成原始字节流</td>
            <td>D6 D0 CE C4</td>
            <td>&nbsp;</td>
        </tr>
        <tr>
            <td>15</td>
            <td>编程者必须根据客户端字符集GB2312生成新的字符串</td>
            <td>4E 2D 65 87（Unicode）</td>
            <td>&nbsp;</td>
        </tr>
        <tr>
            <td>Servlet准备把字符串输出到客户端</td>
        </tr>
        <tr>
            <td>16</td>
            <td>Servlet根据＜Servlet-charset＞生成字节流</td>
            <td>D6D0 CE C4</td>
            <td>Servlet</td>
        </tr>
        <tr>
            <td>17</td>
            <td>Servlet把字节流输出到IE中，如果已指定＜Servlet-charset＞，还会设置IE的编码为＜Servlet-charset＞</td>
            <td>D6 D0 CE C4</td>
        </tr>
        <tr>
            <td>18</td>
            <td>IE根据指定的编码或默认编码查看结果</td>
            <td>&#8220;中文&#8221;（正确显示）</td>
            <td>IE</td>
        </tr>
    </tbody>
</table>
</p>
<p>解释一下，表中第4第5步和第15第16步是用红色标记的，表示要由编码者来作转换。第4、5两步其实就是一句话：&#8220;new String(source.getBytes("GB2312"), "ISO8859-1")&#8221;。第15、16两步也是一句话：&#8220;new String(source.getBytes("ISO8859-1"), "GB2312")&#8221;。亲爱的读者，你在这样编写代码时是否意识到了其中的每一个细节呢？</p>
<p>至于客户端内码和数据库内码为其它值时的流程，和输出对象是系统控制台时的流程，请读者自己想吧。明白了上述流程的原理，相信你可以轻松地写出来。</p>
<p>行文至此，已可告一段落了。终点又回到了起点，对于编程者而言，几乎是什么影响都没有。</p>
<p>因为我们早就被告之要这么做了。</p>
<p>以下给出一个结论，作为结尾。</p>
<p>1、 在Jsp文件中，要指定contentType，其中，charset的值要与客户端浏览器所用的字符集一样；对于其中的字符串常量，不需做任何内码转换；对于字符串变量，要求能根据ContentType中指定的字符集还原成客户端能识别的字节流，简单地说，就是&#8220;字符串变量是基于＜Jsp-charset＞字符集的&#8221;；</p>
<p>2、 在Servlet中，必须用HttpServletResponse.setContentType()设置charset，且设置成与客户端内码一致；对于其中的字符串常量，需要在Javac编译时指定encoding，这个encoding必须与编写源文件的平台的字符集一样，一般说来都是GB2312或GBK；对于字符串变量，与JSP一样，必须&#8220;是基于＜Servlet-charset＞字符集的&#8221;。</p>
<img src ="http://www.blogjava.net/junky/aggbug/111006.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junky/" target="_blank">junky</a> 2007-04-16 16:28 <a href="http://www.blogjava.net/junky/archive/2007/04/16/111006.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>struts+hibernate的替代方案：struts+newxy,开发效率提高十倍(转)</title><link>http://www.blogjava.net/junky/archive/2007/03/09/102774.html</link><dc:creator>junky</dc:creator><author>junky</author><pubDate>Fri, 09 Mar 2007 03:29:00 GMT</pubDate><guid>http://www.blogjava.net/junky/archive/2007/03/09/102774.html</guid><wfw:comment>http://www.blogjava.net/junky/comments/102774.html</wfw:comment><comments>http://www.blogjava.net/junky/archive/2007/03/09/102774.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junky/comments/commentRss/102774.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junky/services/trackbacks/102774.html</trackback:ping><description><![CDATA[
		<div class="con_sample">
				<p>struts+newxy之所以在开发效率上比struts+hibernate能提高十倍、甚至几十倍，是因为克服了struts与hiberate的不足。 利用newxy DAO类，标签， struts+newxy可以在以下几个方面不用写java代码，不用配置struts。 1.数据库的增、删、改； 2.对查询所得数据缓存，指定缓存时长； 3.数据库字符编码与本地字符编码转换； 4.文件上传，上传大小控制； 5.文件下载，下载记数； 6.图片显示； 7.数据分页显示； 8.客户端标记记录集哪条记录被选择； 因为可以不写java代码，不用建立ActionForm类、Action类，因而不用配置struts，不用重新编译类文件、不用重新打包、不用重启服务器。 可以克服struts的不足。 由于struts+newxy用即时注册的方法，可以不象</p>
		</div>
		<div class="con_all">
				<p>
				</p>
				<p>    在java的web开发领域较麻烦的是数据库操纵，如果有工具能像delphi开发数据库运用系统那样高效，它一定会受到开发者的欢迎。 </p>
				<p>    经过五个方面的比较，newxy+struts WEB开发与deiphi桌面开发相比，速度更快，能力更强。 <a href="http://blog.csdn.net/nlhlx/archive/2006/06/12/791047.aspx">http://blog.csdn.net/nlhlx/archive/2006/06/12/791047.aspx</a></p>
				<p>    newxy是hibernate的替代者，struts+newxy是struts+hibernate的替代方案。 </p>
				<p>    struts的不足，下面一篇文章有代表性：《Struts的巨大烦恼 真的不适合大系统？》<a href="http://dev.csdn.net/develop/article/85/85114.shtm">http://dev.csdn.net/develop/article/85/85114.shtm</a>。<br />主要观点是：<br />　    一、转到展示层时，需要配置forward，每一次转到展示层，相信大多数都是直接转到jsp， 而涉及到转向，需要配置forward，如果有十个展示层的jsp，需要配置十次struts， 而且还不包括有时候目录、文件变更，需要重新修改forward，注意，每次修改配置之后， 要求重新部署整个项目，而tomcate这样的服务器，还必须重新启动服务器，如果业务变更复杂频繁的系统， 这样的操作简单不可想象。现在就是这样，几十上百个人同时在线使用我们的 系统， 大家可以想象一下，我的烦恼有多大。<br />    二、当页面表单需要自动变化或者频繁变化时。<br />    对于一个成熟的MIS系统来说,页面表单肯定是不固定的,甚至象有些系统，页面表单是存在数据库中， 需要填写的表单在页面自动生成，比如填写一个人员基本信息,本来只需要填写 姓名、性别、出生年月 三个指标， 而我后来需要增加籍贯这样的指标，我只需要在数据库中添加籍贯这个记录，并在页面就能自动增加籍贯这样的表单。 而 struts在这方面，其优势反而变成了不足，我参考了非常多的人力资源管理系统，这些系统几乎都能够做系统里面就可以控制人员信息的指示， 进行使展示层能随之灵活变化，如果使用了struts，这些灵活性就根本用不上。　同时，如果页面表单频繁变化时，就需要频繁修改formbean对应的方法和属性，而每次修改之后，就要求重新部署，或者重新启动服务器……。<br />    hibernate的不足，下面是一位网友的看法，具有代表性：<br />    一、对象与数据库的映射，关键在于对象关系的映射，但是没做到很理想，配置过多，控制复杂， 另外还会出错。其实本质在于对象不够自由。<br />    二、事务处理。这点上更容易出问题，相对于各种各样的事务管理器，要兼容是一个大问题， 总归在各种应用服务器上有很多问题。其本质在于创建了一个自我数据存取小环境，必然面临各种兼容问题。<br />    三、HQL语言。建立对象查询语言，类SQL，但是不同于任何一种SQL，调试环境复杂。本质在于创建了一种语言，增加学习成本。<br />    这位网友还提出了减化和退化方案。 </p>
				<p>    struts+newxy之所以在开发效率上比struts+hibernate能提高十倍、甚至几十倍，是因为克服了struts与hiberate的不足。<br />    利用newxy DAO类，标签， struts+newxy可以在以下几个方面不用写java代码，不用配置struts。 <a href="http://blog.csdn.net/nlhlx/archive/2006/06/11/788541.aspx">http://blog.csdn.net/nlhlx/archive/2006/06/11/788541.aspx</a></p>
				<p>    1.数据库的增、删、改； <br />    2.对查询所得数据缓存，指定缓存时长； <br />    3.数据库字符编码与本地字符编码转换； <br />    4.文件上传，上传大小控制； <br />    5.文件下载，下载记数； <br />    6.图片显示； <br />    7.数据分页显示； <br />    8.客户端标记记录集哪条记录被选择； </p>
				<p>    因为可以不写java代码，不用建立ActionForm类、Action类，因而不用配置struts，不用重新编译类文件、不用重新打包、不用重启服务器。 可以克服struts的不足。<br />    在克服hibernate的不足方面，newxy采用“退化”和“进化”并用的方案。<br />    newxy在进行数据的查询、增、删、改时都会调用一注册方法，根据业务涉及到的数据库相关数据源名和表名进行注册， 注册的目的是要获得表字段对应的java类名，主关键字段名，主关键字段长度等数据，保存在一个单子实例中，以供DAO类调用。 如果已注册不再注册。<br />    可以对多表查询语句注册，如：“select a.field1,b.field2 from table1 as a,table2 as b where ...";<br />    可以对跨数据源的查询注册。如："select a.field1,b.field2 from table1 as a,DB3.dto.table2 as b where ...";<br />    如果是数据增、删、改，则是对单一表注册；<br />    由于struts+newxy用即时注册的方法，可以不象hibernate那样用静态文件影射数据库到值对象类。开发者不用配置任何文件。可以使用任意查询语句，克服“对象不够自由”问题。<br />    hibernate通过配置文件设置表之间的关系，有一定意义，newxy在这方面算是“退化”的，但struts+newxy在处理数据库表之间关系方面是很容易的。<br />    在事务处理方面，newxy提供了一事务类net.newxy.dbm.Transaction。它可以将多个数据库的操作放在一个事务中。由于DAO类对数据操作前的注册方法得到的表及其字段各种特性都是与数据库直接相关的，而不是事先用静态文件影射， 因而极少发生错误；开发者可以通过Transaction的方法为不同的数据库设置不同的隔离等级；可以设置操时回滚时间，在设置的时间内事务没有完成，会有一线程进行干预，将事务回滚。<br />    hibernate的HQL语言是和数据库与对象影射规则相适应的，它没有特别功能，主要是利用值对象类来查询数据。 newxy也提供了一种查询语言NQL。开发者不需用特殊的语法来构建查询语句。非常容易理解，不会增加学习成本。 </p>
				<p>struts一旦与newxy结合到一起运用是如此简单，下列是struts+newxy代替struts+hibernate的例子。 </p>
				<p>        struts配置中，formBean的type是“net.newxy.struts_faces.DynaFormBean”，开发者不需另外设计ActionForm类。如：<br />            &lt;form-bean name="myFormBean" type="net.newxy.struts_faces.DynaFormBean" /&gt;</p>
				<p>        用户从页面表单submit数据后，在Action类的方法中，开发者可以用DynaFormBean代替struts ActionForm,用DynaDto代替hibernate 对象类。<br />        public ActionForward methodName(ActionMapping actionMapping, ActionForm actionForm,<br />                              HttpServletRequest httpServletRequest,<br />            HttpServletResponse httpServletResponse) throws Exception{<br />            ......<br />            DynaFormBean form=(DynaFormBean)actionForm;<br />            DynaDto dto=(DynaDto)form.getDto();<br />            dto.set_table("table1");//如果用户页面没有传来数据库表名。<br />            try{<br />                IFacade ifacade=IFacadeFactory.getFacade(httpServletRequest.getParameter("_dao"),<br />                      httpServletRequest.getLocale());  //绝大多数情况是：IFacade ifacade=IFacadeFactory.getFacade();</p>
				<p>                //更新或插入，如果result==null,为update，否则为insert。<br />                result = ifacade.update(dto);//或：FormBeanUtils.update(ifacade, form);</p>
				<p>                //删除记录<br />                ifacade.remove(dto);//或:FormBeanUtils.remove(ifacade, form);</p>
				<p>                //数据查询，如果上传了符合newxy多项查询规则的数据。查询记录集放在newForm 的_coll属性中。<br />                DynaFormBean newForm=new DynaFormBean();<br />                FormBeanUtils.createForm(newForm, httpServletRequest);<br />                ......<br />                //开发者如果想知道生成的sql语句，可以这样：<br />                //string sql=form.get_sql();<br />                //由于开发者在对数据进行操作时完全不需知道sql语句，所以没有提供方法让开发者直接得到sql语句来控制数据操作。<br />                //未来版本可能提供这样的方法。<br />            }catch(Exception e){<br />                ......<br />            }<br />        }<br />        如果使用newxy的标签可以不建立Action类，不设置struts的formBean及action，可以不写代码。<br />    </p>
		</div>
<img src ="http://www.blogjava.net/junky/aggbug/102774.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junky/" target="_blank">junky</a> 2007-03-09 11:29 <a href="http://www.blogjava.net/junky/archive/2007/03/09/102774.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts的巨大烦恼 真的不适合大系统？(转)</title><link>http://www.blogjava.net/junky/archive/2007/03/09/102772.html</link><dc:creator>junky</dc:creator><author>junky</author><pubDate>Fri, 09 Mar 2007 03:26:00 GMT</pubDate><guid>http://www.blogjava.net/junky/archive/2007/03/09/102772.html</guid><wfw:comment>http://www.blogjava.net/junky/comments/102772.html</wfw:comment><comments>http://www.blogjava.net/junky/archive/2007/03/09/102772.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junky/comments/commentRss/102772.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junky/services/trackbacks/102772.html</trackback:ping><description><![CDATA[　经过一段时间使用struts，随着系统越做越大，现在，我终于要抛弃struts了，因为到现在，struts的巨大不足和缺陷越来越影响到我的项目的进度和开发效率了。<br /><br />　　背景：现在，我负责着一个大型企业的人力资源管理系统，整个系统管理的人员大约有1.6万人左右，系统基于jboss+oracle，java技术框架为struts，少许的报表用到了 servlet，项目开发的时间差不多一年，好，转入正题。<br /><br />　　到现在为止，我认为formbean 的好处就是和页面表单对应起来,在系统业务处理中，可以实例化formbean之就可以取出页面表单的值来,方便于在业务逻辑中引用。使得业务处理层和展示层可以分离开来，到现在为止，这也是我发现struts的唯一好处。<br /><br />　　但struts带给我的烦恼，各位，实在太多太多了，主要的几点我罗列如下：<br /><br />　　一、转到展示层时，需要配置forward，每一次转到展示层，相信大多数都是直接转到jsp，而涉及到转向，需要配置forward，如果有十个展示层的jsp，需要配置十次struts，而且还不包括有时候目录、文件变更，需要重新修改forward，注意，每次修改配置之后，要求重新部署整个项目，而tomcate这样的服务器，还必须重新启动服务器，如果业务变更复杂频繁的系统，这样的操作简单不可想象。现在就是这样，几十上百个人同时在线使用我们的 系统，大家可以想象一下，我的烦恼有多大。<br /><br />　　二、当页面表单需要自动变化或者频繁变化时。<br /><br />　　对于一个成熟的MIS系统来说,页面表单肯定是不固定的,甚至象有些系统，页面表单是存在数据库中，需要填写的表单在页面自动生成，比如填写一个人员基本信息,本来只需要填写 姓名、性别、出生年月 三个指标，而我后来需要增加籍贯这样的指标，我只需要在数据库中添加籍贯这个记录，并在页面就能自动增加籍贯这样的表单。而 struts在这方面，其优势反而变成了不足，我参考了非常多的人力资源管理系 统，这些系统几乎都能够做系统里面就可以控制人员信息的指示，进行使展示层能随之灵活变化，如果使用了struts，这些灵活性就根本用不上。<br /><br />　　同时，如果页面表单频繁变化时，就需要频繁修改formbean对应的方法和属性，而每次修改之后，就要求重新部署，或者重新启动服务器……。<br /><br />　　三、要引入struts包，引入strtus标签库，现到现为止，我们有所见即所得的dreamwaver、frontpage、webeditor，对于繁杂页面的设计，是非常方便的，而对于struts标签库，没有哪一种软件能够支持。jbuilder我没用过，不知道支持不支持，而为了维护这些标签库，增加工作量支持，也非常容易出错，稍微不小心，就一堆异常抛出来，系统他死给你看。<br /><br />　　总结：<br /><br />　　现在为什么asp.net越来越流行，非常重要的一点，就是asp.net这样的模式，简单，易于控制。而且我现在仍然觉得，利用jsp的文件名作为路径的映射非常方便，而struts还非常去配置action,使之有带有象.do、.main这样后缀的路径访问方式，不但增加了系统功能的复杂性，影响了系统的性能不说，还增加了非常多的系统不可掌握因素。其实 javabean+jsp，利用javabean处理业务逻辑，只利用jsp来展示数据，这正是.net的原型，同样，即可以不用去配置struts、也不需要象serlet一样去配置web.xml带来的麻烦。 所以，并不是所有的框架都是好的，越简单越易于控制。<br />　<br />　　所以，现在，我决定放弃struts，转而采用javabean+jsp的技术结构<img src ="http://www.blogjava.net/junky/aggbug/102772.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junky/" target="_blank">junky</a> 2007-03-09 11:26 <a href="http://www.blogjava.net/junky/archive/2007/03/09/102772.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>eXtremeComponents参考文档</title><link>http://www.blogjava.net/junky/archive/2006/08/31/66967.html</link><dc:creator>junky</dc:creator><author>junky</author><pubDate>Thu, 31 Aug 2006 15:34:00 GMT</pubDate><guid>http://www.blogjava.net/junky/archive/2006/08/31/66967.html</guid><wfw:comment>http://www.blogjava.net/junky/comments/66967.html</wfw:comment><comments>http://www.blogjava.net/junky/archive/2006/08/31/66967.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junky/comments/commentRss/66967.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junky/services/trackbacks/66967.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 版本1.0.0								本文档允许在遵守以下两条原则的条件下被使用和传播： 1）不能凭借本文档索取任何费用 2）以任何方式（印刷物或电子版）使用和传播时本文档时，必须包含本版权申明 								(更新中...)																Table of Contents																						前言	...&nbsp;&nbsp;<a href='http://www.blogjava.net/junky/archive/2006/08/31/66967.html'>阅读全文</a><img src ="http://www.blogjava.net/junky/aggbug/66967.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junky/" target="_blank">junky</a> 2006-08-31 23:34 <a href="http://www.blogjava.net/junky/archive/2006/08/31/66967.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>体验Struts(2)---整体结构 </title><link>http://www.blogjava.net/junky/archive/2006/05/25/48180.html</link><dc:creator>junky</dc:creator><author>junky</author><pubDate>Thu, 25 May 2006 12:27:00 GMT</pubDate><guid>http://www.blogjava.net/junky/archive/2006/05/25/48180.html</guid><wfw:comment>http://www.blogjava.net/junky/comments/48180.html</wfw:comment><comments>http://www.blogjava.net/junky/archive/2006/05/25/48180.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junky/comments/commentRss/48180.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junky/services/trackbacks/48180.html</trackback:ping><description><![CDATA[
		<p>为了让大家更方便的了解我这个设计，我先把我的一些整体的规划都说出来吧，由于我是初学，难免会参照本书籍来看，我买的是那本孙某女的书《精通：*****》，看了看她前面的介绍，我一看了不得，能出书，写的还都不错，这女的可不得了，渐渐疑惑的地方非常多，比如例子里面注释都拽上了英语，搞不懂，而当我从网上下到电子盗版jakarta struts（我已安下栽说明要求的那样在24小时后删除了）这本书的时候我才恍然大悟，原来是抄袭啊？至于是谁抄的谁，口说无凭，不能乱诽谤，不过大家心里都该有杆称！<br /><br />下面就是代码了：<br /><font color="#ff0000">package com.boya.subject.model;<br />public interface Person<br />{<br />    public Long getId();<br />    public void setId( Long id );<br />    public String getName();<br />    public void setName( String name );<br />    public String getPassword();<br />    public void setPassword( String password );<br />    public String getTelphone();<br />    public void setTelphone( String telphone );<br />    public String getUser();<br />    public void setUser( String user );<br />    public String getType();<br />}<br /><br />package com.boya.subject.model;<br />public abstract class User implements Person<br />{<br />    private Long id;<font color="#000000">数据库id</font><br />    private String user;<font color="#000000">用户名</font><br />    private String password;<font color="#000000">密码</font><br />    private String name;<font color="#000000">姓名</font><br />    private String telphone;</font><font color="#000000">电话</font></p>
		<p>
				<font color="#ff0000">    public Long getId()<br />    {<br />        return id;<br />    }</font>
		</p>
		<p>
				<font color="#ff0000">    public void setId( Long id )<br />    {<br />        this.id = id;<br />    }</font>
		</p>
		<p>
				<font color="#ff0000">    public String getName()<br />    {<br />        return name;<br />    }</font>
		</p>
		<p>
				<font color="#ff0000">    public void setName( String name )<br />    {<br />        this.name = name;<br />    }</font>
		</p>
		<p>
				<font color="#ff0000">    public String getPassword()<br />    {<br />        return password;<br />    }</font>
		</p>
		<p>
				<font color="#ff0000">    public void setPassword( String password )<br />    {<br />        this.password = password;<br />    }</font>
		</p>
		<p>
				<font color="#ff0000">    public String getTelphone()<br />    {<br />        return telphone;<br />    }</font>
		</p>
		<p>
				<font color="#ff0000">    public void setTelphone( String telphone )<br />    {<br />        this.telphone = telphone;<br />    }</font>
		</p>
		<p>
				<font color="#ff0000">    public String getUser()<br />    {<br />        return user;<br />    }</font>
		</p>
		<p>
				<font color="#ff0000">    public void setUser( String user )<br />    {<br />        this.user = user;<br />    }<br />}<br /><br />package com.boya.subject.model;<br />public class Admin extends User<br />{<br />    private String grade = null;</font>
				<font color="#000000">管理员权限</font>
		</p>
		<p>
				<font color="#ff0000">    public String getGrade()<br />    {<br />        return grade;<br />    }</font>
		</p>
		<p>
				<font color="#ff0000">    public void setGrade( String grade )<br />    {<br />        this.grade = grade;<br />    }</font>
		</p>
		<p>
				<font color="#ff0000">    public String getType()<br />    {<br />        return "admin";<br />    }<br />}<br /><br />package com.boya.subject.model;<br />public class Teacher extends User<br />{<br />    private String level;</font>
				<font color="#000000">教师职称</font>
		</p>
		<p>
				<font color="#ff0000">    public String getLevel()<br />    {<br />        return level;<br />    }</font>
		</p>
		<p>
				<font color="#ff0000">    public void setLevel( String level )<br />    {<br />        this.level = level;<br />    }</font>
		</p>
		<p>
				<font color="#ff0000">    public String getType()<br />    {<br />        return "teacher";<br />    }<br />}<br /><br />package com.boya.subject.model;</font>
		</p>
		<p>
				<font color="#ff0000">public class Student extends User<br />{<br />    private String sn;<font color="#000000">学生学号<br /></font>    private SchoolClass schoolClass;</font>
				<font color="#000000">班级</font>
		</p>
		<p>
				<font color="#ff0000">    public SchoolClass getSchoolClass()<br />    {<br />        return schoolClass;<br />    }</font>
		</p>
		<p>
				<font color="#ff0000">    public void setSchoolClass( SchoolClass schoolClass )<br />    {<br />        this.schoolClass = schoolClass;<br />    }</font>
		</p>
		<p>
				<font color="#ff0000">    public String getSn()<br />    {<br />        return sn;<br />    }</font>
		</p>
		<p>
				<font color="#ff0000">    public void setSn( String sn )<br />    {<br />        this.sn = sn;<br />    }</font>
		</p>
		<p>
				<font color="#ff0000">    public String getType()<br />    {<br />        return "student";<br />    }<br />}<br /><br /><font color="#000000">而对于Action我分别做了一个抽象类，之后别的从这里继承<br /></font><font color="#000000">先是Action的</font><br /></font>
				<font color="#ff0000">package com.boya.subject.controller;</font>
		</p>
		<p>
				<font color="#ff0000">import java.io.IOException;<br />import javax.servlet.http.HttpServletRequest;<br />import javax.servlet.http.HttpServletResponse;<br />import javax.servlet.http.HttpSession;<br />import org.apache.struts.action.Action;<br />import org.apache.struts.action.ActionForm;<br />import org.apache.struts.action.ActionForward;<br />import org.apache.struts.action.ActionMapping;<br />import com.boya.subject.frame.ID;<br />import com.boya.subject.frame.ServiceFactory;<br />import com.boya.subject.model.Person;<br />import com.boya.subject.service.Service;<br />import com.boya.subject.util.HtmlUtil;</font>
		</p>
		<p>
				<font color="#ff0000">public abstract class BaseAction extends Action<br />{<br />    /**<br />     * 由服务工厂方法创建服务<br />     * @return 数据库操作的服务<br />     * 2006-5-16 18:10:04<br />     */<br />    public Service getService()<br />    {<br />        ServiceFactory factory = (ServiceFactory) getAppObject( ID.SF );<br />        Service service = null;<br />        try<br />        {<br />            service = factory.createService();<br />        }<br />        catch ( Exception e )<br />        {<br />        }<br />        return service;<br />    }</font>
		</p>
		<p>
				<font color="#ff0000">    /**<br />     * 判断用户是否合法登陆<br />     * @param req <br />     * @return 用户是否登陆<br />     * 2006-5-16 18:11:26<br />     */<br />    public boolean isLogin( HttpServletRequest req )<br />    {<br />        if ( getPerson( req ) != null ) return true;<br />        else<br />            return false;<br />    }</font>
		</p>
		<p>
				<font color="#ff0000">    <br />    /**<br />     * 抽象方法,子类实现<br />     * @param mapping<br />     * @param form<br />     * @param req<br />     * @param res<br />     * @return<br />     * @throws Exception<br />     * 2006-5-16 18:12:54<br />     */<br />    protected abstract ActionForward executeAction( ActionMapping mapping,<br />            ActionForm form, HttpServletRequest req, HttpServletResponse res )<br />            throws Exception;</font>
		</p>
		<p>
				<font color="#ff0000">    /**<br />     * 获取session范围的用户<br />     * @param req<br />     * @return 当前用户<br />     * 2006-5-16 18:13:35<br />     */<br />    public abstract Person getPerson( HttpServletRequest req );</font>
		</p>
		<p>
				<font color="#ff0000">    /**<br />     * 父类的执行Action<br />     * @see org.apache.struts.action.Action#execute(org.apache.struts.action.ActionMapping, org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)<br />     */<br />    public ActionForward execute( ActionMapping mapping, ActionForm form,<br />            HttpServletRequest req, HttpServletResponse res ) throws Exception<br />    {<br />        if ( !isLogin( req ) )<br />        {<br />            HtmlUtil.callParentGo( res.getWriter(), ID.M_UNLOGIN, ID.P_INDEX );<br />            return null;<br />        }<br />        return executeAction( mapping, form, req, res );<br />    }</font>
		</p>
		<p>
				<font color="#ff0000">    /**<br />     * 删除session中属性为attribute的对象<br />     * @param req<br />     * @param attribute 对象属性<br />     * 2006-5-16 18:16:59<br />     */<br />    public void removeSessionObject( HttpServletRequest req, String attribute )<br />    {<br />        HttpSession session = req.getSession();<br />        session.removeAttribute( attribute );<br />    }</font>
		</p>
		<p>
				<font color="#ff0000">    /**<br />     * 设置session中属性为attribute的对象<br />     * @param req<br />     * @param attribute 设置属性<br />     * @param o 设置对象<br />     * 2006-5-16 18:17:50<br />     */<br />    public void setSessionObject( HttpServletRequest req, String attribute,<br />            Object o )<br />    {<br />        req.getSession().setAttribute( attribute, o );<br />    }</font>
		</p>
		<p>
				<font color="#ff0000">    /**<br />     * 设置application中属性为attribute的对象<br />     * @param req<br />     * @param attribute 设置属性<br />     * @param o 设置对象<br />     * 2006-5-16 18:17:50<br />     */<br />    public void setAppObject( String attribute, Object o )<br />    {<br />        servlet.getServletContext().setAttribute( attribute, o );<br />    }</font>
		</p>
		<p>
				<font color="#ff0000">    public Object getSessionObject( HttpServletRequest req, String attribute )<br />    {<br />        Object obj = null;<br />        HttpSession session = req.getSession( false );<br />        if ( session != null ) obj = session.getAttribute( attribute );<br />        return obj;<br />    }</font>
		</p>
		<p>
				<font color="#ff0000">    public Object getAppObject( String attribute )<br />    {<br />        return servlet.getServletContext().getAttribute( attribute );<br />    }</font>
		</p>
		<p>
				<font color="#ff0000">    public void callParentGo( HttpServletResponse res, String msg, String url )<br />            throws IOException<br />    {<br />        HtmlUtil.callParentGo( res.getWriter(), msg, url );<br />    }</font>
		</p>
		<p>
				<font color="#ff0000">    public void callMeGo( HttpServletResponse res, String msg, String url )<br />            throws IOException<br />    {<br />        HtmlUtil.callMeGo( res.getWriter(), msg, url );<br />    }</font>
		</p>
		<p>
				<font color="#ff0000">    public void callBack( HttpServletResponse res, String msg )<br />            throws IOException<br />    {<br />        HtmlUtil.callBack( res.getWriter(), msg );<br />    }</font>
		</p>
		<p>
				<font color="#ff0000">
						<font color="#000000">
								<font color="#ff0000">    public void callMeConfirm( HttpServletResponse res, String msg, String ok,<br />            String no ) throws IOException<br />    {<br />        HtmlUtil.callMeConfirm( res.getWriter(), msg, ok, no );<br />    }<br />}<br /></font>再是DispatchAction的<br /></font>
				</font>
				<font color="#ff0000">package com.boya.subject.controller;</font>
		</p>
		<p>
				<font color="#ff0000">import java.io.IOException;<br />import javax.servlet.http.HttpServletRequest;<br />import javax.servlet.http.HttpServletResponse;<br />import javax.servlet.http.HttpSession;<br />import org.apache.struts.action.ActionForm;<br />import org.apache.struts.action.ActionForward;<br />import org.apache.struts.action.ActionMapping;<br />import org.apache.struts.actions.DispatchAction;<br />import com.boya.subject.frame.ID;<br />import com.boya.subject.frame.ServiceFactory;<br />import com.boya.subject.model.Person;<br />import com.boya.subject.service.Service;<br />import com.boya.subject.util.HtmlUtil;</font>
		</p>
		<p>
				<font color="#ff0000">public abstract class BaseDispatchAction extends DispatchAction<br />{<br />    /**<br />     * 由服务工厂方法创建服务<br />     * @return 数据库操作的服务<br />     * 2006-5-16 18:10:04<br />     */<br />    public Service getService()<br />    {<br />        ServiceFactory factory = (ServiceFactory) getAppObject( ID.SF );<br />        Service service = null;<br />        try<br />        {<br />            service = factory.createService();<br />        }<br />        catch ( Exception e )<br />        {<br />        }<br />        return service;<br />    }</font>
		</p>
		<p>
				<font color="#ff0000">    /**<br />     * 判断用户是否合法登陆<br />     * @param req <br />     * @return 用户是否登陆<br />     * 2006-5-16 18:11:26<br />     */<br />    public boolean isLogin( HttpServletRequest req )<br />    {<br />        if ( getPerson( req ) != null ) return true;<br />        else<br />            return false;<br />    }</font>
		</p>
		<p>
				<font color="#ff0000">    /**<br />     * 获取session范围的用户<br />     * @param req<br />     * @return 当前用户<br />     * 2006-5-16 18:13:35<br />     */<br />    public abstract Person getPerson( HttpServletRequest req );</font>
		</p>
		<p>
				<font color="#ff0000">    /**<br />     * 父类的执行DispatchAction<br />     * @see org.apache.struts.action.Action#execute(org.apache.struts.action.ActionMapping, org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)<br />     */<br />    public ActionForward execute( ActionMapping mapping, ActionForm form,<br />            HttpServletRequest req, HttpServletResponse res ) throws Exception<br />    {<br />        try<br />        {<br />            if ( !isLogin( req ) )<br />            {<br />                callParentGo( res, ID.M_UNLOGIN, ID.P_INDEX );<br />                return null;<br />            }<br />            return super.execute( mapping, form, req, res );<br />        }<br />        catch ( NoSuchMethodException e )<br />        {<br />            callBack( res, ID.M_NOMETHOD );<br />            return null;<br />        }<br />    }</font>
		</p>
		<p>
				<font color="#ff0000">    /**<br />     * 删除session中属性为attribute的对象<br />     * @param req<br />     * @param attribute 对象属性<br />     * 2006-5-16 18:16:59<br />     */<br />    public void removeSessionObject( HttpServletRequest req, String attribute )<br />    {<br />        HttpSession session = req.getSession();<br />        session.removeAttribute( attribute );<br />    }</font>
		</p>
		<p>
				<font color="#ff0000">    /**<br />     * 设置session中属性为attribute的对象<br />     * @param req<br />     * @param attribute 设置属性<br />     * @param o 设置对象<br />     * 2006-5-16 18:17:50<br />     */<br />    public void setSessionObject( HttpServletRequest req, String attribute,<br />            Object o )<br />    {<br />        req.getSession().setAttribute( attribute, o );<br />    }</font>
		</p>
		<p>
				<font color="#ff0000">    /**<br />     * 设置application中属性为attribute的对象<br />     * @param req<br />     * @param attribute 设置属性<br />     * @param o 设置对象<br />     * 2006-5-16 18:17:50<br />     */<br />    public void setAppObject( String attribute, Object o )<br />    {<br />        servlet.getServletContext().setAttribute( attribute, o );<br />    }</font>
		</p>
		<p>
				<font color="#ff0000">    public Object getSessionObject( HttpServletRequest req, String attribute )<br />    {<br />        Object obj = null;<br />        HttpSession session = req.getSession( false );<br />        if ( session != null ) obj = session.getAttribute( attribute );<br />        return obj;<br />    }</font>
		</p>
		<p>
				<font color="#ff0000">    public Object getAppObject( String attribute )<br />    {<br />        return servlet.getServletContext().getAttribute( attribute );<br />    }</font>
		</p>
		<p>
				<font color="#ff0000">    public void callParentGo( HttpServletResponse res, String msg, String url )<br />            throws IOException<br />    {<br />        HtmlUtil.callParentGo( res.getWriter(), msg, url );<br />    }</font>
		</p>
		<p>
				<font color="#ff0000">    public void callMeGo( HttpServletResponse res, String msg, String url )<br />            throws IOException<br />    {<br />        HtmlUtil.callMeGo( res.getWriter(), msg, url );<br />    }</font>
		</p>
		<p>
				<font color="#ff0000">    public void callBack( HttpServletResponse res, String msg )<br />            throws IOException<br />    {<br />        HtmlUtil.callBack( res.getWriter(), msg );<br />    }</font>
		</p>
		<p>
				<font color="#ff0000">
						<font color="#000000">
								<font color="#ff0000">    public void callMeConfirm( HttpServletResponse res, String msg, String ok,<br />            String no ) throws IOException<br />    {<br />        HtmlUtil.callMeConfirm( res.getWriter(), msg, ok, no );<br />    }<br />}</font>
								<br />对于程序中的一些提示信息，我比较喜欢用JS来写，所以我把这些都放到了一个类中<br /></font>
				</font>
				<font color="#ff0000">import java.io.IOException;<br />import java.io.Writer;</font>
		</p>
		<p>
				<font color="#ff0000">public class HtmlUtil<br />{<br />    public static void callParentGo( Writer out, String msg, String url )<br />            throws IOException<br />    {<br />        out.write( "&lt;script language=\"javascript\"&gt;" );<br />        out.write( "alert(\"" + msg + "\");" );<br />        out.write( "parent.location.href=\"" + url + "\";" );<br />        out.write( "&lt;/script&gt;" );<br />    }</font>
		</p>
		<p>
				<font color="#ff0000">    public static void callMeGo( Writer out, String msg, String url )<br />            throws IOException<br />    {<br />        out.write( "&lt;script language=\"javascript\"&gt;" );<br />        out.write( "alert(\"" + msg + "\");" );<br />        out.write( "location.href=\"" + url + "\";" );<br />        out.write( "&lt;/script&gt;" );<br />    }</font>
		</p>
		<p>
				<font color="#ff0000">    public static void callMeConfirm( Writer out, String msg ,String ok, String no )<br />            throws IOException<br />    {<br />        out.write( "&lt;script language=\"javascript\"&gt;" );<br />        out.write( "if(window.confirm(\"" + msg + "\")){" );<br />        out.write( "location.href=\"" + ok + "\"}else{" );<br />        out.write( "location.href=\"" + no + "\"}" );<br />        out.write( "&lt;/script&gt;" );<br />    }</font>
		</p>
		<p>
				<font color="#ff0000">
						<font color="#000000">
								<font color="#ff0000">    public static void callBack( Writer out, String msg ) throws IOException<br />    {<br />        out.write( "&lt;script language=\"javascript\"&gt;" );<br />        out.write( "alert(\"" + msg + "\");" );<br />        out.write( "parent.history.back();" );<br />        out.write( "&lt;/script&gt;" );<br />    }<br />}</font>
								<br />
						</font>
				</font>
		</p>
<img src ="http://www.blogjava.net/junky/aggbug/48180.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junky/" target="_blank">junky</a> 2006-05-25 20:27 <a href="http://www.blogjava.net/junky/archive/2006/05/25/48180.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>体验Struts(3)---加上点ajax </title><link>http://www.blogjava.net/junky/archive/2006/05/25/48181.html</link><dc:creator>junky</dc:creator><author>junky</author><pubDate>Thu, 25 May 2006 12:27:00 GMT</pubDate><guid>http://www.blogjava.net/junky/archive/2006/05/25/48181.html</guid><wfw:comment>http://www.blogjava.net/junky/comments/48181.html</wfw:comment><comments>http://www.blogjava.net/junky/archive/2006/05/25/48181.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junky/comments/commentRss/48181.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junky/services/trackbacks/48181.html</trackback:ping><description><![CDATA[你问我什么叫ajax，我也不太了解，我了解的是那支培养了无数荷兰足球精华的Ajax，谁知道怎么有人用几个单词的头字母也能凑出这个单词来，不过感觉用它来做东西，应该会挺有意思的<br />比如当用户在注册的时候，用户点一个按纽不用刷新界面就可以获得一句提示，是有这人还是没有这人啊？这次我尝试了用ajax技术来做一个三级关键的下拉列表，而这是我要讲的关键。<br />其实现在一般的ajax都是向Servlet发出请求，之后服务器响应，再偷摸的把结果传给它，之后显示出来，而换到Struts，有人会发甍，也一样，Action是Servlet，DispatchAction也是，只要把代码往这里写，让它往.do那里请求就行了。<br />在接下来我就向大家介绍我是怎样实现上述功能的<br />因为大学里面的结构是这里的<br />学院-专业-班级-学生<br />在学生注册的时候他是依赖于上述对象的，所以用户注册就需要一个三级的下拉选择<br />而ajax就能象变魔术一样，从服务器那里偷摸弄来您需要的列表<br />下面我先给大家展示一下第一个功能是怎么实现的吧？<br />当用户在注册的时候，点一个按纽，之后会弹出一个alert来告诉你这个用户是否有人用了，下面就让我们来看看这个功能是怎么实现的吧？<br /><br />&lt;html:button styleClass="cancel" property="submit" value="验证用户是否存在" onclick="teacherCheck()"/&gt;<br />这里定义了按纽，用来测试老师是否已经存在了<br />大体的ajax的JS代码都上面这四部分，<br />先是创建XMLHttpRequest，<br /><font color="#ff0000">var xmlHttp;<br />function createXMLHttpRequest()<br />{<br /> if (window.XMLHttpRequest) <br /> { <br />  xmlHttp = new XMLHttpRequest(); <br /> }<br /> else if (window.ActiveXObject) <br /> {<br />  xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); <br />    } <br />}<br /><font color="#000000">之后是客户响应部分的代码</font><br />function teacherCheck() <br />{<br /> var f = document.TeacherRegisterForm <font color="#000000">从表单里读字段<br /></font> var user = f.user.value<br /> if(user=="") <br /> {<br />　　 window.alert("用户名不能为空！")<br />  f.user.focus()<br />　　 return false<br />   }<br /> else <br /> {<br />  createXMLHttpRequest()        <font color="#000000">这里都是精华了<br /></font>  var url = "ajax.do?method=checkUserIsExist&amp;user="+user   <font color="#000000">定义响应地址<br /></font>  xmlHttp.open("GET",url, true)   <font color="#000000"> 发出响应<br /></font>  xmlHttp.onreadystatechange = checkUser  <font color="#000000">把从服务器得到的响应再传给另个函数<br /></font>  xmlHttp.send(null)<br />   }<br />}<br /><br />function checkUser()<br />{<br /> if (xmlHttp.readyState == 4) <br /> {<br />  if (xmlHttp.status == 200) <br />  {<br />   alert(xmlHttp.responseText)        <font color="#000000">这里是对响应结果的操作，在这里我们是滩出对话框，并把服务器发来的信息显示出来<br /></font>  }<br /> }<br />}<br /></font><br />我把所有乱七八糟的操作都放到了一个DispatchAction里，所以它也不例外的在这个DA中了<br /><font color="#ff0000">public ActionForward checkUserIsExist( ActionMapping mapping,<br />            ActionForm form, HttpServletRequest req, HttpServletResponse res )<br />            throws Exception<br />    {<br />        Service service = getService();<br />        res.getWriter().write(service</font><font color="#ff0000">.checkUserIsExistForAjax( req.getParameter( "user" ) ) );<br />        return null;<br />    }<br /></font><font color="#000000">它仅仅是把业务逻辑部分的结果发送回去，而真正的判断是在业务逻辑那里实现的，<br /><font color="#ff0000">public String checkUserIsExistForAjax( String user )<font color="#000000">把结果弄成String的形式传回去<br /></font>    {<br />        Connection connection = null;<br />        PreparedStatement pstmt1 = null;<br />        ResultSet rs = null;<br />        try<br />        {<br />            connection = getConnection();<br />            pstmt1 = connection<br />                    .prepareStatement( "select * from user where user=?" );<br />            pstmt1.setString( 1, user );<br />            rs = pstmt1.executeQuery();<br />            rs.last();<br />            if ( rs.getRow() &gt; 0 )<br />            {<br />                return ID.M_EXIST; <font color="#000000">用户存在</font><br />            }<br />        }<br />        catch ( Exception e )<br />        {<br />            e.printStackTrace();<br />        }<br />        finally<br />        {<br />            close( rs );<br />            close( pstmt1 );<br />            close( connection );<br />        }<br />        return ID.M_NOEXIST;<font color="#000000">用户不存在</font><br />    }</font><br /></font><img src ="http://www.blogjava.net/junky/aggbug/48181.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junky/" target="_blank">junky</a> 2006-05-25 20:27 <a href="http://www.blogjava.net/junky/archive/2006/05/25/48181.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>