<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_Just Happy——开心就好</title><subtitle type="text">每天进步一点点，快乐生活每一天.</subtitle><id>http://feed.cnblogs.com/blog/u/24150/rss</id><updated>2012-04-08T06:47:33Z</updated><author><name>gshine</name><uri>http://www.cnblogs.com/gaojing/</uri></author><generator>feed.cnblogs.com</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/gaojing/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/24150/rss"/><entry><id>http://www.cnblogs.com/gaojing/archive/2012/03/29/2424014.html</id><title type="text">关于“Return empty arrays or collections, not nulls”的思考</title><summary type="text">《effective java》第二版第43条是：Return empty arrays or collections, not nulls。意思是在需要返回数组或者集合的方法中，如果需要返回空数据，不要返回null，而是要返回大小为0的数组或者集合。本文是对这条内容的总结和反思。</summary><published>2012-03-29T10:53:00Z</published><updated>2012-03-29T10:53:00Z</updated><author><name>gshine</name><uri>http://www.cnblogs.com/gaojing/</uri></author><link rel="alternate" href="http://www.cnblogs.com/gaojing/archive/2012/03/29/2424014.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/gaojing/archive/2012/03/29/2424014.html"/><content type="html">&lt;p&gt;《effective java》第二版第43条是：Return empty arrays or collections, not nulls&lt;/p&gt;&lt;p&gt;意思是在需要返回数组或者集合的方法中，如果需要返回空数据，不要返回null，而是要返回大小为0的数组或者集合。&lt;/p&gt;&lt;p&gt;可能很多情况下，会出现这样的代码：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;final&lt;/span&gt; List&amp;lt;Cheese&amp;gt; cheesesInStock = ...;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; &lt;span style="color: #008000;"&gt;/**&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt; &lt;span style="color: #008000;"&gt;* &lt;/span&gt;&lt;span style="color: #808080;"&gt;@return&lt;/span&gt;&lt;span style="color: #008000;"&gt; an array containing all of the cheeses in the shop,&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt; &lt;span style="color: #008000;"&gt;* or null if no cheeses are available for purchase.&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt; &lt;span style="color: #008000;"&gt;*/&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; Cheese[] getCheeses() {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (cheesesInStock.size() == 0)&lt;br /&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt; ...&lt;br /&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt; }&lt;/div&gt;&lt;p&gt;当没有数据时，直接返回null。&lt;/p&gt;&lt;p&gt;但是，采用此种方式，会出现一个问题，就是调用这个代码的client必须要判断这个方法返回的是否为null，否则，可能会抛出NullPointerException异常。&lt;/p&gt;&lt;p&gt;比如：&lt;/p&gt;&lt;p&gt;代码1：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt; Cheese[] cheeses = shop.getCheeses();&lt;br /&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (cheeses != &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt; &amp;amp;&amp;amp;&lt;br /&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt; Arrays.asList(cheeses).contains(Cheese.STILTON))&lt;br /&gt;&lt;span style="color: #008080;"&gt;4&lt;/span&gt; System.out.println("Jolly good, just the thing.");&lt;/div&gt;&lt;p&gt;每一次调用都要加上是否为null的判断，而且很容易忘记检查导致抛出异常。&lt;/p&gt;&lt;p&gt;有人坚持选择返回null的原因是因为，他们认为分配一个空数组或者集合是需要花费时间和空间的，会影响性能。而作者则认为:&lt;/p&gt;&lt;p&gt;1)这点性能损耗微不足道；&lt;/p&gt;&lt;p&gt;2)返回的空数组或者集合通常是immutable，即不可变的。所以可定义成static final（对于数组）或者Collections.emptyList()/emptyMap()/emptySet()来公用同一个对象，减少性能影响。&lt;/p&gt;&lt;p&gt;代码2：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt; &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; The right way to return an array from a collection&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;final&lt;/span&gt; List&amp;lt;Cheese&amp;gt; cheesesInStock = ...;&lt;br /&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;final&lt;/span&gt; Cheese[] EMPTY_CHEESE_ARRAY = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Cheese[0];&lt;br /&gt;&lt;span style="color: #008080;"&gt;4&lt;/span&gt; &lt;span style="color: #008000;"&gt;/**&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;5&lt;/span&gt; &lt;span style="color: #008000;"&gt;* &lt;/span&gt;&lt;span style="color: #808080;"&gt;@return&lt;/span&gt;&lt;span style="color: #008000;"&gt; an array containing all of the cheeses in the shop.&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;6&lt;/span&gt; &lt;span style="color: #008000;"&gt;*/&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;7&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; Cheese[] getCheeses() {&lt;br /&gt;&lt;span style="color: #008080;"&gt;8&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; cheesesInStock.toArray(EMPTY_CHEESE_ARRAY);&lt;br /&gt;&lt;span style="color: #008080;"&gt;9&lt;/span&gt; }&lt;/div&gt;&lt;p&gt;代码3：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt; &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; The right way to return a copy of a collection&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; List&amp;lt;Cheese&amp;gt; getCheeseList() {&lt;br /&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (cheesesInStock.isEmpty())&lt;br /&gt;&lt;span style="color: #008080;"&gt;4&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; Collections.emptyList(); &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Always returns same list&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;5&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;6&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; ArrayList&amp;lt;Cheese&amp;gt;(cheesesInStock);&lt;br /&gt;&lt;span style="color: #008080;"&gt;7&lt;/span&gt; }&lt;/div&gt;&lt;p&gt;&lt;span style="color: #ff0000;"&gt;几点思考：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #ff0000;"&gt;1）自己写接口方法时尽量遵守这条规范，并在方法注释中标明。返回大小为0的数组或者集合。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #ff0000;"&gt;2）文中提到的Collections.emptyList()/emptyMap()/emptySet()这个需要慎用。因为这几个方法返回的集合对象都是immutable的，即不可更改的。而有时候我们可能需要向返回的集合中添加或者删除元素，这样的话，就会报UnsupportedOperationException异常。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #ff0000;"&gt;3）tips：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #ff0000;"&gt;a) 当要判断某个元素是否在数组中时，可以Arrays.asList(T[] array).contains(T obj))来实现，而无需用循环迭代每个元素来判断。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #ff0000;"&gt;b) 如代码2所示，如果要把ArrayList变成数组，可以使用ArrayList.toArray(T [] array)，里面的array只需设成大小为0的数组即可，仅用来指定返回的类型，T可能为ArrayList中元素的子类。&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/gaojing/aggbug/2424014.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/gaojing/archive/2012/03/29/2424014.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/gaojing/archive/2012/03/15/2413638.html</id><title type="text">关于Class.forName(“com.mysql.jdbc.Driver”)</title><summary type="text">传统的使用jdbc来访问数据库的流程为： Class.forName(“com.mysql.jdbc.Driver”); String url = “jdbc:mysql://localhost:3306/test?user=root&amp;password=123456″; Connection con = DriverManager.getConnection(url); Statement statement = con.createStatement();最开始使用的时候，不明白为什么首先要加载一个驱动类，之后就可以取得了Connection了，很好奇DriverManager是怎么</summary><published>2012-03-15T08:16:00Z</published><updated>2012-03-15T08:16:00Z</updated><author><name>gshine</name><uri>http://www.cnblogs.com/gaojing/</uri></author><link rel="alternate" href="http://www.cnblogs.com/gaojing/archive/2012/03/15/2413638.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/gaojing/archive/2012/03/15/2413638.html"/><content type="html">&lt;p&gt;传统的使用jdbc来访问数据库的流程为：&lt;br /&gt; Class.forName(&amp;ldquo;com.mysql.jdbc.Driver&amp;rdquo;);&lt;br /&gt; String url = &amp;ldquo;jdbc:mysql://localhost:3306/test?user=root&amp;amp;password=123456&amp;Prime;;&lt;br /&gt; Connection con = DriverManager.getConnection(url);&lt;br /&gt; Statement statement = con.createStatement();&lt;/p&gt;&lt;p&gt;最开始使用的时候，不明白为什么首先要加载一个驱动类，之后就可以取得了Connection了，很好奇DriverManager是怎么获得那个驱动类的信息，后来看了下com.mysql.jdbc.Driver这个类的源代码，豁然开朗了。原来在com.mysql.jdbc.Driver类中有这么一段静态初始化代码：&lt;br /&gt; static {&lt;br /&gt; try {&lt;br /&gt; java.sql.DriverManager.registerDriver(new Driver());&lt;br /&gt; } catch (SQLException E) {&lt;br /&gt; throw new RuntimeException(&amp;ldquo;Can&amp;rsquo;t register driver!&amp;rdquo;);&lt;br /&gt; }&lt;br /&gt; }&lt;br /&gt; 也就是，在Class.forName加载完驱动类，开始执行静态初始化代码时，会自动新建一个Driver的对象，并调用DriverManager.registerDriver把自己注册到DriverManager中去。&lt;br /&gt; &lt;br /&gt; &lt;strong&gt;ps1:&lt;/strong&gt; Class.forName(String) 与ClassLoader.loadClass(String)的区别&lt;br /&gt; Class.forName(String): 加载类，并且执行类初始化；可以通过Class.forName(String, boolean, ClassLoader)第二个参数来仅仅加载类不执行初始化；&lt;br /&gt; ClassLoader.loadClass(String): 仅仅加载类，不执行类初始化；&lt;/p&gt;&lt;p&gt;&lt;strong&gt;ps2:&lt;/strong&gt; 有时会看到这种用法：&lt;br /&gt; Class.forName(&amp;ldquo;com.mysql.jdbc.Driver&amp;rdquo;).newInstance();&lt;br /&gt; 这是没有必要的，正如前述，静态初始化已经new了一个Driver的对象，注册到DriverManager中去，在此再建立一个Driver对象则是完全没有必要的，浪费空间。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;ps3:&lt;/strong&gt; 结合ps1，Class.forName(&amp;ldquo;com.mysql.jdbc.Driver&amp;rdquo;);相当于：&lt;br /&gt; ClassLoader loader = Thread.currentThread().getContextClassLoader();&lt;br /&gt; Class cls = loader.loadClass(&amp;ldquo;com.mysql.jdbc.Driver&amp;rdquo;);&lt;br /&gt; cls.newInstance();&lt;br /&gt; 这种方法的问题同ps2, 浪费了一个Driver对象；&lt;/p&gt;&lt;p&gt;&lt;strong&gt;ps4:&lt;/strong&gt; 在java 6中，引入了service provider的概念，即可以在配置文件中配置service（可能是一个interface或者abstract class）的provider（即service的实现类）。配置路径是：/META-INF/services/下面。详细信息见：http://docs.oracle.com/javase/6/docs/technotes/guides/jar/jar.html#Service%20Provider&lt;br /&gt; 而java.sql.DriverManager也添加了对此的支持，因此，在JDK6中，DriverManager的查找Driver的范围为：&lt;br /&gt; 1）system property &amp;ldquo;jdbc.drivers&amp;rdquo; 中配置的Driver值；&lt;br /&gt; 2）用户调用Class.forName()注册的Driver&lt;br /&gt; 3）service provider配置文件java.sql.Driver中配置的Driver值。&lt;br /&gt; 因此，在jdk6中，其实是可以不用调用Class.forName来加载mysql驱动的，因为mysql的驱动程序jar包中已经包含了java.sql.Driver配置文件，并在文件中添加了com.mysql.jdbc.Driver.但在JDK6之前版本，还是要调用这个方法。&lt;/p&gt;&lt;p&gt;参考文档：&lt;br /&gt; 1）http://docs.oracle.com/javase/1.5.0/docs/api/java/sql/DriverManager.html&lt;br /&gt; 2）http://docs.oracle.com/javase/6/docs/api/index.html?java/sql/DriverManager.html&lt;br /&gt; 3）http://docs.oracle.com/javase/6/docs/technotes/guides/jar/jar.html#Service%20Provider&lt;/p&gt;&lt;img src="http://www.cnblogs.com/gaojing/aggbug/2413638.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/gaojing/archive/2012/03/15/2413638.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/gaojing/archive/2012/02/04/2413626.html</id><title type="text">URI和URL的区别</title><summary type="text">这两天在写代码的时候，由于涉及到资源的位置，因此，需要在Java Bean中定义一些字段，用来表示资源的位置，比如：imgUrl，logoUri等等。但是，每次定义的时候，心里都很纠结，是该用imgUrl还是imgUri呢？同样的，另外一个问题：String HttpServletRequest.getRequestURI()；和StringBuffer HttpServletRequest.getRequestURL();返回的内容有何不同？为什么会如此？带着这些问题到网上去搜了下，没发现让自己看了明白的解释，于是，想到了Java类库里有两个对应的类java.net.URI和java.net</summary><published>2012-02-04T14:02:00Z</published><updated>2012-02-04T14:02:00Z</updated><author><name>gshine</name><uri>http://www.cnblogs.com/gaojing/</uri></author><link rel="alternate" href="http://www.cnblogs.com/gaojing/archive/2012/02/04/2413626.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/gaojing/archive/2012/02/04/2413626.html"/><content type="html">&lt;p&gt;这两天在写代码的时候，由于涉及到资源的位置，因此，需要在Java Bean中定义一些字段，用来表示资源的位置，比如：imgUrl，logoUri等等。但是，每次定义的时候，心里都很纠结，是该用imgUrl还是imgUri呢？&lt;/p&gt;&lt;p&gt;同样的，另外一个问题：String HttpServletRequest.getRequestURI()；和StringBuffer HttpServletRequest.getRequestURL();返回的内容有何不同？为什么会如此？&lt;/p&gt;&lt;p&gt;带着这些问题到网上去搜了下，没发现让自己看了明白的解释，于是，想到了Java类库里有两个对应的类java.net.URI和java.net.URL，终于，在这两个类里的javadoc里找到了答案。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;URIs, URLs, and URNs&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;首先，URI，是uniform resource identifier，统一资源标识符，用来唯一的标识一个资源。而URL是uniform resource locator，统一资源定位器，它是一种具体的URI，即URL可以用来标识一个资源，而且还指明了如何locate这个资源。而URN，uniform resource name，统一资源命名，是通过名字来标识资源，比如mailto:java-net@java.sun.com。也就是说，URI是以一种抽象的，高层次概念定义统一资源标识，而URL和URN则是具体的资源标识的方式。URL和URN都是一种URI。&lt;/p&gt;&lt;p&gt;在Java的URI中，一个URI实例可以代表绝对的，也可以是相对的，只要它符合URI的语法规则。而URL类则不仅符合语义，还包含了定位该资源的信息，因此它不能是相对的，schema必须被指定。&lt;/p&gt;&lt;p&gt;ok，现在回答文章开头提出的问题，到底是imgUrl好呢，还是imgUri好？显然，如果说imgUri是肯定没问题的，因为即使它实际上是url，那它也是uri的一种。那么用imgUrl有没有问题呢？此时则要看它的可能取值，如果是绝对路径，能够定位的，那么用imgUrl是没问题的，而如果是相对路径，那还是不要用ImgUrl的好。总之，用imgUri是肯定没问题的，而用imgUrl则要视实际情况而定。&lt;/p&gt;&lt;p&gt;第二个，从HttpServletRequest的javadoc中可以看出，getRequestURI返回一个String，&amp;ldquo;the part of this request&amp;rsquo;s URL from the protocol name up to the query string in the first line of the HTTP request&amp;rdquo;，比如&amp;ldquo;POST /some/path.html?a=b HTTP/1.1&amp;rdquo;，则返回的值为&amp;rdquo;/some/path.html&amp;rdquo;。现在可以明白为什么是getRequestURI而不是getRequestURL了，因为此处返回的是相对的路径。而getRequestURL返回一个StringBuffer，&amp;ldquo;The returned URL contains a protocol, server name, port number, and server path, but it does not include query string parameters.&amp;rdquo;，完整的请求资源路径，不包括querystring。&lt;/p&gt;&lt;p&gt;总结一下：URL是一种具体的URI，它不仅唯一标识资源，而且还提供了定位该资源的信息。URI是一种语义上的抽象概念，可以是绝对的，也可以是相对的，而URL则必须提供足够的信息来定位，所以，是绝对的，而通常说的relative URL，则是针对另一个absolute URL，本质上还是绝对的。&lt;/p&gt;&lt;p&gt;注：这里的绝对(absolute)是指包含scheme，而相对(relative)则不包含scheme。&lt;/p&gt;&lt;p&gt;URI抽象结构 &amp;nbsp; &amp;nbsp;&lt;span style="color: #ff6600;"&gt; [&lt;em&gt;scheme&lt;/em&gt;&lt;tt&gt;&lt;strong&gt;:&lt;/strong&gt;&lt;/tt&gt;&lt;em&gt;&lt;/em&gt;]&lt;em&gt;scheme-specific-part&lt;/em&gt;[&lt;tt&gt;&lt;strong&gt;#&lt;/strong&gt;&lt;/tt&gt;&lt;em&gt;fragment&lt;/em&gt;]&lt;/span&gt;&lt;/p&gt;&lt;p&gt;[&lt;em&gt;scheme&lt;/em&gt;&lt;tt&gt;&lt;strong&gt;:&lt;/strong&gt;&lt;/tt&gt;][&lt;tt&gt;&lt;strong&gt;//&lt;/strong&gt;&lt;/tt&gt;&lt;em&gt;authority&lt;/em&gt;][&lt;em&gt;path&lt;/em&gt;][&lt;tt&gt;&lt;strong&gt;?&lt;/strong&gt;&lt;/tt&gt;&lt;em&gt;query&lt;/em&gt;][&lt;tt&gt;&lt;strong&gt;#&lt;/strong&gt;&lt;/tt&gt;&lt;em&gt;fragment&lt;/em&gt;]&lt;/p&gt;&lt;p&gt;authority为[&lt;em&gt;user-info&lt;/em&gt;&lt;tt&gt;&lt;strong&gt;@&lt;/strong&gt;&lt;/tt&gt;]&lt;em&gt;host&lt;/em&gt;[&lt;tt&gt;&lt;strong&gt;:&lt;/strong&gt;&lt;/tt&gt;&lt;em&gt;port&lt;/em&gt;]&lt;/p&gt;&lt;p&gt;参考资料：&lt;/p&gt;&lt;p&gt;&lt;a href="http://docs.oracle.com/javase/1.5.0/docs/api/java/net/URI.html"&gt;http://docs.oracle.com/javase/1.5.0/docs/api/java/net/URI.html&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Uniform_Resource_Identifier"&gt;http://en.wikipedia.org/wiki/Uniform_Resource_Identifier&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://docs.oracle.com/javaee/5/api/javax/servlet/http/HttpServletRequest.html"&gt;http://docs.oracle.com/javaee/5/api/javax/servlet/http/HttpServletRequest.html&lt;/a&gt;&lt;/p&gt;&lt;p&gt;ps:&lt;/p&gt;&lt;p&gt;java.net.URL类不提供对标准RFC2396规定的特殊字符的转义，因此需要调用者自己对URL各组成部分进行encode。而java.net.URI则会提供转义功能。因此The recommended way &amp;nbsp;to manage the encoding and decoding of URLs is to use &amp;nbsp;java.net.URI. 可以使用URI.toURL()和URL.toURI()方法来对两个类型的对象互相转换。对于HTML FORM的url encode/decode可以使用java.net.URLEncoder和java.net.URLDecoder来完成，但是对URL对象不适用。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/gaojing/aggbug/2413626.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/gaojing/archive/2012/02/04/2413626.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/gaojing/archive/2011/08/23/2413616.html</id><title type="text">关于BeanUtils.copyProperties的使用</title><summary type="text">spring和apache commons-beanutils中分别存在一个BeanUtils，提供了对java bean的常用操作。之前在写程序时，用到了两个不同类型但属性基本相同的对象的拷贝，结果在拷贝java.util.Date类型的对象属性时，由于其值为null，而抛异常。由于时间紧急，所以临时改成了get/set方式，幸亏对象的属性不算多。后来一直耿耿于怀这个问题，今天抽空看了一下spring和apache commons-beanutils包中BeanUtils.copyProperties的实现。spring中实现的方式很简单，就是对两个对象中相同名字的属性进行简单get/set</summary><published>2011-08-23T14:17:00Z</published><updated>2011-08-23T14:17:00Z</updated><author><name>gshine</name><uri>http://www.cnblogs.com/gaojing/</uri></author><link rel="alternate" href="http://www.cnblogs.com/gaojing/archive/2011/08/23/2413616.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/gaojing/archive/2011/08/23/2413616.html"/><content type="html">&lt;p&gt;spring和apache commons-beanutils中分别存在一个BeanUtils，提供了对java bean的常用操作。&lt;/p&gt;&lt;p&gt;之前在写程序时，用到了两个不同类型但属性基本相同的对象的拷贝，结果在拷贝java.util.Date类型的对象属性时，由于其值为null，而抛异常。&lt;/p&gt;&lt;p&gt;由于时间紧急，所以临时改成了get/set方式，幸亏对象的属性不算多。&lt;/p&gt;&lt;p&gt;后来一直耿耿于怀这个问题，今天抽空看了一下spring和apache commons-beanutils包中BeanUtils.copyProperties的实现。&lt;/p&gt;&lt;p&gt;spring中实现的方式很简单，就是对两个对象中相同名字的属性进行简单get/set，仅检查属性的可访问性。&lt;/p&gt;&lt;p&gt;而commons-beanutils则施加了很多的检验，包括类型的转换，甚至于还会检验对象所属的类的可访问性。&lt;/p&gt;&lt;p&gt;而且，commons-beanutils中的装换是不支持java.util.Date的。除了支持基本类型以及基本类型的数组之外，还支持java.sql.Date, java.sql.Time, java.sql.TimeStamp, &amp;nbsp;java.io.File, &amp;nbsp;javaio.URL这些类的对象，其余一概不支持。不过你可以自定义你的类的Converter。然后注册进去。&lt;/p&gt;&lt;p&gt;感觉commons-beanutils包中的这个BeanUtils类的copyProperties方法，太过复杂，约束太多，而且使用不便，虽然可扩展性好了，但是易用性不高。&lt;/p&gt;&lt;p&gt;总结：&lt;/p&gt;&lt;p&gt;关于bean复制，如果属性较少，建议直接写个方法完成get/set即可。如果属性较多，可以自己采用反射实现一个满足自己需要的工具类，或者使用spring的那个beanutils类，不建议使用commons-beanutils包中的那个BeanUtils类，刚看了下，这个类对于内部静态类的对象复制也会出现问题，检验太复杂了，常会出现一些诡异的问题。毕竟我们bean复制一般就是简单的属性copy而已。&lt;/p&gt;&lt;p&gt;而且，由于这些BeanUtils类都是采用反射机制实现的，对程序的效率也会有影响。因此，慎用BeanUtils.copyProperties！！！&lt;/p&gt;&lt;img src="http://www.cnblogs.com/gaojing/aggbug/2413616.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/gaojing/archive/2011/08/23/2413616.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/gaojing/archive/2010/11/12/1875798.html</id><title type="text">关于选择——摘自卫哲在北邮宣讲片段</title><summary type="text">2010-10-19 阿里巴巴 卫哲 校园宣讲会 卫哲在演讲中给出了四个不加盟阿里巴巴的理由，包括工资非最高、要放弃北京去杭州、马云和他都不是技术型CEO以及不想长年累月加班。最后 关于选择 这段话 个人觉得很有道理 分享以共勉[选择了，就不后悔，同样的，你没有选择阿里巴巴，也不要后悔。人生不快乐的一个原因就是对自己的选择后悔，媒体经常问我，卫哲，你现在快四十了，你所有的经历重新来一遍，你会做什么不一样的事，我说我会做一模一样的事，我认为我的经历是最好的，我不后悔，因为后悔也没有用，人生不可能让我重新来一遍，相信我今天所作的每一步选择都是最正确的，我也相信我们做的事、跟的人都是最好的选择，所以</summary><published>2010-11-12T08:20:00Z</published><updated>2010-11-12T08:20:00Z</updated><author><name>gshine</name><uri>http://www.cnblogs.com/gaojing/</uri></author><link rel="alternate" href="http://www.cnblogs.com/gaojing/archive/2010/11/12/1875798.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/gaojing/archive/2010/11/12/1875798.html"/><content type="html">&lt;p&gt;2010-10-19&amp;nbsp; 阿里巴巴 卫哲 校园宣讲会 卫哲在演讲中给出了四个不加盟阿里巴巴的理由，包括工资非最高、要放弃北京去杭州、马云和他都不是技术型CEO以及不想长年累月加班。&lt;/p&gt;&lt;p&gt;最后 关于选择 这段话 个人觉得很有道理&amp;nbsp; 分享以共勉&lt;/p&gt;&lt;p&gt;[&lt;/p&gt;&lt;p&gt;选择了，就不后悔，同样的，你没有选择阿里巴巴，也不要后悔。人生不快乐的一个原因就是对自己的选择后悔，媒体经常问我，卫哲，你现在快四十了，你所有的经历重新来一遍，你会做什么不一样的事，我说我会做一模一样的事，我认为我的经历是最好的，我不后悔，因为后悔也没有用，人生不可能让我重新来一遍，相信我今天所作的每一步选择都是最正确的，我也相信我们做的事、跟的人都是最好的选择，所以阿里巴巴有一幅对联&amp;ldquo;又傻又天真&amp;rdquo;&amp;ldquo;又猛又持久&amp;rdquo;。又傻又天真，就是忘记掉那些很复杂的逻辑思维，相信自己的直觉，相信一些已经很少有人相信的事。又猛又持久，你对做这个事的激情，只有猛，猛三个月没有用，只有持久的努力，才会获得这个回报。&lt;/p&gt;&lt;p&gt;]&lt;/p&gt;&lt;p&gt;其实，关于选择，我也一直是这么认为的，不后悔，就是嘴硬到底，哈哈。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/gaojing/aggbug/1875798.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/gaojing/archive/2010/11/12/1875798.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/gaojing/archive/2010/11/06/1870804.html</id><title type="text">转一篇：如何快速的修改参考文献</title><summary type="text">快速修改论文的参考文献</summary><published>2010-11-06T13:22:00Z</published><updated>2010-11-06T13:22:00Z</updated><author><name>gshine</name><uri>http://www.cnblogs.com/gaojing/</uri></author><link rel="alternate" href="http://www.cnblogs.com/gaojing/archive/2010/11/06/1870804.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/gaojing/archive/2010/11/06/1870804.html"/><content type="html">&lt;p&gt;写论文，参考文献的修改很麻烦，删除一个，添加一个，就需要改一长串数字。怎么办呢。本人推荐一种简单方法：尾注法。&lt;br /&gt;方法如下（以Word2003为例）：&lt;br /&gt;1．光标移到要插入参考文献的地方，菜单中&amp;ldquo;插入&amp;rdquo;&amp;mdash;&amp;mdash;&amp;ldquo;引用&amp;rdquo;-&amp;ldquo;脚注和尾注&amp;rdquo;。 &lt;br /&gt;2．对话框中选择&amp;ldquo;尾注&amp;rdquo;，编号方式选&amp;ldquo;自动编号&amp;rdquo;，所在位置建议选&amp;ldquo;节的结尾&amp;rdquo;。 &lt;br /&gt;3．如&amp;ldquo;自动编号&amp;rdquo;后不是阿拉伯数字，选右下角的&amp;ldquo;选项&amp;rdquo;，在编号格式中选中阿拉伯数字。 &lt;br /&gt;4．确定后在该处就插入了一个上标&amp;ldquo;1&amp;rdquo;，而光标自动跳到文章最后，前面就是一个上标&amp;ldquo;1&amp;rdquo;，这就是输入第一个参考文献的地方。 &lt;br /&gt;5．将文章最后的上标&amp;ldquo;1&amp;rdquo;的格式改成正常（记住是改格式，而不是将它删掉重新输入，否则参考文献以后就是移动的位置，这个序号也不会变），再在它后面输入所插入的参考文献（格式按杂志要求来慢慢输，好像没有什么办法简化）。 &lt;br /&gt;6．对着参考文献前面的&amp;ldquo;1&amp;rdquo;双击，光标就回到了文章内容中插入参考文献的地方，可以继续写文章了。 &lt;br /&gt;7．在下一个要插入参考文献的地方再次按以上方法插入尾注，就会出现一个&amp;ldquo;2&amp;rdquo;（Word已经自动为你排序了），继续输入所要插入的参考文献。 &lt;br /&gt;8．所有文献都引用完后，你会发现在第一篇参考文献前面一条短横线（页面视图里才能看到），如果参考文献跨页了，在跨页的地方还有一条长横线，这些线无法选中，也无法删除。这是尾注的标志，但一般科技论文格式中都不能有这样的线，所以一定要把它们删除。 &lt;br /&gt;9．切换到普通视图，菜单中&amp;ldquo;视图&amp;rdquo;&amp;mdash;&amp;mdash;&amp;ldquo;脚注&amp;rdquo;，这时最下方出现了尾注的编辑栏。 &lt;br /&gt;10．在尾注右边的下拉菜单中选择&amp;ldquo;尾注分隔符&amp;rdquo;，这时那条短横线出现了，选中它，删除。 &lt;br /&gt;11．再在下拉菜单中选择&amp;ldquo;尾注延续分隔符&amp;rdquo;，这是那条长横线出现了，选中它，删除。 &lt;br /&gt;12．切换回到页面视图，参考文献插入已经完成了。这时，无论文章如何改动，参考文献都会自动地排好序了。如果删除了，后面的参考文献也会自动消失，绝不出错。 &lt;br /&gt;13．参考文献越多，这种方法的优势就体现的越大。&lt;br /&gt;还没完，标号上的方括号如何加呢？很简单：在全文中，查找尾注标记^e，然后全部替换为[^&amp;amp;]即可；如果用了脚注就查找脚注标记^f,再全部替换为[^&amp;amp;]便可以了（注意查找时让&amp;ldquo;不限定格式&amp;rdquo;按钮为灰色）。&lt;/p&gt;&lt;p&gt;原文地址:http://www.seekbio.com/biotech/study/wskill/2010/a8184614103.html&lt;/p&gt;&lt;p&gt;&lt;span style="color: #ff0000;"&gt;有个问题：如果我要插入好几个文献，比如[3-5]，这种形式的参考文献该怎么插入呢？希望知道的帮忙回答一下。。。&lt;/span&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/gaojing/aggbug/1870804.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/gaojing/archive/2010/11/06/1870804.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/gaojing/archive/2010/11/06/1870410.html</id><title type="text">你在中国有去过那些地区？</title><summary type="text">Which Areas of China Have You Been To?This is my China Map up to 2010-11-6, how about yours?create your own China map</summary><published>2010-11-06T01:55:00Z</published><updated>2010-11-06T01:55:00Z</updated><author><name>gshine</name><uri>http://www.cnblogs.com/gaojing/</uri></author><link rel="alternate" href="http://www.cnblogs.com/gaojing/archive/2010/11/06/1870410.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/gaojing/archive/2010/11/06/1870410.html"/><content type="html">&lt;p&gt;Which Areas of China Have You Been To?&lt;/p&gt;&lt;p&gt;This is my China Map up to 2010-11-6, how about yours?&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2010/20591/2010110609532048.png" alt="" /&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.markwang.com/chinamap/"&gt;create your own China map&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/gaojing/aggbug/1870410.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/gaojing/archive/2010/11/06/1870410.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/gaojing/archive/2010/11/04/1869419.html</id><title type="text">我看360VSQQ</title><summary type="text">之前没怎么关注qq和360之间的明争暗斗，直到昨天晚上腾讯弹出了那个窗口，那封信，“当您看到这封信的时候，我们刚刚作出了一个非常艰难的决定。我们将在装有360软件的电脑上停止运行QQ。。。。”说实话 看到这个消息的时候，我很震惊。疯了，腾讯绝对疯了，竟然拿这个来要挟用户，要么卸载360，要么不要用qq了。这简直是在那用户的利益来当赌注。。。我已经很久没用360了，之前用过，还不错，但是后来发现这个软件越来越臃肿，因此就把它卸载了，个人还是很喜欢简单的，不喜欢看到很多根本没用的功能。但是，在看到腾讯的那个公告之后，我第一时间把qq给删除了，尽管我的电脑上没有360。之前大约听到他们之间的斗争，3</summary><published>2010-11-04T13:52:00Z</published><updated>2010-11-04T13:52:00Z</updated><author><name>gshine</name><uri>http://www.cnblogs.com/gaojing/</uri></author><link rel="alternate" href="http://www.cnblogs.com/gaojing/archive/2010/11/04/1869419.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/gaojing/archive/2010/11/04/1869419.html"/><content type="html">&lt;p&gt;之前没怎么关注qq和360之间的明争暗斗，直到昨天晚上腾讯弹出了那个窗口，那封信，&amp;ldquo;当您看到这封信的时候，我们刚刚作出了一个非常艰难的决定。我们将在装有360软件的电脑上停止运行QQ。。。。&amp;rdquo;&lt;/p&gt;&lt;p&gt;说实话 看到这个消息的时候，我很震惊。疯了，腾讯绝对疯了，竟然拿这个来要挟用户，要么卸载360，要么不要用qq了。这简直是在那用户的利益来当赌注。。。&lt;/p&gt;&lt;p&gt;我已经很久没用360了，之前用过，还不错，但是后来发现这个软件越来越臃肿，因此就把它卸载了，个人还是很喜欢简单的，不喜欢看到很多根本没用的功能。&lt;/p&gt;&lt;p&gt;但是，在看到腾讯的那个公告之后，我第一时间把qq给删除了，尽管我的电脑上没有360。&lt;/p&gt;&lt;p&gt;之前大约听到他们之间的斗争，360除了个扣扣保镖，同时指责qq扫描用户隐私。对于这个我不以为然。&lt;/p&gt;&lt;p&gt;对于互联网的隐私问题，我觉得在互联网条件下是没什么隐私的，聊天记录也没什么见不得人的，不做亏心事，不怕鬼叫门。而且，我始终觉得，真正的隐私只是存在于自己的心里，一旦说出或者写出来，那么就没什么隐私了，毕竟绝对的安全是不存在的。。。所以，对于qq是否扫描我的硬盘，我不关心，但是360指出来，也无可厚非。&lt;/p&gt;&lt;p&gt;这两个公司相斗，问我更偏向于哪一边。肯定不是腾讯，也不可能是360。但是我不希望腾讯把360搞垮，也不希望360把腾讯整崩溃。&lt;/p&gt;&lt;p&gt;其实他们之间互相监督，反而可以促进互联网的发展。最怕的是他们两个合伙来欺骗用户。&lt;/p&gt;&lt;p&gt;但是，他们这样拿用户来赌博，就过分了。&lt;/p&gt;&lt;p&gt;竞争可以，但是别非把对方整死，给对方留口饭吃。。。在这方面，腾讯首当其冲的不负责任，一直在抄袭，就是不让别人活；360势头也不正，揪住不放，未免太过。&lt;/p&gt;&lt;p&gt;一直以来很赞赏腾讯的理念&amp;mdash;&amp;mdash;打造在线生活社区，但是方式确实待商榷。。。&lt;/p&gt;&lt;p&gt;360首开先河，杀毒免费，确也颇有气度，在客户端领域确实技术很牛。。。。&lt;/p&gt;&lt;p&gt;今天开始使用msn了，但是还是会偶尔上上手机qq，毕竟上面那么多朋友。。。其实msn也还不错，整了个去广告的补丁，没有广告，也不错。&lt;/p&gt;&lt;p&gt;g-talk也还行，就是朋友中用的太少，而且客户端功能实在是太少，虽说简单就好，但是也太简单了。。。&lt;/p&gt;&lt;p&gt;他们两个互掐，整的我周围沸沸扬扬，都无心写论文了，没几天时间了，估计这两个&amp;ldquo;活宝&amp;rdquo;应该会在&amp;ldquo;有关部门&amp;rdquo;的协调下和解吧。。。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/gaojing/aggbug/1869419.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/gaojing/archive/2010/11/04/1869419.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/gaojing/archive/2010/10/15/1852300.html</id><title type="text">MBTI职业性格测试-你注定是个程序员？</title><summary type="text">MBTI职业性格测试，看看你是不是个程序员？</summary><published>2010-10-15T07:50:00Z</published><updated>2010-10-15T07:50:00Z</updated><author><name>gshine</name><uri>http://www.cnblogs.com/gaojing/</uri></author><link rel="alternate" href="http://www.cnblogs.com/gaojing/archive/2010/10/15/1852300.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/gaojing/archive/2010/10/15/1852300.html"/><content type="html">&lt;p&gt;今天做了个&lt;a href="http://www.psytopic.com/mag/post/mbti-career-personality-test-psytopic-special-edition.html" target="_blank"&gt;MBTI职业性格测试&lt;/a&gt;，&lt;strong&gt;MBTI&lt;/strong&gt;（Myers-Briggs Type Indicator），一种迫选型、自我报告式的性格评估测试，用以衡量和描述人们在获取信息、作出决策、对待生活等方面的心理活动规律和性格类型。&lt;/p&gt;&lt;p&gt;发现&amp;ldquo;计算机程序员&amp;rdquo;赫然在列，注定了以后要当程序员啊。。。。。&lt;/p&gt;&lt;p&gt;测试结果：&lt;/p&gt;&lt;p&gt;Psytopic分析：您的性格类型是&amp;ldquo;&lt;strong&gt;ISFJ&lt;/strong&gt;&amp;rdquo;(内向+实感+情感+判断) &lt;br /&gt;&lt;br /&gt;沉静，友善，有责任感和谨慎。能坚定不移地承担责任。做事贯彻始终、不辞劳苦和准确无误。忠诚，替人着想，细心；往往记着他所重视的人的种种微小事情，关心别人的感受。努力创造一个有秩序、和谐的工作和家居 环境。 &lt;br /&gt;&lt;br /&gt;ISFJ型的人忠诚、有奉献精神和同情心，理解别人的感受。他们意志清醒而有责任心，乐于为人所需。 ISFJ型的人十分务实，他们喜欢平和谦逊的人。他们喜欢利用大量的事实情况，对于细节则有很强的记力。他们耐心地 对待任务的整个阶段，喜欢事情能够清晰明确。 ISFJ型的人具有强烈的职业道德，所以他们如果知道自己的行为真正有用时，会对需要完成之事承担责任。他们准确系统地完成任务。他们具有传统的价值观，十分保守。他 们利用符合实际的判断标准做决定，通过出色的注重实际的态度增加了稳定性。 ISFJ型的人平和谦虚、勤奋严肃。他们温和、圆通，支持朋友和同伴。他们乐于协助别人，喜欢实际可行地帮助他人。他们利用个人热情与人 交往，在困难中与他人和睦相处。ISFJ型的人不喜欢表达个人情感，但实际上对于大多数的情况和事件都具有强烈的个人反应。他们关心、保护朋友，愿意为朋友献身，他们有为他人服务的意识，愿意完成他们的责任和义 务。 &lt;br /&gt;&lt;br /&gt;您适合的领域有：领域特征不明显，较相关的如：医护领域、消费类商业、服务业领域&lt;br /&gt;&lt;br /&gt;您适合的职业有：&lt;br /&gt;&lt;br /&gt;&amp;middot; 内科医生 &lt;br /&gt;&amp;middot; 营养师 &lt;br /&gt;&amp;middot; 图书/档案管理员 &lt;br /&gt;&amp;middot; 室内装潢设计师 &lt;br /&gt;&amp;middot; 顾客服务代表 &lt;br /&gt;&amp;middot; 记账员 &lt;br /&gt;&amp;middot; 特殊教育教师 &lt;br /&gt;&amp;middot; 酒店管理&lt;br /&gt;&amp;middot; 人事管理人员&lt;br /&gt;&amp;middot; 电脑操作员&lt;br /&gt;&amp;middot; 信贷顾问&lt;br /&gt;&amp;middot; 零售业主&lt;br /&gt;&amp;middot; 房地产代理或经纪人&lt;br /&gt;&amp;middot; 艺术人员&lt;br /&gt;&amp;middot; 商品规划师&lt;br /&gt;&amp;middot; 语言病理学者&lt;br /&gt;&amp;middot; 审计师&lt;br /&gt;&amp;middot; 会计&lt;br /&gt;&amp;middot; 财务经理&lt;br /&gt;&amp;middot; 办公室行政管理&lt;br /&gt;&amp;middot; 后勤和供应管理&lt;br /&gt;&amp;middot; 中层经理&lt;br /&gt;&amp;middot; 公务（法律、税务）执行人员&lt;br /&gt;&amp;middot; 银行信贷员&lt;br /&gt;&amp;middot; 成本估价师&lt;br /&gt;&amp;middot; 保险精算师&lt;br /&gt;&amp;middot; 税务经纪人&lt;br /&gt;&amp;middot; 税务检查员&lt;br /&gt;&amp;middot; 机械、电气工程师&lt;br /&gt;&lt;span style="background-color: #ffff99;"&gt;&amp;middot; &lt;strong&gt;计算机程序员&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&amp;middot; 数据库管理员&lt;br /&gt;&amp;middot; 地质&lt;br /&gt;&amp;middot; 气象学家&lt;br /&gt;&amp;middot; 法律研究者&lt;br /&gt;&amp;middot; 律师&lt;br /&gt;&amp;middot; 外科医生&lt;br /&gt;&amp;middot; 药剂师&lt;br /&gt;&amp;middot; 实验室技术人员&lt;br /&gt;&amp;middot; 牙科医生&lt;br /&gt;&amp;middot; 医学研究员&lt;/p&gt;&lt;img src="http://www.cnblogs.com/gaojing/aggbug/1852300.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/gaojing/archive/2010/10/15/1852300.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/gaojing/archive/2010/08/18/1802577.html</id><title type="text">JSP与Servlet之间设置Cookie可能导致Cookie无法读取的解决办法</title><summary type="text">在jsp中设置了Cookie，可在Servlet中无法读取出相应的Cookie，搜了好多，最终是通过参看Cookie的API文档解决的。其实解决方法很简单，只要设置一下Cookie的path就可以了。另外，如果新建的Cookie不设置maxage的话，关闭浏览器之后该Cookie就失效了。解决了此问题后，顺便看了下Cookie的原理及相关的Java API文档，整理如下：what is Cookie?Cookie 是在http和https协议中，用来实现会话管理(session management)，在用户终端(比如浏览器)上存储的一小段数据。一般用来存储用户的习惯（user prefere</summary><published>2010-08-18T08:30:00Z</published><updated>2010-08-18T08:30:00Z</updated><author><name>gshine</name><uri>http://www.cnblogs.com/gaojing/</uri></author><link rel="alternate" href="http://www.cnblogs.com/gaojing/archive/2010/08/18/1802577.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/gaojing/archive/2010/08/18/1802577.html"/><content type="html">&lt;p&gt;在jsp中设置了Cookie，可在Servlet中无法读取出相应的Cookie，搜了好多，最终是通过参看Cookie的API文档解决的。其实解决方法很简单，只要设置一下Cookie的path就可以了。另外，如果新建的Cookie不设置maxage的话，关闭浏览器之后该Cookie就失效了。&lt;/p&gt;&lt;p&gt;解决了此问题后，顺便看了下Cookie的原理及相关的Java API文档，整理如下：&amp;nbsp;&lt;/p&gt;&lt;p&gt;what is Cookie?&lt;/p&gt;&lt;p&gt;Cookie 是在http和https协议中，用来实现会话管理(session management)，在用户终端(比如浏览器)上存储的一小段数据。一般用来存储用户的习惯（user preferences）, 安全性要求较低的自动登录信息, 以及收集用户的信息。它一般保存在客户端用户浏览器的指定的目录下，因此，尽量不要使用Cookie保存敏感的数据，而且Cookie的数据最好加密。&lt;/p&gt;&lt;p&gt;每个Cookie都有个名字和对应的值。Cookie有几个可选的属性，比如注释comment，路径path，域名domain，以及最大生存时间maxage，和版本version。由于现在的浏览器对这些属性的支持存在bug，因此为了最大的互操作行，尽量不要太依靠这些属性。&lt;/p&gt;&lt;p&gt;Cookies是在服务器端被指定的，通过在HTTP响应的header中添加字段来实现。在Java Servlet中，是通过response.addCookie方法来一次添加一个Cookie的。用户浏览器一般被要求对于每个主机支持20个Cookie，每个Cookie最少支持4KB。使用大量的Cookie一般是不鼓励的。当浏览器发出请求时，这些Cookie会被加在HTTP请求header中发到服务器端。在服务器端，可以通过request.getCookies来获得本次请求中的所有的Cookies。位于不同path下可以存在相同名字的Cookie，在特定path下的Cookie只能被该path以及子目录下的读取。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; setDomain(String pattern);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Specifies the domain within which this cookie should be presented. &lt;br /&gt;The form of the domain name is specified by RFC 2109. &lt;span style="color: #ff0000;"&gt;A domain name begins with a dot (.foo.com) and means that the cookie is visible to servers in a specified Domain Name System (DNS) zone (for example, &lt;a href="http://www.foo.com"&gt;www.foo.com&lt;/a&gt;, but not a.b.foo.com). &lt;/span&gt;By default, cookies are only returned to the server that sent them.&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; setMaxAge(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; expiry);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Sets the maximum age of the cookie in seconds. &lt;br /&gt;A &lt;span style="color: #ff0000;"&gt;positive &lt;/span&gt;value indicates that the cookie will expire after that many seconds have passed. Note that the value is the maximum age when the cookie will expire, not the cookie's current age. A &lt;span style="color: #ff0000;"&gt;negative &lt;/span&gt;value means that the cookie is not stored persistently and will be deleted when the Web browser exits. A &lt;span style="color: #ff0000;"&gt;zero &lt;/span&gt;value causes the cookie to be deleted.&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; setPath(String uri);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;span style="color: #ff0000;"&gt;Specifies a path for the cookie to which the client should return the cookie.&lt;/span&gt; &lt;br /&gt;The cookie is visible to all the pages in the directory you specify, and all the pages in that directory's subdirectories. A cookie's path must include the servlet that set the cookie, for example, /catalog, which makes the cookie visible to all directories on the server under /catalog. Consult RFC 2109 (available on the Internet) for more information on setting path names for cookies.&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;使用方法：&lt;/p&gt;&lt;p&gt;1、添加Cookie：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt; &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;新建一个Cookie，并设置名字和值。 &lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt; &lt;span style="color: #008000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;cookie &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Cookie(&lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;cookiename&lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;cookievalue&lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;); &lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt; &lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;设置Cookie的有效期为2天，如果不设置此有效期，则用户关闭浏览器后此Cookie失效。   &lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;4&lt;/span&gt; &lt;span style="color: #008000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;cookie.setMaxAge(&lt;/span&gt;&lt;span style="color: #000000;"&gt;60&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;60&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;24&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;5&lt;/span&gt; &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;设置Cookie的有效路径，&amp;ldquo;/&amp;rdquo;即该应用下都可以访问该Cookie; &lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;6&lt;/span&gt; &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;如果不设置路径，那么只有设置该Cookie路径及其子路径可以访问.   &lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;7&lt;/span&gt; &lt;span style="color: #000000;"&gt;cookie.setPath(&lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;); &lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;8&lt;/span&gt; &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;将Cookie添加到HTTP响应中去 &lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;9&lt;/span&gt; &lt;span style="color: #000000;"&gt;response.addCookie(cookie); &lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;2、获得Cookie：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt; &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;获取本次请求中的所有Cookies&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt; &lt;span style="color: #000000;"&gt;Cookie[] cookies &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; request.getCookies();&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;(cookies&lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;){&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;4&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt;(Cookie cookie : cookies){   &lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;5&lt;/span&gt; &lt;span style="color: #000000;"&gt;    cookie.getName();&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;6&lt;/span&gt; &lt;span style="color: #000000;"&gt;    cookie.getValue();&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;7&lt;/span&gt; &lt;span style="color: #000000;"&gt;  }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;8&lt;/span&gt; &lt;span style="color: #000000;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;注意：&lt;br /&gt;1 Cookie的名字和值中尽量不要使用特殊字符。关于Cookie的名字，RFC2109中说name只能包含字母或者数字，不能包含逗号、分号、空格及美元符号。而在Cookie的value中建议不用使用逗号，分号，空白字符等。&lt;br /&gt;2 如果jsp和Servlet之间设置和读取Cookie时出现问题的话，一般是因为path的问题，此时通过调用Cookie.setPath来设定Cookie的path。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/gaojing/aggbug/1802577.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/gaojing/archive/2010/08/18/1802577.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
