﻿<?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-沉睡森林@漂在北京-随笔分类-Other</title><link>http://www.blogjava.net/wangbing/category/40300.html</link><description>本处文章除注明“转载”外均为原创，转载请注明出处。 </description><language>zh-cn</language><lastBuildDate>Fri, 20 Apr 2012 01:05:10 GMT</lastBuildDate><pubDate>Fri, 20 Apr 2012 01:05:10 GMT</pubDate><ttl>60</ttl><item><title>rose分析</title><link>http://www.blogjava.net/wangbing/archive/2012/04/19/375262.html</link><dc:creator>王总兵</dc:creator><author>王总兵</author><pubDate>Thu, 19 Apr 2012 05:58:00 GMT</pubDate><guid>http://www.blogjava.net/wangbing/archive/2012/04/19/375262.html</guid><wfw:comment>http://www.blogjava.net/wangbing/comments/375262.html</wfw:comment><comments>http://www.blogjava.net/wangbing/archive/2012/04/19/375262.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wangbing/comments/commentRss/375262.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangbing/services/trackbacks/375262.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 最简单的rose配置：Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->&lt;project&nbsp;xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&nbsp;&nbsp;&nbsp;&nb...&nbsp;&nbsp;<a href='http://www.blogjava.net/wangbing/archive/2012/04/19/375262.html'>阅读全文</a><img src ="http://www.blogjava.net/wangbing/aggbug/375262.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangbing/" target="_blank">王总兵</a> 2012-04-19 13:58 <a href="http://www.blogjava.net/wangbing/archive/2012/04/19/375262.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>maven+jetty开发实例</title><link>http://www.blogjava.net/wangbing/archive/2010/07/08/325589.html</link><dc:creator>王总兵</dc:creator><author>王总兵</author><pubDate>Thu, 08 Jul 2010 12:27:00 GMT</pubDate><guid>http://www.blogjava.net/wangbing/archive/2010/07/08/325589.html</guid><wfw:comment>http://www.blogjava.net/wangbing/comments/325589.html</wfw:comment><comments>http://www.blogjava.net/wangbing/archive/2010/07/08/325589.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/wangbing/comments/commentRss/325589.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangbing/services/trackbacks/325589.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;最近准备离职了，等着到20号离开。所以在公司里面没有什么事情，自己研究了一下maven。以前对他的认识主要是依赖管理，而这几天的学习，对他的plugin机制影响特别深刻。特别的是jetty插件的使用，十分方便。<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;首先需要下载eclipse，推荐最新的Helios版本，安装m2eclipse插件，更新地址为：http://m2eclipse.sonatype.org/sites/m2e/0.10.2.20100623-1649/。新建一个maven项目，并且使用下面的pom文件。具体代码如下：<br />
<br />
<div style="background-color: #eeeeee; font-size: 13px; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; "><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">project&nbsp;</span><span style="color: #FF0000; ">xmlns</span><span style="color: #0000FF; ">="http://maven.apache.org/POM/4.0.0"</span><span style="color: #FF0000; ">&nbsp;xmlns:xsi</span><span style="color: #0000FF; ">="http://www.w3.org/2001/XMLSchema-instance"</span><span style="color: #FF0000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;xsi:schemaLocation</span><span style="color: #0000FF; ">="http://maven.apache.org/POM/4.0.0&nbsp;http://maven.apache.org/maven-v4_0_0.xsd"</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">modelVersion</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">4.0.0</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">modelVersion</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">groupId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">cn.gwssi</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">groupId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">artifactId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">gwssi-extjsptags-demo</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">artifactId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">packaging</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">war</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">packaging</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">version</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">1.0.1-SNAPSHOT</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">version</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">name</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">gwssi-extjsptags-demo&nbsp;Maven&nbsp;Webapp</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">name</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">url</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">http://maven.apache.org</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">url</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">dependencies</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">&lt;!--</span><span style="color: #008000; ">&nbsp;J2EE相关依赖jar包&nbsp;</span><span style="color: #008000; ">--&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">dependency</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">groupId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">org.apache.openejb</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">groupId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">artifactId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">javaee-api</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">artifactId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">version</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">5.0-1</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">version</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">scope</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">provided</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">scope</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">dependency</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">dependency</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">groupId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">javax.faces</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">groupId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">artifactId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">jsf-api</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">artifactId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">version</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">1.2_04</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">version</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">scope</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">provided</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">scope</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">dependency</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">dependency</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">groupId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">javax.servlet</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">groupId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">artifactId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">jstl</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">artifactId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">version</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">1.2</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">version</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">scope</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">provided</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">scope</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">dependency</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">dependency</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">groupId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">javax.servlet.jsp</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">groupId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">artifactId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">jsp-api</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">artifactId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">version</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">2.1</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">version</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">scope</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">provided</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">scope</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">dependency</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">dependency</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">groupId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">javax.faces</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">groupId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">artifactId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">jsf-impl</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">artifactId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">version</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">1.2_04</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">version</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">scope</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">provided</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">scope</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">dependency</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">&lt;!--</span><span style="color: #008000; ">&nbsp;J2EE相关依赖jar包~~~~~~~~~~~~结束&nbsp;</span><span style="color: #008000; ">--&gt;</span><span style="color: #000000; "><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">&lt;!--</span><span style="color: #008000; ">&nbsp;pojo&nbsp;copy&nbsp;(usually&nbsp;for&nbsp;webservice)&nbsp;</span><span style="color: #008000; ">--&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">dependency</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">groupId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">net.sf.dozer</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">groupId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">artifactId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">dozer</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">artifactId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">version</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">5.2.0</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">version</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">dependency</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">dependency</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">groupId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">junit</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">groupId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">artifactId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">junit</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">artifactId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">version</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">4.8.1</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">version</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">type</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">jar</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">type</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">scope</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">test</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">scope</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">dependency</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">dependency</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">groupId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">taglibs</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">groupId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">artifactId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">standard</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">artifactId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">version</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">1.1.2</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">version</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">dependency</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">dependencies</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">build</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">finalName</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">gwssi-extjsptags-demo</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">finalName</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">plugins</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">plugin</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">groupId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">org.apache.maven.plugins</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">groupId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">artifactId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">maven-compiler-plugin</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">artifactId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">configuration</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">source</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">1.5</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">source</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">target</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">1.5</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">target</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">encoding</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">UTF-8</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">encoding</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">configuration</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">plugin</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">plugin</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">groupId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">org.apache.maven.plugins</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">groupId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">artifactId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">maven-javadoc-plugin</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">artifactId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">configuration</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">charset</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">UTF-8</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">charset</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">configuration</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">plugin</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">plugin</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">groupId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">org.mortbay.jetty</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">groupId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">artifactId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">jetty-maven-plugin</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">artifactId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">version</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">7.1.0.RC1</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">version</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">configuration</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">scanIntervalSeconds</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">10</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">scanIntervalSeconds</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">stopKey</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">foo</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">stopKey</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">stopPort</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">9999</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">stopPort</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">configuration</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">dependencies</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">dependency</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">groupId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">commons-logging</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">groupId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">artifactId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">commons-logging</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">artifactId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">version</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">1.1</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">version</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">type</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">jar</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">type</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">dependency</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">dependency</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">groupId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">org.slf4j</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">groupId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">artifactId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">slf4j-jcl</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">artifactId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">version</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">1.0.1</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">version</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">type</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">jar</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">type</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">dependency</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">dependency</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">groupId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">log4j</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">groupId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">artifactId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">log4j</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">artifactId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">version</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">1.2.13</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">version</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">type</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">jar</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">type</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">dependency</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">dependencies</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">plugin</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">plugins</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">build</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">project</span><span style="color: #0000FF; ">&gt;</span></div>
<br />
&nbsp;&nbsp;在eclipse中选择菜单run-》external tools进入，配置2个命令：jetty_run和jetty_stop。其中run命令location为$MAVEN_HOME/bin/mvn.bat，working directory选择当前项目即可，参数输入：-Dslf4j=false -Dlog4j.configuration=file:./target/classes/log4j.properties &nbsp; jetty:run。<br />
&nbsp;&nbsp;stop命令和run命令前面2项相同，参数输入：jetty:stop。<br />
<br />
&nbsp;&nbsp;配置完上面的东西，你马上可以开始一个maven+jetty项目，运行run即可访问http://localhost:8080访问web页面，运行stop关闭服务器。<br />
<br />
<br />
<img src ="http://www.blogjava.net/wangbing/aggbug/325589.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangbing/" target="_blank">王总兵</a> 2010-07-08 20:27 <a href="http://www.blogjava.net/wangbing/archive/2010/07/08/325589.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>The JarRunner Class</title><link>http://www.blogjava.net/wangbing/archive/2010/06/01/322504.html</link><dc:creator>王总兵</dc:creator><author>王总兵</author><pubDate>Tue, 01 Jun 2010 15:51:00 GMT</pubDate><guid>http://www.blogjava.net/wangbing/archive/2010/06/01/322504.html</guid><wfw:comment>http://www.blogjava.net/wangbing/comments/322504.html</wfw:comment><comments>http://www.blogjava.net/wangbing/archive/2010/06/01/322504.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wangbing/comments/commentRss/322504.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangbing/services/trackbacks/322504.html</trackback:ping><description><![CDATA[<span style="font-family: Simsun; font-size: medium; ">The JarRunner application is launched with a command of this form:</span><blockquote style="font-family: Simsun; font-size: medium; ">
<pre>java JarRunner <em>url [arguments]</em>
</pre>
</blockquote><span style="font-family: Simsun; font-size: medium; ">In the previous section, we've seen how</span>&nbsp;<span style="font-family: Simsun; font-size: medium; "><tt>JarClassLoader</tt></span>&nbsp;<span style="font-family: Simsun; font-size: medium; ">is able to identify and load the main class of a JAR-bundled application from a given URL. To complete the JarRunner application, therefore, we need to be able to take a URL and any arguments from the command line, and pass them to an instance of</span>&nbsp;<span style="font-family: Simsun; font-size: medium; "><tt>JarClassLoader</tt></span><span style="font-family: Simsun; font-size: medium; ">. These tasks belong to the</span>&nbsp;<span style="font-family: Simsun; font-size: medium; "><tt>JarRunner</tt></span>&nbsp;<span style="font-family: Simsun; font-size: medium; ">class, the entry point of the JarRunner application.</span>
<p style="font-family: Simsun; font-size: medium; ">It begins by creating a&nbsp;<tt>java.net.URL</tt>&nbsp;object from the URL specified on the command line:</p>
<blockquote style="font-family: Simsun; font-size: medium; ">
<pre>public static void main(String[] args) {
if (args.length &lt; 1) {
usage();
}
URL url = null;
try {
url = new URL(args[0]);
} catch (MalformedURLException e) {
fatal("Invalid URL: " + args[0]);
}
...
</pre>
</blockquote><span style="font-family: Simsun; font-size: medium; ">If</span>&nbsp;<span style="font-family: Simsun; font-size: medium; "><tt>args.length&nbsp;&lt;&nbsp;1</tt></span><span style="font-family: Simsun; font-size: medium; ">, that means no URL was specified on the command line, so a usage message is printed. If the first command-line argument is a good URL, a new</span>&nbsp;<span style="font-family: Simsun; font-size: medium; "><tt>URL</tt></span>&nbsp;<span style="font-family: Simsun; font-size: medium; ">object is created to represent it.</span>
<p style="font-family: Simsun; font-size: medium; ">Next, JarRunner creates a new instance of&nbsp;<tt>JarClassLoader</tt>, passing to the constructor the URL that was specified on the command-line:</p>
<blockquote style="font-family: Simsun; font-size: medium; ">
<pre>JarClassLoader cl = new JarClassLoader(url);
</pre>
</blockquote><span style="font-family: Simsun; font-size: medium; ">As we saw in the previous section, it's through</span>&nbsp;<span style="font-family: Simsun; font-size: medium; "><tt>JarClassLoader</tt></span>&nbsp;<span style="font-family: Simsun; font-size: medium; ">that JarRunner taps into the JAR-handling APIs.</span>
<p style="font-family: Simsun; font-size: medium; ">The URL that's passed to the&nbsp;<tt>JarClassLoader</tt>&nbsp;constructor is the URL of the JAR-bundled application that you want to run. JarRunner next calls the class loader's&nbsp;<tt>getMainClassName</tt>&nbsp;method to identify the entry-point class for the application:</p>
<blockquote style="font-family: Simsun; font-size: medium; ">
<pre>String name = null;
try {
<strong>name = cl.getMainClassName();</strong>
} catch (IOException e) {
System.err.println("I/O error while loading JAR file:");
e.printStackTrace();
System.exit(1);
}
if (name == null) {
fatal("Specified jar file does not contain a 'Main-Class'" +
" manifest attribute");
}
</pre>
</blockquote><span style="font-family: Simsun; font-size: medium; ">The key statement is highlighted in bold. The other statements are for error handling.</span>
<p style="font-family: Simsun; font-size: medium; ">Once&nbsp;<tt>JarRunner</tt>&nbsp;has identified the application's entry-point class, only two steps remain: passing any arguments to the application and actually launching the application.&nbsp;<tt>JarRunner</tt>&nbsp;performs these steps with this code:</p>
<blockquote style="font-family: Simsun; font-size: medium; ">
<pre>// Get arguments for the application
String[] newArgs = new String[args.length - 1];
<strong>System.arraycopy(args, 1, newArgs, 0, newArgs.length);</strong>
// Invoke application's main class
try {
cl.invokeClass(name, newArgs);
} catch (ClassNotFoundException e) {
fatal("Class not found: " + name);
} catch (NoSuchMethodException e) {
fatal("Class does not define a 'main' method: " + name);
} catch (InvocationTargetException e) {
e.getTargetException().printStackTrace();
System.exit(1);
}
</pre>
</blockquote><span style="font-family: Simsun; font-size: medium; ">Recall that the first command-line argument was the URL of the JAR-bundled application. Any arguments to be passed to that application are therefore in element</span>&nbsp;<span style="font-family: Simsun; font-size: medium; "><tt>1</tt></span>&nbsp;<span style="font-family: Simsun; font-size: medium; ">and beyond in the</span>&nbsp;<span style="font-family: Simsun; font-size: medium; "><tt>args</tt></span>&nbsp;<span style="font-family: Simsun; font-size: medium; ">array.</span>&nbsp;<span style="font-family: Simsun; font-size: medium; "><tt>JarRunner</tt></span>&nbsp;<span style="font-family: Simsun; font-size: medium; ">takes those elements, and creates a new array called</span>&nbsp;<span style="font-family: Simsun; font-size: medium; "><tt>newArgs</tt></span>&nbsp;<span style="font-family: Simsun; font-size: medium; ">to pass to the application (bold line above).</span>&nbsp;<span style="font-family: Simsun; font-size: medium; "><tt>JarRunner</tt></span>&nbsp;<span style="font-family: Simsun; font-size: medium; ">then passes the entry-point's class name and the new argument list to the</span>&nbsp;<span style="font-family: Simsun; font-size: medium; "><tt>invokeClass</tt></span><span style="font-family: Simsun; font-size: medium; ">method of</span>&nbsp;<span style="font-family: Simsun; font-size: medium; "><tt>JarClassLoader</tt></span><span style="font-family: Simsun; font-size: medium; ">. As we saw in the previous section,</span>&nbsp;<span style="font-family: Simsun; font-size: medium; "><tt>invokeClass</tt></span>&nbsp;<span style="font-family: Simsun; font-size: medium; ">will load the application's entry-point class, pass it any arguments, and launch the application.</span>
<img src ="http://www.blogjava.net/wangbing/aggbug/322504.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangbing/" target="_blank">王总兵</a> 2010-06-01 23:51 <a href="http://www.blogjava.net/wangbing/archive/2010/06/01/322504.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>The JarClassLoader Class</title><link>http://www.blogjava.net/wangbing/archive/2010/06/01/322503.html</link><dc:creator>王总兵</dc:creator><author>王总兵</author><pubDate>Tue, 01 Jun 2010 15:50:00 GMT</pubDate><guid>http://www.blogjava.net/wangbing/archive/2010/06/01/322503.html</guid><wfw:comment>http://www.blogjava.net/wangbing/comments/322503.html</wfw:comment><comments>http://www.blogjava.net/wangbing/archive/2010/06/01/322503.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wangbing/comments/commentRss/322503.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangbing/services/trackbacks/322503.html</trackback:ping><description><![CDATA[<div id="PageTitle" style="margin-top: 0px; margin-right: 5px; margin-bottom: 0.5em; margin-left: 0px; color: #f90000; font-family: sans-serif; font-weight: bold; font-size: 20px; ">The JarClassLoader Class</div>
<blockquote style="font-family: Simsun; font-size: medium; ">The&nbsp;<tt>JarClassLoader</tt>&nbsp;class extends&nbsp;<tt>java.net.URLClassLoader</tt>. As its name implies,&nbsp;<tt>URLClassLoader</tt>&nbsp;is designed to be used for loading classes and resources that are accessed by searching a set of URLs. The URLs can refer either to directories or to JAR files.
<p>In addition to subclassing&nbsp;<tt>URLClassLoader</tt>,&nbsp;<tt>JarClassLoader</tt>&nbsp;also makes use of features in two other new JAR-related APIs, the&nbsp;<tt>java.util.jar</tt>package and the&nbsp;<tt>java.net.JarURLConnection</tt>&nbsp;class. In this section, we'll look in detail at the constructor and two methods of<tt>JarClassLoader</tt>.</p>
</blockquote>
<h3 style="color: #f90000; font-family: sans-serif; font-size: medium; ">The JarClassLoader Constructor</h3>
<blockquote style="font-family: Simsun; font-size: medium; ">The constructor takes an instance of&nbsp;<tt>java.net.URL</tt>&nbsp;as an argument. The URL passed to this constructor will be used elsewhere in<tt>JarClassLoader</tt>&nbsp;to find the JAR file from which classes are to be loaded.<blockquote>
<pre>public JarClassLoader(URL url) {
super(new URL[] { url });
this.url = url;
}
</pre>
</blockquote>The&nbsp;<tt>URL</tt>&nbsp;object is passed to the constructor of the superclass,&nbsp;<tt>URLClassLoader</tt>, which takes a&nbsp;<tt>URL[]</tt>&nbsp;array, rather than a single&nbsp;<tt>URL</tt>instance, as an argument.</blockquote>
<h3 style="color: #f90000; font-family: sans-serif; font-size: medium; ">The getMainClassName Method</h3>
<blockquote style="font-family: Simsun; font-size: medium; ">Once a&nbsp;<tt>JarClassLoader</tt>&nbsp;object is constructed with the URL of a JAR-bundled application, it's going to need a way to determine which class in the JAR file is the application's entry point. That's the job of the&nbsp;<tt>getMainClassName</tt>&nbsp;method:<blockquote>
<pre>public String getMainClassName() throws IOException {
URL u = new URL("jar", "", url + "!/");
JarURLConnection uc = (JarURLConnection)u.openConnection();
Attributes attr = uc.getMainAttributes();
return attr != null
? attr.getValue(Attributes.Name.MAIN_CLASS)
: null;
}
</pre>
</blockquote>You may recall from a&nbsp;<a href="http://java.sun.com/docs/books/tutorial/deployment/jar/run.html#1.2">previous lesson</a>&nbsp;that a JAR-bundled application's entry point is specified by the&nbsp;<tt>Main-Class</tt>&nbsp;header of the JAR file's manifest. To understand how&nbsp;<tt>getMainClassName</tt>&nbsp;accesses the&nbsp;<tt>Main-Class</tt>&nbsp;header value, let's look at the method in detail, paying special attention to the new JAR-handling features that it uses:
<h3 style="color: #f90000; font-family: sans-serif; ">The JarURLConnection class and JAR URLs</h3>
The&nbsp;<tt>getMainClassName</tt>&nbsp;method uses the JAR URL format specified by the&nbsp;<tt>java.net.JarURLConnection</tt>&nbsp;class. The syntax for the URL of a JAR file is as in this example:<blockquote>
<pre>jar:http://www.xxx.yyy/jarfile.jar!/
</pre>
</blockquote>The terminating&nbsp;<tt>!/</tt>&nbsp;separator indicates that the URL refers to an entire JAR file. Anything following the separator refers to specific JAR-file contents, as in this example:<blockquote>
<pre>jar:http://www.xxx.yyy/jarfile.jar!/mypackage/myclass.class
</pre>
</blockquote>
<p>The first line in the&nbsp;<tt>getMainClassName</tt>&nbsp;method is:</p>
<blockquote>
<pre>URL u = new URL("jar", "", url + "!/");
</pre>
</blockquote>This statement constructs a new&nbsp;<tt>URL</tt>&nbsp;object representing a JAR URL, appending the&nbsp;<tt>!/</tt>&nbsp;separator to the URL that was used in creating the<tt>JarClassLoader</tt>&nbsp;instance.
<h3 style="color: #f90000; font-family: sans-serif; ">The java.net.JarURLConnection class</h3>
This class represents a communications link between an application and a JAR file. It has methods for accessing the JAR file's manifest. The second line of&nbsp;<tt>getMainClassName</tt>&nbsp;is:<blockquote>
<pre>JarURLConnection uc = (JarURLConnection)u.openConnection();
</pre>
</blockquote>In this statement,&nbsp;<tt>URL</tt>&nbsp;instance created in the first line opens a&nbsp;<tt>URLConnection</tt>. The&nbsp;<tt>URLConnection</tt>&nbsp;instance is then cast to&nbsp;<tt>JarURLConnection</tt>so it can take advantage of&nbsp;<tt>JarURLConnection</tt>'s JAR-handling features.
<h3 style="color: #f90000; font-family: sans-serif; ">Fetching Manifest Attributes: java.util.jar.Attributes</h3>
With a&nbsp;<tt>JarURLConnection</tt>&nbsp;open to a JAR file, you can access the header information in the JAR file's manifest by using the<tt>getMainAttributes</tt>&nbsp;method of&nbsp;<tt>JarURLConnection</tt>. This method returns an instance of&nbsp;<tt>java.util.jar.Attributes</tt>, a class that maps header names in JAR-file manifests with their associated string values. The third line in&nbsp;<tt>getMainClassName</tt>&nbsp;creates an&nbsp;<tt>Attributes</tt>&nbsp;object:<blockquote>
<pre>Attributes attr = uc.getMainAttributes();
</pre>
</blockquote>
<p>To get the value of the manifest's&nbsp;<tt>Main-Class</tt>&nbsp;header, the fourth line of&nbsp;<tt>getMainClassName</tt>&nbsp;invokes the&nbsp;<tt>Attributes.getValue</tt>&nbsp;method:</p>
<blockquote>
<pre>return attr != null
? attr.getValue(Attributes.Name.MAIN_CLASS)
: null;
</pre>
</blockquote>The method's argument,&nbsp;<tt>Attributes.Name.MAIN_CLASS</tt>, specifies that it's the value of the&nbsp;<tt>Main-Class</tt>&nbsp;header that you want. (The&nbsp;<tt>Attributes.Name</tt>class also provides static fields such as&nbsp;<tt>MANIFEST_VERSION</tt>,&nbsp;<tt>CLASS_PATH</tt>, and&nbsp;<tt>SEALED</tt>&nbsp;for specifying other standard manifest headers.)</blockquote>
<h3 style="color: #f90000; font-family: sans-serif; font-size: medium; ">The invokeClass Method</h3>
<blockquote style="font-family: Simsun; font-size: medium; ">We've seen how&nbsp;<tt>JarURLClassLoader</tt>&nbsp;can identify the main class in a JAR-bundled application. The last method to consider,<tt>JarURLClassLoader.invokeClass</tt>, enables that main class to be invoked to launch the JAR-bundled application:<blockquote>
<pre>public void invokeClass(String name, String[] args)
throws ClassNotFoundException,
NoSuchMethodException,
InvocationTargetException
{
Class c = loadClass(name);
Method m = c.getMethod("main", new Class[] { args.getClass() });
m.setAccessible(true);
int mods = m.getModifiers();
if (m.getReturnType() != void.class || !Modifier.isStatic(mods) ||
!Modifier.isPublic(mods)) {
throw new NoSuchMethodException("main");
}
try {
m.invoke(null, new Object[] { args });
} catch (IllegalAccessException e) {
// This should not happen, as we have disabled access checks
}
}
</pre>
</blockquote>
<p>The&nbsp;<tt>invokeClass</tt>&nbsp;method takes two arguments: the name of the application's entry-point class and an array of string arguments to pass to the entry-point class's&nbsp;<tt>main</tt>&nbsp;method. First, the main class is loaded:</p>
<blockquote>
<pre>Class c = loadClass(name);
</pre>
</blockquote>The&nbsp;<tt>loadClass</tt>&nbsp;method is inherited from&nbsp;<tt>java.lang.ClassLoader</tt>.
<p>Once the main class is loaded, the reflection API of the&nbsp;<tt>java.lang.reflect</tt>&nbsp;package is used to pass the arguments to the class and launch it. You can refer to the tutorial on&nbsp;<a href="http://java.sun.com/docs/books/tutorial/reflect/index.html">The Reflection API</a>&nbsp;for a review of reflection.</p>
</blockquote>
<img src ="http://www.blogjava.net/wangbing/aggbug/322503.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangbing/" target="_blank">王总兵</a> 2010-06-01 23:50 <a href="http://www.blogjava.net/wangbing/archive/2010/06/01/322503.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java或者JAR包获取读取资源文件的路径的问题总结</title><link>http://www.blogjava.net/wangbing/archive/2010/06/01/322501.html</link><dc:creator>王总兵</dc:creator><author>王总兵</author><pubDate>Tue, 01 Jun 2010 15:32:00 GMT</pubDate><guid>http://www.blogjava.net/wangbing/archive/2010/06/01/322501.html</guid><wfw:comment>http://www.blogjava.net/wangbing/comments/322501.html</wfw:comment><comments>http://www.blogjava.net/wangbing/archive/2010/06/01/322501.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wangbing/comments/commentRss/322501.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangbing/services/trackbacks/322501.html</trackback:ping><description><![CDATA[<table width="100%" style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; color: #333333; font-family: Verdana, Arial, Tahoma; font-size: 14px; line-height: 25px; ">
    <tbody style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">
        <tr style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">
            <td style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">这里分为具体两种：</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">第一种：资源文件为一般后缀文件</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">第二种：资源文件为图片文件</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">【NO1】第一种</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp; 使用这行代码可以获取class类的根目录的路径</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp; String path =Thread.currentThread().getContextClassLoader().getResource("").getPath();</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;例子：我用的开发软件MyEclipse 6.5</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;假设项目文件夹如下：</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp; files———bin——core(生成class包)</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&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; |——Main.class（生成的class文件）</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |——resource（ 生成资源文件夹）</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&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; |——a.bat</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&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; |——b.png</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |———src——core(源包)&nbsp;</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&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; |—— Main.java(源代码)</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |——resource（源资源文件夹）&nbsp;</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&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; |——a.bat</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&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; |——b.png</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">//源代码Main.java</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">//============================================================</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">package core;<br style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; " />
            import java.io.File;</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">public class Main {</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp; public static void main(String[] args){<br style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; " />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try{<br style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; " />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String path = Thread.currentThread().getContextClassLoader().getResource("").getPath();&nbsp;&nbsp;&nbsp; //添加<br style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; " />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; File af=new File(path+"/resource");<br style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; " />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(!af.exists()) System.out.println("nullEXIST");;<br style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; " />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String[] files =af.list();<br style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; " />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(files.length==0) System.out.println("nullLENGTH");;<br style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; " />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int i=0;i&lt;files.length;i++){<br style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; " />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(files[i]!=null)System.out.println(files[i]);<br style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; " />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else System.out.println("null");<br style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; " />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; " />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; " />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; " />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch(Exception e){<br style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; " />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("HugeERROR");<br style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; " />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; " />
            &nbsp;&nbsp;&nbsp; }<br style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; " />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; " />
            }</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">// ===============================================================</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp; 运行结果：</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;a.bat</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;b.png&nbsp;&nbsp;</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;就对了&nbsp;&nbsp;</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">【NO2】第二种</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;建议使用下面( 2 )方法，因为（1）jar之后可能出现找不到的问题 (之前我试过出现这种情况)</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;这里代码省了</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">（1）、你将所有资源打包为epm.jar，你的类位于一个包中：package core;你的图片资源全部放在images文件夹中，而images文件夹也位于core包内。这样的话，最终的路径表现为：<br style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; " />
            epm———bin——core(生成class包)</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&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; |——Main.class（生成的class文件）</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |——images（ 生成资源文件夹）</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&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; |——system.bat</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&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; |——background.png</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |———src——core(源包)&nbsp;</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&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; |—— Main.java(源代码)</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |——images（源资源文件夹）&nbsp;</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&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; |——system.bat</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&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; |——background.png</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp; 可以通过相对路径来访问：&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp; java.net.URL imUrl = getClass().getResource("images/background.png");&nbsp;<br style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; " />
            &nbsp; ImageIcon im = new ImageIcon(imUrl);</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">（2）、另一种情况，如果你的类有很多，并且包的结构很复杂，应该把图片放到最外层，让所有的类通过绝对路径来访问该图片</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">epm———bin——core(生成class包)</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&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; |——Main.class（生成的class文件）</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |——images（ 生成资源文件夹）</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&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; |——system.bat</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&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; |——background.png</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |———src——core(源包)&nbsp;</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&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; |—— Main.java(源代码)</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |——images（源资源文件夹）&nbsp;</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&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; |——system.bat</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&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; |——background.png</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">java.net.URL imUrl = getClass().getResource("/images/background.png");<br style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; " />
            ImageIcon im = new ImageIcon(imgUrl);</p>
            <p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">区别非常细微，仅仅是在&#8220;images&#8221;的前面加了一个反斜杠"/"，这个反斜杠就表示根目录，没有反斜杠就表示相对路径。</p>
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.blogjava.net/wangbing/aggbug/322501.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangbing/" target="_blank">王总兵</a> 2010-06-01 23:32 <a href="http://www.blogjava.net/wangbing/archive/2010/06/01/322501.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>maven笔记</title><link>http://www.blogjava.net/wangbing/archive/2010/05/31/322393.html</link><dc:creator>王总兵</dc:creator><author>王总兵</author><pubDate>Mon, 31 May 2010 14:17:00 GMT</pubDate><guid>http://www.blogjava.net/wangbing/archive/2010/05/31/322393.html</guid><wfw:comment>http://www.blogjava.net/wangbing/comments/322393.html</wfw:comment><comments>http://www.blogjava.net/wangbing/archive/2010/05/31/322393.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wangbing/comments/commentRss/322393.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangbing/services/trackbacks/322393.html</trackback:ping><description><![CDATA[<div style="background-color: #eeeeee; font-size: 13px; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; "><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000; ">http:</span><span style="color: #008000; ">//</span><span style="color: #008000; ">subclipse.tigris.org/update_1.6.x&nbsp;&nbsp;&nbsp;SVN插件</span><span style="color: #008000; "><br />
</span><span style="color: #000000; ">http:</span><span style="color: #008000; ">//</span><span style="color: #008000; ">m2eclipse.sonatype.org/sites/m2e&nbsp;MAVEN插件</span><span style="color: #008000; "><br />
</span><span style="color: #000000; "><br />
m2eclipse更新站点<br />
核心组件：http:</span><span style="color: #008000; ">//</span><span style="color: #008000; ">m2eclipse.sonatype.org/sites/m2e</span><span style="color: #008000; "><br />
</span><span style="color: #000000; ">可选组件：http:</span><span style="color: #008000; ">//</span><span style="color: #008000; ">m2eclipse.sonatype.org/sites/m2e-extras</span></div>
<img src ="http://www.blogjava.net/wangbing/aggbug/322393.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangbing/" target="_blank">王总兵</a> 2010-05-31 22:17 <a href="http://www.blogjava.net/wangbing/archive/2010/05/31/322393.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>maven安装jar包到仓库中</title><link>http://www.blogjava.net/wangbing/archive/2010/05/24/321725.html</link><dc:creator>王总兵</dc:creator><author>王总兵</author><pubDate>Mon, 24 May 2010 07:05:00 GMT</pubDate><guid>http://www.blogjava.net/wangbing/archive/2010/05/24/321725.html</guid><wfw:comment>http://www.blogjava.net/wangbing/comments/321725.html</wfw:comment><comments>http://www.blogjava.net/wangbing/archive/2010/05/24/321725.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wangbing/comments/commentRss/321725.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangbing/services/trackbacks/321725.html</trackback:ping><description><![CDATA[mvn install:install-file -Dfile=osworkflow-2.8.0.jar -DgroupId=opensymphony -DartifactId=osworkflow -Dversion=2.8 -Dpackaging=jar
<img src ="http://www.blogjava.net/wangbing/aggbug/321725.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangbing/" target="_blank">王总兵</a> 2010-05-24 15:05 <a href="http://www.blogjava.net/wangbing/archive/2010/05/24/321725.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>线程2种方式的差异</title><link>http://www.blogjava.net/wangbing/archive/2010/04/26/319371.html</link><dc:creator>王总兵</dc:creator><author>王总兵</author><pubDate>Mon, 26 Apr 2010 03:46:00 GMT</pubDate><guid>http://www.blogjava.net/wangbing/archive/2010/04/26/319371.html</guid><wfw:comment>http://www.blogjava.net/wangbing/comments/319371.html</wfw:comment><comments>http://www.blogjava.net/wangbing/archive/2010/04/26/319371.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/wangbing/comments/commentRss/319371.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangbing/services/trackbacks/319371.html</trackback:ping><description><![CDATA[继承Thread类的方式实现起来较为简单，但是继承它的类<br />
就不能再继承别的类了，因此也就不能继承别的类的有用的方法了。而使用是想Runnable<br />
接口的方式就不存在这个问题了，而且这种实现方式将线程主体和线程对象本身分离开来，<br />
逻辑上也较为清晰，所以推荐大家更多地采用这种方式。<br />
<br />
但是对于继承方式调用，使用start方式后实际上里面的属性是不多份的，即多个对象的线程在跑。<br />
而接口方式是同一个对象的多个线程在跑。<br />
<br />
<img src ="http://www.blogjava.net/wangbing/aggbug/319371.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangbing/" target="_blank">王总兵</a> 2010-04-26 11:46 <a href="http://www.blogjava.net/wangbing/archive/2010/04/26/319371.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于Collection接口下相关类接口的问题及分析</title><link>http://www.blogjava.net/wangbing/archive/2010/04/26/319370.html</link><dc:creator>王总兵</dc:creator><author>王总兵</author><pubDate>Mon, 26 Apr 2010 03:43:00 GMT</pubDate><guid>http://www.blogjava.net/wangbing/archive/2010/04/26/319370.html</guid><wfw:comment>http://www.blogjava.net/wangbing/comments/319370.html</wfw:comment><comments>http://www.blogjava.net/wangbing/archive/2010/04/26/319370.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wangbing/comments/commentRss/319370.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangbing/services/trackbacks/319370.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Normal07.8 磅02falsefalsefalseMicrosoftInternetExplorer4/* Style Definitions */table.MsoNormalTable{mso-style-name:普通表格;mso-tstyl...&nbsp;&nbsp;<a href='http://www.blogjava.net/wangbing/archive/2010/04/26/319370.html'>阅读全文</a><img src ="http://www.blogjava.net/wangbing/aggbug/319370.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangbing/" target="_blank">王总兵</a> 2010-04-26 11:43 <a href="http://www.blogjava.net/wangbing/archive/2010/04/26/319370.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JMS应用领域</title><link>http://www.blogjava.net/wangbing/archive/2010/03/23/316344.html</link><dc:creator>王总兵</dc:creator><author>王总兵</author><pubDate>Tue, 23 Mar 2010 10:32:00 GMT</pubDate><guid>http://www.blogjava.net/wangbing/archive/2010/03/23/316344.html</guid><wfw:comment>http://www.blogjava.net/wangbing/comments/316344.html</wfw:comment><comments>http://www.blogjava.net/wangbing/archive/2010/03/23/316344.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wangbing/comments/commentRss/316344.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangbing/services/trackbacks/316344.html</trackback:ping><description><![CDATA[<div style="background-color: #eeeeee; font-size: 13px; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; "><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000; ">1</span><span style="color: #000000; ">.消息类型的选择<br />
Java的JMS消息类型有文本类型,对象类型,字节类型,流类型,XML类型,在实际项目中,用的最多的是文本类型,对象类型和xml类型的消息.建议最好不用对象类型,因为如果用对象类型的话,调试的时候是很麻烦的,首先你必须要写专门的测试代码用来发送消息,第二,必须要管理对象所属的类的不同版本,第三,不方便查看queue或者topic中的消息内容.而如果使用文本类型或者xml类型的消息,那么可以很容易的通过JMS中间件提供的一些管理工具来发送测试消息,查看消息内容,并且更加容易管理不同版本之间的兼容性.如果一定要用对象类型消息的话,建议使用xstream把对象转化为xml&nbsp;.<br />
<br />
</span><span style="color: #000000; ">2</span><span style="color: #000000; ">.是使用queue还是topic</span><span style="color: #000000; ">?</span><span style="color: #000000; "><br />
这两者的定义是很清楚的,也很容易区分.但是在实际项目中,如何来取舍呢</span><span style="color: #000000; ">?</span><span style="color: #000000; ">我的建议是尽量用queue.如果你的项目用到了JMS,那么你的系统也应该是到了需要部署在集群环境的规模了.用topic在集群环境下会带来很多麻烦.举个简单的例子,如果你是用MDB来处理topic的消息,你有一个MDB名为SampleMDB,它以集群的方式分别部署在A服务器和B服务器上.那么有可能同一条topic消息被同一个MDB处理两次.虽然一些JMS中间件提供商为解决这种问题提供了一些解决方案,例如把subsriber分组,但是它为开发和调试都带来了很大的麻烦.topic消息的处理也要比queue的复杂,很难跟踪topic消息的处理过程.<br />
那么,如果不用topic的话,怎么来实现topic这种性质的消息处理呢</span><span style="color: #000000; ">?</span><span style="color: #000000; ">可以写一个消息转发器,把一个queue上的消息转发给所有关注这个queue的其它queue中.例如,有一个queue,名为SampleQ1,一个消息发送者sender,一个消息转发器router,有三个handler&nbsp;A,B,C需要处理这个queue中的消息.那么,sender发送消息到SampleQ1,router接收SampleQ1的消息后分别发送到SampleQ1_A,SampleQ1_B,SampleQ1_C,handler&nbsp;A,B,C分别从队列SampleQ1_A,SampleQ1_B,SampleQ1_C中接收消息.&nbsp;<br />
<br />
</span><span style="color: #000000; ">3</span><span style="color: #000000; ">.用JMS来解决什么问题</span><span style="color: #000000; ">?</span><span style="color: #000000; "><br />
一提起JMS可以做什么,第一想到的就是异步处理.面试的时候问JMS可以做什么</span><span style="color: #000000; ">?</span><span style="color: #000000; ">大多数的回答是:用JMS来异步发送邮件</span><span style="color: #000000; ">!</span><span style="color: #000000; ">其实,还可以用JMS来解决很多复杂的问题,例如分布,并发,系统解耦,负载均衡,热部署,触发器等等,这些复杂的问题因为引入了JMS而变的更加简单.下面简单介绍下解决分布,并发问题的场景.<br />
</span><span style="color: #000000; ">3.1</span><span style="color: #000000; ">&nbsp;用JMS来解决并发问题<br />
queue的概念大家都很清楚了,那就是queue里的一条消息只会被一个消息接收者处理.基于这个概念,我们可以在系统中对并发要求很严格的模块中引入JMS的使用.例如,系统的送积分,一般这个模块是用一个定时器,例如quartz,每天定期查询数据库,如果发现有满足条件的记录,那么就把积分送给会员.如果同时有多个quartz在运行,那么必须严格控制防止并发的对同一条记录送多次积分.解决这个问题有很多方法,可以通过业务的设计,系统的部署,数据库的设计,事务的控制等方法来实现,在这里提一个用JMS来解决问题的方法:在插入记录的同时发送一个queue的消息.这样即使有多个送积分的MDB实例在运行,也只会被一个实例处理.&nbsp;<br />
<br />
</span><span style="color: #000000; ">3</span><span style="color: #000000; ">.2用JMS来解决分布的问题<br />
解决分布有两种类型,第一种是指消息是集中的,但消息的处理是分布的.例如,系统可能会被分为前台与后台,这两个系统是部署在不同的网段里的.那么怎么把前台发生的业务通知后台系统呢</span><span style="color: #000000; ">?</span><span style="color: #000000; ">当然,可以通过一个类似定时器的玩意定期去数据库查询.但这种方式要么就是浪费系统资源,可能在定期查询中80</span><span style="color: #000000; ">%</span><span style="color: #000000; ">的时间都是在做无用功,要么就是业务请求没有被及时处理.,因为定期的时间总是有一个时间间隔的.用JMS来处理这个问题会怎么样呢</span><span style="color: #000000; ">?</span><span style="color: #000000; ">前台系统在处理完业务请求后的同时发送一个消息到queue中,后台系统的消息接收者接收到消息后立即处理.这里消息的处理也可能有一定的延期,但这主要取决于消息服务器的硬件能力,网络带宽,消息接收者的处理速度等.&nbsp;<br />
<br />
第二中是指消息也是分布的.很多消息中间件都提供了消息路由的功能,即消息发送到一个消息服务器后,这个消息服务器根据定义的规则再把这条消息路由转发到其它的消息服务器.例如,可能在北京的一个数据中心部署了数据采集系统,采集到数据后以消息的方式发送到消息服务器,然后消息服务器再把这条消息路由到上海的数据中心,再由上海数据中心部署的数据处理系统来处理这条消息.&nbsp;<br />
<br />
</span><span style="color: #000000; ">4</span><span style="color: #000000; ">.JMS与事务,一定要用JTA事务吗<br />
很多人接触到JTA事务都是从用JMS开始的,毕竟同时要连多个数据库的的系统并不是那么的多</span><span style="color: #000000; ">!</span><span style="color: #000000; ">而要用JTA事务的话,就得要在笨重的应用服务器中部署.(当然,你也可以用类似atomikos的轻量级JTA事务管理器),更重要的是,并不是事务本身的技术有多复杂,而是事务的界定,这种事务的界定有时都不是程序员能决定的事情,需要在设计的时候就要考虑清楚,甚至可能还需要业务人员的参与.(题外话:经常问面试的,用spring的aop做什么</span><span style="color: #000000; ">?</span><span style="color: #000000; ">大多数答:用来管理事务</span><span style="color: #000000; ">!</span><span style="color: #000000; ">事务要真这么简单该多好啊</span><span style="color: #000000; ">!</span><span style="color: #000000; ">)&nbsp;<br />
我也不是要反对用JTA事务,而是要说明一下,用JMS,并非一定要用JTA事务.这可以分为三种场景:<br />
一,必须用JTA事务,这种情况下,一般消息的接收者只从消息本身获得数据并进行处理.所以必须要保证消息的发送与所依赖的业务保持一致.<br />
二.不需要用事务,这种情况下,&nbsp;要么是业务无关紧要,例如用JMS来记录日志.要么是发送的消息仅仅是一个作为后续业务处理的一个触发器</span><span style="color: #000000; ">!</span><span style="color: #000000; ">消息接收者仅仅是从消息中获得一个id,然后根据这个id去查询所依赖的其它数据进行业务处理.即使消息丢失也没关系,可以通过其它的机制来补偿.<br />
三.消息丢失可以通过补偿事务来完成.这个依赖与具体实现,就不详细说了.&nbsp;<br />
<br />
</span><span style="color: #000000; ">5</span><span style="color: #000000; ">.处理消息永远比发送消息慢</span><span style="color: #000000; ">!</span><span style="color: #000000; "><br />
要保证你的JMS应用稳定的运行,那么你必须在开发,部署的时候时刻重视这个问题.&nbsp;<br />
首先,需要把发送消息的连接池与接收消息的连接池分开.以避免接收消息的连接过过而导致发送消息的应用拿不到连接.&nbsp;<br />
在一个连接上并发的处理消息,而不是连接打开,处理一个消息,马上关闭连接.<br />
合理的设置消息的过期时间,否则消息日积月累,最终超出queue的size&nbsp;<br />
对于非关键业务的消息处理,可以采用异步处理的方法:接收到消息后并不是立刻处理,而是放到一个任务池或者线程池中处理.如果消息处理失败,则把消息重新发送回队列中.</span></div>
<img src ="http://www.blogjava.net/wangbing/aggbug/316344.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangbing/" target="_blank">王总兵</a> 2010-03-23 18:32 <a href="http://www.blogjava.net/wangbing/archive/2010/03/23/316344.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>准备找工作</title><link>http://www.blogjava.net/wangbing/archive/2010/03/21/316098.html</link><dc:creator>王总兵</dc:creator><author>王总兵</author><pubDate>Sun, 21 Mar 2010 13:21:00 GMT</pubDate><guid>http://www.blogjava.net/wangbing/archive/2010/03/21/316098.html</guid><wfw:comment>http://www.blogjava.net/wangbing/comments/316098.html</wfw:comment><comments>http://www.blogjava.net/wangbing/archive/2010/03/21/316098.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wangbing/comments/commentRss/316098.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangbing/services/trackbacks/316098.html</trackback:ping><description><![CDATA[最近准备找工作了，需要更新一下知识体系了。NoSQL，集群，多线程，NIO等等，很多以前没有接触，一知半解的东西都需要好好学习下。<br />
工作3年，技术面广了，但是深入程度始终不行。
<img src ="http://www.blogjava.net/wangbing/aggbug/316098.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangbing/" target="_blank">王总兵</a> 2010-03-21 21:21 <a href="http://www.blogjava.net/wangbing/archive/2010/03/21/316098.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>jspSmartUpload组件的一些方法</title><link>http://www.blogjava.net/wangbing/archive/2010/03/16/315644.html</link><dc:creator>王总兵</dc:creator><author>王总兵</author><pubDate>Tue, 16 Mar 2010 15:06:00 GMT</pubDate><guid>http://www.blogjava.net/wangbing/archive/2010/03/16/315644.html</guid><wfw:comment>http://www.blogjava.net/wangbing/comments/315644.html</wfw:comment><comments>http://www.blogjava.net/wangbing/archive/2010/03/16/315644.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wangbing/comments/commentRss/315644.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangbing/services/trackbacks/315644.html</trackback:ping><description><![CDATA[<div style="background-color: #eeeeee; font-size: 13px; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; "><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000; ">　　jspSmartUpload是由www.jspsmart.com网站开发的一个可免费使用的全功能的文件上传下载组件，适于嵌入执行上传下载操作的JSP文件中。该组件有以下几个特点：&nbsp;<br />
1、使用简单。在JSP文件中仅仅书写三五行JAVA代码就可以搞定文件的上传或下载，方便。&nbsp;<br />
2、能全程控制上传。利用jspSmartUpload组件提供的对象及其操作方法，可以获得全部上传文件的信息（包括文件名，大小，类型，扩展名，文件数据等），方便存取。&nbsp;<br />
3、能对上传的文件在大小、类型等方面做出限制。如此可以滤掉不符合要求的文件。&nbsp;<br />
4、下载灵活。仅写两行代码，就能把Web服务器变成文件服务器。不管文件在Web服务器的目录下或在其它任何目录下，都可以利用jspSmartUpload进行下载。&nbsp;<br />
5、能将文件上传到数据库中，也能将数据库中的数据下载下来。这种功能针对的是MYSQL数据库，因为不具有通用性，所以本文不准备举例介绍这种用法。&nbsp;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jspSmartUpload组件可以从www.jspsmart.com网站上自由下载，压缩包的名字是jspSmartUpload.zip。下载后，用WinZip或WinRAR将其解压到Tomcat的webapps目录下（本文以Tomcat服务器为例进行介绍）。解压后，将webapps/jspsmartupload目录下的子目录Web-inf名字改为全大写的WEB-INF，这样一改jspSmartUpload类才能使用。因为Tomcat对文件名大小写敏感，它要求Web应用程序相关的类所在目录为WEB-INF，且必须是大写。接着重新启动Tomcat，这样就可以在JSP文件中使用jspSmartUpload组件了。&nbsp;<br />
<br />
<br />
注意，按上述方法安装后，只有webapps/jspsmartupload目录下的程序可以使用jspSmartUpload组件，如果想让Tomcat服务器的所有Web应用程序都能用它，必须做如下工作：&nbsp;<br />
<br />
1．进入命令行状态，将目录切换到Tomcat的webapps/jspsmartupload/WEB-INF目录下。&nbsp;<br />
2．运行JAR打包命令：jar&nbsp;cvf&nbsp;jspSmartUpload.jar&nbsp;com<br />
（也可以打开资源管理器，切换到当前目录，用WinZip将com目录下的所有文件压缩成jspSmartUpload.zip，然后将jspSmartUpload.zip换名为jspSmartUpload.jar文件即可。）&nbsp;<br />
3．将jspSmartUpload.jar拷贝到Tomcat的shared/lib目录下。&nbsp;<br />
<br />
一、相关类说明篇<br />
㈠&nbsp;File类&nbsp;<br />
这个类包装了一个上传文件的所有信息。通过它，可以得到上传文件的文件名、文件大小、扩展名、文件数据等信息。&nbsp;<br />
File类主要提供以下方法：&nbsp;<br />
1、saveAs作用：将文件换名另存。&nbsp;<br />
原型：&nbsp;<br />
public&nbsp;void&nbsp;saveAs(java.lang.String&nbsp;destFilePathName)<br />
或&nbsp;<br />
public&nbsp;void&nbsp;saveAs(java.lang.String&nbsp;destFilePathName,&nbsp;int&nbsp;optionSaveAs)<br />
其中，destFilePathName是另存的文件名，optionSaveAs是另存的选项，该选项有三个值，分别是SAVEAS_PHYSICAL,SAVEAS_VIRTUAL，SAVEAS_AUTO。SAVEAS_PHYSICAL表明以操作系统的根目录为文件根目录另存文件，SAVEAS_VIRTUAL表明以Web应用程序的根目录为文件根目录另存文件，SAVEAS_AUTO则表示让组件决定，当Web应用程序的根目录存在另存文件的目录时，它会选择SAVEAS_VIRTUAL，否则会选择SAVEAS_PHYSICAL。&nbsp;<br />
<br />
例如，saveAs("/upload/sample.zip",SAVEAS_PHYSICAL)执行后若Web服务器安装在C盘，则另存的文件名实际是c:\upload\sample.zip。而saveAs("/upload/sample.zip",SAVEAS_VIRTUAL)执行后若Web应用程序的根目录是webapps/jspsmartupload，则另存的文件名实际是webapps/jspsmartupload/upload/sample.zip。saveAs("/upload/sample.zip",SAVEAS_AUTO)执行时若Web应用程序根目录下存在upload目录，则其效果同saveAs("/upload/sample.zip",SAVEAS_VIRTUAL)，否则同saveAs("/upload/sample.zip",SAVEAS_PHYSICAL)。&nbsp;<br />
建议：对于Web程序的开发来说，最好使用SAVEAS_VIRTUAL，以便移植。&nbsp;<br />
<br />
2、isMissing<br />
作用：这个方法用于判断用户是否选择了文件，也即对应的表单项是否有值。选择了文件时，它返回false。未选文件时，它返回true。&nbsp;<br />
原型：public&nbsp;boolean&nbsp;isMissing()<br />
<br />
3、getFieldName<br />
作用：取HTML表单中对应于此上传文件的表单项的名字。&nbsp;<br />
原型：public&nbsp;String&nbsp;getFieldName()<br />
<br />
4、getFileName<br />
作用：取文件名（不含目录信息）&nbsp;<br />
原型：public&nbsp;String&nbsp;getFileName()<br />
<br />
5、getFilePathName<br />
作用：取文件全名（带目录）&nbsp;<br />
原型：public&nbsp;String&nbsp;getFilePathName<br />
<br />
6、getFileExt<br />
作用：取文件扩展名（后缀）&nbsp;<br />
原型：public&nbsp;String&nbsp;getFileExt()<br />
<br />
7、getSize<br />
作用：取文件长度（以字节计）&nbsp;<br />
原型：public&nbsp;int&nbsp;getSize()<br />
<br />
8、getBinaryData<br />
作用：取文件数据中指定位移处的一个字节，用于检测文件等处理。&nbsp;<br />
原型：public&nbsp;byte&nbsp;getBinaryData(int&nbsp;index)。其中，index表示位移，其值在0到getSize()-1之间。&nbsp;<br />
<br />
㈡&nbsp;Files类&nbsp;<br />
这个类表示所有上传文件的集合，通过它可以得到上传文件的数目、大小等信息。有以下方法：&nbsp;<br />
1、getCount<br />
作用：取得上传文件的数目。&nbsp;<br />
原型：public&nbsp;int&nbsp;getCount()<br />
<br />
2、getFile<br />
作用：取得指定位移处的文件对象File（这是com.jspsmart.upload.File，不是java.io.File，注意区分）。&nbsp;<br />
原型：public&nbsp;File&nbsp;getFile(int&nbsp;index)。其中，index为指定位移，其值在0到getCount()-1之间。&nbsp;<br />
<br />
3、getSize<br />
作用：取得上传文件的总长度，可用于限制一次性上传的数据量大小。&nbsp;<br />
原型：public&nbsp;long&nbsp;getSize()<br />
<br />
4、getCollection<br />
作用：将所有上传文件对象以Collection的形式返回，以便其它应用程序引用，浏览上传文件信息。&nbsp;<br />
原型：public&nbsp;Collection&nbsp;getCollection()<br />
<br />
5、getEnumeration<br />
作用：将所有上传文件对象以Enumeration（枚举）的形式返回，以便其它应用程序浏览上传文件信息。&nbsp;<br />
原型：public&nbsp;Enumeration&nbsp;getEnumeration()<br />
<br />
㈢&nbsp;Request类&nbsp;<br />
这个类的功能等同于JSP内置的对象request。只所以提供这个类，是因为对于文件上传表单，通过request对象无法获得表单项的值，必须通过jspSmartUpload组件提供的Request对象来获取。该类提供如下方法：&nbsp;<br />
<br />
1、getParameter<br />
作用：获取指定参数之值。当参数不存在时，返回值为null。&nbsp;<br />
原型：public&nbsp;String&nbsp;getParameter(String&nbsp;name)。其中，name为参数的名字。&nbsp;<br />
<br />
2、getParameterValues<br />
作用：当一个参数可以有多个值时，用此方法来取其值。它返回的是一个字符串数组。当参数不存在时，返回值为null。&nbsp;<br />
原型：public&nbsp;String[]&nbsp;getParameterValues(String&nbsp;name)。其中，name为参数的名字。&nbsp;<br />
<br />
3、getParameterNames<br />
作用：取得Request对象中所有参数的名字，用于遍历所有参数。它返回的是一个枚举型的对象。&nbsp;<br />
原型：public&nbsp;Enumeration&nbsp;getParameterNames()<br />
<br />
㈣&nbsp;SmartUpload类这个类完成上传下载工作。&nbsp;<br />
<br />
A．上传与下载共用的方法：&nbsp;<br />
只有一个：initialize。&nbsp;<br />
作用：执行上传下载的初始化工作，必须第一个执行。&nbsp;<br />
原型：有多个，主要使用下面这个：&nbsp;<br />
public&nbsp;final&nbsp;void&nbsp;initialize(javax.servlet.jsp.PageContext&nbsp;pageContext)<br />
其中，pageContext为JSP页面内置对象（页面上下文）。&nbsp;<br />
<br />
B．上传文件使用的方法：&nbsp;<br />
1、upload<br />
作用：上传文件数据。对于上传操作，第一步执行initialize方法，第二步就要执行这个方法。&nbsp;<br />
原型：public&nbsp;void&nbsp;upload()<br />
2、save<br />
作用：将全部上传文件保存到指定目录下，并返回保存的文件个数。&nbsp;<br />
原型：public&nbsp;int&nbsp;save(String&nbsp;destPathName)<br />
和public&nbsp;int&nbsp;save(String&nbsp;destPathName,int&nbsp;option)<br />
其中，destPathName为文件保存目录，option为保存选项，它有三个值，分别是SAVE_PHYSICAL,SAVE_VIRTUAL和SAVE_AUTO。（同File类的saveAs方法的选项之值类似）SAVE_PHYSICAL指示组件将文件保存到以操作系统根目录为文件根目录的目录下，SAVE_VIRTUAL指示组件将文件保存到以Web应用程序根目录为文件根目录的目录下，而SAVE_AUTO则表示由组件自动选择。<br />
注：save(destPathName)作用等同于save(destPathName,SAVE_AUTO)。&nbsp;<br />
<br />
3、getSize<br />
作用：取上传文件数据的总长度&nbsp;<br />
原型：public&nbsp;int&nbsp;getSize()<br />
<br />
4、getFiles<br />
作用：取全部上传文件，以Files对象形式返回，可以利用Files类的操作方法来获得上传文件的数目等信息。&nbsp;<br />
原型：public&nbsp;Files&nbsp;getFiles()<br />
<br />
5、getRequest<br />
作用：取得Request对象，以便由此对象获得上传表单参数之值。&nbsp;<br />
原型：public&nbsp;Request&nbsp;getRequest()<br />
<br />
6、setAllowedFilesList<br />
作用：设定允许上传带有指定扩展名的文件，当上传过程中有文件名不允许时，组件将抛出异常。&nbsp;<br />
原型：public&nbsp;void&nbsp;setAllowedFilesList(String&nbsp;allowedFilesList)<br />
其中，allowedFilesList为允许上传的文件扩展名列表，各个扩展名之间以逗号分隔。如果想允许上传那些没有扩展名的文件，可以用两个逗号表示。例如：setAllowedFilesList("doc,txt,,")将允许上传带doc和txt扩展名的文件以及没有扩展名的文件。&nbsp;<br />
<br />
7、setDeniedFilesList<br />
作用：用于限制上传那些带有指定扩展名的文件。若有文件扩展名被限制，则上传时组件将抛出异常。&nbsp;<br />
原型：public&nbsp;void&nbsp;setDeniedFilesList(String&nbsp;deniedFilesList)<br />
其中，deniedFilesList为禁止上传的文件扩展名列表，各个扩展名之间以逗号分隔。如果想禁止上传那些没有扩展名的文件，可以用两个逗号来表示。例如：setDeniedFilesList("exe,bat,,")将禁止上传带exe和bat扩展名的文件以及没有扩展名的文件。&nbsp;<br />
<br />
8、setMaxFileSize<br />
作用：设定每个文件允许上传的最大长度。&nbsp;<br />
原型：public&nbsp;void&nbsp;setMaxFileSize(long&nbsp;maxFileSize)<br />
其中，maxFileSize为为每个文件允许上传的最大长度，当文件超出此长度时，将不被上传。&nbsp;<br />
<br />
9、setTotalMaxFileSize<br />
作用：设定允许上传的文件的总长度，用于限制一次性上传的数据量大小。&nbsp;<br />
原型：public&nbsp;void&nbsp;setTotalMaxFileSize(long&nbsp;totalMaxFileSize)<br />
其中，totalMaxFileSize为允许上传的文件的总长度。&nbsp;<br />
<br />
C．下载文件常用的方法&nbsp;<br />
1、setContentDisposition<br />
作用：将数据追加到MIME文件头的CONTENT-DISPOSITION域。jspSmartUpload组件会在返回下载的信息时自动填写MIME文件头的CONTENT-DISPOSITION域，如果用户需要添加额外信息，请用此方法。&nbsp;<br />
原型：public&nbsp;void&nbsp;setContentDisposition(String&nbsp;contentDisposition)<br />
其中，contentDisposition为要添加的数据。如果contentDisposition为null，则组件将自动添加"attachment;"，以表明将下载的文件作为附件，结果是IE浏览器将会提示另存文件，而不是自动打开这个文件（IE浏览器一般根据下载的文件扩展名决定执行什么操作，扩展名为doc的将用word程序打开，扩展名为pdf的将用acrobat程序打开，等等）。&nbsp;<br />
<br />
2、downloadFile<br />
作用：下载文件。&nbsp;<br />
原型：共有以下三个原型可用，第一个最常用，后两个用于特殊情况下的文件下载（如更改内容类型，更改另存的文件名）。&nbsp;<br />
①&nbsp;public&nbsp;void&nbsp;downloadFile(String&nbsp;sourceFilePathName)<br />
其中，sourceFilePathName为要下载的文件名（带目录的文件全名）&nbsp;<br />
②&nbsp;public&nbsp;void&nbsp;downloadFile(String&nbsp;sourceFilePathName,String&nbsp;contentType)<br />
其中，sourceFilePathName为要下载的文件名（带目录的文件全名）,contentType为内容类型（MIME格式的文件类型信息，可被浏览器识别）。&nbsp;<br />
③&nbsp;public&nbsp;void&nbsp;downloadFile(String&nbsp;sourceFilePathName,String&nbsp;contentType,String&nbsp;destFileName)<br />
其中，sourceFilePathName为要下载的文件名（带目录的文件全名）,contentType为内容类型（MIME格式的文件类型信息，可被浏览器识别）,destFileName为下载后默认的另存文件名。&nbsp;<br />
<br />
二、文件上传篇&nbsp;<br />
㈠&nbsp;表单要求&nbsp;<br />
对于上传文件的FORM表单，有两个要求：&nbsp;<br />
1、METHOD应用POST，即METHOD="POST"。&nbsp;<br />
2、增加属性：ENCTYPE="multipart/form-data"<br />
下面是一个用于上传文件的FORM表单的例子：&nbsp;<br />
</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">FORM&nbsp;</span><span style="color: #FF0000; ">METHOD</span><span style="color: #0000FF; ">="POST"</span><span style="color: #FF0000; ">&nbsp;ENCTYPE</span><span style="color: #0000FF; ">="multipart/form-data"</span><span style="color: #FF0000; ">&nbsp;ACTION</span><span style="color: #0000FF; ">="/jspSmartUpload/upload.jsp"</span><span style="color: #0000FF; ">&gt;&lt;</span><span style="color: #800000; ">INPUT&nbsp;</span><span style="color: #FF0000; ">TYPE</span><span style="color: #0000FF; ">="FILE"</span><span style="color: #FF0000; ">&nbsp;NAME</span><span style="color: #0000FF; ">="MYFILE"</span><span style="color: #0000FF; ">&gt;&lt;</span><span style="color: #800000; ">INPUT&nbsp;</span><span style="color: #FF0000; ">TYPE</span><span style="color: #0000FF; ">="SUBMIT"</span><span style="color: #0000FF; ">&gt;&lt;/</span><span style="color: #800000; ">FORM</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;<br />
其他不多讨论</span></div>
<img src ="http://www.blogjava.net/wangbing/aggbug/315644.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangbing/" target="_blank">王总兵</a> 2010-03-16 23:06 <a href="http://www.blogjava.net/wangbing/archive/2010/03/16/315644.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>警告: Parameters: Invalid chunk ignored.</title><link>http://www.blogjava.net/wangbing/archive/2010/03/05/314614.html</link><dc:creator>王总兵</dc:creator><author>王总兵</author><pubDate>Fri, 05 Mar 2010 07:12:00 GMT</pubDate><guid>http://www.blogjava.net/wangbing/archive/2010/03/05/314614.html</guid><wfw:comment>http://www.blogjava.net/wangbing/comments/314614.html</wfw:comment><comments>http://www.blogjava.net/wangbing/archive/2010/03/05/314614.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wangbing/comments/commentRss/314614.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangbing/services/trackbacks/314614.html</trackback:ping><description><![CDATA[<span  style="color: #ffffff; font-family: Arial, Helvetica, sans-serif; font-size: 14px; line-height: 22px; ">
<p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><strong>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><font  color="#000000" face="Simsun"><span  style="font-weight: normal; line-height: normal; font-size: medium;">警告：Parameters:Invalid chunk ignored<br />
<br />
原因：在链接参数中存在一定的问题和业务逻辑没关系，比如说在一个链接http://url?param1=value1&amp;redundance=rValue，<br />
<br />
<br />
<br />
其中redundance变量没有在业务逻辑中使用。<br />
<br />
解决方法：<br />
<br />
方法1：在业务逻辑中使用所有传入的值；<br />
<br />
方法2：去除冗余参数；<br />
<br />
还有一种情况<br />
<br />
很多朋友把以上的连接写成：http://url?param1=value1&amp;&amp;redundance=rValue，<br />
<br />
<br />
<br />
差别：多了一个"&amp;"<br />
<br />
所以，即使是你把所有的参数都在业务逻辑中使用了。但是还是会有这个警告。这时你只要吧多余的&#8220;&amp;&#8221;符号去掉就好了。<br />
<br />
<br />
<br />
&nbsp;<br />
<br />
<br />
<br />
警告: Parameters: Invalid chunk ignored.<br />
<br />
当POST body 或 query-string参数以&#8216;&amp;&#8217;结束或者包含&#8216;&amp;=&#8217;、&#8216;&amp;&amp;&#8217;这样的字符串时出现警告: Parameters: Invalid chunk ignored</span></font></p>
</p>
</strong></p>
</span>
<img src ="http://www.blogjava.net/wangbing/aggbug/314614.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangbing/" target="_blank">王总兵</a> 2010-03-05 15:12 <a href="http://www.blogjava.net/wangbing/archive/2010/03/05/314614.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>2010年新的旅程</title><link>http://www.blogjava.net/wangbing/archive/2010/02/19/313418.html</link><dc:creator>王总兵</dc:creator><author>王总兵</author><pubDate>Fri, 19 Feb 2010 09:23:00 GMT</pubDate><guid>http://www.blogjava.net/wangbing/archive/2010/02/19/313418.html</guid><wfw:comment>http://www.blogjava.net/wangbing/comments/313418.html</wfw:comment><comments>http://www.blogjava.net/wangbing/archive/2010/02/19/313418.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wangbing/comments/commentRss/313418.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangbing/services/trackbacks/313418.html</trackback:ping><description><![CDATA[2010年，新的开始。妹妹今天结婚，希望她可以幸福。我也幸福，虽然感冒在身，但是不妨碍我的幸福。<br />
<br />
<br />
新的一年少说多做，成熟一些，理智一些。<br />
<br />
<br />
希望大家都少生病，多赚钱。爸妈身体好，岳父岳母身体好。<br />
<br />
<br />
<img src ="http://www.blogjava.net/wangbing/aggbug/313418.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangbing/" target="_blank">王总兵</a> 2010-02-19 17:23 <a href="http://www.blogjava.net/wangbing/archive/2010/02/19/313418.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]理解ThreadLocal</title><link>http://www.blogjava.net/wangbing/archive/2010/01/10/308945.html</link><dc:creator>王总兵</dc:creator><author>王总兵</author><pubDate>Sun, 10 Jan 2010 12:47:00 GMT</pubDate><guid>http://www.blogjava.net/wangbing/archive/2010/01/10/308945.html</guid><wfw:comment>http://www.blogjava.net/wangbing/comments/308945.html</wfw:comment><comments>http://www.blogjava.net/wangbing/archive/2010/01/10/308945.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wangbing/comments/commentRss/308945.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangbing/services/trackbacks/308945.html</trackback:ping><description><![CDATA[<span style="font-family: verdana, sans-serif; font-size: 14px; line-height: 21px; ">
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; "><strong>ThreadLocal是什么</strong></p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">早在JDK 1.2的版本中就提供java.lang.ThreadLocal，ThreadLocal为解决多线程程序的并发问题提供了一种新的思路。使用这个工具类可以很简洁地编写出优美的多线程程序。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">ThreadLocal很容易让人望文生义，想当然地认为是一个&#8220;本地线程&#8221;。其实，ThreadLocal并不是一个Thread，而是Thread的局部变量，也许把它命名为ThreadLocalVariable更容易让人理解一些。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">当使用ThreadLocal维护变量时，ThreadLocal为每个使用该变量的线程提供独立的变量副本，所以每一个线程都可以独立地改变自己的副本，而不会影响其它线程所对应的副本。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">从线程的角度看，目标变量就象是线程的本地变量，这也是类名中&#8220;Local&#8221;所要表达的意思。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">线程局部变量并不是Java的新发明，很多语言（如IBM IBM XL FORTRAN）在语法层面就提供线程局部变量。在Java中没有提供在语言级支持，而是变相地通过ThreadLocal的类提供支持。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">所以，在Java中编写线程局部变量的代码相对来说要笨拙一些，因此造成线程局部变量没有在Java开发者中得到很好的普及。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">ThreadLocal的接口方法</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">ThreadLocal类接口很简单，只有4个方法，我们先来了解一下：</p>
<ul style="margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 35px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; ">
    <li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 2px; padding-right: 0px; padding-bottom: 2px; padding-left: 0px; list-style-type: disc; ">void set(Object value)</li>
</ul>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">设置当前线程的线程局部变量的值。</p>
<ul style="margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 35px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; ">
    <li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 2px; padding-right: 0px; padding-bottom: 2px; padding-left: 0px; list-style-type: disc; ">public Object get()</li>
</ul>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">该方法返回当前线程所对应的线程局部变量。</p>
<ul style="margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 35px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; ">
    <li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 2px; padding-right: 0px; padding-bottom: 2px; padding-left: 0px; list-style-type: disc; ">public void remove()</li>
</ul>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">将当前线程局部变量的值删除，目的是为了减少内存的占用，该方法是JDK 5.0新增的方法。需要指出的是，当线程结束后，对应该线程的局部变量将自动被垃圾回收，所以显式调用该方法清除线程的局部变量并不是必须的操作，但它可以加快内存回收的速度。</p>
<ul style="margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 35px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; ">
    <li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 2px; padding-right: 0px; padding-bottom: 2px; padding-left: 0px; list-style-type: disc; ">protected Object initialValue()</li>
</ul>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">返回该线程局部变量的初始值，该方法是一个protected的方法，显然是为了让子类覆盖而设计的。这个方法是一个延迟调用方法，在线程第1次调用get()或set(Object)时才执行，并且仅执行1次。ThreadLocal中的缺省实现直接返回一个null。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">值得一提的是，在JDK5.0中，ThreadLocal已经支持泛型，该类的类名已经变为ThreadLocal&lt;T&gt;。API方法也相应进行了调整，新版本的API方法分别是void set(T value)、T get()以及T initialValue()。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">ThreadLocal是如何做到为每一个线程维护变量的副本的呢？其实实现的思路很简单：在ThreadLocal类中有一个Map，用于存储每一个线程的变量副本，Map中元素的键为线程对象，而值对应线程的变量副本。我们自己就可以提供一个简单的实现版本：</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; "><a name="_Ref159302868" style="text-decoration: none; color: #993333; ">代码清单</a>1 SimpleThreadLocal</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">public class SimpleThreadLocal {</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">private Map valueMap = Collections.synchronizedMap(new HashMap());</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">public void set(Object newValue) {</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">valueMap.put(<strong>Thread.currentThread(), newValue</strong>);<strong>①键为线程对象，值为本线程的变量副本</strong></p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">}</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">public Object get() {</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">Thread currentThread = Thread.currentThread();</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">Object o = valueMap.get(currentThread);<strong>②返回本线程对应的变量</strong></p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">if (o == null &amp;&amp; !valueMap.containsKey(currentThread)) {<strong>③如果在Map中不存在，放到Map</strong></p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; "><strong>中保存起来。</strong></p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">o = initialValue();</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">valueMap.put(currentThread, o);</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">}</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">return o;</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">}</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">public void remove() {</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">valueMap.remove(Thread.currentThread());</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">}</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">public Object initialValue() {</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">return null;</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">}</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">}</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">虽然代码清单9‑3这个ThreadLocal实现版本显得比较幼稚，但它和JDK所提供的ThreadLocal类在实现思路上是相近的。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">一个TheadLocal实例</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">下面，我们通过一个具体的实例了解一下ThreadLocal的具体使用方法。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; "><a name="_Ref159316926" style="text-decoration: none; color: #993333; ">代码清单</a>2 SequenceNumber</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">package com.baobaotao.basic;</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">public class SequenceNumber {</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; "><strong>①</strong><strong>通过匿名内部类覆盖</strong><strong>ThreadLocal</strong><strong>的</strong><strong>initialValue()</strong><strong>方法，指定初始值</strong></p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">private static ThreadLocal&lt;Integer&gt; seqNum = new&nbsp;<strong>ThreadLocal&lt;Integer&gt;</strong>(){</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">public Integer initialValue(){</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">return 0;</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">}</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">};</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; "><strong>②</strong><strong>获取下一个序列值</strong></p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">public int getNextNum(){</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">seqNum.set(seqNum.get()+1);</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">return seqNum.get();</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">}</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">public static void main(String[] args)</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">{</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">SequenceNumber&nbsp;<strong>sn</strong>&nbsp;= new SequenceNumber();</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; "><strong>③</strong><strong>&nbsp;3</strong><strong>个线程共享</strong><strong>sn</strong><strong>，各自产生序列号</strong></p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">TestClient t1 = new TestClient(<strong>sn</strong>);</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">TestClient t2 = new TestClient(<strong>sn</strong>);</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">TestClient t3 = new TestClient(<strong>sn</strong>);</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">t1.start();</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">t2.start();</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">t3.start();</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">}</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">private static class TestClient extends Thread</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">{</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">private SequenceNumber sn;</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">public TestClient(SequenceNumber sn) {</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">this.sn = sn;</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">}</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">public void run()</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">{</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">for (int i = 0; i &lt; 3; i++) {<strong>④每个线程打出</strong><strong>3</strong><strong>个序列值</strong></p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">System.out.println("thread["+Thread.currentThread().getName()+</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">"] sn["+<strong>sn.getNextNum()</strong>+"]");</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">}</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">}</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">}</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">}</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">通常我们通过匿名内部类的方式定义ThreadLocal的子类，提供初始的变量值，如例子中①处所示。TestClient线程产生一组序列号，在③处，我们生成3个TestClient，它们共享同一个SequenceNumber实例。运行以上代码，在控制台上输出以下的结果：</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">thread[Thread-2] sn[1]</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">thread[Thread-0] sn[1]</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">thread[Thread-1] sn[1]</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">thread[Thread-2] sn[2]</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">thread[Thread-0] sn[2]</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">thread[Thread-1] sn[2]</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">thread[Thread-2] sn[3]</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">thread[Thread-0] sn[3]</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">thread[Thread-1] sn[3]</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">考察输出的结果信息，我们发现每个线程所产生的序号虽然都共享同一个SequenceNumber实例，但它们并没有发生相互干扰的情况，而是各自产生独立的序列号，这是因为我们通过ThreadLocal为每一个线程提供了单独的副本。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">Thread同步机制的比较</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">ThreadLocal和线程同步机制相比有什么优势呢？ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">在同步机制中，通过对象的锁机制保证同一时间只有一个线程访问变量。这时该变量是多个线程共享的，使用同步机制要求程序慎密地分析什么时候对变量进行读写，什么时候需要锁定某个对象，什么时候释放对象锁等繁杂的问题，程序设计和编写难度相对较大。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">而ThreadLocal则从另一个角度来解决多线程的并发访问。ThreadLocal会为每一个线程提供一个独立的变量副本，从而隔离了多个线程对数据的访问冲突。因为每一个线程都拥有自己的变量副本，从而也就没有必要对该变量进行同步了。ThreadLocal提供了线程安全的共享对象，在编写多线程代码时，可以把不安全的变量封装进ThreadLocal。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">由于ThreadLocal中可以持有任何类型的对象，低版本JDK所提供的get()返回的是Object对象，需要强制类型转换。但JDK 5.0通过泛型很好的解决了这个问题，在一定程度地简化ThreadLocal的使用，代码清单 9 2就使用了JDK 5.0新的ThreadLocal&lt;T&gt;版本。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">概括起来说，对于多线程资源共享的问题，同步机制采用了&#8220;以时间换空间&#8221;的方式，而ThreadLocal采用了&#8220;以空间换时间&#8221;的方式。前者仅提供一份变量，让不同的线程排队访问，而后者为每一个线程都提供了一份变量，因此可以同时访问而互不影响。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">Spring使用ThreadLocal解决线程安全问题</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">我们知道在一般情况下，只有无状态的Bean才可以在多线程环境下共享，在Spring中，绝大部分Bean都可以声明为singleton作用域。就是因为Spring对一些Bean（如RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder等）中非线程安全状态采用ThreadLocal进行处理，让它们也成为线程安全的状态，因为有状态的Bean就可以在多线程中共享了。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">一般的Web应用划分为展现层、服务层和持久层三个层次，在不同的层中编写对应的逻辑，下层通过接口向上层开放功能调用。在一般情况下，从接收请求到返回响应所经过的所有程序调用都同属于一个线程，如图9‑2所示：</p>
<p align="center" style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; "><img title="通通透透理解ThreadLocal" src="http://img.zdnet.com.cn/0/438/liOsRM8PmNF4U.gif" alt="通通透透理解ThreadLocal" align="center" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-right-color: black; border-right-style: solid; border-top-color: black; border-top-style: solid; border-left-color: black; border-left-style: solid; border-bottom-color: black; border-bottom-style: solid; " /></p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; "><a name="_Ref160678715" style="text-decoration: none; color: #993333; ">图</a>1同一线程贯通三层</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">这样你就可以根据需要，将一些非线程安全的变量以ThreadLocal存放，在同一次请求响应的调用线程中，所有关联的对象引用到的都是同一个变量。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">下面的实例能够体现Spring对有状态Bean的改造思路：</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">代码清单3 TopicDao：非线程安全</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">public class TopicDao {</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">private Connection conn;<strong>①</strong><strong>一个非线程安全的变量</strong></p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">public void addTopic(){</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">Statement stat = conn.createStatement();<strong>②</strong><strong>引用非线程安全变量</strong></p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">&#8230;</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">}</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">}</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">由于①处的conn是成员变量，因为addTopic()方法是非线程安全的，必须在使用时创建一个新TopicDao实例（非singleton）。下面使用ThreadLocal对conn这个非线程安全的&#8220;状态&#8221;进行改造：</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">代码清单4 TopicDao：线程安全</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">import java.sql.Connection;</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">import java.sql.Statement;</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">public class TopicDao {</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; "><strong>①使用ThreadLocal保存Connection变量</strong></p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">private static&nbsp;<strong>ThreadLocal&lt;Connection&gt;</strong>&nbsp;connThreadLocal = new ThreadLocal&lt;Connection&gt;();</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">public static Connection getConnection(){</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; "><strong>②如果connThreadLocal没有本线程对应的Connection创建一个新的Connection，</strong></p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; "><strong>并将其保存到线程本地变量中。</strong></p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">if (connThreadLocal.get() == null) {</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">Connection conn = ConnectionManager.getConnection();</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">connThreadLocal.set(conn);</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">return conn;</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">}else{</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">return connThreadLocal.get();<strong>③直接返回线程本地变量</strong></p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">}</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">}</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">public void addTopic() {</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; "><strong>④从ThreadLocal中获取线程对应的Connection</strong></p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">Statement stat = getConnection().createStatement();</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">}</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">}</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">不同的线程在使用TopicDao时，先判断connThreadLocal.get()是否是null，如果是null，则说明当前线程还没有对应的Connection对象，这时创建一个Connection对象并添加到本地线程变量中；如果不为null，则说明当前的线程已经拥有了Connection对象，直接使用就可以了。这样，就保证了不同的线程使用线程相关的Connection，而不会使用其它线程的Connection。因此，这个TopicDao就可以做到singleton共享了。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">当然，这个例子本身很粗糙，将Connection的ThreadLocal直接放在DAO只能做到本DAO的多个方法共享Connection时不发生线程安全问题，但无法和其它DAO共用同一个Connection，要做到同一事务多DAO共享同一Connection，必须在一个共同的外部类使用ThreadLocal保存Connection。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; "><strong>小结</strong></p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">ThreadLocal是解决线程安全问题一个很好的思路，它通过为每个线程提供一个独立的变量副本解决了变量并发访问的冲突问题。在很多情况下，ThreadLocal比直接使用synchronized同步机制解决线程安全问题更简单，更方便，且结果程序拥有更高的并发性。</p>
</span>
<img src ="http://www.blogjava.net/wangbing/aggbug/308945.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangbing/" target="_blank">王总兵</a> 2010-01-10 20:47 <a href="http://www.blogjava.net/wangbing/archive/2010/01/10/308945.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>tomcat乱码的问题</title><link>http://www.blogjava.net/wangbing/archive/2010/01/10/308926.html</link><dc:creator>王总兵</dc:creator><author>王总兵</author><pubDate>Sun, 10 Jan 2010 08:35:00 GMT</pubDate><guid>http://www.blogjava.net/wangbing/archive/2010/01/10/308926.html</guid><wfw:comment>http://www.blogjava.net/wangbing/comments/308926.html</wfw:comment><comments>http://www.blogjava.net/wangbing/archive/2010/01/10/308926.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/wangbing/comments/commentRss/308926.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangbing/services/trackbacks/308926.html</trackback:ping><description><![CDATA[很久以前没有出现过乱码的问题了，最近却发现有乱码的问题，麻烦。<br />
<br />
baidu了一下，发现在tomcat的/conf/server.xml里面修改一下配置即可。<br />
<br />
<div style="background-color: #eeeeee; font-size: 13px; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; "><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Connector&nbsp;</span><span style="color: #FF0000; ">port</span><span style="color: #0000FF; ">="8080"</span><span style="color: #FF0000; ">&nbsp;protocol</span><span style="color: #0000FF; ">="HTTP/1.1"</span><span style="color: #FF0000; ">&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;connectionTimeout</span><span style="color: #0000FF; ">="20000"</span><span style="color: #FF0000; ">&nbsp;&nbsp;URIEncoding</span><span style="color: #0000FF; ">="UTF-8"</span><span style="color: #FF0000; ">&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;redirectPort</span><span style="color: #0000FF; ">="8443"</span><span style="color: #FF0000; ">&nbsp;</span><span style="color: #0000FF; ">/&gt;</span></div>
<img src ="http://www.blogjava.net/wangbing/aggbug/308926.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangbing/" target="_blank">王总兵</a> 2010-01-10 16:35 <a href="http://www.blogjava.net/wangbing/archive/2010/01/10/308926.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JAVA动态调用的一个问题</title><link>http://www.blogjava.net/wangbing/archive/2010/01/01/307975.html</link><dc:creator>王总兵</dc:creator><author>王总兵</author><pubDate>Fri, 01 Jan 2010 04:43:00 GMT</pubDate><guid>http://www.blogjava.net/wangbing/archive/2010/01/01/307975.html</guid><wfw:comment>http://www.blogjava.net/wangbing/comments/307975.html</wfw:comment><comments>http://www.blogjava.net/wangbing/archive/2010/01/01/307975.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wangbing/comments/commentRss/307975.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangbing/services/trackbacks/307975.html</trackback:ping><description><![CDATA[<p class="MsoNormal" align="left" style="text-align:left;mso-pagination:widow-orphan"><span style="font-size:13.5pt;mso-bidi-font-size:11.0pt;font-family:宋体;mso-ascii-font-family:
Simsun;mso-hansi-font-family:Simsun;mso-bidi-font-family:宋体;color:black;
mso-font-kerning:0pt">在做程序过程中使用到了一个动态调用，具体的代码如下：</span><span lang="EN-US" style="font-size:13.5pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;
color:black;mso-font-kerning:0pt"><o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left;mso-pagination:widow-orphan;
background:#EEEEEE;word-break:break-all"><span lang="EN-US" style="font-size:
10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;color:black;
mso-font-kerning:0pt">&nbsp;&nbsp; &nbsp;</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;
color:blue;mso-font-kerning:0pt">public</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;
color:black;mso-font-kerning:0pt">&nbsp;</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;
color:blue;mso-font-kerning:0pt">static</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;
color:black;mso-font-kerning:0pt">&nbsp;Object&nbsp;invokePrivateMethod(Object&nbsp;object,&nbsp;String&nbsp;methodName,&nbsp;Object<span style="mso-no-proof:yes"><!--[if gte vml 1]><v:shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f">
<v:stroke joinstyle="miter" />
<v:formulas>
<v:f eqn="if lineDrawn pixelLineWidth 0" />
<v:f eqn="sum @0 1 0" />
<v:f eqn="sum 0 0 @1" />
<v:f eqn="prod @2 1 2" />
<v:f eqn="prod @3 21600 pixelWidth" />
<v:f eqn="prod @3 21600 pixelHeight" />
<v:f eqn="sum @0 0 1" />
<v:f eqn="prod @6 1 2" />
<v:f eqn="prod @7 21600 pixelWidth" />
<v:f eqn="sum @8 21600 0" />
<v:f eqn="prod @7 21600 pixelHeight" />
<v:f eqn="sum @10 21600 0" />
</v:formulas>
<v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect" />
<o:lock v:ext="edit" aspectratio="t" />
</v:shapetype><v:shape id="图片_x0020_1" o:spid="_x0000_i1025" type="#_x0000_t75" alt="http://www.blogjava.net/Images/dot.gif" style='width:11.25pt;height:15pt;
visibility:visible;mso-wrap-style:square'>
<v:imagedata src="file:///C:\Users\WANGBING\AppData\Local\Temp\msohtmlclip1\01\clip_image001.gif" o:title="dot" />
</v:shape><![endif]--><img width="15" height="20" src="file:///C:/Users/WANGBING/AppData/Local/Temp/msohtmlclip1/01/clip_image001.gif" alt="http://www.blogjava.net/Images/dot.gif" v:shapes="图片_x0020_1" /></span>&nbsp;params)&nbsp;</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:
宋体;color:blue;mso-font-kerning:0pt">throws</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;
color:black;mso-font-kerning:0pt">&nbsp;NoSuchMethodException&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Assert.notNull(object);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Assert.hasText(methodName);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Class[]&nbsp;types&nbsp;=&nbsp;</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:
宋体;color:blue;mso-font-kerning:0pt">new</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;
color:black;mso-font-kerning:0pt">&nbsp;Class[params.length];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;
color:blue;mso-font-kerning:0pt">for</span><span lang="EN-US" style="font-size:
10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;color:black;
mso-font-kerning:0pt">&nbsp;(</span><span lang="EN-US" style="font-size:10.0pt;
font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;color:blue;mso-font-kerning:
0pt">int</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;
mso-bidi-font-family:宋体;color:black;mso-font-kerning:0pt">&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;params.length;&nbsp;i++)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;types[i]&nbsp;=&nbsp;params[i].getClass();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Class&nbsp;clazz&nbsp;=&nbsp;object.getClass();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Method&nbsp;method&nbsp;=&nbsp;</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:
宋体;color:blue;mso-font-kerning:0pt">null</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;
color:black;mso-font-kerning:0pt">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;
color:blue;mso-font-kerning:0pt">for</span><span lang="EN-US" style="font-size:
10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;color:black;
mso-font-kerning:0pt">&nbsp;(Class&nbsp;superClass&nbsp;=&nbsp;clazz;&nbsp;superClass&nbsp;!=&nbsp;Object.</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:
宋体;color:blue;mso-font-kerning:0pt">class</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;
color:black;mso-font-kerning:0pt">;&nbsp;superClass&nbsp;=&nbsp;superClass.getSuperclass())&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:
宋体;color:blue;mso-font-kerning:0pt">try</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;
color:black;mso-font-kerning:0pt">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;method&nbsp;=&nbsp;superClass.getDeclaredMethod(methodName,&nbsp;types);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:
宋体;color:blue;mso-font-kerning:0pt">break</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;
color:black;mso-font-kerning:0pt">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:
宋体;color:blue;mso-font-kerning:0pt">catch</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;
color:black;mso-font-kerning:0pt">&nbsp;(NoSuchMethodException&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:
宋体;color:green;mso-font-kerning:0pt">//&nbsp;</span><span style="font-size:
10.0pt;font-family:宋体;mso-ascii-font-family:Simsun;mso-hansi-font-family:Simsun;
mso-bidi-font-family:宋体;color:green;mso-font-kerning:0pt">方法不在当前类定义</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:
宋体;color:green;mso-font-kerning:0pt">,</span><span style="font-size:10.0pt;
font-family:宋体;mso-ascii-font-family:Simsun;mso-hansi-font-family:Simsun;
mso-bidi-font-family:宋体;color:green;mso-font-kerning:0pt">继续向上转型</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:
宋体;color:green;mso-font-kerning:0pt"><br />
</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;
mso-bidi-font-family:宋体;color:black;mso-font-kerning:0pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;
color:blue;mso-font-kerning:0pt">if</span><span lang="EN-US" style="font-size:
10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;color:black;
mso-font-kerning:0pt">&nbsp;(method&nbsp;==&nbsp;</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;
color:blue;mso-font-kerning:0pt">null</span><span lang="EN-US" style="font-size:
10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;color:black;
mso-font-kerning:0pt">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:
宋体;color:blue;mso-font-kerning:0pt">throw</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;
color:black;mso-font-kerning:0pt">&nbsp;</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;
color:blue;mso-font-kerning:0pt">new</span><span lang="EN-US" style="font-size:
10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;color:black;
mso-font-kerning:0pt">&nbsp;NoSuchMethodException("No&nbsp;Such&nbsp;Method:"&nbsp;+&nbsp;clazz.getSimpleName()&nbsp;+&nbsp;"."&nbsp;+&nbsp;methodName);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;
color:blue;mso-font-kerning:0pt">boolean</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;
color:black;mso-font-kerning:0pt">&nbsp;accessible&nbsp;=&nbsp;method.isAccessible();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;method.setAccessible(</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:
宋体;color:blue;mso-font-kerning:0pt">true</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;
color:black;mso-font-kerning:0pt">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Object&nbsp;result&nbsp;=&nbsp;</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:
宋体;color:blue;mso-font-kerning:0pt">null</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;
color:black;mso-font-kerning:0pt">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;
color:blue;mso-font-kerning:0pt">try</span><span lang="EN-US" style="font-size:
10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;color:black;
mso-font-kerning:0pt">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result&nbsp;=&nbsp;method.invoke(object,&nbsp;params);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;
color:blue;mso-font-kerning:0pt">catch</span><span lang="EN-US" style="font-size:
10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;color:black;
mso-font-kerning:0pt">&nbsp;(Exception&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ReflectionUtils.handleReflectionException(e);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;method.setAccessible(accessible);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;
color:blue;mso-font-kerning:0pt">return</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;
color:black;mso-font-kerning:0pt">&nbsp;result;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}</span><span lang="EN-US" style="font-size:10.0pt;
font-family:宋体;mso-bidi-font-family:宋体;mso-font-kerning:0pt"><o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left;mso-pagination:widow-orphan"><span lang="EN-US" style="font-size:13.5pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:
宋体;color:black;mso-font-kerning:0pt"><br />
<br />
</span><span style="font-size:13.5pt;mso-bidi-font-size:11.0pt;font-family:
宋体;mso-ascii-font-family:Simsun;mso-hansi-font-family:Simsun;mso-bidi-font-family:
宋体;color:black;mso-font-kerning:0pt">被调用的方法如下：</span><span lang="EN-US" style="font-size:13.5pt;font-family:宋体;mso-bidi-font-family:宋体;mso-font-kerning:
0pt"><o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left;mso-pagination:widow-orphan;
background:#EEEEEE;word-break:break-all"><span lang="EN-US" style="font-size:
10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;color:teal;
mso-font-kerning:0pt">&nbsp;1</span><span lang="EN-US" style="font-size:10.0pt;
font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;color:black;mso-font-kerning:
0pt">&nbsp;</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;
mso-bidi-font-family:宋体;color:blue;mso-font-kerning:0pt">package</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:
宋体;color:black;mso-font-kerning:0pt">&nbsp;com.test;<br />
</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;
mso-bidi-font-family:宋体;color:teal;mso-font-kerning:0pt">&nbsp;2</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:
宋体;color:black;mso-font-kerning:0pt">&nbsp;<br />
</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;
mso-bidi-font-family:宋体;color:teal;mso-font-kerning:0pt">&nbsp;3</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:
宋体;color:black;mso-font-kerning:0pt">&nbsp;</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;
color:blue;mso-font-kerning:0pt">import</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;
color:black;mso-font-kerning:0pt">&nbsp;javax.servlet.http.HttpServletRequest;<br />
</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;
mso-bidi-font-family:宋体;color:teal;mso-font-kerning:0pt">&nbsp;4</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:
宋体;color:black;mso-font-kerning:0pt">&nbsp;<br />
</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;
mso-bidi-font-family:宋体;color:teal;mso-font-kerning:0pt">&nbsp;5</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:
宋体;color:black;mso-font-kerning:0pt">&nbsp;</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;
color:blue;mso-font-kerning:0pt">public</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;
color:black;mso-font-kerning:0pt">&nbsp;</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;
color:blue;mso-font-kerning:0pt">class</span><span lang="EN-US" style="font-size:
10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;color:black;
mso-font-kerning:0pt">&nbsp;TestMethod&nbsp;{<br />
</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;
mso-bidi-font-family:宋体;color:teal;mso-font-kerning:0pt">&nbsp;6</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:
宋体;color:black;mso-font-kerning:0pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;
mso-bidi-font-family:宋体;color:teal;mso-font-kerning:0pt">&nbsp;7</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:
宋体;color:black;mso-font-kerning:0pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:
宋体;color:blue;mso-font-kerning:0pt">public</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;
color:black;mso-font-kerning:0pt">&nbsp;String&nbsp;loadParams(HttpServletRequest&nbsp;req,String&nbsp;test1,String&nbsp;test2){<br />
</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;
mso-bidi-font-family:宋体;color:teal;mso-font-kerning:0pt">&nbsp;8</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:
宋体;color:black;mso-font-kerning:0pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:
宋体;color:blue;mso-font-kerning:0pt">return</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;
color:black;mso-font-kerning:0pt">&nbsp;req.getParameter("username");<br />
</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;
mso-bidi-font-family:宋体;color:teal;mso-font-kerning:0pt">&nbsp;9</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:
宋体;color:black;mso-font-kerning:0pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;
mso-bidi-font-family:宋体;color:teal;mso-font-kerning:0pt">10</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:
宋体;color:black;mso-font-kerning:0pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;
mso-bidi-font-family:宋体;color:teal;mso-font-kerning:0pt">11</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:
宋体;color:black;mso-font-kerning:0pt">&nbsp;}</span><span lang="EN-US" style="font-size:10.0pt;font-family:宋体;mso-bidi-font-family:宋体;mso-font-kerning:
0pt"><o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left;mso-pagination:widow-orphan"><span lang="EN-US" style="font-size:13.5pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:
宋体;color:black;mso-font-kerning:0pt"><br />
</span><span style="font-size:13.5pt;mso-bidi-font-size:11.0pt;font-family:
宋体;mso-ascii-font-family:Simsun;mso-hansi-font-family:Simsun;mso-bidi-font-family:
宋体;color:black;mso-font-kerning:0pt">在</span><span lang="EN-US" style="font-size:
13.5pt;mso-bidi-font-size:11.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:
宋体;color:black;mso-font-kerning:0pt">servlet</span><span style="font-size:13.5pt;
mso-bidi-font-size:11.0pt;font-family:宋体;mso-ascii-font-family:Simsun;
mso-hansi-font-family:Simsun;mso-bidi-font-family:宋体;color:black;mso-font-kerning:
0pt">里面调用：</span><span lang="EN-US" style="font-size:13.5pt;font-family:宋体;
mso-bidi-font-family:宋体;mso-font-kerning:0pt"><o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left;mso-pagination:widow-orphan;
background:#EEEEEE;word-break:break-all"><span lang="EN-US" style="font-size:
10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;color:black;
mso-font-kerning:0pt">&nbsp;&nbsp; &nbsp;</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;
color:blue;mso-font-kerning:0pt">public</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;
color:black;mso-font-kerning:0pt">&nbsp;</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;
color:blue;mso-font-kerning:0pt">void</span><span lang="EN-US" style="font-size:
10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;color:black;
mso-font-kerning:0pt">&nbsp;doGet(HttpServletRequest&nbsp;request,&nbsp;HttpServletResponse&nbsp;response)&nbsp;</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:
宋体;color:blue;mso-font-kerning:0pt">throws</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;
color:black;mso-font-kerning:0pt">&nbsp;ServletException,&nbsp;IOException&nbsp;{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;
color:blue;mso-font-kerning:0pt">try</span><span lang="EN-US" style="font-size:
10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;color:black;
mso-font-kerning:0pt">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;v&nbsp;=&nbsp;(String)&nbsp;MethodUtils.invokeMethod("com.test.TestMethod",&nbsp;"loadParams",&nbsp;request,&nbsp;"1",&nbsp;"2");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;
color:blue;mso-font-kerning:0pt">catch</span><span lang="EN-US" style="font-size:
10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;color:black;
mso-font-kerning:0pt">&nbsp;(SecurityException&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;
color:blue;mso-font-kerning:0pt">catch</span><span lang="EN-US" style="font-size:
10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;color:black;
mso-font-kerning:0pt">&nbsp;(IllegalArgumentException&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;
color:blue;mso-font-kerning:0pt">catch</span><span lang="EN-US" style="font-size:
10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;color:black;
mso-font-kerning:0pt">&nbsp;(ClassNotFoundException&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;
color:blue;mso-font-kerning:0pt">catch</span><span lang="EN-US" style="font-size:
10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;color:black;
mso-font-kerning:0pt">&nbsp;(InstantiationException&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;
color:blue;mso-font-kerning:0pt">catch</span><span lang="EN-US" style="font-size:
10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;color:black;
mso-font-kerning:0pt">&nbsp;(IllegalAccessException&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;
color:blue;mso-font-kerning:0pt">catch</span><span lang="EN-US" style="font-size:
10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;color:black;
mso-font-kerning:0pt">&nbsp;(NoSuchMethodException&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span lang="EN-US" style="font-size:10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;
color:blue;mso-font-kerning:0pt">catch</span><span lang="EN-US" style="font-size:
10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;color:black;
mso-font-kerning:0pt">&nbsp;(InvocationTargetException&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}</span><span lang="EN-US" style="font-size:10.0pt;
font-family:宋体;mso-bidi-font-family:宋体;mso-font-kerning:0pt"><o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="margin-bottom:13.5pt;text-align:left;
mso-pagination:widow-orphan"><span lang="EN-US" style="font-size:13.5pt;
font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;color:black;mso-font-kerning:
0pt"><br />
</span><span style="font-size:13.5pt;mso-bidi-font-size:11.0pt;font-family:
宋体;mso-ascii-font-family:Simsun;mso-hansi-font-family:Simsun;mso-bidi-font-family:
宋体;color:black;mso-font-kerning:0pt">但是调用报错，提示：</span><span lang="EN-US" style="font-size:13.5pt;font-family:宋体;mso-bidi-font-family:宋体;mso-font-kerning:
0pt"><o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left;mso-pagination:widow-orphan;
background:#EEEEEE;word-break:break-all"><span lang="EN-US" style="font-size:
10.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;color:black;
mso-font-kerning:0pt">java.lang.NoSuchMethodException:&nbsp;com.test.TestMethod.loadParams(org.apache.catalina.connector.RequestFacade,&nbsp;java.lang.String,&nbsp;java.lang.String)<br />
&nbsp;&nbsp;&nbsp;&nbsp;at&nbsp;java.lang.Class.getMethod(Class.java:1605)<br />
&nbsp;&nbsp;&nbsp;&nbsp;at&nbsp;com.test.MethodUtils.invokeMethod(MethodUtils.java:20)<br />
&nbsp;&nbsp;&nbsp;&nbsp;at&nbsp;com.test.TestHelloWorld.doGet(TestHelloWorld.java:46)<br />
&nbsp;&nbsp;&nbsp;&nbsp;at&nbsp;javax.servlet.http.HttpServlet.service(HttpServlet.java:617)<br />
&nbsp;&nbsp;&nbsp;&nbsp;at&nbsp;javax.servlet.http.HttpServlet.service(HttpServlet.java:717)<br />
&nbsp;&nbsp;&nbsp;&nbsp;at&nbsp;org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)<br />
&nbsp;&nbsp;&nbsp;&nbsp;at&nbsp;org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)<br />
&nbsp;&nbsp;&nbsp;&nbsp;at&nbsp;org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)<br />
&nbsp;&nbsp;&nbsp;&nbsp;at&nbsp;org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)<br />
&nbsp;&nbsp;&nbsp;&nbsp;at&nbsp;org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)<br />
&nbsp;&nbsp;&nbsp;&nbsp;at&nbsp;org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)<br />
&nbsp;&nbsp;&nbsp;&nbsp;at&nbsp;org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)<br />
&nbsp;&nbsp;&nbsp;&nbsp;at&nbsp;org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)<br />
&nbsp;&nbsp;&nbsp;&nbsp;at&nbsp;org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849)<br />
&nbsp;&nbsp;&nbsp;&nbsp;at&nbsp;org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)<br />
&nbsp;&nbsp;&nbsp;&nbsp;at&nbsp;org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)<br />
&nbsp;&nbsp;&nbsp;&nbsp;at&nbsp;java.lang.Thread.run(Thread.java:619)</span><span lang="EN-US" style="font-size:10.0pt;font-family:宋体;mso-bidi-font-family:宋体;
mso-font-kerning:0pt"><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:13.5pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;
mso-bidi-font-family:宋体;color:black;mso-font-kerning:0pt"><br />
</span><span style="font-size:13.5pt;mso-bidi-font-size:11.0pt;font-family:
宋体;mso-ascii-font-family:Simsun;mso-hansi-font-family:Simsun;mso-bidi-font-family:
宋体;color:black;mso-font-kerning:0pt">发现，</span><span lang="EN-US" style="font-size:13.5pt;mso-bidi-font-size:11.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;
mso-bidi-font-family:宋体;color:black;mso-font-kerning:0pt">request</span><span style="font-size:13.5pt;mso-bidi-font-size:11.0pt;font-family:宋体;mso-ascii-font-family:
Simsun;mso-hansi-font-family:Simsun;mso-bidi-font-family:宋体;color:black;
mso-font-kerning:0pt">这个接口被</span><span lang="EN-US" style="font-size:13.5pt;
mso-bidi-font-size:11.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:
宋体;color:black;mso-font-kerning:0pt">tomcat</span><span style="font-size:13.5pt;
mso-bidi-font-size:11.0pt;font-family:宋体;mso-ascii-font-family:Simsun;
mso-hansi-font-family:Simsun;mso-bidi-font-family:宋体;color:black;mso-font-kerning:
0pt">实例化后，传入的是</span><span lang="EN-US" style="font-size:13.5pt;mso-bidi-font-size:
11.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;color:black;
mso-font-kerning:0pt">RequestFacade</span><span style="font-size:13.5pt;
mso-bidi-font-size:11.0pt;font-family:宋体;mso-ascii-font-family:Simsun;
mso-hansi-font-family:Simsun;mso-bidi-font-family:宋体;color:black;mso-font-kerning:
0pt">这个对象了，这样找不到对应的函数了。</span><span lang="EN-US" style="font-size:10.0pt;
font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;color:black;mso-font-kerning:
0pt"><br />
</span><span style="font-size:13.5pt;mso-bidi-font-size:11.0pt;font-family:
宋体;mso-ascii-font-family:Simsun;mso-hansi-font-family:Simsun;mso-bidi-font-family:
宋体;color:black;mso-font-kerning:0pt">不知道这种情况是如何处理，我简单的做了一个自己的对象，进行了包装，把</span><span lang="EN-US" style="font-size:13.5pt;mso-bidi-font-size:11.0pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;
mso-bidi-font-family:宋体;color:black;mso-font-kerning:0pt">request</span><span style="font-size:13.5pt;mso-bidi-font-size:11.0pt;font-family:宋体;mso-ascii-font-family:
Simsun;mso-hansi-font-family:Simsun;mso-bidi-font-family:宋体;color:black;
mso-font-kerning:0pt">包装在里面，这样就可以。</span><span lang="EN-US" style="font-size:
13.5pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:宋体;color:black;
mso-font-kerning:0pt"><br />
</span><span style="font-size:13.5pt;mso-bidi-font-size:11.0pt;font-family:
宋体;mso-ascii-font-family:Simsun;mso-hansi-font-family:Simsun;mso-bidi-font-family:
宋体;color:black;mso-font-kerning:0pt">但是，接口和实例应该是可以自由转换的，怎么不行呢？</span><span lang="EN-US" style="font-size:13.5pt;font-family:&quot;Simsun&quot;,&quot;serif&quot;;mso-bidi-font-family:
宋体;color:black;mso-font-kerning:0pt"><br style="mso-special-character:line-break" />
<br style="mso-special-character:line-break" />
</span></p>
<img src ="http://www.blogjava.net/wangbing/aggbug/307975.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangbing/" target="_blank">王总兵</a> 2010-01-01 12:43 <a href="http://www.blogjava.net/wangbing/archive/2010/01/01/307975.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]jQuery.extend函数详细用法</title><link>http://www.blogjava.net/wangbing/archive/2009/11/05/301243.html</link><dc:creator>王总兵</dc:creator><author>王总兵</author><pubDate>Thu, 05 Nov 2009 03:54:00 GMT</pubDate><guid>http://www.blogjava.net/wangbing/archive/2009/11/05/301243.html</guid><wfw:comment>http://www.blogjava.net/wangbing/comments/301243.html</wfw:comment><comments>http://www.blogjava.net/wangbing/archive/2009/11/05/301243.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wangbing/comments/commentRss/301243.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangbing/services/trackbacks/301243.html</trackback:ping><description><![CDATA[<span style="font-family: Arial, sans-serif, Helvetica, Tahoma; font-size: 12px; line-height: 18px; ">
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">jQuery.extend函数详细用法<br />
最近在研究jQuery。把jQuery.extend扩展函数的用法记录下来。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">1、扩展jQuery静态方法.</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">1$.extend({<br />
2test:function(){alert('test函数')}<br />
3})<br />
用法: $.test()</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><br />
2、合并多个对象.<br />
为jQuery.extend(css1,css2)为例，css1,css2个有一些属性(法照样会比处理,这里之讲属性).<br />
extend函数会把css2有而css2没有的属性加到css1中,如果css2的某个属性与css1的某个属性名称享用，就会用css2的属性去覆盖css1的同名属性。css1就是最后的整和对象。或者也可以用 ：<br />
var newcss = jquery.extend(css1,css2)&nbsp; newcss就是合并的新对象。<br />
var newcss = jquery.extend({},css1,css2) newcss就是合并的新对象.而且没有破坏css1的结构。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">1//用法: jQuery.extend(obj1,obj2,obj3,..)<br />
2var Css1={size: "10px",style: "oblique"}<br />
3var Css2={size: "12px",style: "oblique",weight: "bolder"}<br />
4$.jQuery.extend(Css1,Css2)<br />
5//结果:Css1的size属性被覆盖,而且继承了Css2的weight属性<br />
6// Css1 = {size: "12px",style: "oblique",weight: "bolder"}<br />
7</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">3。深度镶套对象<br />
新的extend()允许你更深度的合并镶套对象。下面的例子是一个很好的证明。<br />
1// 以前的 .extend()&nbsp;&nbsp;&nbsp;<br />
2&nbsp;&nbsp; jQuery.extend(&nbsp;&nbsp;&nbsp;<br />
3&nbsp;&nbsp;&nbsp;&nbsp; { name: &#8220;John&#8221;, location: { city: &#8220;Boston&#8221; } },&nbsp;&nbsp;&nbsp;<br />
4&nbsp;&nbsp;&nbsp;&nbsp; { last: &#8220;Resig&#8221;, location: { state: &#8220;MA&#8221; } }&nbsp;&nbsp;&nbsp;<br />
5&nbsp;&nbsp; );&nbsp;&nbsp;&nbsp;<br />
6&nbsp;&nbsp;&nbsp; // 结果:&nbsp;&nbsp;&nbsp;<br />
7&nbsp;&nbsp;&nbsp; // =&gt; { name: &#8220;John&#8221;, last: &#8220;Resig&#8221;, location: { state: &#8220;MA&#8221; } }<br />
8&nbsp; // 新的更深入的 .extend()&nbsp;&nbsp;&nbsp;<br />
9&nbsp;&nbsp; jQuery.extend( true,&nbsp;&nbsp;&nbsp;<br />
10&nbsp;&nbsp; { name: &#8220;John&#8221;, location: { city: &#8220;Boston&#8221; } },&nbsp;&nbsp;&nbsp;<br />
11&nbsp;&nbsp;&nbsp;&nbsp; { last: &#8220;Resig&#8221;, location: { state: &#8220;MA&#8221; } }&nbsp;&nbsp;&nbsp;<br />
12&nbsp; );&nbsp;&nbsp;&nbsp;<br />
13&nbsp; // 结果&nbsp;&nbsp;&nbsp;<br />
14&nbsp;&nbsp; // =&gt; { name: &#8220;John&#8221;, last: &#8220;Resig&#8221;,&nbsp;&nbsp;&nbsp;<br />
15&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; location: { city: &#8220;Boston&#8221;, state: &#8220;MA&#8221; } }&nbsp;&nbsp;<br />
16</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">本篇文章来源于PHP论坛 文章地址：<a href="http://bbs.php.cn/thread-33593-1-4.html" style="color: #108ac6; text-decoration: underline; ">http://bbs.php.cn/thread-33593-1-4.html</a></p>
</span>
<img src ="http://www.blogjava.net/wangbing/aggbug/301243.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangbing/" target="_blank">王总兵</a> 2009-11-05 11:54 <a href="http://www.blogjava.net/wangbing/archive/2009/11/05/301243.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>jquery.flot.js使用笔记</title><link>http://www.blogjava.net/wangbing/archive/2009/10/29/300280.html</link><dc:creator>王总兵</dc:creator><author>王总兵</author><pubDate>Thu, 29 Oct 2009 14:54:00 GMT</pubDate><guid>http://www.blogjava.net/wangbing/archive/2009/10/29/300280.html</guid><wfw:comment>http://www.blogjava.net/wangbing/comments/300280.html</wfw:comment><comments>http://www.blogjava.net/wangbing/archive/2009/10/29/300280.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wangbing/comments/commentRss/300280.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangbing/services/trackbacks/300280.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;公司的项目有一些类似监控的需求，需要输出比较漂亮的图表，并且支持较多的鼠标事件。最开始我使用了VML技术，找了不少网络上的代码，也画出了很漂亮的图表。但是找到的代码都不是很完善，功能较少，需要自己进行较大的修改才可以满足需求。后来无意找到了flot这个jquery插件，看了下他的example，发现我需要的功能基本满足。他具有的功能如下：<br />
&nbsp;&nbsp;1、输出一条或者多条曲线图表，同时可以利用脚本控制显示的条数。<br />
&nbsp;&nbsp;2、可以对图标进行select，然后对选择的区域进行zoom操作。<br />
&nbsp;&nbsp;3、支持x轴使用time模式，可以将序列设置为Date.parse(new Date())的数值，结合select功能可以更好的进行zoom控制。<br />
&nbsp;&nbsp;4、支持2种特定的事件：placeholder和plotclick，可以在鼠标移动到point和单击point时进行操作。<br />
&nbsp;&nbsp;......<br />
<br />
&nbsp;&nbsp;我研究不是很深入，想做一个提示框功能，鼠标移动到point上时提示信息。但是flot没有支持相关的接口，我只能自己写了一个div，整体搭配效果马上就差了很多。总的来说，这个插件还是很不错，包括速度也不错，基本够用。
<img src ="http://www.blogjava.net/wangbing/aggbug/300280.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangbing/" target="_blank">王总兵</a> 2009-10-29 22:54 <a href="http://www.blogjava.net/wangbing/archive/2009/10/29/300280.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]开源协议相关介绍</title><link>http://www.blogjava.net/wangbing/archive/2009/10/28/300112.html</link><dc:creator>王总兵</dc:creator><author>王总兵</author><pubDate>Wed, 28 Oct 2009 14:00:00 GMT</pubDate><guid>http://www.blogjava.net/wangbing/archive/2009/10/28/300112.html</guid><wfw:comment>http://www.blogjava.net/wangbing/comments/300112.html</wfw:comment><comments>http://www.blogjava.net/wangbing/archive/2009/10/28/300112.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wangbing/comments/commentRss/300112.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangbing/services/trackbacks/300112.html</trackback:ping><description><![CDATA[<span  style="color: #002200; font-family: georgia; font-size: 12px; ">
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1.2em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; line-height: 1.5em; ">当Adobe、Microsoft、Sun等一系列巨头开始表现出对&#8221;开源&#8221;的青睐时，&#8221;开源&#8221;的时代即将到来！</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1.2em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; line-height: 1.5em; ">最初来自：sinoprise.com/read.php?tid-662-page-e-fpage-1.html（遗憾的是这个链接已经打不开了），我基本未改动，只是进行了一些排版和整理。<br style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; " />
参考文献：<a href="http://www.fsf.org/licensing/licenses/" style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; color: #477725; text-decoration: none; border-bottom-width: 1px; border-bottom-style: dashed; border-bottom-color: #006600; ">http://www.fsf.org/licensing/licenses/</a></p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1.2em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; line-height: 1.5em; ">现今存在的开源协议很多，而经过Open Source Initiative组织通过批准的开源协议目前有58种（<a href="http://www.opensource.org/licenses/alphabetical" style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; color: #477725; text-decoration: none; border-bottom-width: 1px; border-bottom-style: dashed; border-bottom-color: #006600; ">http://www.opensource.org/licenses/alphabetical</a>）。我们在常见的开源协议如BSD, GPL, LGPL,MIT等都是OSI批准的协议。如果要开源自己的代码，最好也是选择这些被批准的开源协议。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1.2em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; line-height: 1.5em; ">这里我们来看四种最常用的开源协议及它们的适用范围，供那些准备开源或者使用开源产品的开发人员/厂家参考。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1.2em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; line-height: 1.5em; "><strong style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">BSD开源协议（</strong><a href="http://www.fsf.org/licensing/licenses/index_html#OriginalBSD" style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; color: #477725; text-decoration: none; border-bottom-width: 1px; border-bottom-style: dashed; border-bottom-color: #006600; ">original BSD license</a><strong style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">、</strong><a href="http://www.freebsd.org/copyright/freebsd-license.html" id="FreeBSD" name="FreeBSD" style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; color: #477725; text-decoration: none; border-bottom-width: 1px; border-bottom-style: dashed; border-bottom-color: #006600; ">FreeBSD license</a><strong style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">、</strong><a href="http://www.xfree86.org/3.3.6/COPYRIGHT2.html#6" id="OriginalBSD" name="OriginalBSD" style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; color: #477725; text-decoration: none; border-bottom-width: 1px; border-bottom-style: dashed; border-bottom-color: #006600; ">Original BSD license</a><strong style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">）</strong></p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1.2em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; line-height: 1.5em; ">BSD开源协议是一个给于使用者很大自由的协议。基本上使用者可以&#8221;为所欲为&#8221;,可以自由的使用，修改源代码，也可以将修改后的代码作为开源或者专有软件再发布。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1.2em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; line-height: 1.5em; ">但&#8221;为所欲为&#8221;的前提当你发布使用了BSD协议的代码，或则以BSD协议代码为基础做二次开发自己的产品时，需要满足三个条件：</p>
<ol style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1.2em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 2em; line-height: 1.5em; ">
    <li style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0.2em; margin-left: 0px; ">如果再发布的产品中包含源代码，则在源代码中必须带有原来代码中的BSD协议。</li>
    <li style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0.2em; margin-left: 0px; ">如果再发布的只是二进制类库/软件，则需要在类库/软件的文档和版权声明中包含原来代码中的BSD协议。</li>
    <li style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0.2em; margin-left: 0px; ">不可以用开源代码的作者/机构名字和原来产品的名字做市场推广。</li>
</ol>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1.2em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; line-height: 1.5em; ">BSD 代码鼓励代码共享，但需要尊重代码作者的著作权。BSD由于允许使用者修改和重新发布代码，也允许使用或在BSD代码上开发商业软件发布和销售，因此是对商业集成很友好的协议。而很多的公司企业在选用开源产品的时候都首选BSD协议，因为可以完全控制这些第三方的代码，在必要的时候可以修改或者二次开发。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1.2em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; line-height: 1.5em; "><strong style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">Apache Licence 2.0（</strong><a href="http://www.apache.org/licenses/LICENSE-2.0" style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; color: #477725; text-decoration: none; border-bottom-width: 1px; border-bottom-style: dashed; border-bottom-color: #006600; ">Apache License, Version 2.0</a>、<a href="http://www.apache.org/LICENSE-1.1" style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; color: #477725; text-decoration: none; border-bottom-width: 1px; border-bottom-style: dashed; border-bottom-color: #006600; ">Apache License, Version 1.1</a>、<a href="http://www.apache.org/LICENSE-1.0" style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; color: #477725; text-decoration: none; border-bottom-width: 1px; border-bottom-style: dashed; border-bottom-color: #006600; ">Apache License, Version 1.0</a><strong style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">）</strong></p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1.2em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; line-height: 1.5em; ">Apache Licence是著名的非盈利开源组织Apache采用的协议。该协议和BSD类似，同样鼓励代码共享和尊重原作者的著作权，同样允许代码修改，再发布（作为开源或商业软件）。需要满足的条件也和BSD类似：</p>
<ol style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1.2em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 2em; line-height: 1.5em; ">
    <li style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0.2em; margin-left: 0px; ">需要给代码的用户一份Apache Licence</li>
    <li style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0.2em; margin-left: 0px; ">如果你修改了代码，需要再被修改的文件中说明。</li>
    <li style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0.2em; margin-left: 0px; ">在延伸的代码中（修改和有源代码衍生的代码中）需要带有原来代码中的协议，商标，专利声明和其他原来作者规定需要包含的说明。</li>
    <li style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0.2em; margin-left: 0px; ">如果再发布的产品中包含一个Notice文件，则在Notice文件中需要带有Apache Licence。你可以在Notice中增加自己的许可，但不可以表现为对Apache Licence构成更改。</li>
</ol>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1.2em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; line-height: 1.5em; ">Apache Licence也是对商业应用友好的许可。使用者也可以在需要的时候修改代码来满足需要并作为开源或商业产品发布/销售。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1.2em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; line-height: 1.5em; "><strong style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">GPL（</strong><a href="http://www.fsf.org/licensing/licenses/gpl.html" id="GNUGPL" name="GNUGPL" style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; color: #477725; text-decoration: none; border-bottom-width: 1px; border-bottom-style: dashed; border-bottom-color: #006600; ">GNU General Public License</a><strong style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">）</strong></p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1.2em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; line-height: 1.5em; ">我们很熟悉的Linux就是采用了GPL。GPL协议和BSD, Apache Licence等鼓励代码重用的许可很不一样。GPL的出发点是代码的开源/免费使用和引用/修改/衍生代码的开源/免费使用，但不允许修改后和衍生的代码做为闭源的商业软件发布和销售。这也就是为什么我们能用免费的各种linux，包括商业公司的linux和linux上各种各样的由个人，组织，以及商业软件公司开发的免费软件了。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1.2em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; line-height: 1.5em; ">GPL协议的主要内容是只要在一个软件中使用(&#8221;使用&#8221;指类库引用，修改后的代码或者衍生代码)GPL 协议的产品，则该软件产品必须也采用GPL协议，既必须也是开源和免费。<strong style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">这就是所谓的&#8221;传染性&#8221;</strong>。GPL协议的产品作为一个单独的产品使用没有任何问题，还可以享受免费的优势。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1.2em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; line-height: 1.5em; ">由于GPL严格要求使用了GPL类库的软件产品必须使用GPL协议，对于使用GPL协议的开源代码，商业软件或者对代码有保密要求的部门就不适合集成/采用作为类库和二次开发的基础。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1.2em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; line-height: 1.5em; ">其它细节如再发布的时候需要伴随GPL协议等和BSD/Apache等类似。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1.2em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; line-height: 1.5em; "><strong style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">LGPL（</strong><a href="http://www.fsf.org/licensing/licenses/lgpl.html" id="LGPL" name="LGPL" style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; color: #477725; text-decoration: none; border-bottom-width: 1px; border-bottom-style: dashed; border-bottom-color: #006600; ">GNU Lesser General Public License</a><strong style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">）</strong></p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1.2em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; line-height: 1.5em; ">LGPL是GPL的一个为主要为类库使用设计的开源协议。和GPL要求任何使用/修改/衍生之GPL类库的的软件必须采用GPL协议不同。LGPL允许商业软件通过类库引用(link)方式使用LGPL类库而不需要开源商业软件的代码。这使得采用LGPL协议的开源代码可以被商业软件作为类库引用并发布和销售。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1.2em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; line-height: 1.5em; ">但是如果修改LGPL协议的代码或者衍生，则所有修改的代码，涉及修改部分的额外代码和衍生的代码都必须采用LGPL协议。因此LGPL协议的开源代码很适合作为第三方类库被商业软件引用，但不适合希望以LGPL协议代码为基础，通过修改和衍生的方式做二次开发的商业软件采用。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1.2em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; line-height: 1.5em; ">GPL/LGPL都保障原作者的知识产权，避免有人利用开源代码复制并开发类似的产品</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1.2em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; line-height: 1.5em; "><strong style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">MIT（<a href="http://www.opensource.org/licenses/mit-license.php" style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; color: #477725; text-decoration: none; border-bottom-width: 1px; border-bottom-style: dashed; border-bottom-color: #006600; ">MIT</a>）</strong></p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1.2em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; line-height: 1.5em; ">MIT是和BSD一样宽范的许可协议,作者只想保留版权,而无任何其他了限制.也就是说,你必须在你的发行版里包含原许可协议的声明,无论你是以二进制发布的还是以源代码发布的.</p>
<p id="gulink" style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1.2em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; line-height: 1.5em; ">本文来自：<a href="http://www.awflasher.com/blog/archives/939" title="五种开源协议的比较(BSD,Apache,GPL,LGPL,MIT) - 整理" style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; color: #000000; text-decoration: none; border-bottom-width: 1px; border-bottom-style: none; border-bottom-color: #006600; border-top-style: none; border-right-style: none; border-left-style: none; border-width: initial; border-color: initial; ">http://www.awflasher.com/blog/archives/939</a></p>
</span>
<img src ="http://www.blogjava.net/wangbing/aggbug/300112.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangbing/" target="_blank">王总兵</a> 2009-10-28 22:00 <a href="http://www.blogjava.net/wangbing/archive/2009/10/28/300112.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>统计查询开发的一点整理</title><link>http://www.blogjava.net/wangbing/archive/2009/09/02/293516.html</link><dc:creator>王总兵</dc:creator><author>王总兵</author><pubDate>Tue, 01 Sep 2009 16:01:00 GMT</pubDate><guid>http://www.blogjava.net/wangbing/archive/2009/09/02/293516.html</guid><wfw:comment>http://www.blogjava.net/wangbing/comments/293516.html</wfw:comment><comments>http://www.blogjava.net/wangbing/archive/2009/09/02/293516.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/wangbing/comments/commentRss/293516.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangbing/services/trackbacks/293516.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;最近负责的两块主要是统计报表，具体有差不多400个报表需要开发。在开发过程中使用到了润乾的报表软件，也使用了润乾的OLAP组件，建立了一大堆的中间表，然后使用Oracle的ODI做定时任务晚上抽取数据到中间表，第二天提供给客户统计。也有一些比较复杂的业务没有办法使用ODI抽取，只能写成JAVA的方式晚上做批处理。批处理数据量都比较大，代码质量不高的话很容易内存溢出；ODI对开发人员的SQL语句要求较好，因为源数据可能需要经过很多处理，建立为VIEW然后才使用ODI抽取。如何提高SQL语句的效率是关键的问题，建立必要的索引，不断的优化SQL语句。但是，不管是批处理还是ODI都不是最麻烦的，最麻烦的是400张报表涉及到上千个数据项的分析工作。下面5个人，2个在做JAVA批处理，1个在做ODI，2个在做报表，不停的问我数据项，而我不是一个数据项仓库，N多不清楚的只有打电话给客户或者询问我们这边对应的子系统的负责人。而系统从原来的CS模式迁移过来的历史数据，质量很难保证，数据迁移工作存在很大的质量问题。很多数据项知道怎么查，但是一个SQL语句过去，查出来的数据差了十万八千里，客户那里肯干。总之，报表开发数据项麻烦，性能是大问题，对历史数据的报表更加困难。<br />
<br />
&nbsp;&nbsp;9月份公司安排不加班，我希望可以陆续整理点关于ODI开发的文档。感觉对ODI的使用还是比较深入，从最开始简单的抽取数据，到后来的定时任务，到现在修改KM进行简单的优化处理。对ODI的使用逐步深入，感觉Oracle的这个产品还是相当不错的。相对于我们使用的另外一个Oracle的产品BAM来说，这个产品买的是相当划算了。BAM我们也买了，但是最终定的技术方案还是没有使用。主要是支持太差劲了，网上也没有多少文档。那个产品在国内应该是使用的非常的少，上次BAM的产品经理来中国，说是来直接和BAM的客户面对面，了解客户的需求然后改进他们的产品。好像是一个USA，结果不知怎么Oracle这边安排到了我们公司来面对面。可是我们根本没有使用这个产品，公司领导没有人甩他，安排了几个人去和他一起开了个小座谈会。记忆最深的就是，老外讲了N久之后说要喝水，我马上给拿了开水一杯过来了。可是他摇头，后来和他一起来的美女告诉我，外国人说喝水都是要加点东西要么茶要么咖啡，不然就喝冷水。后来随便哪里抓了点茶叶丢了进去，那次算是我第一次和老外亲密接触。<br />
<br />
&nbsp;&nbsp;谈到BAM扯远了。在这个项目2年时间，先后参与了很多子系统。90%的系统都是业务系统，什么审查、审批、质检等等，典型的电子政务模式。业务系统做完了，剩下的这10%就是统计查询系统了。项目组90%的系统都差不多结了，而我手中这10%才刚刚开始，郁闷。手里有5个人在一起做统计查询这块的工作，但是面对这么大的项目，需要统计的数据项都是业务系统产生的数据，我们只能一边看PDM一边和客户、其他子系统负责人沟通。而客户以前的报表是基于原有系统产生的，或者是采用逐层上报加体外循环，利用VBA产生的，他们对新系统还很陌生。子系统负责人当前的任务是保证自己负责的业务系统顺利上线，他们每天都在客户现场做测试做支持，管不到我这边。项目组前期对统计查询不够重视，相关的工作没有启动，人员也一直没有保证。是不是别的项目也是这样对待查询统计的？不知道别的大型的项目类似这种统计查询系统后来是怎么开发的。希望有做过类似项目的高手给点指点。<br />
<br />
&nbsp;&nbsp;
<img src ="http://www.blogjava.net/wangbing/aggbug/293516.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangbing/" target="_blank">王总兵</a> 2009-09-02 00:01 <a href="http://www.blogjava.net/wangbing/archive/2009/09/02/293516.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]利用p6spy显示完整的hibernate sql语句</title><link>http://www.blogjava.net/wangbing/archive/2009/08/25/292575.html</link><dc:creator>王总兵</dc:creator><author>王总兵</author><pubDate>Tue, 25 Aug 2009 14:24:00 GMT</pubDate><guid>http://www.blogjava.net/wangbing/archive/2009/08/25/292575.html</guid><wfw:comment>http://www.blogjava.net/wangbing/comments/292575.html</wfw:comment><comments>http://www.blogjava.net/wangbing/archive/2009/08/25/292575.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wangbing/comments/commentRss/292575.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangbing/services/trackbacks/292575.html</trackback:ping><description><![CDATA[<div style="background-color: #eeeeee; font-size: 13px; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; "><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000; ">虽然在hibernate中有show_sql选项，但是显示出来的语句大多类似<br />
&nbsp;select&nbsp;*&nbsp;from&nbsp;xxx&nbsp;where&nbsp;value=?&nbsp;<br />
但是有时候我们需要得到完整的SQL语句，怎么办呢？使用P6SPY就可以完成这个任务<br />
&nbsp;<br />
p6spy是一个开源软件，它可以跟踪任何使用jdbc的应用产生的数据库操作。特别适合于监控ejb服务器产生的&nbsp;sql&nbsp;statements。<br />
官方网址：http://www.p6spy.com/<br />
目前p6spy&nbsp;适用的应用服务器包括jboss,&nbsp;atg,&nbsp;orion,&nbsp;jonas,&nbsp;iplanet,&nbsp;weblogic,&nbsp;websphere,&nbsp;resin&nbsp;and&nbsp;tomcat.<br />
&nbsp;<br />
下面介绍一下p6spy在tomcat应用程序上安装的步骤：<br />
（1）http://www.p6spy.com/download.html，下载zip包<br />
（2）解压出p6spy.jar&nbsp;spy.properties两个文件<br />
（3）将p6spy.jar&nbsp;放入应用程序的WEB-INF/lib目录，将spy.properties放入WEB-INF/classes目录<br />
（4）修改spy.properties<br />
&nbsp;<br />
&nbsp;realdriver&nbsp;=com.mysql.jdbc.Driver&nbsp;将这行前面的#去掉(如果使用的是mysql)<br />
logfile&nbsp;=&nbsp;c://spy.log&nbsp;修改一个你需要的日志文件名<br />
&nbsp;<br />
（5）修改hibernate.xml，修改connection.driver_class的值为com.p6spy.engine.spy.P6SpyDriver<br />
（6）重启tomcat<br />
（7）这样在c:/下的spy.log记录了数据库的访问情况。<br />
<br />
</span></div>
<img src ="http://www.blogjava.net/wangbing/aggbug/292575.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangbing/" target="_blank">王总兵</a> 2009-08-25 22:24 <a href="http://www.blogjava.net/wangbing/archive/2009/08/25/292575.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>匆忙8月</title><link>http://www.blogjava.net/wangbing/archive/2009/08/23/292242.html</link><dc:creator>王总兵</dc:creator><author>王总兵</author><pubDate>Sat, 22 Aug 2009 17:20:00 GMT</pubDate><guid>http://www.blogjava.net/wangbing/archive/2009/08/23/292242.html</guid><wfw:comment>http://www.blogjava.net/wangbing/comments/292242.html</wfw:comment><comments>http://www.blogjava.net/wangbing/archive/2009/08/23/292242.html#Feedback</comments><slash:comments>15</slash:comments><wfw:commentRss>http://www.blogjava.net/wangbing/comments/commentRss/292242.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangbing/services/trackbacks/292242.html</trackback:ping><description><![CDATA[&nbsp;&nbsp; &nbsp;看到日历马上8月要结束了，写点什么也不知道标题。匆忙8月，其实是匆忙每个月，自从2007年7月毕业到公司上班，每周周六加班，周一到周五至少2个晚上加班到9点，每周多工作10个小时左右。2年时间，每周工作8*5＝40个小时，加班10个小时，相当于给公司工作了2.5年了。因为户口，没有在公司干满三年需要交上万的人民币，也因为项目一直不完，始终下不了狠心谈离职。但是，看到身边的同学都纷纷跳槽，高薪不断，我也心里痒痒。但是，当我准备找工作时，我才发现，在公司2年，我已经很少编程了。2年时间大部分精力是在客户沟通需求分析这块，最近1年手下一直有几个刚毕业的学生帮我写代码，我的工作主要是需求分析、库表设计、安排他们开发、安排几个测试的MM测试。每天干不完的事情，打不完的电话，开不完的会议，就是没有再编程。刚毕业那会，我也是编程高手啊，不停的帮同事解决技术问题。其实大部分都是javascript的问题，因为那时刚开始画界面原型，需要大量的js开发。可是，到了今天这个时候，有人问我技术问题，我要么让他去问架构组的技术支持，要么告诉他先不要做，再和客户讨论下，换个简单的方式搞定。心里不是很踏实啊，虽然做了大项目，但是做的真的不踏实了。如果真的说学到了什么，我觉得只有一句话，那就是&#8220;认真做好项目的每件事&#8221;。但是这句话找工作好像远远不够。个人总结下比起毕业那会，有那些提高了呢？<br />
&nbsp;&nbsp; &nbsp;责任心提高了，因为负责两个子系统，从需求，设计到开发、测试，客户签字验收一条龙，责任重了责任心自然起来了。<br />
&nbsp;&nbsp; &nbsp;积极性提高了，每天很想偷懒，但是一旦我偷懒，下面还有3，4个人的工作需要我安排，都是新人，也都是对前途充满期待的年轻人，一旦没有给他们安排工作，马上过来问有什么事情可以做。因为要保证他们工作充实，所以，我被逼着充实了很多。刚毕业那会，经常上网、上qq，现在上班不敢开qq了。以前有领导看着我，我都开qq，现在却因为怕事情做不完，不敢开qq了。<br />
&nbsp;&nbsp; &nbsp;对大项目的理解提高了。项目组有120人左右，整个项目做了2年还没有验收，给我最大的感觉是，大项目实施难度太大了。项目的目标客户大约1万人左右，按照客户的组织机构和使用功能不同，项目分成了20个子系统，每个子系统对应一批客户。客户方从各个机构抽选出大约40人的领域专家，分别负责20个子系统的工作。参与的人多，沟通成本特别大，项目前期大会小会不断，电话一个接一个，email多到快要爆掉。开发中期，淘汰了一批能力不行的开发人员和子系统负责人，项目领导班子换人，开发规范指定不及时，技术问题没有彻底解决，各种公用组件产品的培训没有跟上，整个开发过程不能不说是混乱。项目后期，测试工作繁重，但是测试人员不到位，后来人员到位了但是业务跟不上。测试出现问题，涉及到多个子系统或者公共层面的问题时，各个子系统负责人相互推诿，或者公共的问题悬而不决，客户方对于流程不能下定论，各子系统不肯承担修改业务流程的风险，只能逃避。总之，项目大了什么事情都可能发生，2年项目组经历真是见识不少。<br />
&nbsp;&nbsp; &nbsp;最后提供的应该是喝酒抽烟的本事了，进公司时我还是刚毕业学生，从来不喝白酒。现在倒好，经常和客户老大一起喝上半斤白酒，还有抽烟以前就是毕业那会抽着玩，现在一加班必须抽烟了。加班太多，烟也抽的太多了。
<img src ="http://www.blogjava.net/wangbing/aggbug/292242.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangbing/" target="_blank">王总兵</a> 2009-08-23 01:20 <a href="http://www.blogjava.net/wangbing/archive/2009/08/23/292242.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]天生一对"Maven2+Jetty" -- Maven2创建并管理WebApp，并使用Maven Jetty Plugin在Eclipse中调试</title><link>http://www.blogjava.net/wangbing/archive/2009/07/08/285984.html</link><dc:creator>王总兵</dc:creator><author>王总兵</author><pubDate>Wed, 08 Jul 2009 15:30:00 GMT</pubDate><guid>http://www.blogjava.net/wangbing/archive/2009/07/08/285984.html</guid><wfw:comment>http://www.blogjava.net/wangbing/comments/285984.html</wfw:comment><comments>http://www.blogjava.net/wangbing/archive/2009/07/08/285984.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wangbing/comments/commentRss/285984.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangbing/services/trackbacks/285984.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 天生一对"Maven2+Jetty" -- Maven2创建并管理WebApp，并使用Maven Jetty Plugin在Eclipse中调试Maven2代比1代改进很多，其中主要强调的是--它不仅仅是个依赖包管理器!开始先要推荐一个专讲Maven2的电子书给大家，对MAVEN学习相当有助益：Better Builds with Maven&nbsp;&nbsp;&nbsp;...&nbsp;&nbsp;<a href='http://www.blogjava.net/wangbing/archive/2009/07/08/285984.html'>阅读全文</a><img src ="http://www.blogjava.net/wangbing/aggbug/285984.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangbing/" target="_blank">王总兵</a> 2009-07-08 23:30 <a href="http://www.blogjava.net/wangbing/archive/2009/07/08/285984.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]利用Maven开发webapp</title><link>http://www.blogjava.net/wangbing/archive/2009/07/07/285847.html</link><dc:creator>王总兵</dc:creator><author>王总兵</author><pubDate>Tue, 07 Jul 2009 09:24:00 GMT</pubDate><guid>http://www.blogjava.net/wangbing/archive/2009/07/07/285847.html</guid><wfw:comment>http://www.blogjava.net/wangbing/comments/285847.html</wfw:comment><comments>http://www.blogjava.net/wangbing/archive/2009/07/07/285847.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/wangbing/comments/commentRss/285847.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangbing/services/trackbacks/285847.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp; 目前在网上能够看到的关于Maven的教程大多是一些基本的设置，但是用于一个完整的项目开发的并不是很多（如果大家有，欢迎回复），只能自己一点点整了。</p>
&nbsp;&nbsp;&nbsp; 1、安装Maven2.0.4；<br />
&nbsp;&nbsp;&nbsp; 2、运行mvn；<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这个主要是为了能够在%user_profile%/目录下创建.m目录。这个目录是maven的默认工作目录。<br />
&nbsp;&nbsp;&nbsp; 3、创建一个基本的eclipse项目；<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mvn archetype:create -DgroupId=org.powersoft -DartifactId=app<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mvn eclipse:eclipse<br />
&nbsp;&nbsp;&nbsp; 4、创建一个webapp；<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mvn archetype:create -DgroupId=org.powersoft -DartifactId=hrms -DarchetypeArtifactId=maven-archetype-webapp<br />
&nbsp;&nbsp;&nbsp; 5、将生成的src/main下的webapp目录拷贝到在第3步中创建的eclipse项目中的src/main目录下；<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这个将作为web的根目录<br />
&nbsp;&nbsp;&nbsp; 6、将以上创建的项目导入到eclisep工程中；<br />
&nbsp;&nbsp;&nbsp; 7、由于我们将在项目使用Spring，hibernate和xfire，修改pom.xml文件<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;project xmlns="<a href="http://maven.apache.org/POM/4.0.0">http://maven.apache.org/POM/4.0.0</a>"<br />
&nbsp;xmlns:xsi="<a href="http://www.w3.org/2001/XMLSchema-instance">http://www.w3.org/2001/XMLSchema-instance</a>"<br />
&nbsp;xsi:schemaLocation="<a href="http://maven.apache.org/POM/4.0.0">http://maven.apache.org/POM/4.0.0</a> <a href="http://maven.apache.org/maven-v4_0_0.xsd">http://maven.apache.org/maven-v4_0_0.xsd</a>"&gt;<br />
&nbsp;&lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;<br />
&nbsp;&lt;groupId&gt;org.powersoft&lt;/groupId&gt;<br />
&nbsp;&lt;artifactId&gt;hrms&lt;/artifactId&gt;<br />
&nbsp;&lt;packaging&gt;war&lt;/packaging&gt;<br />
&nbsp;&lt;name&gt;Maven Quick Start Archetype&lt;/name&gt;<br />
&nbsp;&lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;<br />
&nbsp;&lt;url&gt;http://maven.apache.org&lt;/url&gt;<br />
&nbsp;&lt;dependencies&gt;<br />
&nbsp;&nbsp;&lt;dependency&gt; <br />
&nbsp;&nbsp;&nbsp;&lt;groupId&gt;junit&lt;/groupId&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;artifactId&gt;junit&lt;/artifactId&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;version&gt;3.8.1&lt;/version&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;scope&gt;test&lt;/scope&gt;<br />
&nbsp;&nbsp;&lt;/dependency&gt;<br />
&nbsp;&nbsp;&lt;!--<br />
&nbsp;&nbsp;&lt;dependency&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;groupId&gt;org.hibernate&lt;/groupId&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;artifactId&gt;hibernate&lt;/artifactId&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;version&gt;3.2.0.cr5&lt;/version&gt;<br />
&nbsp;&nbsp;&lt;/dependency&gt;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;--&gt;<br />
&nbsp;&nbsp;&lt;dependency&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;groupId&gt;org.springframework&lt;/groupId&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;artifactId&gt;spring&lt;/artifactId&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;version&gt;2.0&lt;/version&gt;<br />
&nbsp;&nbsp;&lt;/dependency&gt;<br />
&nbsp;&nbsp;&lt;dependency&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;groupId&gt;org.codehaus.xfire&lt;/groupId&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;artifactId&gt;xfire-aegis&lt;/artifactId&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;version&gt;1.2.2&lt;/version&gt;<br />
&nbsp;&nbsp;&lt;/dependency&gt;<br />
&nbsp;&nbsp;&lt;dependency&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;groupId&gt;org.codehaus.xfire&lt;/groupId&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;artifactId&gt;xfire-core&lt;/artifactId&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;version&gt;1.2.2&lt;/version&gt;<br />
&nbsp;&nbsp;&lt;/dependency&gt;<br />
&nbsp;&nbsp;&lt;dependency&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;groupId&gt;org.codehaus.xfire&lt;/groupId&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;artifactId&gt;xfire-annotations&lt;/artifactId&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;version&gt;1.2.2&lt;/version&gt;<br />
&nbsp;&nbsp;&lt;/dependency&gt;<br />
&nbsp;&nbsp;&lt;dependency&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;groupId&gt;org.codehaus.xfire&lt;/groupId&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;artifactId&gt;xfire-spring&lt;/artifactId&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;version&gt;1.2.2&lt;/version&gt;<br />
&nbsp;&nbsp;&lt;/dependency&gt;<br />
&nbsp;&nbsp;&lt;dependency&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;groupId&gt;org.codehaus.xfire&lt;/groupId&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;artifactId&gt;xfire-xmlbeans&lt;/artifactId&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;version&gt;1.2.2&lt;/version&gt;<br />
&nbsp;&nbsp;&lt;/dependency&gt;<br />
&nbsp;&lt;/dependencies&gt;<br />
&nbsp;<br />
&nbsp;&lt;build&gt;<br />
&nbsp;&nbsp;&lt;plugins&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;plugin&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;groupId&gt;<strong><font color="#ff0000">org.mortbay.jetty</font></strong>&lt;/groupId&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;artifactId&gt;<strong><font color="#ff0000">maven-jetty-plugin</font></strong>&lt;/artifactId&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;configuration&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;scanIntervalSeconds&gt;10&lt;/scanIntervalSeconds&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;contextPath&gt;/hrmsweb&lt;/contextPath&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;systemProperties&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&lt;systemProperty&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&lt;name&gt;org.apache.commons.logging.Log&lt;/name&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;value&gt;org.apache.commons.logging.impl.SimpleLog&lt;/value&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&lt;/systemProperty&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/systemProperties&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/configuration&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;/plugin&gt;<br />
&nbsp;&nbsp;&lt;/plugins&gt;<br />
&nbsp;&lt;/build&gt;<br />
&lt;/project&gt;<br />
&nbsp;&nbsp;&nbsp; 8、在eclipse中启用maven2的plugin，将会看到一些jar在下载，可以喝咖啡去了<br />
９、运行mvn jetty:run，将启动jetty web server。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;这样你就可以跟往常使用eclipse开发项目一样，编写类了，这个jetty插件会自动检测代码修改，并重新部署应用。
<img src ="http://www.blogjava.net/wangbing/aggbug/285847.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangbing/" target="_blank">王总兵</a> 2009-07-07 17:24 <a href="http://www.blogjava.net/wangbing/archive/2009/07/07/285847.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]Maven2安装总结</title><link>http://www.blogjava.net/wangbing/archive/2009/07/06/285668.html</link><dc:creator>王总兵</dc:creator><author>王总兵</author><pubDate>Mon, 06 Jul 2009 05:37:00 GMT</pubDate><guid>http://www.blogjava.net/wangbing/archive/2009/07/06/285668.html</guid><wfw:comment>http://www.blogjava.net/wangbing/comments/285668.html</wfw:comment><comments>http://www.blogjava.net/wangbing/archive/2009/07/06/285668.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/wangbing/comments/commentRss/285668.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangbing/services/trackbacks/285668.html</trackback:ping><description><![CDATA[<p>以前虽然使用过Maven1.0，当发现现在的Maven2.0的变化和1.0比起来变化很大，配置上倒还一样，但是使用上有很大不同，如果你还用1.0的命令，会发现许多不能使用。闲话少叙，进入正题。</p>
<p>首先当然去Apache网站下载Maven2了。下载地址：http://maven.apache.org/download.html 。我下载的版本是maven-2.0.4-bin.zip</p>
<p>然后我把maven-2.0.4-bin.zip解<font color="#ff0000">压到D:\maven-2.0.4</font></p>
<p>下面就是配置环境变量了，这和1.0的版本是一样的。（1）<font color="#ff6600">MAVEN_HOME</font>:D:\maven-2.0.4 （2）在Path 中加入<font color="#ff9900">%MAVEN_HOME%\bin</font>，如下图示： <br />
</p>
<div forimg="1"><img class="blogimg" small="0" src="http://hiphotos.baidu.com/hivemind/pic/item/1d965acf3510213ff9dc61e1.jpg" border="0"  alt="" /></div>
<p> 这样配置就OK了。然后，我建立了如下目录：E:\app\mavenApp，当然这些可以随便建立，呵呵。</p>
<p> 下面说一些Maven1.x和Maven2.x的不同（一些摘自一些网友文章）<br />
------------------------------------<br />
Maven2 把配置文件压缩成了<font color="#ff6600">pom.xml</font>和<font color="#ff6600">settings.xml </font>两个文件，简洁了不少。POM是Maven的核心对象模型，在Maven2中POM已由project.xml转移到pom.xml中使用，版本也由3升级为4。对于项目，一般只需要pom.xml就行了。在Maven2中不需要也不提倡使用maven.xml</p>
<p>生命周期的引入<br />
在Maven2中有了明确的生命周期概念，而且都提供与之对应的命令，使得项目构建更加清晰明了。主要的生命周期阶段：</p>
<p>validate，验证工程是否正确，所有需要的资源是否可用。 <br />
compile，编译项目的源代码。 <br />
test-compile，编译项目测试代码。 <br />
test，使用已编译的测试代码，测试已编译的源代码。 <br />
package，已发布的格式，如jar，将已编译的源代码打包。 <br />
integration-test，在集成测试可以运行的环境中处理和发布包。 <br />
verify，运行任何检查，验证包是否有效且达到质量标准。 <br />
install，把包安装在本地的repository中，可以被其他工程作为依赖来使用 <br />
deploy，在整合或者发布环境下执行，将最终版本的包拷贝到远程的repository，使得其他的开发者或者工程可以共享。 <br />
generate-sources，产生应用需要的任何额外的源代码，如xdoclet。 </p>
<p>新增Dependency Scope<br />
在POM 4中，&lt;dependency&gt;中还引入了&lt;scope&gt;，它主要管理依赖的部署。目前&lt;scope&gt;可以使用5个值：</p>
<p>compile，缺省值，适用于所有阶段，会随着项目一起发布。 <br />
provided，类似compile，期望JDK、容器或使用者会提供这个依赖。如servlet.jar。 <br />
runtime，只在运行时使用，如JDBC驱动，适用运行和测试阶段。 <br />
test，只在测试时使用，用于编译和运行测试代码。不会随项目发布。 <br />
system，类似provided，需要显式提供包含依赖的jar，Maven不会在Repository中查找它。<br />
------------------------------------</p>
<p><font color="#000066">下面说些基本设置，打开D:\maven-2.0.4\conf\settings.xml<br />
1.
改变&lt;localRepository&gt;E:/app/m2/repository&lt;/localRepository&gt;
目的：改变本地的数据仓库目录（存放从远程下载的jar包），如果不改变也可以，如不改变，缺省目录为：C:\Documents and
Settings\主机名\.m2\repository<br />
2. 配置代理，主要目的是为了能从远程下载jar包，根据实际的网路情况进行配置吧。因为我现在单位是有代理服务器的，如果不配置，就不能从远程下载jar包了。我的配置如下（注意：如果你的网络没有代理服务器，就不用配置这个步骤）<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;proxy&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;id&gt;optional&lt;/id&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;active&gt;true&lt;/active&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;protocol&gt;http&lt;/protocol&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;host&gt;192.168.17.100&lt;/host&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;port&gt;8889&lt;/port&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;nonProxyHosts&gt;192.168.*.*&lt;/nonProxyHosts&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;/proxy&gt;</font></p>
<p><br />
<br />
下面就是一些goal命令了，这里和Maven1有不少不同，常用的命令有：<br />
</p>
<div id="blog_text" class="cnt">
<li>创建Maven的普通java项目：mvn archetype:create -DgroupId=com.codeline.commons -DartifactId=pjoName&nbsp;&nbsp;&nbsp;&nbsp;</li>
<li>创建Maven的Web项目：mvn archetype:create -DgroupId=com.mycompany.app<br />
-DartifactId=my-webapp<br />
-DarchetypeArtifactId=maven-archetype-webapp&nbsp;&nbsp;&nbsp;&nbsp;</li>
<li>编译源代码：mvn compile （或者：mvn compiler:compile）&nbsp;&nbsp;&nbsp;</li>
<li>编译测试代码：mvn test-compile&nbsp;&nbsp;&nbsp;&nbsp;</li>
<li>运行测试：mvn test&nbsp;&nbsp;&nbsp;&nbsp;</li>
<li>产生site：mvn site&nbsp;&nbsp;&nbsp;&nbsp;</li>
<li>打包：mvn package&nbsp;&nbsp;&nbsp;&nbsp;</li>
<li>在本地Repository中安装jar：mvn install&nbsp;&nbsp;&nbsp;&nbsp;</li>
<li>清除产生的项目：mvn clean&nbsp;&nbsp;&nbsp;&nbsp;</li>
<li>生成eclipse项目：mvn eclipse:eclipse&nbsp;&nbsp;&nbsp;</li>
<li>生成idea项目：mvn idea:idea&nbsp;&nbsp;&nbsp;</li>
<li>组合使用goal命令，如只打包不测试：mvn -Dtest package&nbsp;&nbsp;&nbsp;&nbsp;</li>
<li>编译测试的内容：mvn test-compile&nbsp;&nbsp;&nbsp;</li>
<li>只打jar包: mvn jar:jar&nbsp;&nbsp;&nbsp;</li>
<li>只测试而不编译，也不测试编译：mvn test -skipping compile -skipping test-compile (这里要特别注意 <font color="#9900ff">-skipping</font> 的灵活运用，当然也可以用于其他组合命令)&nbsp;&nbsp;&nbsp;</li>
<li>清除eclipse的一些系统设置:mvn eclipse:clean&nbsp;&nbsp;&nbsp;
<p>=========================================================</p>
<p>配置存储库</p>
<p>要求项目的每个开发者必须在conf目录中配置存储库是不方便的，所以Maven可以同时查看多个存储库并且将它们全部配置在pom.xml文件
中。让我们看看一个例子，它展示了如何在应用程序用使用多个存储库。在以下从pom.xml文件摘录的片断中，我们设置了两个存储库来让Maven寻找依
赖项。Ibiblio一直是默认的存储库，我们又添加了Planet
Mirror作为后援存储库。我们也可以让团队使用的本地web服务器作为第二个存储库。</p>
<p>&lt;repositories&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;repository&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;id&gt;Ibiblio&lt;/id&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;name&gt;Ibiblio&lt;/name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;url&gt;http://www.ibiblio.org/maven/&lt;/url&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;/repository&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;repository&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;id&gt;PlanetMirror&lt;/id&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;name&gt;Planet Mirror&lt;/name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;url&gt;<font color="#ff6600">http://public.planetmirror.com/pub/maven/</font>&lt;/url&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;/repository&gt;<br />
&nbsp;&nbsp; &lt;/repositories&gt;<br />
<br />
<font color="#cc6600">==================================================</font><br />
遇到的小问题解决。<br />
<font color="#ff0000">*</font> 当建立一个工程后，执行 mvn eclipse:eclipse
，建立一个maven的工程，用eclipse打开后，发现报如下错误：Unbound classpath variable:
'M2_REPO/junit/junit/3.8.1/junit-3.8.1.jar' in project my-webapp&nbsp;&nbsp;
，这是因为在Eclipse 没有配置 M2_REPO 变量，配置步骤：window &gt;&gt; preferences &gt;&gt;
Java &gt;&gt; Build Path &gt;&gt; Classpath Variables<br />
新建一个 M2_REPO 的变量，变量值指向你系统的Maven2的数据仓库位置。如图：<br />
</p>
<div forimg="1"><img class="blogimg" small="0" src="http://hiphotos.baidu.com/hivemind/pic/item/2f59981120c40e7ccb80c4e2.jpg" border="0"  alt="" /></div>
<p><br />
<font color="#ff9900">------------------------------------------<br />
</font><font color="#ff0000">* </font>POM.XML 继承的写法<br />
&lt;project xmlns="<a href="http://maven.apache.org/POM/4.0.0">http://maven.apache.org/POM/4.0.0</a>"<br />
&nbsp;&nbsp;&nbsp;&nbsp; xmlns:xsi="<a href="http://www.w3.org/2001/XMLSchema-instance">http://www.w3.org/2001/XMLSchema-instance</a>"<br />
&nbsp;&nbsp;&nbsp;&nbsp; xsi:schemaLocation="<a href="http://maven.apache.org/POM/4.0.0">http://maven.apache.org/POM/4.0.0</a> <a href="http://maven.apache.org/maven-v4_0_0.xsd">http://maven.apache.org/maven-v4_0_0.xsd</a>"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;groupId&gt;org.apache.hivemind&lt;/groupId&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;artifactId&gt;hivemind-examples&lt;/artifactId&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;packaging&gt;jar&lt;/packaging&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;version&gt;2.0-alpha-1&lt;/version&gt;<br />
<font color="#ff6600">&nbsp;&nbsp;&nbsp;&nbsp; &lt;parent&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;groupId&gt;org.apache.hivemind&lt;/groupId&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;artifactId&gt;hivemind-project&lt;/artifactId&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;version&gt;2.0-alpha-1&lt;/version&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;relativePath&gt;../pom.xml&lt;/relativePath&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;/parent&gt;</font><br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;name&gt;HiveMind Examples&lt;/name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;inceptionYear&gt;2003&lt;/inceptionYear&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;dependencies&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;dependency&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;groupId&gt;org.apache.hivemind&lt;/groupId&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;artifactId&gt;hivemind-framework&lt;/artifactId&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;version&gt;2.0-alpha-1&lt;/version&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/dependency&gt;<br />
</p>
<p><font color="#ff0000">* </font>如何安装Jar（或war）依赖到本地的数据仓库中？<br />
下面具一个如何把dwr.jar包上传到本地数据仓库的例子，一看例子，大家就明了了。<br />
- 下载<font color="#6600ff">dwr.jar</font>包到本地，我把它放到了 C:/ （C盘根目录），如图示：<br />
</p>
<div forimg="1"><img class="blogimg" small="0" src="http://hiphotos.baidu.com/hivemind/pic/item/db8f68a7eeeb7697d04358e2.jpg" border="0"  alt="" /></div>
<p><br />
- 进入&#8220;命令行提示符&#8221;，进入到C:/，然后执行 <font color="#666600"><font color="#996600"><font color="#996600">mvn install:install-file -Dfile</font>=</font><font color="#6600ff">dwr.jar</font> <font color="#996600">-</font><font color="#996600">DgroupId=<font color="#cc0000">dwr.mocha </font>-DartifactId=<font color="#cc00ff">dwrDart</font> -Dversion=<font color="#006600"><font color="#009900">1.0</font></font> -Dpackaging=</font><font color="#0000ff">jar</font> </font>这样就把dwr传到了本地仓库中（我的本地仓库地址为：<font style="background-color: #cccccc;" color="#000000">E:\app\m2\repository\</font>），上传到仓库中的jar包名为<font color="#cc00ff">dwrDart</font>-<font color="#009900">1.0</font>.<font color="#0000ff">jar</font>,目录结构为<font color="#cc0000">dwr/mocha/</font><font color="#cc00ff">dwrDart</font>/<font color="#cc0000"><font color="#009900">1.0</font></font>/<font color="#cc00ff">dwrDart</font>-<font color="#cc0000"><font color="#009900">1.0</font></font>.<font color="#0000ff">jar</font>如图示：</p>
<div forimg="1"><img class="blogimg" small="0" src="http://hiphotos.baidu.com/hivemind/pic/item/a872a710c8318703203f2ee3.jpg" border="0"  alt="" /></div>
<p><br />
</p>
<div forimg="1"><img class="blogimg" small="0" src="http://hiphotos.baidu.com/hivemind/pic/item/98a34406734cb479030881ec.jpg" border="0"  alt="" />&nbsp;&nbsp;
<div forimg="1"><img class="blogimg" small="0" src="http://hiphotos.baidu.com/hivemind/pic/item/960cf333f04f6f41ac4b5fec.jpg" border="0"  alt="" /></div>
</div>
</li>
</div>
<img src ="http://www.blogjava.net/wangbing/aggbug/285668.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangbing/" target="_blank">王总兵</a> 2009-07-06 13:37 <a href="http://www.blogjava.net/wangbing/archive/2009/07/06/285668.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]如何在Java中避免equals方法的隐藏陷阱</title><link>http://www.blogjava.net/wangbing/archive/2009/06/19/283289.html</link><dc:creator>王总兵</dc:creator><author>王总兵</author><pubDate>Fri, 19 Jun 2009 13:01:00 GMT</pubDate><guid>http://www.blogjava.net/wangbing/archive/2009/06/19/283289.html</guid><wfw:comment>http://www.blogjava.net/wangbing/comments/283289.html</wfw:comment><comments>http://www.blogjava.net/wangbing/archive/2009/06/19/283289.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wangbing/comments/commentRss/283289.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangbing/services/trackbacks/283289.html</trackback:ping><description><![CDATA[<span  style="font-family: verdana; font-size: 14px; line-height: 21px; ">
<h1 style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0.5em; padding-left: 1.5em; font-size: 15px; font-family: 'Microsoft yahei', heiti, verdana, sans-serif; text-align: center; ">如何在Java中避免equals方法的隐藏陷阱</h1>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; text-align: center; "><strong></strong></p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; text-align: center; "><strong>译者：赵锟</strong></p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; text-align: center; ">zhaokun.km (at)gmail.com</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; text-align: center; ">&nbsp;</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; text-align: center; ">转自：<a href="http://cocre.com/?p=1051" style="text-decoration: none; color: #336699; ">http://cocre.com/?p=1051</a>&nbsp;<a href="http://cocre.com/" style="text-decoration: none; color: #336699; ">酷壳</a></p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; "><strong></strong></p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; "><strong></strong></p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; "><strong>译者注</strong>&nbsp;:你可能会觉得Java很简单，Object的equals实现也会非常简单，但是事实并不是你想象的这样，耐心的读完本文，你会发现你对Java了解的是如此的少。如果这篇文章是一份Java程序员的入职笔试，那么不知道有多少人会掉落到这样的陷阱中。原文转自<a onclick="pageTracker._trackPageview('/outgoing/www.artima.com/lejava/articles/equality.html?referer=http://cocre.com/?page_id=368');" href="http://www.artima.com/lejava/articles/equality.html" style="text-decoration: none; color: #336699; "><span style="line-height: 21px; color: #2970a6; ">http://www.artima.com/lejava/articles/equality.html</span></a>&nbsp;三位作者都是不同领域的大拿，有兴趣的读者可以从上面这个连接直接去阅读原文。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; "><strong>摘要</strong><br />
本文描述重载equals方法的技术，这种技术即使是具现类的子类增加了字段也能保证equal语义的正确性。<br />
在《Effective Java》的第8项中，Josh Bloch描述了当继承类作为面向对象语言中的等价关系的基础问题，要保证派生类的equal正确性语义所会面对的困难。Bloch这样写到：</p>
<blockquote style="border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: dotted; border-right-style: dotted; border-bottom-style: dotted; border-left-style: dotted; border-top-color: #98a47f; border-right-color: #98a47f; border-bottom-color: #98a47f; border-left-color: #98a47f; background-image: initial; background-repeat: initial; background-attachment: initial; background-color: #f5f5f5; font: normal normal normal 12px/normal simsun; padding-top: 10px; padding-right: 10px; padding-bottom: 10px; padding-left: 10px; margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; background-position: initial initial; ">
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; "><strong>除非你忘记了面向对象抽象的好处，否则在当你继承一个新类或在类中增加了一个值组件时你无法同时保证equal的语义依然正确</strong></p>
</blockquote>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">在《Programming in Scala》中的第28章演示了一种方法，这种方法允许即使继承了新类，增加了新的值组件，equal的语义仍然能得到保证。虽然在这本书中这项技术是在使用Scala类环境中，但是这项技术同样可以应用于Java定义的类中。在本文中的描述来自于Programming in Scala中的文字描述，但是代码被我从scala翻译成了Java</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">　</p>
<h4 style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">常见的等价方法陷阱</h4>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">java.lang.Object 类定义了equals这个方法，它的子类可以通过重载来覆盖它。不幸的是，在面向对象中写出正确的equals方法是非常困难的。事实上，在研究了大量的Java代码后，2007 paper的作者得出了如下的一个结论：</p>
<blockquote style="border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: dotted; border-right-style: dotted; border-bottom-style: dotted; border-left-style: dotted; border-top-color: #98a47f; border-right-color: #98a47f; border-bottom-color: #98a47f; border-left-color: #98a47f; background-image: initial; background-repeat: initial; background-attachment: initial; background-color: #f5f5f5; font: normal normal normal 12px/normal simsun; padding-top: 10px; padding-right: 10px; padding-bottom: 10px; padding-left: 10px; margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; background-position: initial initial; ">
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">几乎所有的equals方法的实现都是错误的！</p>
</blockquote>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">这个问题是因为等价是和很多其他的事物相关联。例如其中之一，一个的类型C的错误等价方法可能意味着你无法将这个类型C的对象可信赖的放入到容器中。比如说，你有两个元素elem1和elem2他们都是类型C的对象，并且他们是相等，即elem1.equals(elm2)返回ture。但是，只要这个equals方法是错误的实现，那么你就有可能会看见如下的一些行为：</p>
<pre class="brush: java">Set hashSet&lt;C&gt; = new java.util.HashSet&lt;C&gt;();
hashSet.add(elem1);
hashSet.contains(elem2);    // returns false!</pre>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">当equals重载时，这里有4个会引发equals行为不一致的常见陷阱：</p>
<ol style="margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 35px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; ">
    <li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 2px; padding-right: 0px; padding-bottom: 2px; padding-left: 0px; list-style-type: decimal; ">定义了错误的equals方法签名(signature) Defining equals with the wrong signature.</li>
    <li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 2px; padding-right: 0px; padding-bottom: 2px; padding-left: 0px; list-style-type: decimal; ">重载了equals的但没有同时重载hashCode的方法。 Changing equals without also changing hashCode.</li>
    <li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 2px; padding-right: 0px; padding-bottom: 2px; padding-left: 0px; list-style-type: decimal; ">建立在会变化字域上的equals定义。 Defining equals in terms of mutable fields.</li>
    <li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 2px; padding-right: 0px; padding-bottom: 2px; padding-left: 0px; list-style-type: decimal; ">不满足等价关系的equals错误定义 Failing to define equals as an equivalence relation.</li>
</ol>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">在剩下的章节中我们将依次讨论这4中陷阱。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">　</p>
<h4 style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">陷阱1：定义错误equals方法签名(signature)</h4>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">考虑为下面这个简单类Point增加一个等价性方法：</p>
<pre class="brush: java">public class Point {
private final int x;
private final int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
// ...
}</pre>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">看上去非常明显，但是按照这种方式来定义equals就是错误的。</p>
<pre class="brush: java">// An utterly wrong definition of equals
public boolean equals(Point other) {
return (this.getX() == other.getX() &amp;&amp; this.getY() == other.getY());
}</pre>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">这个方法有什么问题呢？初看起来，它工作的非常完美：</p>
<pre class="brush: java">Point p1 = new Point(1, 2);
Point p2 = new Point(1, 2);
Point q = new Point(2, 3);
System.out.println(p1.equals(p2)); // prints true
System.out.println(p1.equals(q)); // prints false</pre>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">然而，当我们一旦把这个Point类的实例放入到一个容器中问题就出现了：</p>
<pre class="brush: java">import java.util.HashSet;
HashSet&lt;Point&gt; coll = new HashSet&lt;Point&gt;();
coll.add(p1);
System.out.println(coll.contains(p2)); // prints false</pre>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">为什么coll中没有包含p2呢？甚至是p1也被加到集合里面，p1和p2是是等价的对象吗？在下面的程序中，我们可以找到其中的一些原因，定义p2a是一个指向p2的对象，但是p2a的类型是Object而非Point类型：</p>
<pre class="brush: java">Object p2a = p2;</pre>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">现在我们重复第一个比较，但是不再使用p2而是p2a,我们将会得到如下的结果：</p>
<pre class="brush: java">System.out.println(p1.equals(p2a)); // prints false</pre>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">到底是那里出了了问题？事实上，之前所给出的equals版本并没有覆盖Object类的equals方法，因为他的类型不同。下面是Object的equals方法的定义</p>
<pre class="brush: java">public boolean equals(Object other)</pre>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">因为Point类中的equals方法使用的是以Point类而非Object类做为参数，因此它并没有覆盖Object中的equals方法。而是一种变化了的重载。在Java中重载被解析为静态的参数类型而非运行期的类型，因此当静态参数类型是Point,Point的equals方法就被调用。然而当静态参数类型是Object时，Object类的equals就被调用。因为这个方法并没有被覆盖，因此它仍然是实现成比较对象标示。这就是为什么虽然p1和p2a具有同样的x,y值，&#8221;p1.equals(p2a)&#8221;仍然返回了false。这也是会什么HasSet的contains方法返回false的原因，因为这个方法操作的是泛型，他调用的是一般化的Object上equals方法而非Point类上变化了的重载方法equals</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">一个更好但不完美的equals方法定义如下：</p>
<pre class="brush: java">// A better definition, but still not perfect
@Override public boolean equals(Object other) {
boolean result = false;
if (other instanceof Point) {
Point that = (Point) other;
result = (this.getX() == that.getX() &amp;&amp; this.getY() == that.getY());
}
return result;
}</pre>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">现在equals有了正确的类型，它使用了一个Object类型的参数和一个返回布尔型的结果。这个方法的实现使用instanceof操作和做了一个造型。它首先检查这个对象是否是一个Point类，如果是，他就比较两个点的坐标并返回结果，否则返回false。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">　</p>
<h4 style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">陷阱2：重载了equals的但没有同时重载hashCode的方法</h4>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">如果你使用上一个定义的Point类进行p1和p2a的反复比较，你都会得到你预期的true的结果。但是如果你将这个类对象放入到HashSet.contains()方法中测试，你就有可能仍然得到false的结果：</p>
<pre class="brush: java">Point p1 = new Point(1, 2);
Point p2 = new Point(1, 2);
HashSet&lt;Point&gt; coll = new HashSet&lt;Point&gt;();
coll.add(p1);
System.out.println(coll.contains(p2)); // 打印 false (有可能)</pre>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">事实上，这个个结果不是100%的false，你也可能有返回ture的经历。如果你得到的结果是true的话，那么你试试其他的坐标值，最终你一定会得到一个在集合中不包含的结果。导致这个结果的原因是Point重载了equals却没有重载hashCode。<br />
注意上面例子的的容器是一个HashSet，这就意味着容器中的元素根据他们的哈希码被被放入到&#8221;哈希桶 hash buckets&#8221;中。contains方法首先根据哈希码在哈希桶中查找，然后让桶中的所有元素和所给的参数进行比较。现在，虽然最后一个Point类的版本重定义了equals方法，但是它并没有同时重定义hashCode。因此，hashCode仍然是Object类的那个版本，即：所分配对象的一个地址的变换。所以p1和p2的哈希码理所当然的不同了，甚至是即时这两个点的坐标完全相同。不同的哈希码导致他们具有极高的可能性被放入到集合中不同的哈希桶中。contains方法将会去找p2的哈希码对应哈希桶中的匹配元素。但是大多数情况下，p1一定是在另外一个桶中，因此，p2永远找不到p1进行匹配。当然p2和p2也可能偶尔会被放入到一个桶中，在这种情况下，contains的结果就为true了。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">最新一个Point类实现的问题是，它的实现违背了作为Object类的定义的hashCode的语义。</p>
<blockquote style="border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: dotted; border-right-style: dotted; border-bottom-style: dotted; border-left-style: dotted; border-top-color: #98a47f; border-right-color: #98a47f; border-bottom-color: #98a47f; border-left-color: #98a47f; background-image: initial; background-repeat: initial; background-attachment: initial; background-color: #f5f5f5; font: normal normal normal 12px/normal simsun; padding-top: 10px; padding-right: 10px; padding-bottom: 10px; padding-left: 10px; margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; background-position: initial initial; ">
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; "><strong><br />
如果两个对象根据equals(Object)方法是相等的，那么在这两个对象上调用hashCode方法应该产生同样的值<br />
</strong></p>
</blockquote>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">事实上，在Java中，hashCode和equals需要一起被重定义是众所周知的。此外，hashCode只可以依赖于equals依赖的域来产生值。对于Point这个类来说，下面的的hashCode定义是一个非常合适的定义。</p>
<pre class="brush: java">public class Point {
private final int x;
private final int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
@Override public boolean equals(Object other) {
boolean result = false;
if (other instanceof Point) {
Point that = (Point) other;
result = (this.getX() == that.getX() &amp;&amp; this.getY() == that.getY());
}
return result;
}
<span style="color: #339966; ">
@Override public int hashCode() {
return (41 * (41 + getX()) + getY());
}
</span>
}</pre>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">这只是hashCode一个可能的实现。x域加上常量41后的结果再乘与41并将结果在加上y域的值。这样做就可以以低成本的运行时间和低成本代码大小得到一个哈希码的合理的分布(<strong>译者注：</strong>性价比相对较高的做法)。<br />
增加hashCode方法重载修正了定义类似Point类等价性的问题。然而，关于类的等价性仍然有其他的问题点待发现。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">　</p>
<h4 style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">陷阱3：建立在会变化字段上的equals定义</h4>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">让我们在Point类做一个非常微小的变化</p>
<pre class="brush: java">public class Point {
<span style="color: #339966; ">
private int x;
private int y;
</span>
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
<span style="color: #339966; ">
public void setX(int x) { // Problematic
this.x = x;
}
public void setY(int y) {
this.y = y;
}
</span>
@Override public boolean equals(Object other) {
boolean result = false;
if (other instanceof Point) {
Point that = (Point) other;
result = (this.getX() == that.getX() &amp;&amp; this.getY() == that.getY());
}
return result;
}
@Override public int hashCode() {
return (41 * (41 + getX()) + getY());
}
}</pre>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">唯一的不同是x和y域不再是final，并且两个set方法被增加到类中来，并允许客户改变x和y的值。equals和hashCode这个方法的定义现在是基于在这两个会发生变化的域上，因此当他们的域的值改变时，结果也就跟着改变。因此一旦你将这个point对象放入到集合中你将会看到非常神奇的效果。</p>
<pre class="brush: java">Point p = new Point(1, 2);
HashSet&lt;Point&gt; coll = new HashSet&lt;Point&gt;();
coll.add(p);
System.out.println(coll.contains(p)); // 打印 true</pre>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">现在如果你改变p中的一个域，这个集合中还会包含point吗，我们将拭目以待。</p>
<pre class="brush: java">p.setX(p.getX() + 1);
System.out.println(coll.contains(p)); // (有可能)打印 false</pre>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">看起来非常的奇怪。p去那里去了？如果你通过集合的迭代器来检查p是否包含，你将会得到更奇怪的结果。</p>
<pre class="brush: java">Iterator&lt;Point&gt; it = coll.iterator();
boolean containedP = false;
while (it.hasNext()) {
Point nextP = it.next();
if (nextP.equals(p)) {
containedP = true;
break;
}
}
System.out.println(containedP); // 打印 true</pre>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">结果是，集合中不包含p，但是p在集合的元素中！到底发生了什么！当然，所有的这一切都是在x域的修改后才发生的，p最终的的hashCode是在集合coll错误的哈希桶中。即，原始哈希桶不再有其新值对应的哈希码。换句话说，p已经在集合coll的是视野范围之外，虽然他仍然属于coll的元素。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">从这个例子所得到的教训是，当equals和hashCode依赖于会变化的状态时，那么就会给用户带来问题。如果这样的对象被放入到集合中，用户必须小心，不要修改这些这些对象所依赖的状态，这是一个小陷阱。如果你需要根据对象当前的状态进行比较的话，你应该不要再重定义equals，应该起其他的方法名字而不是equals。对于我们的Point类的最后的定义，我们最好省略掉hashCode的重载，并将比较的方法名命名为equalsContents，或其他不同于equals的名字。那么Point将会继承原来默认的equals和hashCode的实现，因此当我们修改了x域后p依然会呆在其原来在容器中应该在位置。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">　</p>
<h4 style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">陷阱4：不满足等价关系的equals错误定义</h4>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">Object中的equals的规范阐述了equals方法必须实现在非null对象上的等价关系：</p>
<ul style="margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 35px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; ">
    <li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 2px; padding-right: 0px; padding-bottom: 2px; padding-left: 0px; list-style-type: disc; ">自反原则：对于任何非null值X,表达式x.equals(x)总返回true。</li>
    <li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 2px; padding-right: 0px; padding-bottom: 2px; padding-left: 0px; list-style-type: disc; ">等价性：对于任何非空值x和y，那么当且仅当y.equals(x)返回真时，x.equals(y)返回真。</li>
    <li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 2px; padding-right: 0px; padding-bottom: 2px; padding-left: 0px; list-style-type: disc; ">传递性：对于任何非空值x,y,和z，如果x.equals(y)返回真，且y.equals(z)也返回真，那么x.equals(z)也应该返回真。</li>
    <li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 2px; padding-right: 0px; padding-bottom: 2px; padding-left: 0px; list-style-type: disc; ">一致性：对于非空x,y，多次调用x.equals(y)应该一致的返回真或假。提供给equals方法比较使用的信息不应该包含改过的信息。</li>
    <li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 2px; padding-right: 0px; padding-bottom: 2px; padding-left: 0px; list-style-type: disc; ">对于任何非空值x,x.equals(null)应该总返回false.</li>
</ul>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">Point类的equals定义已经被开发成了足够满足equals规范的定义。然而，当考虑到继承的时候，事情就开始变得非常复杂起来。比如说有一个Point的子类ColoredPoint，它比Point多增加了一个类型是Color的color域。假设Color被定义为一个枚举类型：</p>
<pre class="brush: java">public enum Color {
RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET;
}</pre>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">ColoredPoint重载了equals方法，并考虑到新加入color域，代码如下：</p>
<pre class="brush: java">public class ColoredPoint extends Point { // Problem: equals not symmetric
private final Color color;
public ColoredPoint(int x, int y, Color color) {
super(x, y);
this.color = color;
}
@Override public boolean equals(Object other) {
boolean result = false;
if (other instanceof ColoredPoint) {
ColoredPoint that = (ColoredPoint) other;
result = (this.color.equals(that.color) &amp;&amp; super.equals(that));
}
return result;
}
}</pre>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">这是很多程序员都有可能写成的代码。注意在本例中，类ColoredPointed不需要重载hashCode，因为新的ColoredPoint类上的equals定义，严格的重载了Point上equals的定义。hashCode的规范仍然是有效，如果两个着色点(colored point)相等，其坐标必定相等，因此它的hashCode也保证了具有同样的值。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">对于ColoredPoint类自身对象的比较是没有问题的，但是如果使用ColoredPoint和Point混合进行比较就要出现问题。</p>
<pre class="brush: java">Point p = new Point(1, 2);
ColoredPoint cp = new ColoredPoint(1, 2, Color.RED);
System.out.println(p.equals(cp)); // 打印真 true
System.out.println(cp.equals(p)); // 打印假 false</pre>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">&#8220;p等价于cp&#8221;的比较这个调用的是定义在Point类上的equals方法。这个方法只考虑两个点的坐标。因此比较返回真。在另外一方面，&#8220;cp等价于p&#8221;的比较这个调用的是定义在ColoredPoint类上的equals方法，返回的结果却是false，这是因为p不是ColoredPoint，所以equals这个定义违背了对称性。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">违背对称性对于集合来说将导致不可以预期的后果，例如：</p>
<pre class="brush: java">Set&lt;Point&gt; hashSet1 = new java.util.HashSet&lt;Point&gt;();
hashSet1.add(p);
System.out.println(hashSet1.contains(cp));    // 打印 false
Set&lt;Point&gt; hashSet2 = new java.util.HashSet&lt;Point&gt;();
hashSet2.add(cp);
System.out.println(hashSet2.contains(p));    // 打印 true</pre>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">因此虽然p和cp是等价的，但是contains测试中一个返回成功，另外一个却返回失败。<br />
你如何修改equals的定义，才能使得这个方法满足对称性？本质上说有两种方法，你可以使得这种关系变得更一般化或更严格。更一般化的意思是这一对对象，a和b，被用于进行对比，无论是a比b还是b比a 都返回true，下面是代码：</p>
<pre class="brush: java">public class ColoredPoint extends Point { // Problem: equals not transitive
private final Color color;
public ColoredPoint(int x, int y, Color color) {
super(x, y);
this.color = color;
}
@Override public boolean equals(Object other) {
boolean result = false;
if (other instanceof ColoredPoint) {
ColoredPoint that = (ColoredPoint) other;
result = (this.color.equals(that.color) &amp;&amp; super.equals(that));
}
else if (other instanceof Point) {
Point that = (Point) other;
result = that.equals(this);
}
return result;
}
}</pre>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">在ColoredPoint中的equals的新定义比老定义中检查了更多的情况:如果对象是一个Point对象而不是ColoredPoint，方法就转变为Point类的equals方法调用。这个所希望达到的效果就是equals的对称性，不管&#8221;cp.equals(p)&#8221;还是&#8221;p.equals(cp)&#8221;的结果都是true。然而这种方法，equals的规范还是被破坏了，现在的问题是这个新等价性不满足传递性。考虑下面的一段代码实例，定义了一个点和这个点上上两种不同颜色点：</p>
<pre class="brush: java">ColoredPoint redP = new ColoredPoint(1, 2, Color.RED);
ColoredPoint blueP = new ColoredPoint(1, 2, Color.BLUE);</pre>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">redP等价于p，p等价于blueP</p>
<pre class="brush: java">System.out.println(redP.equals(p)); // prints true
System.out.println(p.equals(blueP)); // prints true</pre>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">然而，对比redP和blueP的结果是false:</p>
<pre class="brush: java">System.out.println(redP.equals(blueP)); // 打印 false</pre>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">因此，equals的传递性就被违背了。<br />
使equals的关系更一般化似乎会将我们带入到死胡同。我们应该采用更严格化的方法。一种更严格化的equals方法是认为不同类的对象是不同的。这个可以通过修改Point类和ColoredPoint类的equals方法来达到。你能增加额外的比较来检查是否运行态的这个Point类和那个Point类是同一个类，就像如下所示的代码一样：</p>
<pre class="brush: java">// A technically valid, but unsatisfying, equals method
public class Point {
private final int x;
private final int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
@Override public boolean equals(Object other) {
boolean result = false;
if (other instanceof Point) {
Point that = (Point) other;
result = (this.getX() == that.getX() &amp;&amp; this.getY() == that.getY()
<span style="color: #339966; ">&amp;&amp; this.getClass().equals(that.getClass())</span>);
}
return result;
}
@Override public int hashCode() {
return (41 * (41 + getX()) + getY());
}
}</pre>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">你现在可以将ColoredPoint类的equals实现用回刚才那个不满足对称性要的equals实现了。</p>
<pre class="brush: java">public class ColoredPoint extends Point { // 不再违反对称性需求
private final Color color;
public ColoredPoint(int x, int y, Color color) {
super(x, y);
this.color = color;
}
@Override public boolean equals(Object other) {
boolean result = false;
if (other instanceof ColoredPoint) {
ColoredPoint that = (ColoredPoint) other;
result = (this.color.equals(that.color) &amp;&amp; super.equals(that));
}
return result;
}
}</pre>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">这里，Point类的实例只有当和另外一个对象是同样类，并且有同样的坐标时候，他们才被认为是相等的，即意味着 .getClass()返回的是同样的值。这个新定义的等价关系满足了对称性和传递性因为对于比较对象是不同的类时结果总是false。所以着色点(colored point)永远不会等于点(point)。通常这看起来非常合理，但是这里也存在着另外一种争论——这样的比较过于严格了。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">考虑我们如下这种稍微的迂回的方式来定义我们的坐标点(1,2)</p>
<pre class="brush: java">Point pAnon = new Point(1, 1) {
@Override public int getY() {
return 2;
}
};</pre>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">pAnon等于p吗？答案是假，因为p和pAnon的java.lang.Class对象不同。p是Point，而pAnon是Point的一个匿名派生类。但是，非常清晰的是pAnon的确是在坐标1，2上的另外一个点。所以将他们认为是不同的点是没有理由的。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">　</p>
<h4 style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">canEqual 方法</h4>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">到此，我们看其来似乎是遇到阻碍了，存在着一种正常的方式不仅可以在不同类继承层次上定义等价性，并且保证其等价的规范性吗？事实上，的确存在这样的一种方法，但是这就要求除了重定义equals和hashCode外还要另外的定义一个方法。基本思路就是在重载equals(和hashCode)的同时，它应该也要要明确的声明这个类的对象永远不等价于其他的实现了不同等价方法的超类的对象。为了达到这个目标，我们对每一个重载了equals的类新增一个方法canEqual方法。这个方法的方法签名是：</p>
<pre class="brush: java">public boolean canEqual(Object other)</pre>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">如果other 对象是canEquals(重)定义那个类的实例时，那么这个方法应该返回真，否则返回false。这个方法由equals方法调用，并保证了两个对象是可以相互比较的。下面Point类的新的也是最终的实现：</p>
<pre class="brush: java">public class Point {
private final int x;
private final int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
@Override public boolean equals(Object other) {
boolean result = false;
if (other instanceof Point) {
Point that = (Point) other;
result =<span style="color: #339966; ">(that.canEqual(this) &amp;&amp; </span>this.getX() == that.getX() &amp;&amp; this.getY() == that.getY());
}
return result;
}
@Override public int hashCode() {
return (41 * (41 + getX()) + getY());
}
<span style="color: #339966; ">
public boolean canEqual(Object other) {
return (other instanceof Point);
}
</span>
}</pre>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">这个版本的Point类的equals方法中包含了一个额外的需求，通过canEquals方法来决定另外一个对象是否是是满足可以比较的对象。在Point中的canEqual宣称了所有的Point类实例都能被比较。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">下面是ColoredPoint相应的实现</p>
<pre class="brush: java">public class ColoredPoint extends Point { // 不再违背对称性
private final Color color;
public ColoredPoint(int x, int y, Color color) {
super(x, y);
this.color = color;
}
@Override public boolean equals(Object other) {
boolean result = false;
if (other instanceof ColoredPoint) {
ColoredPoint that = (ColoredPoint) other;
result = <span style="color: #339966; ">(that.canEqual(this) &amp;&amp; </span>this.color.equals(that.color) &amp;&amp; super.equals(that));
}
return result;
}
@Override public int hashCode() {
return (41 * super.hashCode() + color.hashCode());
}
<span style="color: #339966; ">
@Override public boolean canEqual(Object other) {
return (other instanceof ColoredPoint);
}
</span>}</pre>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">在上显示的新版本的Point类和ColoredPoint类定义保证了等价的规范。等价是对称和可传递的。比较一个Point和ColoredPoint类总是返回false。因为点p和着色点cp,&#8220;p.equals(cp)返回的是假。并且，因为cp.canEqual(p)总返回false。相反的比较，cp.equals(p)同样也返回false，由于p不是一个ColoredPoint，所以在ColoredPoint的equals方法体内的第一个instanceof检查就失败了。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">另外一个方面，不同的Point子类的实例却是可以比较的，同样没有重定义等价性方法的类也是可以比较的。对于这个新类的定义，p和pAnon的比较将总返回true。下面是一些例子：</p>
<pre class="brush: java">Point p = new Point(1, 2);
ColoredPoint cp = new ColoredPoint(1, 2, Color.INDIGO);
Point pAnon = new Point(1, 1) {
@Override public int getY() {
return 2;
}
};
Set&lt;Point&gt; coll = new java.util.HashSet&lt;Point&gt;();
coll.add(p);
System.out.println(coll.contains(p)); // 打印 true
System.out.println(coll.contains(cp)); // 打印 false
System.out.println(coll.contains(pAnon)); // 打印 true</pre>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">这些例子显示了如果父类在equals的实现定义并调用了canEquals，那么开发人员实现的子类就能决定这个子类是否可以和它父类的实例进行比较。例如ColoredPoint，因为它以&#8221;一个着色点永远不可以等于普通不带颜色的点重载了&#8221; canEqual，所以他们就不能比较。但是因为pAnon引用的匿名子类没有重载canEqual,因此它的实例就可以和Point的实例进行对比。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">canEqual方法的一个潜在的争论是它是否违背了Liskov替换准则(LSP)。例如，通过比较运行态的类来实现的比较技术(<strong>译者注：</strong>&nbsp;canEqual的前一版本，使用.getClass()的那个版本)，将导致不能定义出一个子类，这个子类的实例可以和其父类进行比较，因此就违背了LSP。这是因为，LSP原则是这样的，在任何你能使用父类的地方你都可以使用子类去替换它。在之前例子中，虽然cp的x,y坐标匹配那些在集合中的点，然而&#8221;coll.contains(cp)&#8221;仍然返回false，这看起来似乎违背得了LSP准则，因为你不能这里能使用Point的地方使用一个ColoredPointed。但是我们认为这种解释是错误的，因为LSP原则并没有要求子类和父类的行为一致，而仅要求其行为能一种方式满足父类的规范。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">通过比较运行态的类来编写equals方法(<strong>译者注：</strong>&nbsp;canEqual的前一版本，使用.getClass()的那个版本)的问题并不是违背LSP准则的问题，但是它也没有为你指明一种创建派生类的实例能和父类实例进行对比的的方法。例如，我们使用这种运行态比较的技术在之前的&#8221;coll.contains(pAnon)&#8221;将会返回false，并且这并不是我们希望的。相反我们希望&#8220;coll.contains(cp)&#8221;返回false，因为通过在ColoredPoint中重载的equals，我基本上可以说，一个在坐标1，2上着色点和一个坐标1，2上的普通点并不是一回事。然而，在最后的例子中，我们能传递Point两种不同的子类实例到集合中contains方法，并且我们能得到两个不同的答案，并且这两个答案都正确。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; "><strong>&#8211;全文完&#8211;</strong></p>
<div><strong><br />
</strong></div>
</span>
<img src ="http://www.blogjava.net/wangbing/aggbug/283289.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangbing/" target="_blank">王总兵</a> 2009-06-19 21:01 <a href="http://www.blogjava.net/wangbing/archive/2009/06/19/283289.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JSONObject使用的一点问题</title><link>http://www.blogjava.net/wangbing/archive/2009/06/16/282648.html</link><dc:creator>王总兵</dc:creator><author>王总兵</author><pubDate>Tue, 16 Jun 2009 09:40:00 GMT</pubDate><guid>http://www.blogjava.net/wangbing/archive/2009/06/16/282648.html</guid><wfw:comment>http://www.blogjava.net/wangbing/comments/282648.html</wfw:comment><comments>http://www.blogjava.net/wangbing/archive/2009/06/16/282648.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/wangbing/comments/commentRss/282648.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangbing/services/trackbacks/282648.html</trackback:ping><description><![CDATA[在使用JSONObject时发现下面的问题：<br />
<br />
<div style="background-color: #eeeeee; font-size: 13px; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; "><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000FF; ">package</span><span style="color: #000000; ">&nbsp;com.example;<br />
<br />
</span><span style="color: #0000FF; ">import</span><span style="color: #000000; ">&nbsp;net.sf.json.JSONObject;<br />
<br />
</span><span style="color: #0000FF; ">import</span><span style="color: #000000; ">&nbsp;org.junit.Test;<br />
<br />
</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">class</span><span style="color: #000000; ">&nbsp;TestDozer&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">/**</span><span style="color: #008000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span style="color: #808080; ">@param</span><span style="color: #008000; ">&nbsp;args<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">static</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;main(String[]&nbsp;args)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;TODO&nbsp;Auto-generated&nbsp;method&nbsp;stub</span><span style="color: #008000; "><br />
</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;test1()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Map1&nbsp;map1&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&nbsp;Map1();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;map1.put(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">username</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">username</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;map1.put(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">password</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">password</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;s&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;JSONObject.fromObject(map1).toString();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">s====&gt;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">+</span><span style="color: #000000; ">&nbsp;s);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;s====&gt;{"username":"username","password":"password"}</span><span style="color: #008000; "><br />
</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;@Test<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;test2()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Map2&nbsp;map1&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&nbsp;Map2();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;map1.put(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">password</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">password</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;map1.setUsername(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">username</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;s&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;JSONObject.fromObject(map1).toString();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">s====&gt;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">+</span><span style="color: #000000; ">&nbsp;s);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;s====&gt;{"password":"password"}</span><span style="color: #008000; "><br />
</span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
}<br />
</span></div>
<br />
<div style="background-color: #eeeeee; font-size: 13px; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; "><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000FF; ">package</span><span style="color: #000000; ">&nbsp;com.example;<br />
<br />
</span><span style="color: #0000FF; ">import</span><span style="color: #000000; ">&nbsp;java.util.HashMap;<br />
<br />
</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">class</span><span style="color: #000000; ">&nbsp;Map1&nbsp;</span><span style="color: #0000FF; ">extends</span><span style="color: #000000; ">&nbsp;HashMap&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
}<br />
</span></div>
<br />
<br />
<div style="background-color: #eeeeee; font-size: 13px; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; "><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000FF; ">package</span><span style="color: #000000; ">&nbsp;com.example;<br />
<br />
</span><span style="color: #0000FF; ">import</span><span style="color: #000000; ">&nbsp;java.util.HashMap;<br />
<br />
</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">class</span><span style="color: #000000; ">&nbsp;Map2&nbsp;</span><span style="color: #0000FF; ">extends</span><span style="color: #000000; ">&nbsp;HashMap{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">private</span><span style="color: #000000; ">&nbsp;String&nbsp;username;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;String&nbsp;getUsername()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;username;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;setUsername(String&nbsp;username)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">this</span><span style="color: #000000; ">.username&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;username;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
}<br />
</span></div>
<br />
两次输出的json字符串不一样，让我很郁闷。
 <img src ="http://www.blogjava.net/wangbing/aggbug/282648.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangbing/" target="_blank">王总兵</a> 2009-06-16 17:40 <a href="http://www.blogjava.net/wangbing/archive/2009/06/16/282648.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>