﻿<?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-妖人学java-文章分类-java</title><link>http://www.blogjava.net/shypwang/category/25145.html</link><description /><language>zh-cn</language><lastBuildDate>Fri, 21 Mar 2008 17:42:28 GMT</lastBuildDate><pubDate>Fri, 21 Mar 2008 17:42:28 GMT</pubDate><ttl>60</ttl><item><title>使用.bat文件在Windows下运行Java程序时怎样避免DOS窗口 </title><link>http://www.blogjava.net/shypwang/articles/187636.html</link><dc:creator>妖人</dc:creator><author>妖人</author><pubDate>Fri, 21 Mar 2008 02:17:00 GMT</pubDate><guid>http://www.blogjava.net/shypwang/articles/187636.html</guid><wfw:comment>http://www.blogjava.net/shypwang/comments/187636.html</wfw:comment><comments>http://www.blogjava.net/shypwang/articles/187636.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/shypwang/comments/commentRss/187636.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/shypwang/services/trackbacks/187636.html</trackback:ping><description><![CDATA[<h1 class="block_title"><a id="viewpost1_TitleUrl" href="http://www.blogjava.net/NeonWay/archive/2006/04/24/42817.html" target="_blank" rel="nofollow">使用.bat文件在Windows下运行Java程序时怎样避免DOS窗口 </a></h1>
<span id="LblContent">我们在启动脚本中一般使用类似如下的命令执行一个Java程序：<br />
&nbsp;&nbsp;&nbsp;&nbsp;java&nbsp;xxx.xxx.MailClass.class<br />
或：<br />
&nbsp;&nbsp;&nbsp;&nbsp;java&nbsp;-jar&nbsp;xxx.jar<br />
这样在Java程序启动时，加载的DOS窗口一直出现，直到你关闭了Java程序才一起关闭。<br />
<br />
很多朋友询问怎样才能避免这个DOS窗口，你只需要把.bat中的启动命名修改为：<br />
&nbsp;&nbsp;&nbsp;&nbsp;start&nbsp;javaw&nbsp;xxx.xxx.MailClass.class<br />
或:<br />
&nbsp;&nbsp;&nbsp;&nbsp;start&nbsp;javaw&nbsp;-jar&nbsp;xxx.jar<br />
即可。<br />
<br />
<br />
注：DOS窗口还是会一闪而过，因为javaw是一个需要dos加载的命令。<br />
</span>
<img src ="http://www.blogjava.net/shypwang/aggbug/187636.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/shypwang/" target="_blank">妖人</a> 2008-03-21 10:17 <a href="http://www.blogjava.net/shypwang/articles/187636.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>1 java,javac,jar 命令</title><link>http://www.blogjava.net/shypwang/articles/187633.html</link><dc:creator>妖人</dc:creator><author>妖人</author><pubDate>Fri, 21 Mar 2008 02:07:00 GMT</pubDate><guid>http://www.blogjava.net/shypwang/articles/187633.html</guid><wfw:comment>http://www.blogjava.net/shypwang/comments/187633.html</wfw:comment><comments>http://www.blogjava.net/shypwang/articles/187633.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/shypwang/comments/commentRss/187633.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/shypwang/services/trackbacks/187633.html</trackback:ping><description><![CDATA[<p>&nbsp; </p>
<h1>1 java,javac,jar <span style="font-family: 宋体">命令</span></h1>
<p><span style="font-family: 宋体">源代码目录</span></p>
<p>src</p>
<p>src/javactest/pa/A.java</p>
<p>src/javactest/pb/B.java</p>
<p><span style="font-family: 宋体">其中</span>A<span style="font-family: 宋体">引用</span>B</p>
<p><span style="font-family: 宋体">类目录</span></p>
<p>classes</p>
<p>src <span style="font-family: 宋体">和</span>classes<span style="font-family: 宋体">目录同级，假设父目录为</span>test</p>
<p><span style="font-family: 宋体">（一）关于</span>javac</p>
<p>&nbsp;&nbsp; <span style="font-family: 宋体">（</span>1<span style="font-family: 宋体">）先编译</span>B<span style="font-family: 宋体">再编译</span>A</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; cd test</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; javac -d classes src/javactest/pb/B.java</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; javac -cp classes src/javactest/pa/A.java </p>
<p>&nbsp;&nbsp; <span style="font-family: 宋体">（</span>2<span style="font-family: 宋体">）使用</span>sourcepath<span style="font-family: 宋体">编译</span>A,<span style="font-family: 宋体">如果</span>java<span style="font-family: 宋体">有变更，会重新编译</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; cd test</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; javac -d classes -sourcepath src src/javactest/pa/A.java</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-family: 宋体">或</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; javac -d classes -sourcepath src -cp classes src/javactest/pa/A.java </p>
<p><span style="font-family: 宋体">（二）关于</span>jar</p>
<p>&nbsp;&nbsp; <span style="font-family: 宋体">（</span>1<span style="font-family: 宋体">）创建</span>jar</p>
<p style="margin-left: 27pt"><strong>i</strong><strong><span style="font-family: 宋体">）</span></strong></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; cd classes</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; jar cvf javactest.jar . </p>
<p><span style="font-family: 宋体">则</span>jar<span style="font-family: 宋体">包生成在</span>classes<span style="font-family: 宋体">目录下</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; <strong><span style="font-size: 10pt; color: black">ii)</span></strong></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; cd test</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; jar cvf javactest.jar <span style="background: yellow">&#8211;C classes .</span></p>
<p><span style="font-family: 宋体">则</span>jar<span style="font-family: 宋体">包生成在</span>test<span style="font-family: 宋体">目录下</span></p>
<p><span style="background: yellow; font-family: 宋体">注意</span>-C classes<span style="font-family: 宋体">相当于把当前路径改为</span>classes<span style="font-family: 宋体">，</span>jar<span style="font-family: 宋体">包中不会出现</span>classes<span style="font-family: 宋体">目录。</span></p>
<p><span style="font-family: 宋体">如果：</span></p>
<p style="text-indent: 21pt">cd test</p>
<p>&nbsp;&nbsp;&nbsp; jar cvf javactest.jar classes </p>
<p><span style="font-family: 宋体">这里有问题，</span>jar<span style="font-family: 宋体">中会将</span>classes<span style="font-family: 宋体">目录加入</span></p>
<p style="text-indent: 26.35pt"><strong>iii) </strong><span style="font-family: 宋体">以自己的</span>manifest.mf<span style="font-family: 宋体">来创建</span>jar<span style="font-family: 宋体">，在</span>test<span style="font-family: 宋体">目录下创建</span>manifest.mf<span style="font-family: 宋体">文件</span></p>
<p style="text-indent: 26.25pt">cd test</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; jar cvfm javactest.jar manifest.mf &#8211;C classes . </p>
<p style="text-indent: 10.5pt"><span style="font-family: 宋体">（</span>2<span style="font-family: 宋体">）列出</span>jar<span style="font-family: 宋体">中内容</span></p>
<p style="text-indent: 10.5pt">&nbsp;&nbsp; cd test</p>
<p style="text-indent: 10.5pt">&nbsp;&nbsp; jar tvf javactest.jar</p>
<p style="text-indent: 10.5pt"><span style="font-family: 宋体">（</span>3<span style="font-family: 宋体">）提取</span>jar<span style="font-family: 宋体">中内容</span></p>
<p style="text-indent: 10.5pt">&nbsp;&nbsp; cd test</p>
<p style="text-indent: 10.5pt">&nbsp;&nbsp; jar xvf javactest.jar<span style="font-size: 10pt; color: black"> META-INF/MANIFEST.MF</span></p>
<p>&nbsp;<span style="font-family: 宋体">（</span>3<span style="font-family: 宋体">）更新</span>jar</p>
<p style="text-indent: 21pt">cd test</p>
<p style="text-indent: 21pt">jar &#8211;uvf javactest.jar images/icon_button.gif </p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">加入</span>images/icon_button.gif</p>
<p style="text-indent: 21pt"><span style="background: yellow; font-family: 宋体">注意</span><span style="font-family: 宋体">：不能加入</span><span style="font-size: 10pt; color: black">META-INF/MANIFEST.MF</span></p>
<p style="text-indent: 15pt"><span style="font-size: 10pt; color: black; font-family: 宋体">（</span><span style="font-size: 10pt; color: black">4</span><span style="font-size: 10pt; color: black; font-family: 宋体">）更新</span><span style="font-size: 10pt; color: black">MANIFEST.MF</span></p>
<p style="text-indent: 21.75pt"><span style="font-family: 宋体">修改</span><span style="font-size: 10pt; color: black">MANIFEST.MF,</span><span style="font-size: 10pt; color: black; font-family: 宋体">加入</span></p>
<p style="text-indent: 21.75pt"><span style="font-size: 10pt; background: yellow; color: black">Main-Class: javactest.pa.A</span></p>
<p style="text-indent: 21.75pt"><span style="font-size: 10pt; background: yellow; color: black; font-family: 宋体">注意</span><span style="font-size: 10pt; color: black; font-family: 宋体">：</span><span style="font-size: 10pt; color: black">Main-Class</span><span style="font-size: 10pt; color: black; font-family: 宋体">后的冒号后必须有空格，并且最后必须换行</span></p>
<p style="text-indent: 21.75pt"><span style="font-size: 10pt; color: black">cd test</span></p>
<p style="text-indent: 21.75pt"><span style="font-size: 10pt; color: black">jar uvfm javactest.jar META-INF/MANIFEST.MF</span></p>
<p><span style="font-family: 宋体">（三）关于</span>java</p>
<p>&nbsp;&nbsp; java &#8211;jar javactest.jar</p>
<p style="text-indent: 15.75pt">java -cp javactest.jar javactest.pa.A</p>
<p><span style="font-family: 宋体">参考资料</span></p>
<p><a href="http://www.idevelopment.info/data/Programming/java/miscellaneous_java/Using_CLASSPATH_and_SOURCEPATH.html">http://www.idevelopment.info/data/Programming/java/miscellaneous_java/Using_CLASSPATH_and_SOURCEPATH.html</a></p>
<p><a href="http://www.idevelopment.info/data/Programming/java/miscellaneous_java/Using_CLASSPATH_and_Other_APIs.pdf">http://www.idevelopment.info/data/Programming/java/miscellaneous_java/Using_CLASSPATH_and_Other_APIs.pdf</a></p>
<p><a href="http://www.idevelopment.info/data/Programming/java/miscellaneous_java/Using_the_JAR_Utility.pdf">http://www.idevelopment.info/data/Programming/java/miscellaneous_java/Using_the_JAR_Utility.pdf</a></p>
<p><a href="http://java.sun.com/j2se/1.4.2/docs/tooldocs/windows/java.html">http://java.sun.com/j2se/1.4.2/docs/tooldocs/windows/java.html</a></p>
<p><a href="http://java.sun.com/j2se/1.4.2/docs/tooldocs/windows/javac.html">http://java.sun.com/j2se/1.4.2/docs/tooldocs/windows/javac.html</a></p>
<p><a href="http://java.sun.com/j2se/1.5.0/docs/guide/jar/jar.html">http://java.sun.com/j2se/1.5.0/docs/guide/jar/jar.html</a></p>
<h1>2 jar file specification</h1>
<p><a href="http://java.sun.com/javase/6/docs/technotes/guides/jar/jar.html">http://java.sun.com/javase/6/docs/technotes/guides/jar/jar.html</a></p>
<p><strong></strong>&nbsp;</p>
<img src ="http://www.blogjava.net/shypwang/aggbug/187633.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/shypwang/" target="_blank">妖人</a> 2008-03-21 10:07 <a href="http://www.blogjava.net/shypwang/articles/187633.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ConnectionPool,Dao,DataSource关系</title><link>http://www.blogjava.net/shypwang/articles/154624.html</link><dc:creator>妖人</dc:creator><author>妖人</author><pubDate>Sun, 21 Oct 2007 00:29:00 GMT</pubDate><guid>http://www.blogjava.net/shypwang/articles/154624.html</guid><wfw:comment>http://www.blogjava.net/shypwang/comments/154624.html</wfw:comment><comments>http://www.blogjava.net/shypwang/articles/154624.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/shypwang/comments/commentRss/154624.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/shypwang/services/trackbacks/154624.html</trackback:ping><description><![CDATA[1、ConnectionPool,Dao,DataSource关系<br />
ConnectionPool 为了管理Connection<br />
Dao 为了将Business logic和Database logic 分离<br />
将ConnectionPool放在naming space 中,是为了可以Globally取得ConnectionPool<br />
<br />
在j2ee开发中，一般用DataSource subsystem取代ConnectionPool,并且注册在JNDI中，Dao使用DataSource。
<br />
DataSource也是用来管理Connection的
<img src ="http://www.blogjava.net/shypwang/aggbug/154624.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/shypwang/" target="_blank">妖人</a> 2007-10-21 08:29 <a href="http://www.blogjava.net/shypwang/articles/154624.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>What is the difference between the getRequestDispatcher(String) and getNamedDispatcher(String) methods in the ServletContext Class?</title><link>http://www.blogjava.net/shypwang/articles/154621.html</link><dc:creator>妖人</dc:creator><author>妖人</author><pubDate>Sun, 21 Oct 2007 00:19:00 GMT</pubDate><guid>http://www.blogjava.net/shypwang/articles/154621.html</guid><wfw:comment>http://www.blogjava.net/shypwang/comments/154621.html</wfw:comment><comments>http://www.blogjava.net/shypwang/articles/154621.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/shypwang/comments/commentRss/154621.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/shypwang/services/trackbacks/154621.html</trackback:ping><description><![CDATA[<strong>What is the difference between the getRequestDispatcher(String) and getNamedDispatcher(String) methods in the ServletContext Class?</strong>
<p>
<strong>NamedDispatcher</strong>
</p>
<p>
Returns a RequestDispatcher object that acts as a wrapper for the named servlet.
</p>
<p>
getNamedDispatcher(String) method takes the name of the Servlet as parameter which is declared via Deployment descriptor.
</p>
<p>
<em>Example: Deployment Descriptor</em>
</p>
<p>
<code><br />
<span class="xml_tag_symbols">&lt;</span><span class="xml_tag_name">servlet</span><span class="xml_tag_symbols">&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;<span class="xml_tag_symbols">&lt;</span><span class="xml_tag_name">servlet-name</span><span class="xml_tag_symbols">&gt;</span>FirstServlet<span class="xml_tag_symbols">&lt;/</span><span class="xml_tag_name">servlet-name</span><span class="xml_tag_symbols">&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;<span class="xml_tag_symbols">&lt;</span><span class="xml_tag_name">servlet-class</span><span class="xml_tag_symbols">&gt;</span>com.example.ServletExample<span class="xml_tag_symbols">&lt;/</span><span class="xml_tag_name">servlet-class</span><span class="xml_tag_symbols">&gt;</span><br />
<span class="xml_tag_symbols">&lt;/</span><span class="xml_tag_name">servlet</span><span class="xml_tag_symbols">&gt;</span><br />
</code>
</p>
<p>
</p>
<pre> RequestDispatcher dispatch = request.getNamedDispatcher(?FirstServlet<a href="http://faq.javaranch.com/edit?FirstServlet">?</a>?);</pre>
dispatch.forward(request, response);
<p>
<strong>Note:</strong>
A servlet instance can determine its name using
servletConfig.getServletName(); This method returns the name of the
class that implements the <em>Servlet</em> interface or extends the <em>HttpServlet</em> class.
</p>
<p>
<strong>RequestDispatcher</strong>
</p>
<p>
Returns a RequestDispatcher object that acts as a wrapper for the resource located at the given path.
</p>
<p>
</p>
<pre> RequestDispatcher dispatch = request.getRequestDispatcher("/tes");</pre>
<p>
Here "/tes" represents the url-pattern element value of the servlet class.
</p>
<p>
<code><br />
<span class="xml_tag_symbols">&lt;</span><span class="xml_tag_name">servlet-mapping</span><span class="xml_tag_symbols">&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;<span class="xml_tag_symbols">&lt;</span><span class="xml_tag_name">servlet-name</span><span class="xml_tag_symbols">&gt;</span>Test<span class="xml_tag_symbols">&lt;/</span><span class="xml_tag_name">servlet-name</span><span class="xml_tag_symbols">&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;<span class="xml_tag_symbols">&lt;</span><span class="xml_tag_name">url-pattern</span><span class="xml_tag_symbols">&gt;</span>/tes<span class="xml_tag_symbols">&lt;/</span><span class="xml_tag_name">url-pattern</span><span class="xml_tag_symbols">&gt;</span><br />
<span class="xml_tag_symbols">&lt;/</span><span class="xml_tag_name">servlet-mapping</span><span class="xml_tag_symbols">&gt;</span><br />
</code>
</p>
<p>
It represents the path of the servlet class. Since both the base as
well as target servlet are in the same package structure by just
specifying the url-pattern element value we will be able to access the
target servlet.
</p>
<p>
We shouldn't specify the entire path like
</p>
<p>
</p>
<pre> String str = "/WEB-INF/classes/com/example/posr/Test"</pre>
<p>
</p>
<pre> RequestDispatcher dispatch = request.getRequestDispatcher(str);</pre>
<p>
To forward a request to a JSP page we use
</p>
<p>
</p>
<pre> RequestDispatcher dispatch = request.getRequestDispatcher("/TestJspOne.jsp");</pre>
Here "/TestJspOne.jsp" the slash denotes the Jsp page is at the root of the application.
<img src ="http://www.blogjava.net/shypwang/aggbug/154621.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/shypwang/" target="_blank">妖人</a> 2007-10-21 08:19 <a href="http://www.blogjava.net/shypwang/articles/154621.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Web Vs Application Server </title><link>http://www.blogjava.net/shypwang/articles/154620.html</link><dc:creator>妖人</dc:creator><author>妖人</author><pubDate>Sun, 21 Oct 2007 00:15:00 GMT</pubDate><guid>http://www.blogjava.net/shypwang/articles/154620.html</guid><wfw:comment>http://www.blogjava.net/shypwang/comments/154620.html</wfw:comment><comments>http://www.blogjava.net/shypwang/articles/154620.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/shypwang/comments/commentRss/154620.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/shypwang/services/trackbacks/154620.html</trackback:ping><description><![CDATA[<h1 class="faqTitle">
<a href="http://faq.javaranch.com/search?WebVsApplicationServer">Web Vs Application Server</a>&nbsp;&nbsp;&nbsp;
<acronym title="post to del.ici.ous">
<img src="http://faq.javaranch.com/images/delicious-16x16.gif" onclick="window.open('http://del.icio.us/post?noui;jump=close;v=4;url='+encodeURIComponent('http://faq.javaranch.com/java/WebVsApplicationServer')+';title='+encodeURIComponent('JavaRanch FAQ: Web Vs Application Server'),'del.icio.us','toolbar=no,width=700,height=400')" border="0"  alt="" />
</acronym>
</h1>
<br />
<br />
<em>What's the difference between a web server, an application server, and a servlet container?</em>
<p>
<em>Is Tomcat an application server?</em>
</p>
<p>
<em>What's the difference between Tomcat and JBoss/Geronimo?</em>
</p>
<p>
In the strictest sense, one could say: A web server serves up static
HTML pages and nothing else. Tomcat is a Servlet/JSP container, and
'Java application servers' are those which support the full JEE
(formerly J2EE) stack.
</p>
<p>The distinctions between these terms, however, have always been
blurry, and continue to become more so over time, and will vary
depending on where and with whom your discussion takes place. To
understand this requires a little history lesson.
</p>
<p>Tomcat started its life as the JServ module for Apache HTTPD
(now known as the Apache web server).
It was only a servlet container and was incapable of handling web
requests on its own. When combined, HTTPD would handle all web
requests, would serve up all the static content on its own and forward
any dynamic requests to JServ. Httpd was the web server and JServ was
the servlet container.
</p>
<p>Eventually, JServ was replaced by the Tomcat application
server, and a connector was added that allowed Tomcat to operate as a
standalone web/application server. At the time Tomcat alone was not
fast enough for use in heavy traffic production environments, and
didn't support SSL so it was standard practice to combine Tomcat with
the Apache web server; much in the same way that JServ and httpd were
used. This is still not uncommon today and there are still valid
reasons for wanting to do so.
</p>
<p>Over time, both Tomcat and the Java Virtual machine, with its
Just In Time compiler, have made huge gains in performance, and in many
cases running Tomcat as a standalone application server is just as fast
or faster than running it in conjunction with the Apache web server.
(Testing your application in both configurations under load is the only
way to know for sure). Tomcat also has full support for SSL.
</p>
<p>
So, as you can see, in the case of Tomcat, the lines between application server and web server have blurred over the years.
</p>
<p>The lines are also somewhat blurry when you look at the Apache
web server itself. It has been hosting large commercial applications
using CGI (Common Gateway Interface) for over a dozen years. In
addition, many modules, such as the one that allows the popular PHP
scripting language to run natively, have become almost standard in an
Apache web server installation.
</p>
<p>Another popular web/application server, Microsoft's IIS
(Internet Information Server), is also used as both a web server and
application server. It too can be configured to pass requests for
dynamic content to Tomcat via an ISAPI filter. It can also be
configured to support popular scripting languages such as PHP, and has
native support for Microsoft's own ASP and ASP.NET platforms. Here
also, the distinction between web server and application server is
blurry. </p>
<p>
In some circles, in order to qualify as a "Java application server" the
server must support the entire JEE (formerly known as J2EE) stack.
Tomcat does not do this. It does not support EJB (Enterprise Java
Beans), amongst other APIs. JBoss and Apache's Geronimo application
server do support the entire JEE stack. Their servlet and JSP
capabilities come from an embedded version of Tomcat (or some other
servlet container).
</p>
<p>Since one actually contains and relies on the other, the
question "Which is better - Tomcat or JBoss" or the phrase, "Tomcat vs
JBoss" is not answerable. They are not legitimate comparisons.
</p>
<p>
Many large, commercial applications are hosted on Tomcat; both with and without an external HTTP web server and without EJB.
</p>
To sum it up, the terms do exist but need to be considered in
the context of their use in order to understand what they really mean.
<img src ="http://www.blogjava.net/shypwang/aggbug/154620.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/shypwang/" target="_blank">妖人</a> 2007-10-21 08:15 <a href="http://www.blogjava.net/shypwang/articles/154620.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>UTF-8 字符处理在 Web 开发中的应用</title><link>http://www.blogjava.net/shypwang/articles/153237.html</link><dc:creator>妖人</dc:creator><author>妖人</author><pubDate>Tue, 16 Oct 2007 05:12:00 GMT</pubDate><guid>http://www.blogjava.net/shypwang/articles/153237.html</guid><wfw:comment>http://www.blogjava.net/shypwang/comments/153237.html</wfw:comment><comments>http://www.blogjava.net/shypwang/articles/153237.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/shypwang/comments/commentRss/153237.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/shypwang/services/trackbacks/153237.html</trackback:ping><description><![CDATA[<table border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr valign="top">
            <td width="100%">
            <h1>UTF-8 字符处理在 Web 开发中的应用</h1>
            <img alt="" src="http://www.ibm.com/i/c.gif" class="display-img" height="6" width="1" /></td>
            <td class="no-print" width="192"><img alt="developerWorks" src="http://www.ibm.com/developerworks/i/dw.gif" height="18" width="192" /></td>
        </tr>
    </tbody>
</table>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr valign="top">
            <td width="10"><img alt="" src="http://www.ibm.com/i/c.gif" height="1" width="10" /></td>
            <td width="100%">
            <table class="no-print" align="right" border="0" cellpadding="0" cellspacing="0" width="160">
                <tbody>
                    <tr>
                        <td width="10"><img alt="" src="http://www.ibm.com/i/c.gif" height="1" width="10" /></td>
                        <td>
                        <table border="0" cellpadding="0" cellspacing="0" width="150">
                            <tbody>
                                <tr>
                                    <td class="v14-header-1-small">文档选项</td>
                                </tr>
                            </tbody>
                        </table>
                        <table class="v14-gray-table-border" border="0" cellpadding="0" cellspacing="0">
                            <tbody>
                                <tr>
                                    <td class="no-padding" width="150"><img alt="" src="http://www.ibm.com/i/c.gif" height="1" width="8" /><input value="Web 应用要适应多语言的需求。不同国家的用户应该可以输入本国语言的字符， 同时 Web 应用又应该可以根据不同的区域设置来用多国语言显示页面。 当前，不同的语言有不同的编码方式来显示对应的语言信息，例如中文可以用 GB2312 编码来显示,日文可以用 Shift-JIS 编码来显示。但 UTF-8 编码方式几乎可以包括了所有的语言字符。用 UTF-8 编码来处理 Web 应用信息的输入和显示可以使不同 Web 应用之间的信息交互标准化，并且可以简化应用的开发过程。" name="body" type="hidden" /><input name="subject" value="UTF-8 字符处理在 Web 开发中的应用" type="hidden" /><input name="lang" value="cn" type="hidden" /><noscript>
                                    <tr valign="top">
                                        <td width="8"><img alt="" height="1" width="8" src="//www.ibm.com/i/c.gif" /></td>
                                        <td width="16"><img alt="" width="16" height="16" src="//www.ibm.com/i/c.gif" /></td>
                                        <td class="small" width="122">
                                        <p><span class="ast">未显示需要 JavaScript
                                        的文档选项</span></p>
                                        </td>
                                    </tr>
                                    </noscript>
                                    <table border="0" cellpadding="0" cellspacing="0" width="143">
                                        <form action="https://www.ibm.com/developerworks/secure/email-it.jsp" name="email">
                                        </form>
                                        <script language="JavaScript" type="text/javascript">
                                        <!-- document.write('
                                        <tr valign="top">
                                            <td width="8"><img src="//www.ibm.com/i/c.gif" width="8" height="1" alt="" /></td>
                                            <td width="16"><img src="//www.ibm.com/i/v14/icons/em.gif" height="16" width="16" vspace="3" alt="将此页作为电子邮件发送"  /></td>
                                            <td width="122">
                                            <p><a class="smallplainlink" href="javascript:document.email.submit();"><strong>将此页作为电子邮件发送</strong></a></p>
                                            </td>
                                        </tr>
                                        ');
                                        //-->
                                        </script>
                                        <tbody>
                                            <tr valign="top">
                                                <td width="8"><img src="http://www.ibm.com/i/c.gif" alt="" height="1" width="8" /></td>
                                                <td width="16"><img src="http://www.ibm.com/i/v14/icons/em.gif" alt="将此页作为电子邮件发送" height="16" vspace="3" width="16" /></td>
                                                <td width="122">
                                                <p><a class="smallplainlink" href="javascript:document.email.submit();"><strong>将此页作为电子邮件发送</strong></a></p>
                                                </td>
                                            </tr>
                                        </tbody>
                                    </table>
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                        <!--start RESERVED FOR FUTURE USE INCLUDE FILES--><!-- this content will be automatically generated across all content areas -->
                        <br />
                        <!--end RESERVED FOR FUTURE USE INCLUDE FILES--><br />
                        </td>
                    </tr>
                </tbody>
            </table>
            <p>级别： 初级</p>
            <p><a href="http://www.ibm.com/developerworks/cn/web/wa-lo-utf8/#author">殷 健</a>, 软件工程师，IBM CSDL<br />
            </p>
            <p>2006 年  7 月  27 日</p>
            <blockquote>Web
            应用要适应多语言的需求。不同国家的用户应该可以输入本国语言的字符， 同时 Web 应用又应该可以根据不同的区域设置来用多国语言显示页面。
            当前，不同的语言有不同的编码方式来显示对应的语言信息，例如中文可以用 GB2312 编码来显示,日文可以用 Shift-JIS 编码来显示。但
            UTF-8 编码方式几乎可以包括了所有的语言字符。用 UTF-8 编码来处理 Web 应用信息的输入和显示可以使不同 Web
            应用之间的信息交互标准化，并且可以简化应用的开发过程。</blockquote><!--start RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters -->
            <!--end RESERVED FOR FUTURE USE INCLUDE FILES-->
            <p><a name="N1003F"><span class="atitle">UTF-8 编码介绍</span></a></p>
            <p>UTF-8 编码是一种被广泛应用的编码，这种编码致力于把全球的语言纳入一个统一的编码，目前已经将几种亚洲语言纳入。UTF 代表 UCS Transformation Format.</p>
            <p>UTF-8 采用变长度字节来表示字符，理论上最多可以到 6 个字节长度。UTF-8 编码兼容了 ASC II(0-127)， 也就是说 UTF-8 对于 ASC II 字符的编码是和 ASC II 一样的。对于超过一个字节长度的字符，才用以下编码规范：</p>
            <p>左边第一个字节1的个数表示这个字符编码字节的位数，例如两位字节字符编码样式为为：110xxxxx 10xxxxxx；
            三位字节字符的编码样式为：1110xxxx 10xxxxxx 10xxxxxx.；以此类推，六位字节字符的编码样式为：1111110x
            10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx。 xxx
            的值由字符编码的二进制表示的位填入。只用最短的那个足够表达一个字符编码的多字节串。例如：</p>
            <p>Unicode 字符： 00 A9（版权符号） = 1010 1001， UTF-8 编码为：11000010 10101001 =
            0x C2 0xA9; 字符 22 60 (不等于符号) = 0010 0010 0110 0000， UTF-8 编码为：11100010
            10001001 10100000 = 0xE2 0x89 0xA0</p>
            <br />
            <table border="0" cellpadding="0" cellspacing="0" width="100%">
                <tbody>
                    <tr>
                        <td><img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" /><br />
                        <img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" /></td>
                    </tr>
                </tbody>
            </table>
            <table class="no-print" align="right" cellpadding="0" cellspacing="0">
                <tbody>
                    <tr align="right">
                        <td><img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" /><br />
                        <table border="0" cellpadding="0" cellspacing="0">
                            <tbody>
                                <tr>
                                    <td valign="middle"><img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" /><br />
                                    </td>
                                    <td align="right" valign="top"><a href="http://www.ibm.com/developerworks/cn/web/wa-lo-utf8/#main" class="fbox"><strong>回页首</strong></a></td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <br />
            <p><a name="N10051"><span class="atitle">HTTP 通讯协议</span></a></p>
            <p><a name="N10057"><span class="smalltitle">HTTP 请求</span></a></p>
            <p>在 HTTP
            通讯中，在客户端发出的请求报文中，首先设置的是方法。方法是用来告诉服务器客户端发起的动作请求。在请求的报文头部，客户端还可以同时发送附加的信息，
            比如客户端使用的浏览器和客户端可以解释的内容类型等。这些信息可以被服务器端应用程序使用以生成响应。下面是一个 HTTP 请求消息的示例：</p>
            <br />
            <a name="N10060"><strong>图1. HTTP 请求消息头</strong></a><br />
            <table border="0" cellpadding="0" cellspacing="0" width="100%">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">GET /intro.html HTTP/1.0<br />
                        User-Agent: Mozilla/4.0 (compatible; MSIE 4.0; Windows 95)<br />
                        Accept: image/gif, image/jpeg, text/*, */*<br />
                        Accept-language : zh<br />
                        Accept-Charset: iso-8859-1<br />
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>这个请求通过 GET 方法来获取资源 /intro.htm。User-Agent 提供了客户端浏览器的信息，同时 Accept
            提供了客户端可以接受的媒体类型。Accep-language 指出了客户端浏览器的首选语言， Accept-Charset
            提供了浏览器的首选字符集，服务器端程序能够根据客户端的要求来生成需要的响应。
            用户可以通过配置浏览器来设置首选语言。以 IE 为示例如下：</p>
            <br />
            <a name="N1006F"><strong>图2. 浏览器首选语言设置</strong></a><br />
            <img alt="图2. 浏览器首选语言设置" src="http://www.ibm.com/developerworks/cn/web/wa-lo-utf8/images/image002.jpg" border="0" height="280" width="432" />
            <br />
            <p>当浏览器发出请求后，可以通过以下代码来读取客户端浏览器的首选语言和国家代码。</p>
            <br />
            <a name="N10082"><strong>图3. 服务器端 Servlet 读取浏览器首选国家和语言</strong></a><br />
            <table border="0" cellpadding="0" cellspacing="0" width="100%">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">protected void insertproc(HttpServletRequest req, HttpServletResponse resp)<br />
                        throws ServletException, IOException{<br />
                        Locale reqLocal = req.getLocale();<br />
                        System.out.println("The country is :" + reqLocal.getCountry());<br />
                        System.out.println("The language is :" + reqLocal.getLanguage());<br />
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>服务器端的输出结果为：</p>
            <br />
            <a name="N1008F"><strong>图4. 服务器端 Servlet 读取浏览器首选国家和语言结果</strong></a><br />
            <table border="0" cellpadding="0" cellspacing="0" width="100%">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">[06-3-10 14:56:32:516 CST] 6ce078f9 SystemOut     O The country is :CN<br />
                        [06-3-10 14:56:32:516 CST] 6ce078f9 SystemOut     O The language is :zh<br />
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p><a name="N10099"><span class="smalltitle">HTTP 响应</span></a></p>
            <p>当服务器端收到请求后，会处理请求并发回应答。服务器通过应答消息的头部来指明诸如服务器软件和相应的内容类型等信息。以下是一个应答消息头的示例：</p>
            <br />
            <a name="N100A2"><strong>图5.HTTP 应答消息头</strong></a><br />
            <table border="0" cellpadding="0" cellspacing="0" width="100%">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">Date: Saturday, 23-May-98 03:25:12 GMT<br />
                        Server: JavaWebServer/1.1.1<br />
                        MIME-version: 1.0<br />
                        Content-type: text/html; charset=UTF-8<br />
                        Content-length: 1029<br />
                        Last-modified: Thursday, 7-May-98 12:15:35 GMT<br />
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>Content-type 表明了应答消息的 MIME 类型和应答消息体的字符集，浏览器会用相应的字符集来显示消息内容。例如，在以上示例中字符集是 UTF-8，浏览器会用 UTF-8 编码来解析和现实返回的消息体。同时页面输入也会被用 UTF-8 编码。</p>
            <br />
            <table border="0" cellpadding="0" cellspacing="0" width="100%">
                <tbody>
                    <tr>
                        <td><img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" /><br />
                        <img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" /></td>
                    </tr>
                </tbody>
            </table>
            <table class="no-print" align="right" cellpadding="0" cellspacing="0">
                <tbody>
                    <tr align="right">
                        <td><img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" /><br />
                        <table border="0" cellpadding="0" cellspacing="0">
                            <tbody>
                                <tr>
                                    <td valign="middle"><img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" /><br />
                                    </td>
                                    <td align="right" valign="top"><a href="http://www.ibm.com/developerworks/cn/web/wa-lo-utf8/#main" class="fbox"><strong>回页首</strong></a></td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <br />
            <p><a name="N100AF"><span class="atitle">Web 页面显示编码</span></a></p>
            <p>可以通过以下几种方式来设置内容类型。</p>
            <p><a name="N100B8"><span class="smalltitle">在 HTML 中设置页面的编码方式</span></a></p>
            <p>如果被访问的是一个静态的 HTML 页面。可以通过以下方式来设置页面的编码方式。</p>
            <br />
            <a name="N100C1"><strong>图6. 设置页面编码的静态 HTML 文件</strong></a><br />
            <table border="0" cellpadding="0" cellspacing="0" width="100%">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"&gt;<br />
                        &lt;HTML&gt;<br />
                        &lt;HEAD&gt;<br />
                        &lt;META http-equiv="Content-Type" content="text/html; charset=UTF-8"&gt;<br />
                        &lt;TITLE&gt;example.html&lt;/TITLE&gt;<br />
                        &lt;/HEAD&gt;<br />
                        &lt;BODY&gt;<br />
                        &lt;/BODY&gt;<br />
                        &lt;/HTML&gt;<br />
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>标记"&lt;META http-equiv="Content-Type" content="text/html;
            charset=UTF-8"&gt;" 将应答消息头中 Content_type 设置为"text/html; charset=UTF-8".</p>
            <p><a name="N100CE"><span class="smalltitle">在 Servlet 中设置页面显示编码方式</span></a></p>
            <p>在 Servlet 中，我们可以通过以下方式来设置应答消息的内容类型。</p>
            <br />
            <a name="N100D7"><strong>图7.设置页面编码的 Servlet 片断</strong></a><br />
            <table border="0" cellpadding="0" cellspacing="0" width="100%">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">protected void insertproc(HttpServletRequest req, HttpServletResponse resp)<br />
                        throws ServletException, IOException{<br />
                        resp.setContentType("text/html;charset=UTF-8");<br />
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>代码行"resp.setContentType("text/html;charset=UTF-8");"将应答消息头中 Content_type 设置为"text/html; charset=UTF-8"。	</p>
            <p><a name="N100E4"><span class="smalltitle">在 JSP 中设置页面显示编码方式</span></a></p>
            <p>我们通过以下示例说明如何在 JSP 中设置页面的编码格式。</p>
            <br />
            <a name="N100ED"><strong>图8. 设置业面编码的 JSP 页面指令</strong></a><br />
            <table border="0" cellpadding="0" cellspacing="0" width="100%">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">&lt;%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%&gt;<br />
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>在这行的页面指令中的"text/html; charset=UTF-8"将应答消息中的"Content-type" 设置为"text/html; charset=UTF-8"。</p>
            <p>"pageEncoding"只是指明了 JSP 页面本身的编码格式，指明了 JSP
            是以什么编码方式保存。容器在读取文件时将起转化为内部使用的 Unicode. 当应答发送回至浏览器时，容器会将内部使用的 Unicode
            转化为在 Content-type 中指定的字符集。</p>
            <p>如果没有指定 PageEncoding，可以通过使用 Content-type 指定的字符集来解释 JSP 页面字节。</p>
            <p>为了能正常显示 UTF-8 编码的字符，要满足以下两个条件：</p>
            <p>1.	通知浏览器应答消息使用的字符集。</p>
            <p>2.	配置浏览器使其能有正常显示 UTF-8 编码的字体。</p>
            <br />
            <table border="0" cellpadding="0" cellspacing="0" width="100%">
                <tbody>
                    <tr>
                        <td><img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" /><br />
                        <img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" /></td>
                    </tr>
                </tbody>
            </table>
            <table class="no-print" align="right" cellpadding="0" cellspacing="0">
                <tbody>
                    <tr align="right">
                        <td><img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" /><br />
                        <table border="0" cellpadding="0" cellspacing="0">
                            <tbody>
                                <tr>
                                    <td valign="middle"><img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" /><br />
                                    </td>
                                    <td align="right" valign="top"><a href="http://www.ibm.com/developerworks/cn/web/wa-lo-utf8/#main" class="fbox"><strong>回页首</strong></a></td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <br />
            <p><a name="N10109"><span class="atitle">Web 页面输入编码</span></a></p>
            <p>HTML 的表单可以接受非西欧语言字符的输入。当需要创建一个需要接受非西欧语言字符输入的表单时，必须通知浏览器应该为用户输入使用哪个字符集，我们可以通过设置 page 指令的 contentType 属性来设置。</p>
            <p>我们需要注意的是，当表单被提交后，浏览器会将表单字段值转换为指定字符集对应的字节值，然后根据 HTTP 标准 URL
            编码方案对结果字节进行编码。当使用 ISO-8859-1 编码时，任何 a 到 z， A 到 Z 和 0 到 9
            之外的字符都会被转化为十六进制格式的字节值，并在前面加上一个百分号（%）.例如，如果表单的字符集被设为 UTF-8,
            字符"中文"被传递的编码格式为："%E4%B8%AD%E6%96%87"。为了对输入的信息进行处理，容器必须知道浏览器是使用什么字符集对输入进行
            编码的。问题是当今多数的浏览器并不提供这种信息，因此你必须自己提供这种信息，并告诉容器用哪个字符集对输入进行解码。</p>
            <p><a name="N10115"><span class="smalltitle">页面输入编码设定</span></a></p>
            <p>在本文第3部分中说明了如何设置页面的显示编码，在设置页面编码的同时，也就指定了页面的输入方式。如果页面的显示被设置为UTF-8，那么用户所有的页面输入都会按照 UTF-8 编码。</p>
            <p><a name="N1011E"><span class="smalltitle">页面输入输出过程编码设置</span></a></p>
            <p>服务器端程序在读取表单输入之前要设定输入编码。我们可以看一下示例。</p>
            <p>以下是一个用来提示用户输入的 JSP 页面：</p>
            <br />
            <a name="N1012A"><strong>图9. 用以界面输入的 JSP 页面</strong></a><br />
            <table border="0" cellpadding="0" cellspacing="0" width="100%">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">&lt;%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%&gt;<br />
                        &lt;HTML&gt;<br />
                        &lt;HEAD&gt;<br />
                        &lt;TITLE&gt;insertdb.jsp&lt;/TITLE&gt;<br />
                        &lt;/HEAD&gt;<br />
                        &lt;BODY&gt;<br />
                        &lt;P&gt;<br />
                        &lt;FORM METHOD=POST ACTION="./InsertDbProcDs"&gt;<br />
                        &lt;TABLE&gt;<br />
                        &lt;TR&gt;<br />
                        &lt;TD&gt;Name:&lt;/TD&gt;<br />
                        &lt;TD&gt;&lt;input type="text" name="col2" value=""&gt;&lt;/TD&gt;<br />
                        &lt;TR&gt;<br />
                        &lt;TD&gt;&lt;INPUT type="submit" value="submit"&gt;&lt;/TD&gt;<br />
                        &lt;/TR&gt;<br />
                        &lt;/TR&gt;<br />
                        &lt;/TABLE&gt;<br />
                        &lt;/RORM&gt;<br />
                        &lt;/P&gt;<br />
                        &lt;/BODY&gt;<br />
                        &lt;/HTML&gt;<br />
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>页面指令元素的属性 Content-type 值为"text/html; charset=UTF-8"，这会向浏览器指明页面是按照
            UTF-8 编码的，并且所有用户通过页面的输入也会按照 UTF-8 编码。被 Action 所触发的 Servlet 如下例所示。</p>
            <br />
            <a name="N10137"><strong>图10. 用以按 UTF-8 读取输入并输出的 Servlet</strong></a><br />
            <table border="0" cellpadding="0" cellspacing="0" width="100%">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">    protected void insertproc(HttpServletRequest req, HttpServletResponse resp)<br />
                        throws ServletException, IOException{<br />
                        String test1 = req.getParameter("col2");<br />
                        PrintWriter out = resp.getWriter();<br />
                        resp.setContentType("text/html;charset=UTF-8");<br />
                        out.println("&lt;HTML&gt;");<br />
                        out.println("The input is " + test1);<br />
                        out.println("&lt;/HTML&gt;");<br />
                        <br />
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>通过表单页面输入"中文"并提交表单，得到的结果为：</p>
            <br />
            <a name="N10146"><strong>图11.正确显示结果的页面</strong></a><br />
            <img alt="图11.正确显示结果的页面" src="http://www.ibm.com/developerworks/cn/web/wa-lo-utf8/images/image004.jpg" border="0" height="353" width="554" />
            <br />
            <p>如果我们注释掉语句：resp.setContentType("text/html;charset=UTF-8")， 如下例：</p>
            <br />
            <a name="N10159"><strong>图12. 用以按非 UTF-8 读取输入并输出的 Servlet</strong></a><br />
            <table border="0" cellpadding="0" cellspacing="0" width="100%">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">protected void insertproc(HttpServletRequest req, HttpServletResponse resp)<br />
                        throws ServletException, IOException{<br />
                        String test1 = req.getParameter("col2");<br />
                        PrintWriter out = resp.getWriter();<br />
                        //resp.setContentType("text/html;charset=UTF-8")<br />
                        out.println("&lt;HTML&gt;");<br />
                        out.println("The input is " + test1);<br />
                        out.println("&lt;/HTML&gt;");<br />
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>输入"中文"并提交表单，得到的结果为：</p>
            <br />
            <a name="N10168"><strong>图13. 错误显示输入结果的页面</strong></a><br />
            <img alt="图13. 错误显示输入结果的页面" src="http://www.ibm.com/developerworks/cn/web/wa-lo-utf8/images/image006.jpg" border="0" height="352" width="553" />
            <br />
            <p>页面不能正确显示 UTF-8 编码的字符。</p>
            <p>在被触发的 Servlet 中通过设置 resp.setContentType("text/html;charset=UTF-8")
            来向浏览器指明输出的编码字符集为 UTF-8，浏览器会用正确的字符集来显示输出。如果 Servlet 中没有显示的调用
            resp.setContentType("text/html;charset=UTF-8")
            来设定输出字符集，浏览器将不能正确的解码和显示输出。</p>
            <br />
            <table border="0" cellpadding="0" cellspacing="0" width="100%">
                <tbody>
                    <tr>
                        <td><img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" /><br />
                        <img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" /></td>
                    </tr>
                </tbody>
            </table>
            <table class="no-print" align="right" cellpadding="0" cellspacing="0">
                <tbody>
                    <tr align="right">
                        <td><img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" /><br />
                        <table border="0" cellpadding="0" cellspacing="0">
                            <tbody>
                                <tr>
                                    <td valign="middle"><img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" /><br />
                                    </td>
                                    <td align="right" valign="top"><a href="http://www.ibm.com/developerworks/cn/web/wa-lo-utf8/#main" class="fbox"><strong>回页首</strong></a></td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <br />
            <p><a name="N1017E"><span class="atitle">结论</span></a></p>
            <p>本文给出了一些在 Web 应用开发中如何显示和输入 UTF-8 编码字符的方法。便于读者在开发实践中参考。</p>
            <br />
            <br />
            <p><a name="resources"><span class="atitle">参考资料 </span></a></p>
            <ul>
                <li><strong>参考资源：</strong><br />
                Java Servlet Programming(<a href="http://www.oreilly.com/">O'Reilly Media. Inc</a>)<br />
                Java server Pages(<a href="http://www.oreilly.com/">O'Reilly Media. Inc</a>)<br />
                <br />
                <br />
                </li>
                <li><strong>相关资源：</strong><br />
                在developerworks 关于字符编码的文章：<br />
                <a href="http://www.ibm.com/developerworks/cn/Websphere/library/techarticles/likejia/0510/">JAVA 编程／WAS 对多语言（双字节）的支持</a><br />
                <a href="http://www.ibm.com/developerworks/cn/java/java_chinese/">Java 编程技术中汉字问题的分析及解决</a><br />
                <a href="http://www.ibm.com/developerworks/cn/java/jsp_dbcsz/">JSP/Servlet 中的汉字编码问题</a></li>
            </ul>
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.blogjava.net/shypwang/aggbug/153237.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/shypwang/" target="_blank">妖人</a> 2007-10-16 13:12 <a href="http://www.blogjava.net/shypwang/articles/153237.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> 关于UTF8,UTF16,UTF32,UTF16-LE,UTF16-BE</title><link>http://www.blogjava.net/shypwang/articles/140846.html</link><dc:creator>妖人</dc:creator><author>妖人</author><pubDate>Wed, 29 Aug 2007 04:32:00 GMT</pubDate><guid>http://www.blogjava.net/shypwang/articles/140846.html</guid><wfw:comment>http://www.blogjava.net/shypwang/comments/140846.html</wfw:comment><comments>http://www.blogjava.net/shypwang/articles/140846.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/shypwang/comments/commentRss/140846.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/shypwang/services/trackbacks/140846.html</trackback:ping><description><![CDATA[<div class="postTitle">		<a  href="http://blog.csdn.net/dengyunze/archive/2004/10/31/160958.aspx"><img  src="http://blog.csdn.net/images/authorship.gif" border="0" height="13" width="15">&nbsp;关于UTF8,UTF16,UTF32,UTF16-LE,UTF16-BE</a>	</div>
<p>&nbsp;&nbsp;<font size="4">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Unicode
是Unicode.org制定的编码标准，目前得到了绝大部分操作系统和编程语言的支持。Unicode.org官方对Unicode的定义是：
Unicode provides a unique number for every
character。可见，Unicode所做的是为每个字符定义了一个相应的数字表示。比如，&#8220;a&#8220;的Unicode值是0x0061,&#8220;一&#8221;的
Unicde值是0x4E00，这是最简单的情况，每个字符用2个字节表示。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Unicode.org定义了百万个以上的
字符，如果将所有的字符用统一的格式表示，需要的是4个字节。&#8220;a&#8220;的Unicode表示就会变成0x00000061，而&#8220;一&#8220;的Unicode值是
0x00004E00。实际上，这就是UTF32，Linux操作系统上所使用的Unicode方案。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;但是，仔细分析可
以发现，其实绝大部分字符只使用2个字节就可以表示了。英文的Unicode范围是0x0000-0x007F，中文的Unicode范围是0x4E00
-0x9F**，真正需要扩展到4个字节来表示的字符少之又少，所以有些系统直接使用2个字节来表示Unicode。比如Windows系统上，
Unicode就是两个字节的。对于那些需要4个字节才能表示的字符，使用一种代理的手法来扩展(其实就是在低两个字节上做一个标记，表示这是一个代理，
需要连接上随后的两个字节，才能组成一个字符)。这样的好处是大量的节约了存取空间，也提高了处理的速度。这种Unicode表示方法就是UTF16。一
般在Windows平台上，提到Unicode,那就是指UTF16了。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;至于UTF16-LE和
UTF16-BE，与计算机的CPU构架有关。LE指Little Endian，而BE指Big
Endian。关于这方面的信息，网上有很多相关的帖子。我们一般的X86系统都是Little
Endian的，可以认为UTF16=UTF16-LE.<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;由于对于欧洲和北美，实际上使用的编码范围在0x0000-
0x00FF之间，只需要一个字符就可以表示所有的字符。即使是使用UTF16来作为内存的存取方式，还是会带来巨大的空间浪费，因此就有了UTF8的编
码方式。这是一种很灵活的编码，对于只需要1个字节的字符，就使用一个字节，对于中日韩等原本需要两个字节才能表示的字符，则通过一个UTF16－
UTF8的算法实现相互之间的转换（一般需要3个字节才能表示），而对于需要4个字节才能表示的字符，UTF8可以扩展到6个字节每个字符。UTF8使用
的算法很有意思，大致映射关系如下：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UTF-32&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UTF8<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font size="3">0x00000000 - 0x0000007F&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0xxxxxxx&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x00000080 - 0x000007FF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 110xxxxx 10xxxxxx <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x00000800 - 0x0000FFFF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1110xxxx 10xxxxxx 10xxxxxx <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x00010000 - 0x001FFFFF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;11110xxx 10xxxxxx 10xxxxxx 10xxxxxx <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x00200000 - 0x03FFFFFF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x04000000 - 0x7FFFFFFF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx&nbsp;</font><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;可以发现这和IP的分址算法很是相像。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;由于UTF8可以方便的转换为UTF16和UTF32（不需要码表，转换算法可以在Unicode.org上找到<a  href="http://ftp//www.unicode.org/Public/PROGRAMS/CVTUTF/">C代码</a>）。而且UTF8在每个操作系统平台上的实现都是一样的，也不存在跨平台的问题，所以UTF8成为跨平台的Unicode很好的解决方案。当然，对于中文来说，由于每个字符需要3个字节才能表示，还是有点浪费的。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
<br><br>
<p id="TBPingURL">Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=160958</p><img src ="http://www.blogjava.net/shypwang/aggbug/140846.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/shypwang/" target="_blank">妖人</a> 2007-08-29 12:32 <a href="http://www.blogjava.net/shypwang/articles/140846.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java数据库连接：JDBC应用说明</title><link>http://www.blogjava.net/shypwang/articles/139365.html</link><dc:creator>妖人</dc:creator><author>妖人</author><pubDate>Sun, 26 Aug 2007 01:09:00 GMT</pubDate><guid>http://www.blogjava.net/shypwang/articles/139365.html</guid><wfw:comment>http://www.blogjava.net/shypwang/comments/139365.html</wfw:comment><comments>http://www.blogjava.net/shypwang/articles/139365.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/shypwang/comments/commentRss/139365.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/shypwang/services/trackbacks/139365.html</trackback:ping><description><![CDATA[<table class="zhi12" align="center" border="0" cellpadding="0" cellspacing="0" width="96%">
    <tbody>
        <tr>
            <td style="font-weight: normal; font-size: 16pt; line-height: normal; font-style: normal; font-variant: normal;" height="49">
            <div align="center"><strong><font color="#003399">Java数据库连接：JDBC应用说明 </font></strong></div>
            </td>
        </tr>
        <tr>
            <td bgcolor="#e2ffff" height="28">
            <div align="center"> <img  src="http://www.chinaitlab.com/www/news/images/c7.gif" height="12" width="17">                            ChinaITLab收集整理 &nbsp; &nbsp;<img  src="http://www.chinaitlab.com/www/news/images/c2.gif" height="12" width="12">
            2005-11-9 &nbsp;<img  src="http://www.chinaitlab.com/www/news/images/c3.gif" height="12" width="13">                            <a rel="nofollow">保存本文</a>                            &nbsp;<img  src="http://www.chinaitlab.com/www/news/images/c5.gif" height="18" width="11">                            <a  href="http://www.chinaitlab.com/www/news/article_show.asp?id=37628####" rel="nofollow" target="_blank">推荐给好友</a>                            &nbsp;<img  src="http://www.chinaitlab.com/www/news/images/c6.gif" height="17" width="17">                            <a rel="nofollow" class="A01">QQ上看本站</a>
            <img  src="http://www.chinaitlab.com/www/news/images/c1.gif" height="12" width="13"> <a rel="nofollow">收藏本站</a>                          </div>
            </td>
        </tr>
    </tbody>
</table>
<table class="zhi14" align="center" border="0" cellpadding="0" cellspacing="0" height="38" width="648">
    <tbody>
        <tr>
            <td height="20" width="648">&nbsp;</td>
        </tr>
        <tr>
            <td height="18" valign="top" width="648">    <br>  ■DriverManager 类<br>  <br>  DriverManager 类是 JDBC 的管理层，作用于用户和驱动程序之间。它跟踪可用的驱动程序，并在数据库和相应驱动程序之间建立连接。另外，DriverManager
            类也处理诸如驱动程序登录时间限制及登录和跟踪消息的显示等事务。<br>  <br>
            对于简单的应用程序，一般程序员需要在此类中直接使用的唯一方法是
            DriverManager.getConnection。正如名称所示，该方法将建立与数据库的连接。JDBC 允许用户调用
            DriverManager 的方法 getDriver、getDrivers 和 registerDriver 及 Driver 的方法
            connect。但多数情况下，让 DriverManager 类管理建立连接的细节为上策。<br>  <br>  ■跟踪可用驱动程序<br>  <br>
            DriverManager 类包含一列 Driver 类，它们已通过调用方法 DriverManager.registerDriver
            对自己进行了注册。所有 Driver 类都必须包含有一个静态部分。它创建该类的实例，然后在加载该实例时 DriverManager
            类进行注册。这样，用户正常情况下将不会直接调用
            DriverManager.registerDriver；而是在加载驱动程序时由驱动程序自动调用。加载 Driver 类，然后自动在
            DriverManager 中注册的方式有两种：<br>  <br>  通过调用方法 Class.forName。这将显式地加载驱动程序类。由于这与外部设置无关，因此推荐使用这种加载驱动程序的方法。以下代码加载类 acme.db.Driver：<br>  <br>  Class.forName("acme.db.Driver");<br>  <br>
            如果将 acme.db.Driver 编写为加载时创建实例，并调用以该实例为参数的 DriverManager.registerDriver（本该如此），则它在 DriverManager 的驱动程序列表中，并可用于创建连接。<br>  <br>
            通过将驱动程序添加到 java.lang.System 的属性 jdbc.drivers 中。这是一个由 DriverManager
            类加载的驱动程序类名的列表，由冒号分隔：初始化 DriverManager 类时，它搜索系统属性
            jdbc.drivers，如果用户已输入了一个或多个驱动程序，则 DriverManager 类将试图加载它们。以下代码说明程序员如何在
            ~/.hotjava/properties 中输入三个驱动程序类（启动时，HotJava 将把它加载到系统属性列表中）：<br>  <br>  jdbc.drivers=foo.bah.Driver:wombat.sql.Driver:bad.test.ourDriver;<br>  <br>  对 DriverManager 方法的第一次调用将自动加载这些驱动程序类。<br>  <br>
            注意：加载驱动程序的第二种方法需要持久的预设环境。如果对这一点不能保证，则调用方法 Class.forName
            显式地加载每个驱动程序就显得更为安全。这也是引入特定驱动程序的方法，因为一旦 DriverManager 类被初始化，它将不再检查
            jdbc.drivers 属性列表。<br>  <br>  在以上两种情况中，新加载的 Driver
            类都要通过调用 DriverManager.registerDriver 类进行自我注册。如上所述，加载类时将自动执行这一过程。<br>  <br>  由于安全方面的原因，JDBC 管理层将跟踪哪个类加载器提供哪个驱动程序。这样，当 DriverManager 类打开连接时，它仅使用本地文件系统或与发出连接请求的代码相同的类加载器提供的驱动程序。<br>  <br>  ■建立连接<br>  <br>
            加载 Driver 类并在 DriverManager 类中注册后，它们即可用来与数据库建立连接。当调用
            DriverManager.getConnection 方法发出连接请求时，DriverManager
            将检查每个驱动程序，查看它是否可以建立连接。<br>  <br> 有时可能有多个 JDBC 驱动程序可以与给定的 URL
            连接。例如，与给定远程数据库连接时，可以使用 JDBC-ODBC 桥驱动程序、JDBC
            到通用网络协议驱动程序或数据库厂商提供的驱动程序。在这种情况下，测试驱动程序的顺序至关重要，因为 DriverManager
            将使用它所找到的第一个可以成功连接到给定 URL 的驱动程序。 DriverManager
            试图按注册的顺序使用每个驱动程序（jdbc.drivers
            中列出的驱动程序总是先注册）。它将跳过代码不可信任的驱动程序，除非加载它们的源与试图打开连接的代码的源相同。它通过轮流在每个驱动程序上调用方法
            Driver.connect，并向它们传递用户开始传递给方法 DriverManager.getConnection 的 URL
            来对驱动程序进行测试，然后连接第一个认出该 URL
            的驱动程序。这种方法初看起来效率不高，但由于不可能同时加载数十个驱动程序，因此每次连接实际只需几个过程调用和字符串比较。以下代码是通常情况下用驱
            动程序（例如 JDBC-ODBC 桥驱动程序）建立连接所需所有步骤的示例：<br>  <br>  Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); //加载驱动程序<br>  String url = "jdbc:odbc:fred";<br>  DriverManager.getConnection(url, "userID", "passwd");<br>  <br>  8.语句<br>  <br>  ■Statement 对象概述<br>  <br>
            Statement 对象用于将 SQL 语句发送到数据库中。实际上有三种 Statement 对象，它们都作为在给定连接上执行 SQL
            语句的包容器：Statement、PreparedStatement（它从 Statement 继承而来）和
            CallableStatement（它从 PreparedStatement 继承而来）。它们都专用于发送特定类型的 SQL 语句：
            Statement 对象用于执行不带参数的简单 SQL 语句；PreparedStatement 对象用于执行带或不带 IN 参数的预编译
            SQL 语句；CallableStatement 对象用于执行对数据库已存储过程的调用。<br>  <br>  Statement 接口提供了执行语句和获取结果的基本方法。PreparedStatement 接口添加了处理 IN 参数的方法；而 CallableStatement 添加了处理 OUT 参数的方法。<br>  <br>  ■创建 Statement 对象<br>  <br>  建立了到特定数据库的连接之后，就可用该连接发送 SQL 语句。Statement 对象用 Connection 的方法 createStatement 创建，如下列代码段中所示：<br>  <br>  Connection con = DriverManager.getConnection(url, "sunny", "");<br>  Statement stmt = con.createStatement();<br>  <br>  为了执行 Statement 对象，被发送到数据库的 SQL 语句将被作为参数提供给 Statement 的方法：<br>  <br>  ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM Table2");<br>  <br>  ■使用 Statement 对象执行语句<br>  <br>  Statement 接口提供了三种执行 SQL 语句的方法：executeQuery、executeUpdate 和 execute。使用哪一个方法由 SQL 语句所产生的内容决定。<br>  <br>   方法
            executeQuery 用于产生单个结果集的语句，例如 SELECT 语句。<br>  <br>
            方法 executeUpdate 用于执行 INSERT、UPDATE 或 DELETE 语句以及 SQL DDL（数据定义语言）语句，例如
            CREATE TABLE 和 DROP TABLE。INSERT、UPDATE 或 DELETE
            语句的效果是修改表中零行或多行中的一列或多列。executeUpdate 的返回值是一个整数，指示受影响的行数（即更新计数）。对于
            CREATE TABLE 或 DROP TABLE 等不操作行的语句，executeUpdate 的返回值总为零。<br>  <br>   方法 execute 用于执行返回多个结果集、多个更新计数或二者组合的语句。<br>  <br>  执行语句的所有方法都将关闭所调用的 Statement 对象的当前打开结果集（如果存在）。这意味着在重新执行 Statement 对象之前，需要完成对当前 ResultSet 对象的处理。<br>  <br>
            应注意，继承了 Statement 接口中所有方法的 PreparedStatement 接口都有自己的
            executeQuery、executeUpdate 和 execute 方法。Statement 对象本身不包含 SQL 语句，因而必须给
            Statement.execute 方法提供 SQL 语句作为参数。PreparedStatement 对象并不将 SQL
            语句作为参数提供给这些方法，因为它们已经包含预编译 SQL 语句。CallableStatement 对象继承这些方法的
            PreparedStatement 形式。对于这些方法的 PreparedStatement 或 CallableStatement
            版本，使用查询参数将抛出 SQLException。<br>  <br>  ■语句完成<br>  <br>
            当连接处于自动提交模式时，其中所执 行的语句在完成时将自动提交或还原。语句在已执行且所有结果返回时，即认为已完成。对于返回一个结果集的
            executeQuery 方法，在检索完 ResultSet 对象的所有行时该语句完成。对于方法
            executeUpdate，当它执行时语句即完成。但在少数调用方法 execute 的情况中，在检索所有结果集或它生成的更新计数之后语句才完成。<br>  <br>  有些 DBMS 将已存储过程中的每条语句视为独立的语句；而另外一些则将整个过程视为一个复合语句。在启用自动提交时，这种差别就变得非常重要，因为它影响什么时候调用 commit 方法。在前一种情况中，每条语句单独提交；在后一种情况中，所有语句同时提交。<br>  <br>  ■关闭 Statement 对象<br>  <br>  Statement 对象将由 Java 垃圾收集程序自动关闭。而作为一种好的编程风格，应在不需要 Statement 对象时显式地关闭它们。这将立即释放 DBMS 资源，有助于避免潜在的内存问题。<br>  <br>  9.结果设置<br>  <br>
            ■概述<br>  <br>
            ResultSet 包含符合 SQL 语句中条件的所有行，并且它通过一套 get 方法（这些 get
            方法可以访问当前行中的不同列）提供了对这些行中数据的访问。ResultSet.next 方法用于移动到 ResultSet
            中的下一行，使下一行成为当前行。<br>  <br>  ■行和光标<br>  <br> ResultSet
            维护指向其当前数据行的光标。每调用一次 next 方法，光标向下移动一行。最初它位于第一行之前，因此第一次调用 next
            将把光标置于第一行上，使它成为当前行。随着每次调用 next 导致光标向下移动一行，按照从上至下的次序获取 ResultSet 行。在
            ResultSet 对象或其父辈 Statement 对象关闭之前，光标一直保持有效。在 SQL
            中，结果表的光标是有名字的。如果数据库允许定位更新或定位删除，则需要将光标的名字作为参数提供给更新或删除命令。可通过调用方法
            getCursorName 获得光标名。 注意：不是所有 DBMS支持定位更新和删除。可使用
            DatabaseMetaData.supportsPositionedDelete 和 supportsPositionedUpdate
            方法来检查特定连接是否支持这些操作。当支持这些操作时，DBMS/驱动程序必须确保适当锁定选定行，以使定位更新不会导致更新异常或其它并发问题。<br>  <br>  ■列<br>
            <br>
            方法 getXXX
            提供了获取当前行中某列值的途径。在每一行内，可按任何次序获取列值。但为了保证可移植性，应该从左至右获取列值，并且一次性地读取列值。列名或列号可用
            于标识要从中获取数据的列。例如，如果 ResultSet 对象 rs
            的第二列名为&#8220;title&#8221;，并将值存储为字符串，则下列任一代码将获取存储在该列中的值：<br>  <br>  String s = rs.getString("title");<br>  String s = rs.getString(2);<br>  <br>  注意列是从左至右编号的，并且从列 1 开始。同时，用作 getXXX 方法的输入的列名不区分大小写。<br>  <br>
            提供使用列名这个选项的目的是为了让在查询中指定列名的用户可使用相同的名字作为 getXXX 方法的参数。另一方面，如果 select
            语句未指定列名（例如在&#8220;select * from table1&#8221;中或列是导出的时），则应该使用列号。这些情况下，用户将无法确切知道列名。<br>  <br>
            有些情况下，SQL 查询返回的结果集中可能有多个列具有相同的名字。如果列名用作 getXXX 方法的参数，则 getXXX
            将返回第一个匹配列名的值。因而，如果多个列具有相同的名字，则需要使用列索引来确保检索了正确的列值。这时，使用列号效率要稍微高一些。<br>  <br>
            ■数据类型和转换<br>  <br>
            对于 getXXX 方法，JDBC 驱动程序试图将基本数据转换成指定 Java 类型，然后返回适合的 Java 值。例如，如果 getXXX
            方法为 getString，而基本数据库中数据类型为 VARCHAR，则 JDBC 驱动程序将把 VARCHAR 转换成 Java
            String。getString 的返回值将为 Java String 对象。可使用 ResultSet.getXXX 方法获取常见的
            JDBC 数据类型。<br>  <br>  准备语句<br>  <br>  ■概述<br>  <br>  该 PreparedStatement 接口继承 Statement，并与之在两方面有所不同：<br>  <br>  PreparedStatement 实例包含已编译的 SQL 语句。这就是使语句&#8220;准备好&#8221;。<br>  <br>
            包含于 PreparedStatement 对象中的 SQL 语句可具有一个或多个 IN 参数。IN 参数的值在 SQL
            语句创建时未被指定。相反的，该语句为每个 IN 参数保留一个问号（&#8220;？&#8221;）作为占位符。每个问号的值必须在该语句执行之前，通过适当的
            setXXX 方法来提供。<br>  <br>  由于 PreparedStatement 对象已预编译过，所以其执行速度要快于 Statement 对象。因此，多次执行的 SQL 语句经常创建为 PreparedStatement 对象，以提高效率。<br>  <br>
            作为 Statement 的子类，PreparedStatement 继承了 Statement
            的所有功能。另外它还添加了一整套方法，用于设置发送给数据库以取代 IN 参数占位符的值。同时，三种方法 execute、
            executeQuery 和 executeUpdate 已被更改以使之不再需要参数。这些方法的 Statement 形式（接受 SQL
            语句参数的形式）不应该用于 PreparedStatement 对象。<br>  <br>  ■创建 PreparedStatement 对象<br>  <br>  以下的代码段（其中 con 是 Connection 对象）创建包含带两个 IN 参数占位符的 SQL 语句的 PreparedStatement 对象：<br>  <br>  PreparedStatement pstmt = con.prepareStatement(<br>  "UPDATE table4 SET m = ? WHERE x = ?");<br>  <br>  pstmt 对象包含语句 "UPDATE table4 SET m = ? WHERE x = ?"，它已发送给 DBMS，并为执行作好了准备。<br>  <br>  ■传递 IN 参数<br>  <br>
            在执行 PreparedStatement 对象之前，必须设置每个 ? 参数的值。这可通过调用 setXXX 方法来完成，其中 XXX
            是与该参数相应的类型。例如，如果参数具有 Java 类型 long，则使用的方法就是 setLong。setXXX
            方法的第一个参数是要设置的参数的序数位置，第二个参数是设置给该参数的值。例如，以下代码将第一个参数设为 123456789，第二个参数设为
            100000000：<br>  <br>  pstmt.setLong(1, 123456789);<br>  pstmt.setLong(2, 100000000);<br>  <br>  一旦设置了给定语句的参数值，就可用它多次执行该语句，直到调用 clearParameters 方法清除它为止。<br>  <br>  在连接的缺省模式下（启用自动提交），当语句完成时将自动提交或还原该语句。<br>  <br>  如果基本数据库和驱动程序在语句提交之后仍保持这些语句的打开状态，则同一个 PreparedStatement 可执行多次。如果这一点不成立，那么试图通过使用 PreparedStatement 对象代替 Statement 对象来提高性能是没有意义的。<br>  <br>
            利用 pstmt（前面创建的 PreparedStatement 对象），以下代码例示了如何设置两个参数占位符的值并执行 pstmt 10
            次。如上所述，为做到这一点，数据库不能关闭 pstmt。在该示例中，第一个参数被设置为 "Hi"并保持为常数。在 for
            循环中，每次都将第二个参数设置为不同的值：从 0 开始，到 9 结束。<br>  <br>  pstmt.setString(1, "Hi");<br>  for (int i = 0; i &lt; 10; i++) {<br>  pstmt.setInt(2, i);<br>  int rowCount = pstmt.executeUpdate();<br>  }<br>  <br>  ■IN 参数中数据类型的一致性<br>  <br>
            setXXX 方法中的 XXX 是 Java 类型。它是一种隐含的 JDBC 类型（一般 SQL 类型），因为驱动程序将把 Java
            类型映射为相应的 JDBC 类型（遵循该 JDBC Guide中&#167;8.6.2 &#8220;映射 Java 和 JDBC 类型&#8221;表中所指定的映射），并将该
            JDBC 类型发送给数据库。例如，以下代码段将 PreparedStatement 对象 pstmt 的第二个参数设置为 44，Java
            类型为 short：<br>  <br>  pstmt.setShort(2, 44);<br>  <br>  驱动程序将 44 作为 JDBC SMALLINT 发送给数据库，它是 Java short 类型的标准映射。<br>  <br>
            程序员的责任是确保将每个 IN 参数的 Java 类型映射为与数据库所需的 JDBC 数据类型兼容的 JDBC 类型。不妨考虑数据库需要
            JDBC SMALLINT 的情况。如果使用方法 setByte ，则驱动程序将 JDBC TINYINT
            发送给数据库。这是可行的，因为许多数据库可从一种相关的类型转换为另一种类型，并且通常 TINYINT 可用于 SMALLINT
            适用的任何地方。然而，对于要适用于尽可能多的数据库的应用程序，最好使用与数据库所需的确切的 JDBC 类型相应的 Java 类型。如果所需的
            JDBC 类型是 SMALLINT，则使用 setShort 代替 setByte 将使应用程序的可移植性更好。<br>  <br>  ■ JDBC URL<br>  <br>
            JDBC URL 提供了一种标识数据库的方法，可以使相应的驱动程序能识别该数据库并与之建立连接。实际上，驱动程序编程员将决定用什么 JDBC
            URL 来标识特定的驱动程序。用户不必关心如何来形成 JDBC URL；他们只须使用与所用的驱动程序一起提供的 URL 即可。JDBC
            的作用是提供某些约定，驱动程序编程员在构造他们的 JDBC URL 时应该遵循这些约定。<br>  <br>  (1) 由于 JDBC URL 要与各种不同的驱动程序一起使用，因此这些约定应非常灵活。它们应允许不同的驱动程序使用不同的方案来命名数据库。例如， odbc 子协议允许（但并不是要求） URL 含有属性值。<br>  <br>  (2) JDBC URL 应允许驱动程序编程员将一切所需的信息编入其中。这样就可以让要与给定数据库对话的 applet 打开数据库连接，而无须要求用户去做任何系统管理工作。<br>  <br>
            (3) JDBC URL 应允许某种程度的间接性。也就是说，JDBC URL
            可指向逻辑主机或数据库名，而这种逻辑主机或数据库名将由网络命名系统动态地转换为实际的名称。这可以使系统管理员不必将特定主机声明为 JDBC
            名称的一部份。网络命名服务（例如 DNS、 NIS 和 DCE ）有多种,而对于使用哪种命名服务并无限制。<br>  <br>  JDBC URL
            的标准语法如下所示。<br>  <br>  它由三部分组成，各部分间用冒号分隔：jdbc:&lt; 子协议 &gt;:&lt; 子名称 &gt;<br>  <br>  JDBC URL 的三个部分可分解如下：<br>  <br>   jdbc ─ 协议。JDBC URL 中的协议总是 jdbc。<br>  <br>
            &lt;子协议&gt; ─ 驱动程序名或数据库连接机制（这种机制可由一个或多个驱动程序支持）的名称。子协议名的典型示例是
            "odbc"，该名称是为用于指定 ODBC 风格的数据资源名称的 URL 专门保留的。例如，为了通过 JDBC-ODBC
            桥来访问某个数据库，可以用如下所示的 URL：<br>  jdbc:odbc:fred<br>  <br>  本例中，子协议为 "odbc"，子名称 "fred" 是本地 ODBC 数据资源。 如果要用网络命名服务（这样 JDBC URL 中的数据库名称不必是实际名称），则命名服务可以作为子协议。例如，可用如下所示的 URL ：<br>  <br>  jdbc:dcenaming:accounts-payable<br>  <br>  本例中，该 URL 指定了本地 DCE 命名服务应该将 数据库名称 "accounts-payable" 解析为更为具体的 可用于连接真实数据库的名称。<br>  <br>
            &lt;子名称&gt; ─
            一种标识数据库的方法。子名称可以依不同的子协议而变化。它还可以有子名称的子名称（含有驱动程序编程员所选的任何内部语法）。使用子名称的目的是为定位
            数据库提供足够的信息。前例中，因为 ODBC 将提供其余部份的信息，因此用 "fred"
            就已足够。然而，位于远程服务器上的数据库需要更多的信息。例如，如果数据库是通过 Internet 来访问的，则在 JDBC URL
            中应将网络地址作为子名称的一部份包括进去，且必须遵循如下所示的标准 URL 命名约定：<br>  <br>  //主机名:端口/子协议<br>  <br>  假设 "dbnet" 是个用于将某个主机连接到 Internet 上的协议，则 JDBC URL 类似：<br>  <br>  jdbc:dbnet://wombat:356/fred<br>  <br>  ■ "odbc" 子协议<br>  <br>  子协议 odbc 是一种特殊情况。它是为用于指定 ODBC 风格的数据资源名称的 URL 而保留的，并具有下列特性：允许在子名称（数据资源名称）后面指定任意多个属性值。odbc 子协议的完整语法为：<br>  <br>  jdbc:odbc:&lt; 数据资源名称 &gt;[;&lt; 属性名 &gt;=&lt; 属性值 &gt;]*<br>  <br>  因此，以下都是合法的 jdbc:odbc 名称：<br>  <br>  jdbc:odbc:qeor7<br>  jdbc:odbc:wombat<br>
            jdbc:odbc:wombat;CacheSize=20;ExtensionCase=LOWER<br>  jdbc:odbc:qeora;UID=kgh;PWD=fooey<br>  <br>  ■注册子协议<br>  <br>
            驱动程序编程员可保留某个名称以将之用作 JDBC URL 的子协议名。当 DriverManager
            类将此名称加到已注册的驱动程序清单中时，为之保留该名称的驱动程序应能识别该名称并与它所标识的数据库建立连接。例如，odbc 是为 JDBC-
            ODBC 桥而保留的。示例之二，假设有个 Miracle 公司，它可能会将 "miracle" 注册为连接到其 Miracle DBMS 上的
            JDBC 驱动程序的子协议，从而使其他人都无法使用这个名称。</td>
        </tr>
    </tbody>
</table><img src ="http://www.blogjava.net/shypwang/aggbug/139365.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/shypwang/" target="_blank">妖人</a> 2007-08-26 09:09 <a href="http://www.blogjava.net/shypwang/articles/139365.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>DynamicProxy [精華]</title><link>http://www.blogjava.net/shypwang/articles/138590.html</link><dc:creator>妖人</dc:creator><author>妖人</author><pubDate>Wed, 22 Aug 2007 05:22:00 GMT</pubDate><guid>http://www.blogjava.net/shypwang/articles/138590.html</guid><wfw:comment>http://www.blogjava.net/shypwang/comments/138590.html</wfw:comment><comments>http://www.blogjava.net/shypwang/articles/138590.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/shypwang/comments/commentRss/138590.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/shypwang/services/trackbacks/138590.html</trackback:ping><description><![CDATA[<span>
最近在寫學校案子用到hibernate,正巧以前打工的地方學習<wbr>到一個方法,
<br>在javaworld@tw也有人提到過,因此整理一下.
<br>Hibernate + Struts 學習筆記提到過的使用dynamic proxy的做法,
<br>來避免巢狀呼叫,也可以讓service delegate不會跟hibernate綁的死死的.
<br>首先dynamic proxy會利用到java.lang.reflect<wbr>.Proxy跟java.lang.reflect<wbr>.InvocationHandler. 直接看以下程式碼
<br>HogeIF.java
<br>
<table bgcolor="#999999" border="0" cellpadding="3" cellspacing="1">
    <tbody>
        <tr>
            <td align="left" bgcolor="#dddddd" valign="top" width="1">
            <pre><font color="#555555">1<br>2<br>3<br></font></pre>
            </td>
            <td align="left" bgcolor="#ffffff" valign="top">
            <pre><font><strong>public</strong></font> <font><strong>interface</strong></font> HogeIF <font>{</font><br>  <font><strong>public</strong></font> <font><br><strong>void</strong></font> printMessage(String message);<br><font>}</font>
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>Hoge.java
<br>
<table bgcolor="#999999" border="0" cellpadding="3" cellspacing="1">
    <tbody>
        <tr>
            <td align="left" bgcolor="#dddddd" valign="top" width="1">
            <pre><font color="#555555">1<br>2<br>3<br>4<br>5<br></font></pre>
            </td>
            <td align="left" bgcolor="#ffffff" valign="top">
            <pre><font><strong>public</strong></font> <font><strong>class</strong></font> Hoge <font><strong>implements</strong></font><br> HogeIF<font>{</font><br>  <font><strong>public</strong></font> <font><strong>void</strong></font> printMessage(String message) <font>{</font><br><br>    System.out.println(message);<br>  <font>}</font><br><font>}</font>
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>執行時必須寫成
<br>
<table bgcolor="#999999" border="0" cellpadding="3" cellspacing="1">
    <tbody>
        <tr>
            <td align="left" bgcolor="#dddddd" valign="top" width="1">
            <pre><font color="#555555">1<br>2<br></font></pre>
            </td>
            <td align="left" bgcolor="#ffffff" valign="top">
            <pre>HogeIF hoge = <font><strong>new</strong></font> Hoge();<br>hoge.printMessage(<font>"hogehoge"</font>);<br></pre>
            </td>
        </tr>
    </tbody>
</table>
<br>如果想對此方法做點前後置處理,那就寫個proxy
<br>HogeProxy.java
<br>
<table bgcolor="#999999" border="0" cellpadding="3" cellspacing="1">
    <tbody>
        <tr>
            <td align="left" bgcolor="#dddddd" valign="top" width="1">
            <pre><font color="#555555">1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br><br>9<br>10<br>
            <script><!--
            D(["mb","11\u003cbr\>\u003c/font\>\u003c/pre\>\u003c/td\>\u003ctd align\u003d\"left\" bgcolor\u003d\"#ffffff\" valign\u003d\"top\"\>\u003cpre\>\u003cfont\>\u003cb\>public\u003c/b\>\u003c/font\> \u003cfont\>\u003cb\>class\u003c/b\>\u003c/font\> HogeProxy \u003cfont\>\n\u003cb\>implements\u003c/b\>\u003c/font\> HogeIF\u003cfont\>{\u003c/font\>\u003cbr\>  \u003cfont\>\u003cb\>private\u003c/b\>\u003c/font\> HogeIF hoge;\u003cbr\>  \u003cfont\>\u003cb\>public\u003c/b\>\u003c/font\> HogeProxy(HogeIF hoge)\n\u003cfont\>{\u003c/font\>\u003cbr\>    this.hoge \u003d hoge;\u003cbr\>  \u003cfont\>}\u003c/font\>\u003cbr\>  \u003cfont\>\u003cb\>public\u003c/b\>\u003c/font\> \u003cfont\>\u003cb\>void\u003c/b\>\u003c/font\> printMessage(String message) \n\u003cfont\>{\u003c/font\>\u003cbr\>    System.out.println(\u003cfont\>&quot;before&quot;\u003c/font\>);\u003cbr\>    hoge.printMessage(message);\u003cbr\>    System.out.println(\u003cfont\>&quot;after&quot;\u003c/font\>\n);\u003cbr\>  \u003cfont\>}\u003c/font\>\u003cbr\>\u003cfont\>}\u003c/font\>\n\u003c/pre\>\u003c/td\>\u003c/tr\>\u003c/tbody\>\u003c/table\>\n\u003cbr\>這樣就會變成\n\u003cbr\>\u003ctable bgcolor\u003d\"#999999\" border\u003d\"0\" cellpadding\u003d\"3\" cellspacing\u003d\"1\"\>\u003ctbody\>\u003ctr\>\u003ctd align\u003d\"left\" bgcolor\u003d\"#dddddd\" valign\u003d\"top\" width\u003d\"1\"\>\u003cpre\>\u003cfont color\u003d\"#555555\"\>1\u003cbr\>2\u003cbr\>3\u003cbr\>\u003c/font\>\u003c/pre\>\u003c/td\>\u003ctd align\u003d\"left\" bgcolor\u003d\"#ffffff\" valign\u003d\"top\"\>\n\u003cpre\>before\u003cbr\>hogehoge\u003cbr\>after\u003cbr\>\u003c/pre\>\u003c/td\>\u003c/tr\>\u003c/tbody\>\u003c/table\>\n\u003cbr\>如果每個method都需要加工,需要加工的class都impl\u003cWBR\>ement不同interface,或者每個class有不同me\u003cWBR\>thod,那麼........就要寫非常多的proxy來用.\u003cWBR\>.. 在這邊改個方法使用dynamic proxy...\n\u003cbr\>DynamicHogeProxy.java\n\u003cbr\>\u003ctable bgcolor\u003d\"#999999\" border\u003d\"0\" cellpadding\u003d\"3\" cellspacing\u003d\"1\"\>\u003ctbody\>\u003ctr\>\u003ctd align\u003d\"left\" bgcolor\u003d\"#dddddd\" valign\u003d\"top\" width\u003d\"1\"\>\u003cpre\>\u003cfont color\u003d\"#555555\"\>1\u003cbr\>2\u003cbr\>3\u003cbr\>4\u003cbr\>5\u003cbr\>6\u003cbr\>7\u003cbr\>8\u003cbr\>\n9\u003cbr\>10\u003cbr\>11\u003cbr\>12\u003cbr\>13\u003cbr\>14\u003cbr\>15\u003cbr\>16\u003cbr\>17\u003cbr\>18\u003cbr\>19\u003cbr\>20\u003cbr\>21\u003cbr\>22\u003cbr\>23\u003cbr\>24\u003cbr\>25\u003cbr\>26\u003cbr\>27\u003cbr\>\u003c/font\>\u003c/pre\>\u003c/td\>\u003ctd align\u003d\"left\" bgcolor\u003d\"#ffffff\" valign\u003d\"top\"\>\u003cpre\>\u003cfont\>\u003cb\>import\n\u003c/b\>\u003c/font\> java.lang.reflect.InvocationHan\u003cWBR\>dler;\u003cbr\>\u003cfont\>\u003cb\>import\u003c/b\>\u003c/font\> java.lang.reflect.InvocationTar\u003cWBR\>getException;\u003cbr\>\u003cfont\>\u003cb\>import\u003c/b\>\u003c/font\> java.lang.reflect.Method\n;\u003cbr\>\u003cfont\>\u003cb\>public\u003c/b\>\u003c/font\> \u003cfont\>\u003cb\>class\u003c/b\>\u003c/font\> DynamicHogeProxy \u003cfont\>\u003cb\>implements\u003c/b\>\u003c/font\> InvocationHandler \u003cfont\>\n{\u003c/font\>\u003cbr\>  \u003cfont\>\u003cb\>private\u003c/b\>\u003c/font\> Object obj;\u003cbr\>  \u003cfont\>\u003cb\>public\u003c/b\>\u003c/font\> \u003cfont\>\u003cb\>static\u003c/b\>\u003c/font\> Object newInstance(Object obj) \n",1]
            );
            //--></script>
            11<br></font></pre>
            </td>
            <td align="left" bgcolor="#ffffff" valign="top">
            <pre><font><strong>public</strong></font> <font><strong>class</strong></font> HogeProxy <font><br><strong>implements</strong></font> HogeIF<font>{</font><br>  <font><strong>private</strong></font> HogeIF hoge;<br>  <font><strong>public</strong></font> HogeProxy(HogeIF hoge)<br><font>{</font><br>    this.hoge = hoge;<br>  <font>}</font><br>  <font><strong>public</strong></font> <font><strong>void</strong></font> printMessage(String message) <br><font>{</font><br>    System.out.println(<font>"before"</font>);<br>    hoge.printMessage(message);<br>    System.out.println(<font>"after"</font><br>);<br>  <font>}</font><br><font>}</font>
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>這樣就會變成
<br>
<table bgcolor="#999999" border="0" cellpadding="3" cellspacing="1">
    <tbody>
        <tr>
            <td align="left" bgcolor="#dddddd" valign="top" width="1">
            <pre><font color="#555555">1<br>2<br>3<br></font></pre>
            </td>
            <td align="left" bgcolor="#ffffff" valign="top">
            <pre>before<br>hogehoge<br>after<br></pre>
            </td>
        </tr>
    </tbody>
</table>
<br>如果每個method都需要加工,需要加工的class都impl<wbr>ement不同interface,或者每個class有不同me<wbr>thod,那麼........就要寫非常多的proxy來用.<wbr>.. 在這邊改個方法使用dynamic proxy...
<br>DynamicHogeProxy.java
<br>
<table bgcolor="#999999" border="0" cellpadding="3" cellspacing="1">
    <tbody>
        <tr>
            <td align="left" bgcolor="#dddddd" valign="top" width="1">
            <pre><font color="#555555">1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br><br>9<br>10<br>11<br>12<br>13<br>14<br>15<br>16<br>17<br>18<br>19<br>20<br>21<br>22<br>23<br>24<br>25<br>26<br>27<br></font></pre>
            </td>
            <td align="left" bgcolor="#ffffff" valign="top">
            <pre><font><strong>import<br></strong></font> java.lang.reflect.InvocationHan<wbr>dler;<br><font><strong>import</strong></font> java.lang.reflect.InvocationTar<wbr>getException;<br><font><strong>import</strong></font> java.lang.reflect.Method<br>;<br><font><strong>public</strong></font> <font><strong>class</strong></font> DynamicHogeProxy <font><strong>implements</strong></font> InvocationHandler <font><br>{</font><br>  <font><strong>private</strong></font> Object obj;<br>  <font><strong>public</strong></font> <font><strong>static</strong></font> Object newInstance(Object obj) <br>
            <script><!--
            D(["mb","\u003cfont\>{\u003c/font\>\u003cbr\>    \u003cfont\>\u003cb\>return\u003c/b\>\u003c/font\> java.lang.reflect.Proxy\u003cWBR\>.newProxyInstance(obj.getClass()\u003cbr\>        .getClassLoader(), obj.getClass().getInterfaces(),\u003cbr\>        \n\u003cfont\>\u003cb\>new\u003c/b\>\u003c/font\> DynamicHogeProxy(obj));\u003cbr\>  \u003cfont\>}\u003c/font\>\u003cbr\>  \u003cfont\>\u003cb\>private\u003c/b\>\u003c/font\> DynamicHogeProxy(Object obj) \u003cfont\>\n{\u003c/font\>\u003cbr\>    this.obj \u003d obj;\u003cbr\>  \u003cfont\>}\u003c/font\>\u003cbr\>  \u003cfont\>\u003cb\>public\u003c/b\>\u003c/font\> Object invoke(Object proxy, Method m, Object[] args)\u003cbr\>      \u003cfont\>\n\u003cb\>throws\u003c/b\>\u003c/font\> Throwable \u003cfont\>{\u003c/font\>\u003cbr\>    Object result;\u003cbr\>    \u003cfont\>\u003cb\>try\u003c/b\>\u003c/font\> \u003cfont\>{\u003c/font\>\u003cbr\>      System.out.println(\u003cfont\>\n&quot;before&quot;\u003c/font\>);\u003cbr\>      result \u003d m.invoke(obj, args);\u003cbr\>      System.out.println(\u003cfont\>&quot;after&quot;\u003c/font\>);\u003cbr\>      \u003cfont\>\u003cb\>return\u003c/b\>\u003c/font\> result;\u003cbr\>\n    \u003cfont\>}\u003c/font\> \u003cfont\>\u003cb\>catch\u003c/b\>\u003c/font\> (InvocationTargetException e) \u003cfont\>{\u003c/font\>\u003cbr\>      \u003cfont\>\u003cb\>throw\u003c/b\>\u003c/font\> \ne.getTargetException();\u003cbr\>    \u003cfont\>}\u003c/font\>\u003cfont\>\u003cb\>finally\u003c/b\>\u003c/font\> \u003cfont\>{\u003c/font\>\u003cbr\>    \u003cfont\>}\u003c/font\>\u003cbr\>  \u003cfont\>\n}\u003c/font\>\u003cbr\>\u003cfont\>}\u003c/font\>\n\u003c/pre\>\u003c/td\>\u003c/tr\>\u003c/tbody\>\u003c/table\>\n\u003cbr\>執行時寫成\n\u003cbr\>\u003ctable bgcolor\u003d\"#999999\" border\u003d\"0\" cellpadding\u003d\"3\" cellspacing\u003d\"1\"\>\u003ctbody\>\u003ctr\>\u003ctd align\u003d\"left\" bgcolor\u003d\"#dddddd\" valign\u003d\"top\" width\u003d\"1\"\>\u003cpre\>\u003cfont color\u003d\"#555555\"\>1\u003cbr\>2\u003cbr\>\u003c/font\>\u003c/pre\>\u003c/td\>\u003ctd align\u003d\"left\" bgcolor\u003d\"#ffffff\" valign\u003d\"top\"\>\n\u003cpre\>HogeIF hoge \u003d (HogeIF)DynamicHogeProxy\u003cWBR\>.newInstance(\u003cfont\>\u003cb\>new\u003c/b\>\u003c/font\> Hoge());\u003cbr\>hoge.printMessage(\u003cfont\>&quot;hogehoge&quot;\u003c/font\>);\u003cbr\>\u003c/pre\>\u003c/td\>\u003c/tr\>\u003c/tbody\>\u003c/table\>\n\n\u003cbr\>這樣就可以達到跟上一個例子一樣的效果了.\n回到本篇正題,最近用hibernate希望他自動關閉sessi\u003cWBR\>on,但是又不希望在dao的每個method都開開關關\u003cWBR\>,也不希望service\ndelegate裡面去做開關,因此我把每個service delegate都使用dynamic\nproxy來invoke...這樣就可以做到整個呼叫過程\u003cWBR\>,session的開關只有一次,也就不用擔心巢狀呼叫了.\n因此我在每個dao的每個操作的method的開頭加上Threa\u003cWBR\>dLocalSession.currentSession();\n然後每個service delegate都使用dynamic proxy 去invoke. dynamic proxy的內容如下\n\u003cbr\>\u003ctable bgcolor\u003d\"#999999\" border\u003d\"0\" cellpadding\u003d\"3\" cellspacing\u003d\"1\"\>\u003ctbody\>\u003ctr\>\u003ctd align\u003d\"left\" bgcolor\u003d\"#dddddd\" valign\u003d\"top\" width\u003d\"1\"\>\u003cpre\>\u003cfont color\u003d\"#555555\"\>",1]
            );
            //--></script>
            <font>{</font><br>    <font><strong>return</strong></font> java.lang.reflect.Proxy<wbr>.newProxyInstance(obj.getClass()<br>        .getClassLoader(), obj.getClass().getInterfaces(),<br>        <br><font><strong>new</strong></font> DynamicHogeProxy(obj));<br>  <font>}</font><br>  <font><strong>private</strong></font> DynamicHogeProxy(Object obj) <font><br>{</font><br>    this.obj = obj;<br>  <font>}</font><br>  <font><strong>public</strong></font> Object invoke(Object proxy, Method m, Object[] args)<br>      <font><br><strong>throws</strong></font> Throwable <font>{</font><br>    Object result;<br>    <font><strong>try</strong></font> <font>{</font><br>      System.out.println(<font><br>"before"</font>);<br>      result = m.invoke(obj, args);<br>      System.out.println(<font>"after"</font>);<br>      <font><strong>return</strong></font> result;<br><br>    <font>}</font> <font><strong>catch</strong></font> (InvocationTargetException e) <font>{</font><br>      <font><strong>throw</strong></font> <br>e.getTargetException();<br>    <font>}</font><font><strong>finally</strong></font> <font>{</font><br>    <font>}</font><br>  <font><br>}</font><br><font>}</font>
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>執行時寫成
<br>
<table bgcolor="#999999" border="0" cellpadding="3" cellspacing="1">
    <tbody>
        <tr>
            <td align="left" bgcolor="#dddddd" valign="top" width="1">
            <pre><font color="#555555">1<br>2<br></font></pre>
            </td>
            <td align="left" bgcolor="#ffffff" valign="top">
            <pre>HogeIF hoge = (HogeIF)DynamicHogeProxy<wbr>.newInstance(<font><strong>new</strong></font> Hoge());<br>hoge.printMessage(<font>"hogehoge"</font>);<br></pre>
            </td>
        </tr>
    </tbody>
</table>
<br>這樣就可以達到跟上一個例子一樣的效果了.
回到本篇正題,最近用hibernate希望他自動關閉sessi<wbr>on,但是又不希望在dao的每個method都開開關關<wbr>,也不希望service
delegate裡面去做開關,因此我把每個service delegate都使用dynamic
proxy來invoke...這樣就可以做到整個呼叫過程<wbr>,session的開關只有一次,也就不用擔心巢狀呼叫了.
因此我在每個dao的每個操作的method的開頭加上Threa<wbr>dLocalSession.currentSession();
然後每個service delegate都使用dynamic proxy 去invoke. dynamic proxy的內容如下
<br>
<table bgcolor="#999999" border="0" cellpadding="3" cellspacing="1">
    <tbody>
        <tr>
            <td align="left" bgcolor="#dddddd" valign="top" width="1">
            <pre><font color="#555555">
            <script><!--
            D(["mb","1\u003cbr\>2\u003cbr\>3\u003cbr\>4\u003cbr\>5\u003cbr\>6\u003cbr\>7\u003cbr\>8\u003cbr\>\n9\u003cbr\>10\u003cbr\>11\u003cbr\>12\u003cbr\>13\u003cbr\>14\u003cbr\>15\u003cbr\>16\u003cbr\>17\u003cbr\>18\u003cbr\>19\u003cbr\>20\u003cbr\>21\u003cbr\>22\u003cbr\>23\u003cbr\>24\u003cbr\>25\u003cbr\>26\u003cbr\>27\u003cbr\>28\u003cbr\>29\u003cbr\>30\u003cbr\>\u003c/font\>\u003c/pre\>\u003c/td\>\u003ctd align\u003d\"left\" bgcolor\u003d\"#ffffff\" valign\u003d\"top\"\>\u003cpre\>\u003cfont\>\n\u003cb\>import\u003c/b\>\u003c/font\> java.lang.reflect.InvocationHan\u003cWBR\>dler;\u003cbr\>\u003cfont\>\u003cb\>import\u003c/b\>\u003c/font\> java.lang.reflect.InvocationTar\u003cWBR\>getException;\u003cbr\>\u003cfont\>\u003cb\>import\u003c/b\>\u003c/font\> java.lang.reflect.Method\n;\u003cbr\>\u003cfont\>\u003cb\>import\u003c/b\>\u003c/font\> java.lang.reflect.Proxy;\u003cbr\>&#160;\u003cbr\>\u003cfont\>\u003cb\>public\u003c/b\>\u003c/font\> \u003cfont\>\u003cb\>class\u003c/b\>\u003c/font\> DynamicHogeProxy \u003cfont\>\n\u003cb\>implements\u003c/b\>\u003c/font\> InvocationHandler\u003cfont\>{\u003c/font\>\u003cbr\>  \u003cfont\>\u003cb\>private\u003c/b\>\u003c/font\> Object obj;\u003cbr\>  \u003cfont\>\u003cb\>private\u003c/b\>\u003c/font\> DynamicHogeProxy(Object obj) \n\u003cfont\>{\u003c/font\>\u003cbr\>    this.obj \u003d obj;\u003cbr\>  \u003cfont\>}\u003c/font\>\u003cbr\>  \u003cfont\>\u003cb\>public\u003c/b\>\u003c/font\> \u003cfont\>\u003cb\>static\u003c/b\>\u003c/font\> Object newInstance(Object obj) \n\u003cfont\>{\u003c/font\>\u003cbr\>    \u003cfont\>\u003cb\>return\u003c/b\>\u003c/font\> Proxy.newProxyInstance(obj.getClass().getClassLoader(),\u003cbr\>        obj.getClass().getInterfaces(), \u003cfont\>\n\u003cb\>new\u003c/b\>\u003c/font\> DynamicHogeProxy(\u003cbr\>            obj));\u003cbr\>  \u003cfont\>}\u003c/font\>\u003cbr\>  \u003cfont\>\u003cb\>public\u003c/b\>\u003c/font\> Object invoke(Object proxy, Method method, Object[] args)\u003cbr\>      \n\u003cfont\>\u003cb\>throws\u003c/b\>\u003c/font\> Throwable \u003cfont\>{\u003c/font\>\u003cbr\>    Object result \u003d \u003cfont\>\u003cb\>null\u003c/b\>\u003c/font\>;\u003cbr\>    \u003cfont\>\u003cb\>if\n\u003c/b\>\u003c/font\> (obj !\u003d \u003cfont\>\u003cb\>null\u003c/b\>\u003c/font\>) \u003cfont\>{\u003c/font\>\u003cbr\>      \u003cfont\>\u003cb\>try\u003c/b\>\u003c/font\> \u003cfont\>{\u003c/font\>\u003cbr\>        result \u003d \nmethod.invoke(obj, args);\u003cbr\>      \u003cfont\>}\u003c/font\> \u003cfont\>\u003cb\>catch\u003c/b\>\u003c/font\> (InvocationTargetException e) \u003cfont\>{\u003c/font\>\u003cbr\>        \u003cfont\>\n\u003cb\>throw\u003c/b\>\u003c/font\> e.getCause();\u003cbr\>      \u003cfont\>}\u003c/font\> \u003cfont\>\u003cb\>finally\u003c/b\>\u003c/font\> \u003cfont\>{\u003c/font\>\u003cbr\>        ThreadLocalSession.closeSession();\u003cbr\>      \n\u003cfont\>}\u003c/font\>\u003cbr\>    \u003cfont\>}\u003c/font\>\u003cbr\>    \u003cfont\>\u003cb\>return\u003c/b\>\u003c/font\> result;\u003cbr\>  \u003cfont\>}\u003c/font\>\u003cbr\>\u003cfont\>}\u003c/font\>\n\n\u003c/pre\>\u003c/td\>\u003c/tr\>\u003c/tbody\>\u003c/table\>\n\u003cbr\>這種寫法缺點是一定得撰寫interface才可以\u003cWBR\>,不然會發生ClassCastException.\n\u003cbr\>\u003ctable bgcolor\u003d\"#999999\" border\u003d\"0\" cellpadding\u003d\"3\" cellspacing\u003d\"1\"\>",1]
            );
            //--></script>
            1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br><br>9<br>10<br>11<br>12<br>13<br>14<br>15<br>16<br>17<br>18<br>19<br>20<br>21<br>22<br>23<br>24<br>25<br>26<br>27<br>28<br>29<br>30<br></font></pre>
            </td>
            <td align="left" bgcolor="#ffffff" valign="top">
            <pre><font><br><strong>import</strong></font> java.lang.reflect.InvocationHan<wbr>dler;<br><font><strong>import</strong></font> java.lang.reflect.InvocationTar<wbr>getException;<br><font><strong>import</strong></font> java.lang.reflect.Method<br>;<br><font><strong>import</strong></font> java.lang.reflect.Proxy;<br>&nbsp;<br><font><strong>public</strong></font> <font><strong>class</strong></font> DynamicHogeProxy <font><br><strong>implements</strong></font> InvocationHandler<font>{</font><br>  <font><strong>private</strong></font> Object obj;<br>  <font><strong>private</strong></font> DynamicHogeProxy(Object obj) <br><font>{</font><br>    this.obj = obj;<br>  <font>}</font><br>  <font><strong>public</strong></font> <font><strong>static</strong></font> Object newInstance(Object obj) <br><font>{</font><br>    <font><strong>return</strong></font> Proxy.newProxyInstance(obj.getClass().getClassLoader(),<br>        obj.getClass().getInterfaces(), <font><br><strong>new</strong></font> DynamicHogeProxy(<br>            obj));<br>  <font>}</font><br>  <font><strong>public</strong></font> Object invoke(Object proxy, Method method, Object[] args)<br>      <br><font><strong>throws</strong></font> Throwable <font>{</font><br>    Object result = <font><strong>null</strong></font>;<br>    <font><strong>if<br></strong></font> (obj != <font><strong>null</strong></font>) <font>{</font><br>      <font><strong>try</strong></font> <font>{</font><br>        result = <br>method.invoke(obj, args);<br>      <font>}</font> <font><strong>catch</strong></font> (InvocationTargetException e) <font>{</font><br>        <font><br><strong>throw</strong></font> e.getCause();<br>      <font>}</font> <font><strong>finally</strong></font> <font>{</font><br>        ThreadLocalSession.closeSession();<br>      <br><font>}</font><br>    <font>}</font><br>    <font><strong>return</strong></font> result;<br>  <font>}</font><br><font>}</font><br><br></pre>
            </td>
        </tr>
    </tbody>
</table>
<br>這種寫法缺點是一定得撰寫interface才可以<wbr>,不然會發生ClassCastException.
<br>
<table bgcolor="#999999" border="0" cellpadding="3" cellspacing="1">
    <script><!--
    D(["mb","\u003ctbody\>\u003ctr\>\u003ctd align\u003d\"left\" bgcolor\u003d\"#dddddd\" valign\u003d\"top\" width\u003d\"1\"\>\u003cpre\>\u003cfont color\u003d\"#555555\"\>1\u003cbr\>2\u003cbr\>\u003c/font\>\u003c/pre\>\u003c/td\>\u003ctd align\u003d\"left\" bgcolor\u003d\"#ffffff\" valign\u003d\"top\"\>\n\u003cpre\>HogeIF hoge \u003d (HogeIF)DynamicHogeProxy\u003cWBR\>.newInstance(\u003cfont\>\u003cb\>new\u003c/b\>\u003c/font\> Hoge()); \u003cfont\>//ok!!!\u003c/font\>\u003cbr\>Hoge hoge \u003d (Hoge)DynamicHogeProxy.newInsta\u003cWBR\>nce(\u003cfont\>\n\u003cb\>new\u003c/b\>\u003c/font\> Hoge()); \u003cfont\>//ClassCastException\u003c/font\>\n\u003c/pre\>\u003c/td\>\u003c/tr\>\u003c/tbody\>\u003c/table\>\n\u003cbr\>而且一開始產生proxy時效能會稍微差一點. 另外,要達到上述功能現在也可以用AspectJ來做...恩.\u003cWBR\>.. \n\t\t\t\u003c/span\>\n",0]
    );
    D(["ce"]);
    //--></script>
    <tbody>
        <tr>
            <td align="left" bgcolor="#dddddd" valign="top" width="1">
            <pre><font color="#555555">1<br>2<br></font></pre>
            </td>
            <td align="left" bgcolor="#ffffff" valign="top">
            <pre>HogeIF hoge = (HogeIF)DynamicHogeProxy<wbr>.newInstance(<font><strong>new</strong></font> Hoge()); <font>//ok!!!</font><br>Hoge hoge = (Hoge)DynamicHogeProxy.newInsta<wbr>nce(<font><br><strong>new</strong></font> Hoge()); <font>//ClassCastException</font>
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>而且一開始產生proxy時效能會稍微差一點. 另外,要達到上述功能現在也可以用AspectJ來做...恩.<wbr>..</span> <img src ="http://www.blogjava.net/shypwang/aggbug/138590.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/shypwang/" target="_blank">妖人</a> 2007-08-22 13:22 <a href="http://www.blogjava.net/shypwang/articles/138590.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>