??xml version="1.0" encoding="utf-8" standalone="yes"?>va天堂va亚洲va影视中文字幕 ,国产成人亚洲精品狼色在线,亚洲人成综合在线播放http://www.tkk7.com/junky/category/11524.htmlzh-cnFri, 29 Jun 2007 20:58:12 GMTFri, 29 Jun 2007 20:58:12 GMT60WebWork教程- Interceptor(拦截?http://www.tkk7.com/junky/archive/2007/06/28/126717.htmljunkyjunkyThu, 28 Jun 2007 01:37:00 GMThttp://www.tkk7.com/junky/archive/2007/06/28/126717.htmlhttp://www.tkk7.com/junky/comments/126717.htmlhttp://www.tkk7.com/junky/archive/2007/06/28/126717.html#Feedback0http://www.tkk7.com/junky/comments/commentRss/126717.htmlhttp://www.tkk7.com/junky/services/trackbacks/126717.html阅读全文

junky 2007-06-28 09:37 发表评论
]]>
Strust拦截?/title><link>http://www.tkk7.com/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.tkk7.com/junky/archive/2007/06/28/126715.html</guid><wfw:comment>http://www.tkk7.com/junky/comments/126715.html</wfw:comment><comments>http://www.tkk7.com/junky/archive/2007/06/28/126715.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/junky/comments/commentRss/126715.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/junky/services/trackbacks/126715.html</trackback:ping><description><![CDATA[1.概述 <br><br>Strust拦截器改q了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插g,可以在需要的M地方调用. <br><br><br>4.配置struts插g: <br><br>把Strust拦截器配|ؓ一个struts插g,只需要修?Struts 配置文g可以了,修改后的配置文g.一般看h像这U样? <br><br><plug-in className="net.sf.struts.saif.SAIFPlugin"> <br><set-property property="interceptor-config" value="/WEB-INF/interceptor-config.xml" /> <br></plug-in> <br><br><br>5.拦截器的配置 <br><br>在interceptor-config.xml文g中定义了所有拦?当然可以是另外的M文g?. q个文g包含拦截定义和它们应该如何被使用. <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><interceptor-config> <br><interceptor name="componentInterceptor" type="net.sf.struts.saif.ComponentInterceptor"/> <br><interceptor name="testInterceptor" type="net.sf.struts.saif.TestInterceptor"/> <br><br><default-interceptors> <br><interceptor name="componentInterceptor"/> <br></default-interceptors> <br><br><action type="org.apache.struts.webapp.example.EditRegistrationAction"> <br><interceptor name="testInterceptor"/> <br></action> <br></interceptor-config> <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.tkk7.com/junky/aggbug/126715.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/junky/" target="_blank">junky</a> 2007-06-28 09:35 <a href="http://www.tkk7.com/junky/archive/2007/06/28/126715.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>深入剖析JSP和Servlet对中文的处理(?http://www.tkk7.com/junky/archive/2007/04/16/111006.htmljunkyjunkyMon, 16 Apr 2007 08:28:00 GMThttp://www.tkk7.com/junky/archive/2007/04/16/111006.htmlhttp://www.tkk7.com/junky/comments/111006.htmlhttp://www.tkk7.com/junky/archive/2007/04/16/111006.html#Feedback0http://www.tkk7.com/junky/comments/commentRss/111006.htmlhttp://www.tkk7.com/junky/services/trackbacks/111006.html世界上的各地区都有本地的语言。地区差异直接导致了语言环境的差异。在开发一个国际化E序的过E中Q处理语a问题显得很重要了?/p>

q是一个世界范围内都存在的问题Q所以,Java提供了世界性的解决Ҏ。本文描q的Ҏ是用于处理中文的Q但是,推而广之,对于处理世界上其它国家和地区的语a同样适用?/p>

汉字是双字节的。所谓双字节是指一个双字要占用两个BYTE的位|(?6位)Q分别称为高位和低位。中国规定的汉字~码为GB2312Q这是强制性的Q目前几乎所有的能处理中文的应用E序都支持GB2312。GB2312包括了一二汉字?区符P高位?xa1?xfeQ低位也是从0xa1?xfeQ其中,汉字的编码范围ؓ0xb0a1?xf7fe?/p>

另外有一U编码,叫做GBKQ但q是一份规范,不是强制的。GBK提供?0902个汉字,它兼容GB2312Q编码范围ؓ0x8140?xfefe。GBK中的所有字W都可以一一映射到Unicode 2.0?/p>

在不久的来Q中国会颁布另一U标准:GB18030-2000QGBK2KQ。它收录了藏、蒙{少数民族的字型Q从Ҏ上解决了字位不的问题。注意:它不再是定长的。其二字节部份与GBK兼容Q四字节部分是扩充的字符、字形。它的首字节和第三字节从0x81?xfeQ二字节和第四字节从0x30?x39?/p>

本文不打介lUnicodeQ有兴趣的可以浏?#8220;http://www.unicode.org/”查看更多的信息。Unicode有一个特性:它包括了世界上所有的字符字Ş。所以,各个地区的语a都可以徏立与Unicode的映关p,而Java正是利用了这一点以辑ֈ异种语言之间的{换?/p>

在JDK中,与中文相关的~码有:

? JDK中与中文相关的编码列?/font>

~码名称 说明
ASCII 7位,与ascii7相同
ISO8859-1 8-位,?8859_1,ISO-8859-1,ISO_8859-1,latin1...{相?/td>
GB2312-80 16位,与gb2312,gb2312-1980,EUC_CN,euccn,1381,Cp1381, 1383, Cp1383, ISO2022CN,ISO2022CN_GB...{相?/td>
GBK 与MS936相同Q注意:区分大小?/td>
UTF8 与UTF-8相同
GB18030 与cp1392?392相同Q目前支持的JDK很少

在实际编E时Q接触得比较多的是GB2312QGBKQ和ISO8859-1?/p>

Z么会?#8220;?”?/strong>

上文说过Q异U语a之间的{换是通过Unicode来完成的。假设有两种不同的语aA和BQ{换的步骤为:先把A转化为UnicodeQ再把Unicode转化为B?/p>

举例说明。有GB2312中有一个汉?#8220;?#8221;Q其~码?#8220;C0EE”Q欲转化为ISO8859-1~码。步骤ؓQ先?#8220;?#8221;字{化ؓUnicodeQ得?#8220;674E”Q再?#8220;674E”转化为ISO8859-1字符。当Ӟq个映射不会成功Q因为ISO8859-1中根本就没有?#8220;674E”对应的字W?/p>

当映不成功Ӟ问题发生了Q当从某语言向Unicode转化Ӟ如果在某语言中没有该字符Q得到的是Unicode的代?#8220;\uffffd”Q?#8220;\u”表示是Unicode~码Q)。而从Unicode向某语言转化Ӟ如果某语a没有对应的字W,则得到的?#8220;0x3f”Q?#8220;?”Q。这是“?”的由来?/p>

例如Q把字符buf =“0x80 0x40 0xb0 0xa1”q行new String(buf, "gb2312")操作Q得到的l果?#8220;\ufffd\u554a”Q再println出来Q得到的l果是“??#8221;Q因?#8220;0x80 0x40”是GBK中的字符Q在GB2312中没有?/p>

再如Q把字符串String="\u00d6\u00ec\u00e9\u0046\u00bb\u00f9"q行new String (buf.getBytes("GBK"))操作Q得到的l果?#8220;3fa8aca8a6463fa8b4”Q其中,“\u00d6”?#8220;GBK”中没有对应的字符Q得?#8220;3f”Q?#8220;\u00ec”对应着“a8ac”Q?#8220;\u00e9”对应着“a8a6”Q?#8220;0046”对应着“46”Q因是ASCII字符Q,“\u00bb”没找刎ͼ得到“3f”Q最后,“\u00f9”对应着“a8b4”。把q个字符串println一下,得到的结果是“?ìéF?ù”。看到没Q这里ƈ不全是问P因ؓGBK与Unicode映射的内容中除了汉字外还有字W,本例是最好的明证?/p>

所以,在汉字{码时Q如果发生错乱,得到的不一定都是问号噢Q不q,错了l究是错了,50步和100步ƈ没有质的差别?/p>

或者会问:如果源字W集中有Q而Unicode中没有,l果会如何?回答是不知道。因为我手头没有能做q个试的源字符集。但有一Ҏ肯定的,那就是源字符集不够规范。在Java中,如果发生q种情况Q是会抛出异常的?/p>

什么是UTF

UTFQ是Unicode Text Format的羃写,意ؓUnicode文本格式。对于UTFQ是q样定义的:

Q?Q如果Unicode?6位字W的?位是0Q则用一个字节表C,q个字节的首位是“0”Q剩下的7位与原字W中的后7位相同,?#8220;\u0034”Q?000 0000 0011 0100Q,?#8220;34” (0011 0100)表示Q(与源Unicode字符是相同的Q;

Q?Q如果Unicode?6位字W的?位是0Q则?个字节表C,首字节是“110”开_后面?位与源字W中除去?个零后的最?位相同;W二个字节以“10”开_后面?位与源字W中的低6位相同。如“\u025d”Q?000 0010 0101 1101Q,转化后ؓ“c99d”Q?100 1001 1001 1101Q;

Q?Q如果不W合上述两个规则Q则用三个字节表C。第一个字节以“1110”开_后四位ؓ源字W的高四位;W二个字节以“10”开_后六位ؓ源字W中间的六位Q第三个字节?#8220;10”开_后六位ؓ源字W的低六位;?#8220;\u9da7”Q?001 1101 1010 0111Q,转化?#8220;e9b6a7”Q?110 1001 1011 0110 1010 0111Q;

可以q么描述JAVAE序中Unicode与UTF的关p,虽然不绝对:字符串在内存中运行时Q表CؓUnicode代码Q而当要保存到文g或其它介质中LQ用的是UTF。这个{化过E是由writeUTF和readUTF来完成的?/p>

好了Q基性的差不多了Q下面进入正题?/p>

先把q个问题x是一个黑匣子。先看黑匣子的一U表C:

input(charsetA)-Qprocess(Unicode)-Qoutput(charsetB)

单,q就是一个IPO模型Q即输入、处理和输出。同L内容要经q?#8220;从charsetA到unicode再到charsetB”的{化?/p>

再看二表示Q?/p>

SourceFile(jsp,java)-Qclass-Qoutput

在这个图中,可以看出Q输入的是jsp和java源文Ӟ在处理过E中Q以Class文g体,然后输出。再l化CU表C:

jsp-Qtemp file-Qclass-Qbrowser,os console,db

app,servlet-Qclass-Qbrowser,os console,db

q个囑ְ更明白了。Jsp文g先生成中间的Java文gQ再生成Class。而Servlet和普通App则直接编译生成Class。然后,从Class再输出到览器、控制台或数据库{?/p>

JSPQ从源文件到Class的过E?/strong>

Jsp的源文g是以“.jsp”l尾的文本文件。在本节中,阐qJSP文g的解释和~译q程Qƈ跟踪其中的中文变化?/p>

1、JSP/Servlet引擎提供的JSP转换工具QjspcQ搜索JSP文g中用Q?@ page contentType ="text/html; charset=QJsp-charsetQ?%Q中指定的charset。如果在JSP文g中未指定QJsp-charsetQ,则取JVM中的默认讄file.encodingQ一般情况下Q这个值是ISO8859-1Q?/p>

2、jspc用相当于“javac –encoding QJsp-charsetQ?#8221;的命令解释JSP文g中出现的所有字W,包括中文字符和ASCII字符Q然后把q些字符转换成Unicode字符Q再转化成UTF格式Q存为JAVA文g。ASCII码字W{化ؓUnicode字符时只是简单地在前面加“00”Q如“A”Q{化ؓ“\u0041”Q不需要理由,Unicode的码表就是这么编的)。然后,l过到UTF的{换,又变?#8220;41”了!q也是可以使用普通文本编辑器查看由JSP生成的JAVA文g的原因;

3、引擎用相当?#8220;javac –encoding UNICODE”的命令,把JAVA文g~译成CLASS文gQ?/p>

先看一下这些过E中中文字符的{换情c有如下源代码:

Q?@ page contentType="text/html; charset=gb2312"%Q<htmlQ<bodyQ<% String a="中文"; out.println(a);%Q</bodyQ</htmlQ?/td>

q段代码是在UltraEdit for Windows上编写的。保存后Q?#8220;中文”两个字的16q制~码?#8220;D6 D0 CE C4”QGB2312~码Q。经查表Q?#8220;中文”两字的Unicode~码?#8220;\u4E2D\u6587”Q用 UTF表示是“E4 B8 AD E6 96 87”。打开引擎生成的由JSP文g转变而成的JAVA文gQ发现其中的“中文”两个字确实被“E4 B8 AD E6 96 87”替代了,再查看由JAVA文g~译生成的CLASS文gQ发现结果与JAVA文g中的完全一栗?/p>

再看JSP中指定的CharSet为ISO-8859-1的情c?/p>

Q?@ page contentType="text/html; charset=ISO-8859-1"%Q?br>QhtmlQ?br>QbodyQ?br>Q? String a="中文"; out.println(a);%Q?br>Q?bodyQ?br>Q?htmlQ?/td>

同样Q该文g是用UltraEdit~写的,“中文”q两个字也是存ؓGB2312~码“D6 D0 CE C4”。先模拟一下生成的JAVA文g和CLASS文g的过E:jspc用ISO-8859-1来解?#8220;中文”Qƈ把它映射到Unicode。由于ISO-8859-1?位的Q且是拉丁语p,其映规则就是在每个字节前加“00”Q所以,映射后的Unicode~码应ؓ“\u00D6\u00D0\u00CE\u00C4”Q{化成UTF后应该是“C3 96 C3 90 C3 8E C3 84”。好Q打开文g看一下,JAVA文g和CLASS文g中,“中文”果然都表CZؓ“C3 96 C3 90 C3 8E C3 84”?/p>

如果上述代码中不指定QJsp-charsetQ,xW一行写?#8220;Q?@ page contentType="text/html" %Q?#8221;QJSPC会用file.encoding的设|来解释JSP文g。在RedHat 6.2上,其处理结果与指定为ISO-8859-1是完全相同的?/p>

到现在ؓ止,已经解释了从JSP文g到CLASS文g的{变过E中中文字符的映过E。一句话Q从“JspCharSet到Unicode再到UTF”。下表ȝ了这个过E:

? “中文”从JSP到CLASS的{化过E?/font>

Jsp-CharSet JSP文g?/td> JAVA文g?/td> CLASS文g?/td>
GB2312 D6 D0 CE C4(GB2312) 从\u4E2D\u6587(Unicode)到E4 B8 AD E6 96 87 (UTF) E4 B8 AD E6 96 87 (UTF)
ISO-8859-1 D6 D0 CE C4(GB2312) 从\u00D6\u00D0\u00CE\u00C4 (Unicode)到C3 96 C3 90 C3 8E C3 84 (UTF) C3 96 C3 90 C3 8E C3 84 (UTF)
无(默认Qfile.encodingQ?/td> 同ISO-8859-1 同ISO-8859-1 同ISO-8859-1

下节先讨论Servlet从JAVA文g到CLASS文g的{化过E,然后再解释从CLASS文g如何输出到客L。之所以这样安排,是因为JSP和Servlet在输出时处理Ҏ是一L?/p>

ServletQ从源文件到Class的过E?/strong>

Servlet源文件是?#8220;.java”l尾的文本文件。本节将讨论Servlet的编译过Eƈ跟踪其中的中文变化?/p>

?#8220;javac”~译Servlet源文件。javac可以?#8220;-encoding QCompile-charsetQ?#8221;参数Q意思是“用< Compile-charset Q中指定的编码来解释Serlvet源文?#8221;?/p>

源文件在~译Ӟ用<Compile-charsetQ来解释所有字W,包括中文字符和ASCII字符。然后把字符帔R转变成Unicode字符Q最后,把Unicode转变成UTF?/p>

在Servlet中,q有一个地方设|输出流的CharSet。通常在输出结果前Q调用HttpServletResponse的setContentTypeҎ来达C在JSP中设|<Jsp-charsetQ一L效果Q称之ؓQServlet-charsetQ?/p>

注意Q文中一共提C三个变量Q<Jsp-charsetQ、<Compile-charsetQ和QServlet-charsetQ。其中,JSP文g只与QJsp-charsetQ有养I而<Compile-charsetQ和QServlet-charsetQ只与Servlet有关?/p>

看下例:

import javax.servlet.*;

import javax.servlet.http.*;

class testServlet extends HttpServlet

 public void doGet(HttpServletRequest req,HttpServletResponse resp)
 throws ServletException,java.io.IOException
 { 
  resp.setContentType("text/html; charset=GB2312");
  java.io.PrintWriter out=resp.getWriter();
  out.println("QhtmlQ?);
  out.println("#中文#");
  out.println("Q?htmlQ?);
 }
}

该文件也是用UltraEdit for Windows~写的,其中?#8220;中文”两个字保存ؓ“D6 D0 CE C4”QGB2312~码Q?/p>

开始编译。下表是QCompile-charsetQ不同时QCLASS文g?#8220;中文”两字的十六进制码。在~译q程中,QServlet-charsetQ不起Q何作用。<Servlet-charsetQ只对CLASS文g的输Z生媄响,实际上是QServlet-charsetQ和QCompile-charsetQ一P辑ֈ与JSP文g中的QJsp-charsetQ相同的效果Q因为<Jsp-charsetQ对~译和CLASS文g的输出都会生媄响?/p>

? “中文”从Servlet源文件到Class的{变过E?/font>

Compile-charset Servlet源文件中 Class文g?/td> {效的Unicode?/td>
GB2312 D6 D0 CE C4 (GB2312) E4 B8 AD E6 96 87 (UTF) \u4E2D\u6587 (在Unicode中=“中文”)
ISO-8859-1 D6 D0 CE C4 (GB2312) C3 96 C3 90 C3 8E C3 84 (UTF) \u00D6 \u00D0 \u00CE \u00C4 (在D6 D0 CE C4前面各加了一?0)
无(默认Q?/td> D6 D0 CE C4 (GB2312) 同ISO-8859-1 同ISO-8859-1

普通JavaE序的编译过E与Servlet完全一栗?/p>

CLASS文g中的中文表示法是不是昭然若揭了?OKQ接下来看看CLASS又是怎样输出中文的呢Q?/p>

ClassQ输出字W串

上文说过Q字W串在内存中表现为Unicode~码。至于这UUnicode~码表示了什么,那要看它是从哪种字符集映过来的Q也是说要看它的祖先。这好比在托q行李时Q外观都是纸子Q里面装了什么就要看寄邮件的人实际邮了什么东ѝ?/p>

看看上面的例子,如果l一串Unicode~码“00D6 00D0 00CE 00C4”Q如果不作{换,直接用Unicode码表来对照它Ӟ是四个字W(而且是特D字W)Q假如把它与“ISO8859-1”q行映射Q则直接L前面?#8220;00”卛_得到“D6 D0 CE C4”Q这是ASCII码表中的四个字符Q而假如把它当作GB2312来进行映,得到的结果很可能是一大堆qQ因为在GB2312中有可能没有Q也有可能有Q字W与00D6{字W对应(如果对应不上Q将得到0x3fQ也是问号Q如果对应上了,׃00D6{字W太靠前Q估计也是一些特D符P真正的汉字在Unicode中的~码?E00开始)?/p>

各位看到了,同样的Unicode字符Q可以解释成不同的样子。当Ӟq其中有一U是我们期望的结果。以上例而论Q?#8220;D6 D0 CE C4”应该是我们所惌的,当把“D6 D0 CE C4”输出到IE中时Q用“体中?#8221;方式查看Q就能看到清楚的“中文”两个字了。(当然了,如果你一定要?#8220;西欧字符”来看Q那也没办法Q你得不到M有何时何地的东西Qؓ什么呢Q因?#8220;00D6 00D0 00CE 00C4”本来是由ISO8859-1转化q去的?/p>

l出如下l论Q?/p>

在Class输出字符串前Q会Unicode的字W串按照某一U内码重新生成字节流Q然后把字节输入,相当于进行了一?#8220;String.getBytes(???)”操作???代表某一U字W集?/p>

如果是ServletQ那么,q种内码是在HttpServletResponse.setContentType()Ҏ中指定的内码Q也是上文定义的<Servlet-charsetQ?/p>

如果是JSPQ那么,q种内码是在<%@ page contentType=""%Q中指定的内码,也就是上文定义的QJsp-charsetQ?/p>

如果是JavaE序Q那么,q种内码是file.encoding中指定的内码Q默认ؓISO8859-1?/p>

当输出对象是览器时

以流行的览器IEZ。IE支持多种内码。假如IE接收C一个字节流“D6 D0 CE C4”Q你可以试用各U内码去查看。你会发现用“体中?#8221;时能得到正确的结果。因?#8220;D6 D0 CE C4”本来是体中文中“中文”两个字的~码?/p>

OKQ完整地看一遍?/p>

JSPQ源文g为GB2312格式的文本文Ӟ且JSP源文件中?#8220;中文”q两个汉?/p>

如果指定了<Jsp-charsetQؓGB2312Q{化过E如下表?/p>

? Jsp-charset = GB2312时的变化q程

序号 步骤说明 l果
1 ~写JSP源文Ӟ且存为GB2312格式 D6 D0 CE C4QD6D0=?CEC4=文)
2 jspc把JSP源文件{化ؓ临时JAVA文gQƈ把字W串按照GB2312映射到UnicodeQƈ用UTF格式写入JAVA文g?/td> E4 B8 AD E6 96 87
3 把时JAVA文g~译成CLASS文g E4 B8 AD E6 96 87
4 q行Ӟ先从CLASS文g中用readUTFd字符Ԍ在内存中的是Unicode~码 4E 2D 65 87Q在Unicode?E2D=?6587=文)
5 ҎJsp-charset=GB2312把Unicode转化为字节流 D6 D0 CE C4
6 把字节流输出到IE中,q设|IE的编码ؓGB2312Q作者按Q这个信息隐藏在HTTP头中Q?/td> D6 D0 CE C4
7 IE?#8220;体中?#8221;查看l果 “中文”Q正显C)

如果指定了<Jsp-charsetQؓISO8859-1Q{化过E如下表?/p>

? Jsp-charset = ISO8859-1时的变化q程

序号 步骤说明 l果
1 ~写JSP源文Ӟ且存为GB2312格式 D6 D0 CE C4QD6D0=?CEC4=文)
2 jspc把JSP源文件{化ؓ临时JAVA文gQƈ把字W串按照ISO8859-1映射到UnicodeQƈ用UTF格式写入JAVA文g?/td> C3 96 C3 90 C3 8E C3 84
3 把时JAVA文g~译成CLASS文g C3 96 C3 90 C3 8E C3 84
4 q行Ӟ先从CLASS文g中用readUTFd字符Ԍ在内存中的是Unicode~码 00 D6 00 D0 00 CE 00 C4Q啥都不是!Q!Q?/td>
5 ҎJsp-charset=ISO8859-1把Unicode转化为字节流 D6 D0 CE C4
6 把字节流输出到IE中,q设|IE的编码ؓISO8859-1Q作者按Q这个信息隐藏在HTTP头中Q?/td> D6 D0 CE C4
7 IE?#8220;西欧字符”查看l果 qQ其实是四个ASCII字符Q但׃大于128Q所以显C出来的怪模怪样
8 改变IE的页面编码ؓ“体中?#8221; “中文”Q正显C)

奇怪了Qؓ什么把QJsp-charsetQ设成GB2312和ISO8859-1是一个样的,都能正确昄Q因4?中的W?步和W?步互逆,是相?#8220;抉|”的。只不过当指定ؓISO8859-1Ӟ要增加第8步操作,Dؓ不便?/p>

再看看不指定QJsp-charsetQ?时的情况?/p>

? 未指定Jsp-charset 时的变化q程

序号 步骤说明 l果
1 ~写JSP源文Ӟ且存为GB2312格式 D6 D0 CE C4QD6D0=?CEC4=文)
2 jspc把JSP源文件{化ؓ临时JAVA文gQƈ把字W串按照ISO8859-1映射到UnicodeQƈ用UTF格式写入JAVA文g?/td> C3 96 C3 90 C3 8E C3 84
3 把时JAVA文g~译成CLASS文g C3 96 C3 90 C3 8E C3 84
4 q行Ӟ先从CLASS文g中用readUTFd字符Ԍ在内存中的是Unicode~码 00 D6 00 D0 00 CE 00 C4
5 ҎJsp-charset=ISO8859-1把Unicode转化为字节流 D6 D0 CE C4
6 把字节流输出到IE?/td> D6 D0 CE C4
7 IE用发求时的页面的~码查看l果 视情况而定。如果是体中文,则能正确昄Q否则,需执行?中的W??/td>

ServletQ源文g为JAVA文gQ格式是GB2312Q源文g中含?#8220;中文”q两个汉?/p>

如果QCompile-charsetQ=GB2312Q<Servlet-charsetQ?GB2312

? Compile-charset=Servlet-charset=GB2312 时的变化q程

序号 步骤说明 l果
1 ~写Servlet源文Ӟ且存为GB2312格式 D6 D0 CE C4QD6D0=?CEC4=文)
2 用javac –encoding GB2312把JAVA源文件编译成CLASS文g E4 B8 AD E6 96 87 QUTFQ?/td>
3 q行Ӟ先从CLASS文g中用readUTFd字符Ԍ在内存中的是Unicode~码 4E 2D 65 87 (Unicode)
4 ҎServlet-charset=GB2312把Unicode转化为字节流 D6 D0 CE C4 (GB2312)
5 把字节流输出到IE中ƈ讄IE的编码属性ؓServlet-charset=GB2312 D6 D0 CE C4 (GB2312)
6 IE?#8220;体中?#8221;查看l果 “中文”Q正显C)

如果QCompile-charsetQ=ISO8859-1Q<Servlet-charsetQ?ISO8859-1

? Compile-charset=Servlet-charset=ISO8859-1时的变化q程

序号 步骤说明 l果
1 ~写Servlet源文Ӟ且存为GB2312格式 D6 D0 CE C4QD6D0=?CEC4=文)
2 用javac –encoding ISO8859-1把JAVA源文件编译成CLASS文g C3 96 C3 90 C3 8E C3 84 QUTFQ?/td>
3 q行Ӟ先从CLASS文g中用readUTFd字符Ԍ在内存中的是Unicode~码 00 D6 00 D0 00 CE 00 C4
4 ҎServlet-charset=ISO8859-1把Unicode转化为字节流 D6 D0 CE C4
5 把字节流输出到IE中ƈ讄IE的编码属性ؓServlet-charset=ISO8859-1 D6 D0 CE C4 (GB2312)
6 IE?#8220;西欧字符”查看l果 qQ原因同?Q?/td>
7 改变IE的页面编码ؓ“体中?#8221; “中文”Q正显C)

如果不指定Compile-charset或Servlet-charsetQ其默认值均为ISO8859-1?/p>

当Compile-charset=Servlet-charsetӞW?步和W?步能互逆,“抉|”Q显C结果均能正。读者可试着写一下Compile-charsetQ>Servlet-charset时的情况Q肯定是不正的?/p>

当输出对象是数据库时

输出到数据库Ӟ原理与输出到览器也是一L。本节只是ServletZQJSP的情况请读者自行推对{?/p>

假设有一个ServletQ它能接收来自客LQIEQ简体中文)的汉字字W串Q然后把它写入到内码为ISO8859-1的数据库中,然后再从数据库中取出q个字符Ԍ昄到客L?/p>

? 输出对象是数据库时的变化q程Q?Q?/font>

序号 步骤说明 l果 ?/td>
1 在IE中输?#8220;中文” D6 D0 CE C4 IE
2 IE把字W串转变成UTFQƈ送入传输中 E4 B8 AD E6 96 87
3 Servlet接收到输入流Q用readUTFd 4E 2D 65 87(unicode) Servlet
4 ~程者在Servlet中必L字符串根据GB2312q原为字节流 D6 D0 CE C4
5 ~程者根据数据库内码ISO8859-1生成新的字符?/td> 00 D6 00 D0 00 CE 00 C4
6 把新生成的字W串提交lJDBC 00 D6 00 D0 00 CE 00 C4
7 JDBC到数据库内码ؓISO8859-1 00 D6 00 D0 00 CE 00 C4 JDBC
8 JDBC把接收到的字W串按照ISO8859-1生成字节?/td> D6 D0 CE C4
9 JDBC把字节流写入数据库中 D6 D0 CE C4
10 完成数据存储工作 D6 D0 CE C4 数据?/td>
以下是从数据库中取出数的q程
11 JDBC从数据库中取出字节流 D6 D0 CE C4 JDBC
12 JDBC按照数据库的字符集ISO8859-1生成字符Ԍq提交给Servlet 00 D6 00 D0 00 CE 00 C4 (Unicode)  
13 Servlet获得字符?/td> 00 D6 00 D0 00 CE 00 C4 (Unicode) Servlet
14 ~程者必L据数据库的内码ISO8859-1q原成原始字节流 D6 D0 CE C4  
15 ~程者必L据客L字符集GB2312生成新的字符?/td> 4E 2D 65 87QUnicodeQ?/td>  
Servlet准备把字W串输出到客L
16 ServletҎQServlet-charsetQ生成字节流 D6D0 CE C4 Servlet
17 Servlet把字节流输出到IE中,如果已指定<Servlet-charsetQ,q会讄IE的编码ؓQServlet-charsetQ?/td> D6 D0 CE C4
18 IEҎ指定的编码或默认~码查看l果 “中文”Q正显C) IE

解释一下,表中W?W?步和W?5W?6步是用红色标记的Q表Cq码者来作{换。第4?两步其实是一句话Q?#8220;new String(source.getBytes("GB2312"), "ISO8859-1")”。第15?6两步也是一句话Q?#8220;new String(source.getBytes("ISO8859-1"), "GB2312")”。亲q读者,你在q样~写代码时是否意识到了其中的每一个细节呢Q?/p>

至于客户端内码和数据库内码ؓ其它值时的流E,和输出对象是pȝ控制台时的流E,误者自己想吧。明白了上述程的原理,怿你可以轻村֜写出来?/p>

行文xQ已可告一D落了。终点又回到了v点,对于~程者而言Q几乎是什么媄响都没有?/p>

因ؓ我们早就被告之要q么做了?/p>

以下l出一个结论,作ؓl尾?/p>

1?在Jsp文g中,要指定contentTypeQ其中,charset的D与客L览器所用的字符集一P对于其中的字W串帔RQ不需做Q何内码{换;对于字符串变量,要求能根据ContentType中指定的字符集还原成客户端能识别的字节流Q简单地_是“字符串变量是ZQJsp-charsetQ字W集?#8221;Q?/p>

2?在Servlet中,必须用HttpServletResponse.setContentType()讄charsetQ且讄成与客户端内码一_对于其中的字W串帔RQ需要在Javac~译时指定encodingQ这个encoding必须与编写源文g的^台的字符集一P一般说来都是GB2312或GBKQ对于字W串变量Q与JSP一P必须“是基于<Servlet-charsetQ字W集?#8221;?/p>

junky 2007-04-16 16:28 发表评论
]]>
struts+hibernate的替代方案:struts+newxy,开发效率提高十??http://www.tkk7.com/junky/archive/2007/03/09/102774.htmljunkyjunkyFri, 09 Mar 2007 03:29:00 GMThttp://www.tkk7.com/junky/archive/2007/03/09/102774.htmlhttp://www.tkk7.com/junky/comments/102774.htmlhttp://www.tkk7.com/junky/archive/2007/03/09/102774.html#Feedback0http://www.tkk7.com/junky/comments/commentRss/102774.htmlhttp://www.tkk7.com/junky/services/trackbacks/102774.html

struts+newxy之所以在开发效率上比struts+hibernate能提高十倍、甚臛_十倍,是因为克服了struts与hiberate的不?利用newxy DAOc,标签Q?struts+newxy可以在以下几个方面不用写java代码Q不用配|struts?1.数据库的增、删、改Q?2.Ҏ询所得数据缓存,指定~存旉Q?3.数据库字W编码与本地字符~码转换Q?4.文g上传Q上传大控Ӟ 5.文g下蝲Q下载记敎ͼ 6.囄昄Q?7.数据分页昄Q?8.客户端标记记录集哪条记录被选择Q?因ؓ可以不写java代码Q不用徏立ActionFormcRActionc,因而不用配|strutsQ不用重新编译类文g、不用重新打包、不用重启服务器?可以克服struts的不?׃struts+newxy用即时注册的ҎQ可以不?/p>

    在java的web开发领域较ȝ的是数据库操U,如果有工兯像delphi开发数据库q用pȝ那样高效Q它一定会受到开发者的Ƣ迎?

    l过五个斚w的比较,newxy+struts WEB开发与deiphi桌面开发相比,速度更快Q能力更强?http://blog.csdn.net/nlhlx/archive/2006/06/12/791047.aspx

    newxy是hibernate的替代者,struts+newxy是struts+hibernate的替代方案?

    struts的不I下面一文章有代表性:《Struts的巨大烦?真的不适合大系l??a >http://dev.csdn.net/develop/article/85/85114.shtm?br />主要观点是:
     一、{到展C层Ӟ需要配|forwardQ每一ơ{到展C层Q相信大多数都是直接转到jspQ?而涉及到转向Q需要配|forwardQ如果有十个展示层的jspQ需要配|十ơstrutsQ?而且q不包括有时候目录、文件变_需要重C改forwardQ注意,每次修改配置之后Q?要求重新部v整个目Q而tomcateq样的服务器Q还必须重新启动服务器,如果业务变更复杂频繁的系l, q样的操作简单不可想象。现在就是这P几十上百个h同时在线使用我们?pȝQ?大家可以惌一下,我的烦恼有多大?br />    二、当面表单需要自动变化或者频J变化时?br />    对于一个成熟的MISpȝ来说,面表单肯定是不固定?甚至象有些系l,面表单是存在数据库中, 需要填写的表单在页面自动生成,比如填写一个h员基本信?本来只需要填?姓名、性别、出生年?三个指标Q?而我后来需要增加籍贯这L指标Q我只需要在数据库中dc诏q个记录Qƈ在页面就能自动增加籍贯这L表单??struts在这斚wQ其优势反而变成了不Q我参考了非常多的人力资源理pȝQ这些系l几乎都能够做系l里面就可以控制人员信息的指C, q行使展C层能随之灵zd化,如果使用了strutsQ这些灵zL就Ҏ用不上。 同时Q如果页面表单频J变化时Q就需要频J修改formbean对应的方法和属性,而每ơ修改之后,p求重新部|Ԍ或者重新启动服务器……?br />    hibernate的不I下面是一位网友的看法Q具有代表性:
    一、对象与数据库的映射Q关键在于对象关pȝ映射Q但是没做到很理惻I配置q多Q控制复杂, 另外q会出错。其实本质在于对象不够自由?br />    二、事务处理。这点上更容易出问题Q相对于各种各样的事务管理器Q要兼容是一个大问题Q?d在各U应用服务器上有很多问题。其本质在于创徏了一个自我数据存取小环境Q必焉临各U兼定w题?br />    三、HQL语言。徏立对象查询语aQ类SQLQ但是不同于M一USQLQ调试环境复杂。本质在于创Z一U语aQ增加学习成本?br />    q位|友q提Z减化和退化方案?

    struts+newxy之所以在开发效率上比struts+hibernate能提高十倍、甚臛_十倍,是因为克服了struts与hiberate的不?br />    利用newxy DAOc,标签Q?struts+newxy可以在以下几个方面不用写java代码Q不用配|struts?http://blog.csdn.net/nlhlx/archive/2006/06/11/788541.aspx

    1.数据库的增、删、改Q?
    2.Ҏ询所得数据缓存,指定~存旉Q?
    3.数据库字W编码与本地字符~码转换Q?
    4.文g上传Q上传大控Ӟ
    5.文g下蝲Q下载记敎ͼ
    6.囄昄Q?
    7.数据分页昄Q?
    8.客户端标记记录集哪条记录被选择Q?

    因ؓ可以不写java代码Q不用徏立ActionFormcRActionc,因而不用配|strutsQ不用重新编译类文g、不用重新打包、不用重启服务器?可以克服struts的不?br />    在克服hibernate的不x面,newxy采用“退化”和“进化”ƈ用的Ҏ?br />    newxy在进行数据的查询、增、删、改旉会调用一注册ҎQ根据业务涉及到的数据库相关数据源名和表名进行注册, 注册的目的是要获得表字段对应的javacdQ主关键字段名,d键字D长度等数据Q保存在一个单子实例中Q以供DAOc调用?如果已注册不再注册?br />    可以对多表查询语句注册,如:“select a.field1,b.field2 from table1 as a,table2 as b where ...";
    可以对跨数据源的查询注册。如Q?select a.field1,b.field2 from table1 as a,DB3.dto.table2 as b where ...";
    如果是数据增、删、改Q则是对单一表注册;
    ׃struts+newxy用即时注册的ҎQ可以不象hibernate那样用静态文件媄数据库到值对象类。开发者不用配|Q何文件。可以用Q意查询语句,克服“对象不够自由”问题?br />    hibernate通过配置文g讄表之间的关系Q有一定意义,newxy在这斚w是“退化”的Q但struts+newxy在处理数据库表之间关pL面是很容易的?br />    在事务处理方面,newxy提供了一事务cnet.newxy.dbm.Transaction。它可以多个数据库的操作放在一个事务中。由于DAOcd数据操作前的注册Ҏ得到的表及其字段各种Ҏ都是与数据库直接相关的Q而不是事先用静态文件媄, 因而极发生错误;开发者可以通过Transaction的方法ؓ不同的数据库讄不同的隔ȝU;可以讄操时回滚旉Q在讄的时间内事务没有完成Q会有一U程q行q预Q将事务回滚?br />    hibernate的HQL语言是和数据库与对象影射规则盔R应的,它没有特别功能,主要是利用值对象类来查询数据?newxy也提供了一U查询语aNQL。开发者不需用特D的语法来构建查询语句。非常容易理解,不会增加学习成本?

struts一旦与newxyl合C赯用是如此单,下列是struts+newxy代替struts+hibernate的例子?

        struts配置中,formBean的type是“net.newxy.struts_faces.DynaFormBean”,开发者不需另外设计ActionFormcR如Q?br />            <form-bean name="myFormBean" type="net.newxy.struts_faces.DynaFormBean" />

        用户从页面表单submit数据后,在ActioncȝҎ中,开发者可以用DynaFormBean代替struts ActionForm,用DynaDto代替hibernate 对象cR?br />        public ActionForward methodName(ActionMapping actionMapping, ActionForm actionForm,
                              HttpServletRequest httpServletRequest,
            HttpServletResponse httpServletResponse) throws Exception{
            ......
            DynaFormBean form=(DynaFormBean)actionForm;
            DynaDto dto=(DynaDto)form.getDto();
            dto.set_table("table1");//如果用户面没有传来数据库表名?br />            try{
                IFacade ifacade=IFacadeFactory.getFacade(httpServletRequest.getParameter("_dao"),
                      httpServletRequest.getLocale());  //l大多数情况是:IFacade ifacade=IFacadeFactory.getFacade();

                //更新或插入,如果result==null,为updateQ否则ؓinsert?br />                result = ifacade.update(dto);//或:FormBeanUtils.update(ifacade, form);

                //删除记录
                ifacade.remove(dto);//?FormBeanUtils.remove(ifacade, form);

                //数据查询Q如果上传了W合newxy多项查询规则的数据。查询记录集攑֜newForm 的_coll属性中?br />                DynaFormBean newForm=new DynaFormBean();
                FormBeanUtils.createForm(newForm, httpServletRequest);
                ......
                //开发者如果想知道生成的sql语句Q可以这P
                //string sql=form.get_sql();
                //׃开发者在Ҏ据进行操作时完全不需知道sql语句Q所以没有提供方法让开发者直接得到sql语句来控制数据操作?br />                //未来版本可能提供q样的方法?br />            }catch(Exception e){
                ......
            }
        }
        如果使用newxy的标{֏以不建立Actionc,不设|struts的formBean及actionQ可以不写代码?br />   



junky 2007-03-09 11:29 发表评论
]]>
Struts的巨大烦?真的不适合大系l?(?http://www.tkk7.com/junky/archive/2007/03/09/102772.htmljunkyjunkyFri, 09 Mar 2007 03:26:00 GMThttp://www.tkk7.com/junky/archive/2007/03/09/102772.htmlhttp://www.tkk7.com/junky/comments/102772.htmlhttp://www.tkk7.com/junky/archive/2007/03/09/102772.html#Feedback0http://www.tkk7.com/junky/comments/commentRss/102772.htmlhttp://www.tkk7.com/junky/services/trackbacks/102772.html
  背景Q现在,我负责着一个大型企业的人力资源理pȝQ整个系l管理的人员大约?.6万h左右Q系l基于jboss+oracleQjava技术框架ؓstrutsQ少许的报表用到?servletQ项目开发的旉差不多一q_好,转入正题?br />
  到现在ؓ止,我认为formbean 的好处就是和面表单对应h,在系l业务处理中Q可以实例化formbean之就可以取出面表单的值来,方便于在业务逻辑中引用。得业务处理层和展C层可以分离开来,到现在ؓ止,q也是我发现struts的唯一好处?br />
  但struts带给我的烦恼Q各位,实在太多太多了,主要的几Ҏ|列如下Q?br />
  一、{到展C层Ӟ需要配|forwardQ每一ơ{到展C层Q相信大多数都是直接转到jspQ而涉及到转向Q需要配|forwardQ如果有十个展示层的jspQ需要配|十ơstrutsQ而且q不包括有时候目录、文件变_需要重C改forwardQ注意,每次修改配置之后Q要求重新部|整个项目,而tomcateq样的服务器Q还必须重新启动服务器,如果业务变更复杂频繁的系l,q样的操作简单不可想象。现在就是这P几十上百个h同时在线使用我们?pȝQ大家可以想象一下,我的烦恼有多大?br />
  二、当面表单需要自动变化或者频J变化时?br />
  对于一个成熟的MISpȝ来说,面表单肯定是不固定?甚至象有些系l,面表单是存在数据库中,需要填写的表单在页面自动生成,比如填写一个h员基本信?本来只需要填?姓名、性别、出生年?三个指标Q而我后来需要增加籍贯这L指标Q我只需要在数据库中dc诏q个记录Qƈ在页面就能自动增加籍贯这L表单。?struts在这斚wQ其优势反而变成了不Q我参考了非常多的人力资源理p?l,q些pȝ几乎都能够做pȝ里面可以控制h员信息的指示Q进行展示层能随之灉|变化Q如果用了strutsQ这些灵zL就Ҏ用不上?br />
  同时Q如果页面表单频J变化时Q就需要频J修改formbean对应的方法和属性,而每ơ修改之后,p求重新部|Ԍ或者重新启动服务器……?br />
  三、要引入struts包,引入strtus标签库,现到Cؓ止,我们有所见即所得的dreamwaver、frontpage、webeditorQ对于繁杂页面的设计Q是非常方便的,而对于struts标签库,没有哪一UY件能够支持。jbuilder我没用过Q不知道支持不支持,而ؓ了维护这些标{ֺQ增加工作量支持Q也非常Ҏ出错Q稍微不心Q就一堆异常抛出来Q系l他ȝ你看?br />
  ȝQ?br />
  现在Z么asp.net来流行,非常重要的一点,是asp.netq样的模式,单,易于控制。而且我现在仍然觉得,利用jsp的文件名作ؓ路径的映非常方便,而strutsq非常去配置action,使之有带有象.do?mainq样后缀的\径访问方式,不但增加了系l功能的复杂性,影响了系l的性能不说Q还增加了非常多的系l不可掌握因素。其?javabean+jspQ利用javabean处理业务逻辑Q只利用jsp来展C数据,q正?net的原型,同样Q即可以不用去配|struts、也不需要象serlet一样去配置web.xml带来的麻烦?所以,q不是所有的框架都是好的Q越单越易于控制?br /> 
  所以,现在Q我军_攑ּstrutsQ{而采用javabean+jsp的技术结?img src ="http://www.tkk7.com/junky/aggbug/102772.html" width = "1" height = "1" />

junky 2007-03-09 11:26 发表评论
]]>
eXtremeComponents参考文?/title><link>http://www.tkk7.com/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.tkk7.com/junky/archive/2006/08/31/66967.html</guid><wfw:comment>http://www.tkk7.com/junky/comments/66967.html</wfw:comment><comments>http://www.tkk7.com/junky/archive/2006/08/31/66967.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/junky/comments/commentRss/66967.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/junky/services/trackbacks/66967.html</trackback:ping><description><![CDATA[     摘要: 版本1.0.0 本文档允许在遵守以下两条原则的条件下被用和传播Q?1Q不能凭借本文档索取M费用 2Q以M方式Q印L或电子版Q用和传播时本文档Ӟ必须包含本版权申? (更新?..) Table of Contents 前言 ...  <a href='http://www.tkk7.com/junky/archive/2006/08/31/66967.html'>阅读全文</a><img src ="http://www.tkk7.com/junky/aggbug/66967.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/junky/" target="_blank">junky</a> 2006-08-31 23:34 <a href="http://www.tkk7.com/junky/archive/2006/08/31/66967.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>体验Struts(2)---整体l构 http://www.tkk7.com/junky/archive/2006/05/25/48180.htmljunkyjunkyThu, 25 May 2006 12:27:00 GMThttp://www.tkk7.com/junky/archive/2006/05/25/48180.htmlhttp://www.tkk7.com/junky/comments/48180.htmlhttp://www.tkk7.com/junky/archive/2006/05/25/48180.html#Feedback0http://www.tkk7.com/junky/comments/commentRss/48180.htmlhttp://www.tkk7.com/junky/services/trackbacks/48180.htmlZ让大家更方便的了解我q个设计Q我先把我的一些整体的规划都说出来吧,׃我是初学Q难免会参照本书c来看,我买的是那本孙某女的书《精通:*****》,看了看她前面的介l,我一看了不得Q能ZQ写的还都不错,q女的可不得了,渐渐疑惑的地斚w常多Q比如例子里面注释都拽上了英语,搞不懂,而当我从|上下到电子盗版jakarta strutsQ我已安下栽说明要求的那样在24时后删除了Q这本书的时候我才恍然大悟,原来是抄袭啊Q至于是谁抄的谁Q口说无凭,不能p谤,不过大家心里都该有杆Uͼ

下面是代码了:
package com.boya.subject.model;
public interface Person
{
    public Long getId();
    public void setId( Long id );
    public String getName();
    public void setName( String name );
    public String getPassword();
    public void setPassword( String password );
    public String getTelphone();
    public void setTelphone( String telphone );
    public String getUser();
    public void setUser( String user );
    public String getType();
}

package com.boya.subject.model;
public abstract class User implements Person
{
    private Long id;数据库id
    private String user;用户?/font>
    private String password;密码
    private String name;姓名
    private String telphone;
电话

    public Long getId()
    {
        return id;
    }

    public void setId( Long id )
    {
        this.id = id;
    }

    public String getName()
    {
        return name;
    }

    public void setName( String name )
    {
        this.name = name;
    }

    public String getPassword()
    {
        return password;
    }

    public void setPassword( String password )
    {
        this.password = password;
    }

    public String getTelphone()
    {
        return telphone;
    }

    public void setTelphone( String telphone )
    {
        this.telphone = telphone;
    }

    public String getUser()
    {
        return user;
    }

    public void setUser( String user )
    {
        this.user = user;
    }
}

package com.boya.subject.model;
public class Admin extends User
{
    private String grade = null;
理员权?/font>

    public String getGrade()
    {
        return grade;
    }

    public void setGrade( String grade )
    {
        this.grade = grade;
    }

    public String getType()
    {
        return "admin";
    }
}

package com.boya.subject.model;
public class Teacher extends User
{
    private String level;
教师职称

    public String getLevel()
    {
        return level;
    }

    public void setLevel( String level )
    {
        this.level = level;
    }

    public String getType()
    {
        return "teacher";
    }
}

package com.boya.subject.model;

public class Student extends User
{
    private String sn;学生学号
    private SchoolClass schoolClass;

    public SchoolClass getSchoolClass()
    {
        return schoolClass;
    }

    public void setSchoolClass( SchoolClass schoolClass )
    {
        this.schoolClass = schoolClass;
    }

    public String getSn()
    {
        return sn;
    }

    public void setSn( String sn )
    {
        this.sn = sn;
    }

    public String getType()
    {
        return "student";
    }
}

而对于Action我分别做了一个抽象类Q之后别的从q里l承
先是Action?/font>
package com.boya.subject.controller;

import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import com.boya.subject.frame.ID;
import com.boya.subject.frame.ServiceFactory;
import com.boya.subject.model.Person;
import com.boya.subject.service.Service;
import com.boya.subject.util.HtmlUtil;

public abstract class BaseAction extends Action
{
    /**
     * 由服务工厂方法创建服?br />     * @return 数据库操作的服务
     * 2006-5-16 18:10:04
     */
    public Service getService()
    {
        ServiceFactory factory = (ServiceFactory) getAppObject( ID.SF );
        Service service = null;
        try
        {
            service = factory.createService();
        }
        catch ( Exception e )
        {
        }
        return service;
    }

    /**
     * 判断用户是否合法登陆
     * @param req
     * @return 用户是否登陆
     * 2006-5-16 18:11:26
     */
    public boolean isLogin( HttpServletRequest req )
    {
        if ( getPerson( req ) != null ) return true;
        else
            return false;
    }

   
    /**
     * 抽象Ҏ,子类实现
     * @param mapping
     * @param form
     * @param req
     * @param res
     * @return
     * @throws Exception
     * 2006-5-16 18:12:54
     */
    protected abstract ActionForward executeAction( ActionMapping mapping,
            ActionForm form, HttpServletRequest req, HttpServletResponse res )
            throws Exception;

    /**
     * 获取session范围的用?br />     * @param req
     * @return 当前用户
     * 2006-5-16 18:13:35
     */
    public abstract Person getPerson( HttpServletRequest req );

    /**
     * 父类的执行Action
     * @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)
     */
    public ActionForward execute( ActionMapping mapping, ActionForm form,
            HttpServletRequest req, HttpServletResponse res ) throws Exception
    {
        if ( !isLogin( req ) )
        {
            HtmlUtil.callParentGo( res.getWriter(), ID.M_UNLOGIN, ID.P_INDEX );
            return null;
        }
        return executeAction( mapping, form, req, res );
    }

    /**
     * 删除session中属性ؓattribute的对?br />     * @param req
     * @param attribute 对象属?br />     * 2006-5-16 18:16:59
     */
    public void removeSessionObject( HttpServletRequest req, String attribute )
    {
        HttpSession session = req.getSession();
        session.removeAttribute( attribute );
    }

    /**
     * 讄session中属性ؓattribute的对?br />     * @param req
     * @param attribute 讄属?br />     * @param o 讄对象
     * 2006-5-16 18:17:50
     */
    public void setSessionObject( HttpServletRequest req, String attribute,
            Object o )
    {
        req.getSession().setAttribute( attribute, o );
    }

    /**
     * 讄application中属性ؓattribute的对?br />     * @param req
     * @param attribute 讄属?br />     * @param o 讄对象
     * 2006-5-16 18:17:50
     */
    public void setAppObject( String attribute, Object o )
    {
        servlet.getServletContext().setAttribute( attribute, o );
    }

    public Object getSessionObject( HttpServletRequest req, String attribute )
    {
        Object obj = null;
        HttpSession session = req.getSession( false );
        if ( session != null ) obj = session.getAttribute( attribute );
        return obj;
    }

    public Object getAppObject( String attribute )
    {
        return servlet.getServletContext().getAttribute( attribute );
    }

    public void callParentGo( HttpServletResponse res, String msg, String url )
            throws IOException
    {
        HtmlUtil.callParentGo( res.getWriter(), msg, url );
    }

    public void callMeGo( HttpServletResponse res, String msg, String url )
            throws IOException
    {
        HtmlUtil.callMeGo( res.getWriter(), msg, url );
    }

    public void callBack( HttpServletResponse res, String msg )
            throws IOException
    {
        HtmlUtil.callBack( res.getWriter(), msg );
    }

    public void callMeConfirm( HttpServletResponse res, String msg, String ok,
            String no ) throws IOException
    {
        HtmlUtil.callMeConfirm( res.getWriter(), msg, ok, no );
    }
}
再是DispatchAction?br />
package com.boya.subject.controller;

import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;
import com.boya.subject.frame.ID;
import com.boya.subject.frame.ServiceFactory;
import com.boya.subject.model.Person;
import com.boya.subject.service.Service;
import com.boya.subject.util.HtmlUtil;

public abstract class BaseDispatchAction extends DispatchAction
{
    /**
     * 由服务工厂方法创建服?br />     * @return 数据库操作的服务
     * 2006-5-16 18:10:04
     */
    public Service getService()
    {
        ServiceFactory factory = (ServiceFactory) getAppObject( ID.SF );
        Service service = null;
        try
        {
            service = factory.createService();
        }
        catch ( Exception e )
        {
        }
        return service;
    }

    /**
     * 判断用户是否合法登陆
     * @param req
     * @return 用户是否登陆
     * 2006-5-16 18:11:26
     */
    public boolean isLogin( HttpServletRequest req )
    {
        if ( getPerson( req ) != null ) return true;
        else
            return false;
    }

    /**
     * 获取session范围的用?br />     * @param req
     * @return 当前用户
     * 2006-5-16 18:13:35
     */
    public abstract Person getPerson( HttpServletRequest req );

    /**
     * 父类的执行DispatchAction
     * @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)
     */
    public ActionForward execute( ActionMapping mapping, ActionForm form,
            HttpServletRequest req, HttpServletResponse res ) throws Exception
    {
        try
        {
            if ( !isLogin( req ) )
            {
                callParentGo( res, ID.M_UNLOGIN, ID.P_INDEX );
                return null;
            }
            return super.execute( mapping, form, req, res );
        }
        catch ( NoSuchMethodException e )
        {
            callBack( res, ID.M_NOMETHOD );
            return null;
        }
    }

    /**
     * 删除session中属性ؓattribute的对?br />     * @param req
     * @param attribute 对象属?br />     * 2006-5-16 18:16:59
     */
    public void removeSessionObject( HttpServletRequest req, String attribute )
    {
        HttpSession session = req.getSession();
        session.removeAttribute( attribute );
    }

    /**
     * 讄session中属性ؓattribute的对?br />     * @param req
     * @param attribute 讄属?br />     * @param o 讄对象
     * 2006-5-16 18:17:50
     */
    public void setSessionObject( HttpServletRequest req, String attribute,
            Object o )
    {
        req.getSession().setAttribute( attribute, o );
    }

    /**
     * 讄application中属性ؓattribute的对?br />     * @param req
     * @param attribute 讄属?br />     * @param o 讄对象
     * 2006-5-16 18:17:50
     */
    public void setAppObject( String attribute, Object o )
    {
        servlet.getServletContext().setAttribute( attribute, o );
    }

    public Object getSessionObject( HttpServletRequest req, String attribute )
    {
        Object obj = null;
        HttpSession session = req.getSession( false );
        if ( session != null ) obj = session.getAttribute( attribute );
        return obj;
    }

    public Object getAppObject( String attribute )
    {
        return servlet.getServletContext().getAttribute( attribute );
    }

    public void callParentGo( HttpServletResponse res, String msg, String url )
            throws IOException
    {
        HtmlUtil.callParentGo( res.getWriter(), msg, url );
    }

    public void callMeGo( HttpServletResponse res, String msg, String url )
            throws IOException
    {
        HtmlUtil.callMeGo( res.getWriter(), msg, url );
    }

    public void callBack( HttpServletResponse res, String msg )
            throws IOException
    {
        HtmlUtil.callBack( res.getWriter(), msg );
    }

    public void callMeConfirm( HttpServletResponse res, String msg, String ok,
            String no ) throws IOException
    {
        HtmlUtil.callMeConfirm( res.getWriter(), msg, ok, no );
    }
}

对于E序中的一些提CZ息,我比较喜Ƣ用JS来写Q所以我把这些都攑ֈ了一个类?br />
import java.io.IOException;
import java.io.Writer;

public class HtmlUtil
{
    public static void callParentGo( Writer out, String msg, String url )
            throws IOException
    {
        out.write( "<script language=\"javascript\">" );
        out.write( "alert(\"" + msg + "\");" );
        out.write( "parent.location.href=\"" + url + "\";" );
        out.write( "</script>" );
    }

    public static void callMeGo( Writer out, String msg, String url )
            throws IOException
    {
        out.write( "<script language=\"javascript\">" );
        out.write( "alert(\"" + msg + "\");" );
        out.write( "location.href=\"" + url + "\";" );
        out.write( "</script>" );
    }

    public static void callMeConfirm( Writer out, String msg ,String ok, String no )
            throws IOException
    {
        out.write( "<script language=\"javascript\">" );
        out.write( "if(window.confirm(\"" + msg + "\")){" );
        out.write( "location.href=\"" + ok + "\"}else{" );
        out.write( "location.href=\"" + no + "\"}" );
        out.write( "</script>" );
    }

    public static void callBack( Writer out, String msg ) throws IOException
    {
        out.write( "<script language=\"javascript\">" );
        out.write( "alert(\"" + msg + "\");" );
        out.write( "parent.history.back();" );
        out.write( "</script>" );
    }
}



junky 2006-05-25 20:27 发表评论
]]>
体验Struts(3)---加上点ajax http://www.tkk7.com/junky/archive/2006/05/25/48181.htmljunkyjunkyThu, 25 May 2006 12:27:00 GMThttp://www.tkk7.com/junky/archive/2006/05/25/48181.htmlhttp://www.tkk7.com/junky/comments/48181.htmlhttp://www.tkk7.com/junky/archive/2006/05/25/48181.html#Feedback0http://www.tkk7.com/junky/comments/commentRss/48181.htmlhttp://www.tkk7.com/junky/services/trackbacks/48181.html比如当用户在注册的时候,用户点一个按U不用刷新界面就可以获得一句提C,是有qhq是没有qh啊?q次我尝试了用ajax技术来做一个三U关键的下拉列表Q而这是我要讲的关键?br />其实现在一般的ajax都是向Servlet发出hQ之后服务器响应Q再h的把l果传给它,之后昄出来Q而换到StrutsQ有Z发甍Q也一PAction是ServletQDispatchAction也是Q只要把代码往q里写,让它往.do那里hp了?br />在接下来我就向大家介l我是怎样实现上述功能?br />因ؓ大学里面的结构是q里?br />学院-专业-班-学生
在学生注册的时候他是依赖于上述对象的,所以用h册就需要一个三U的下拉选择
而ajaxp象变术一P从服务器那里h弄来您需要的列表
下面我先l大家展CZ下第一个功能是怎么实现的吧Q?br />当用户在注册的时候,点一个按U,之后会弹Z个alert来告诉你q个用户是否有h用了Q下面就让我们来看看q个功能是怎么实现的吧Q?br />
<html:button styleClass="cancel" property="submit" value="验证用户是否存在" onclick="teacherCheck()"/>
q里定义了按U,用来试老师是否已经存在?br />大体的ajax的JS代码都上面这四部分,
先是创徏XMLHttpRequestQ?br />var xmlHttp;
function createXMLHttpRequest()
{
 if (window.XMLHttpRequest)
 {
  xmlHttp = new XMLHttpRequest();
 }
 else if (window.ActiveXObject)
 {
  xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
}
之后是客户响应部分的代码
function teacherCheck()
{
 var f = document.TeacherRegisterForm 从表单里dD?br /> var user = f.user.value
 if(user=="")
 {
   window.alert("用户名不能ؓI!")
  f.user.focus()
   return false
   }
 else
 {
  createXMLHttpRequest()        q里都是_֍?br />  var url = "ajax.do?method=checkUserIsExist&user="+user   定义响应地址
  xmlHttp.open("GET",url, true)    发出响应
  xmlHttp.onreadystatechange = checkUser  把从服务器得到的响应再传l另个函?br />  xmlHttp.send(null)
   }
}

function checkUser()
{
 if (xmlHttp.readyState == 4)
 {
  if (xmlHttp.status == 200)
  {
   alert(xmlHttp.responseText)        q里是对响应l果的操作,在这里我们是滩出对话框,q把服务器发来的信息昄出来
  }
 }
}

我把所有ؕ七八p的操作都放C一个DispatchAction里,所以它也不例外的在q个DA中了
public ActionForward checkUserIsExist( ActionMapping mapping,
            ActionForm form, HttpServletRequest req, HttpServletResponse res )
            throws Exception
    {
        Service service = getService();
        res.getWriter().write(service
.checkUserIsExistForAjax( req.getParameter( "user" ) ) );
        return null;
    }
它仅仅是把业务逻辑部分的结果发送回去,而真正的判断是在业务逻辑那里实现的,
public String checkUserIsExistForAjax( String user )把结果弄成String的Ş式传回去
    {
        Connection connection = null;
        PreparedStatement pstmt1 = null;
        ResultSet rs = null;
        try
        {
            connection = getConnection();
            pstmt1 = connection
                    .prepareStatement( "select * from user where user=?" );
            pstmt1.setString( 1, user );
            rs = pstmt1.executeQuery();
            rs.last();
            if ( rs.getRow() > 0 )
            {
                return ID.M_EXIST; 用户存在
            }
        }
        catch ( Exception e )
        {
            e.printStackTrace();
        }
        finally
        {
            close( rs );
            close( pstmt1 );
            close( connection );
        }
        return ID.M_NOEXIST;用户不存?/font>
    }



junky 2006-05-25 20:27 发表评论
]]>
վ֩ģ壺 ˮƵ߹ۿѲŸ | ĻѲ| ѳ̱߸߳Ƶ| ߹ۿ޾ƷƬ| պƷþþþþ| ޳AVƬ߳ˮ| ŷƷһ| þþþѿAƬAPP| aëƬþ| ޳˻ɫ߹ۿ| ޳ӰԺ߹ۿ| ޾ƷѹۿƵ| һ234| ޲͵V͵Vɫ| վ߹ۿ| aëƬ߿Ƭ| ɫƷ | avۺר| ٸ| ߹ۿ˳Ƶɫ9 | ۺ| 4444wwwѿ| wwwѻɫ| ۺAV| 77777_ҹþö| ձĻһ| ƵѴȫϼ| Ļ˳й| ۺAV| ŷղ߹ۿ| ҹþþþþþþþ| ҹʱ| 18Ůվ| ˮwww| WWW޾Ʒþ鶹| ޴߹ۿ| ѿav뾫Ʒɫҹ| ҳ˿| ùƵ| һҹߴ| ҹƬ|