2009年12月3日星期四

[note]隐藏滚动栏(scrollBar)二三事

问题一:如何隐藏滚动栏?

1、完全隐藏
在<boby>里加入scroll="no",可隐藏滚动条;

<boby scroll="no">


2、在不需要时隐藏
指当浏览器窗口宽度或高度大于页面的宽或高时,不显示滚动条;反之,则显示;

<boby scroll="auto">

3、样式表方法
在<boby>里加入style="overflow-x:hidden",可隐藏水平滚动条;加入style="overflow-y:hidden",可隐藏垂直滚动条。
这种方法在页面头部为:<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">这种兼容模式下是不行的,其它的没试过,最后终于找到了正确的方法:
被包含页面里加入

<style>
html { overflow-x:hidden; }
</style>

有一段解释是这样说的:body{ overflow-x:hidden; }在标准 DTD 下是不可以的。

4、另一种方法

<style type="text/css">
body {
overflow-x:hidden; /*隐藏水平滚动条*/
overflow-y:hidden; /*隐藏水平滚动条*/
}
</style>

此方法在页面头部为:<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">这种兼容模式下也是不行的。

<style type="text/css">
html {
overflow-x:hidden; /*隐藏水平滚动条*/
overflow-y:hidden; /*隐藏水平滚动条*/
}
</style>

问题二:如何使firefox始终显示滚动条?
firefox在页面高度小于一个屏幕的高度时,是不会显示滚动条的。但是在某些特殊情况下,我们需要这个滚动条。在网上找了些方法:

html {
    overflow:-moz-scrollbars-vertical;
}
以上方法使用firefox私有属性,但在firefox 3.5之下无法使用

body, html {
    min-height:101%;
}
以上方法一切正常,且支持多浏览器

[note]如何限制得到整数的大小

int indexFor(int h, int length)
{
return h & length;
}


只要length是2的次方,那么不论h多到,得到的返回值一定会比length小。

2009年12月2日星期三

[转]理解 Java 的 GC 与 幽灵引用

转自:http://www.javaeye.com/topic/401478

理解 Java 的 GC 与 幽灵引用
 
         Java 中一共有 4 种类型的引用 : StrongReference、 SoftReference、 WeakReference 以及 PhantomReference (传说中的幽灵引用 呵呵),
这 4 种类型的引用与 GC 有着密切的关系,  让我们逐一来看它们的定义和使用场景 :

        1. Strong Reference
       
        StrongReference 是 Java 的默认引用实现,  它会尽可能长时间的存活于 JVM 内, 当没有任何对象指向它时 GC 执行后将会被回收

Java代码
  1. @Test  
  2. public void strongReference() {  
  3.     Object referent = new Object();  
  4.       
  5.     /** 
  6.      * 通过赋值创建 StrongReference  
  7.      */  
  8.     Object strongReference = referent;  
  9.       
  10.     assertSame(referent, strongReference);  
  11.       
  12.     referent = null;  
  13.     System.gc();  
  14.       
  15.     /** 
  16.      * StrongReference 在 GC 后不会被回收 
  17.      */  
  18.     assertNotNull(strongReference);  
  19. }  





        2. WeakReference & WeakHashMap

WeakReference, 顾名思义,  是一个弱引用,  当所引用的对象在 JVM 内不再有强引用时, GC 后 weak reference 将会被自动回收

Java代码
  1. @Test  
  2. public void weakReference() {  
  3.     Object referent = new Object();  
  4.     WeakReference<Object> weakRerference = new WeakReference<Object>(referent);  
  5.   
  6.     assertSame(referent, weakRerference.get());  
  7.       
  8.     referent = null;  
  9.     System.gc();  
  10.       
  11.     /** 
  12.      * 一旦没有指向 referent 的强引用, weak reference 在 GC 后会被自动回收 
  13.      */  
  14.     assertNull(weakRerference.get());  
  15. }  




WeakHashMap 使用 WeakReference 作为 key, 一旦没有指向 key 的强引用, WeakHashMap 在 GC 后将自动删除相关的 entry

Java代码
  1. @Test  
  2. public void weakHashMap() throws InterruptedException {  
  3.     Map<Object, Object> weakHashMap = new WeakHashMap<Object, Object>();  
  4.     Object key = new Object();  
  5.     Object value = new Object();  
  6.     weakHashMap.put(key, value);  
  7.   
  8.     assertTrue(weakHashMap.containsValue(value));  
  9.       
  10.     key = null;  
  11.     System.gc();  
  12.       
  13.     /** 
  14.      * 等待无效 entries 进入 ReferenceQueue 以便下一次调用 getTable 时被清理 
  15.      */  
  16.     Thread.sleep(1000);  
  17.       
  18.     /** 
  19.      * 一旦没有指向 key 的强引用, WeakHashMap 在 GC 后将自动删除相关的 entry 
  20.      */  
  21.     assertFalse(weakHashMap.containsValue(value));  
  22. }  




        3. SoftReference

SoftReference 于 WeakReference 的特性基本一致, 最大的区别在于 SoftReference 会尽可能长的保留引用直到 JVM 内存不足时才会被回收(虚拟机保证), 这一特性使得 SoftReference 非常适合缓存应用

Java代码
  1. @Test  
  2. public void softReference() {  
  3.     Object referent = new Object();  
  4.     SoftReference<Object> softRerference = new SoftReference<Object>(referent);  
  5.   
  6.     assertNotNull(softRerference.get());  
  7.       
  8.     referent = null;  
  9.     System.gc();  
  10.       
  11.     /** 
  12.      *  soft references 只有在 jvm OutOfMemory 之前才会被回收, 所以它非常适合缓存应用 
  13.      */  
  14.     assertNotNull(softRerference.get());  
  15. }  




        4. PhantomReference

        作为本文主角, Phantom Reference(幽灵引用) 与 WeakReference 和 SoftReference 有很大的不同,  因为它的 get() 方法永远返回 null, 这也正是它名字的由来

Java代码
  1. @Test  
  2. public void phantomReferenceAlwaysNull() {  
  3.     Object referent = new Object();  
  4.     PhantomReference<Object> phantomReference = new PhantomReference<Object>(referent, new ReferenceQueue<Object>());  
  5.       
  6.     /** 
  7.      * phantom reference 的 get 方法永远返回 null  
  8.      */  
  9.     assertNull(phantomReference.get());  
  10. }  



         诸位可能要问, 一个永远返回 null 的 reference 要来何用,  请注意构造 PhantomReference 时的第二个参数 ReferenceQueue(事实上 WeakReference & SoftReference 也可以有这个参数),
PhantomReference 唯一的用处就是跟踪 referent  何时被 enqueue 到 ReferenceQueue 中.

     5. RererenceQueue

当一个 WeakReference 开始返回 null 时, 它所指向的对象已经准备被回收, 这时可以做一些合适的清理工作.   将一个 ReferenceQueue 传给一个 Reference 的构造函数, 当对象被回收时, 虚拟机会自动将这个对象插入到 ReferenceQueue 中, WeakHashMap 就是利用 ReferenceQueue 来清除 key 已经没有强引用的 entries.

Java代码
  1. @Test  
  2. public void referenceQueue() throws InterruptedException {  
  3.     Object referent = new Object();       
  4.     ReferenceQueue<Object> referenceQueue = new ReferenceQueue<Object>();  
  5.     WeakReference<Object> weakReference = new WeakReference<Object>(referent, referenceQueue);  
  6.       
  7.     assertFalse(weakReference.isEnqueued());  
  8.     Reference<? extends Object> polled = referenceQueue.poll();  
  9.     assertNull(polled);  
  10.       
  11.     referent = null;  
  12.     System.gc();  
  13.   
  14.     assertTrue(weakReference.isEnqueued());  
  15.     Reference<? extends Object> removed = referenceQueue.remove();  
  16.     assertNotNull(removed);  
  17. }  



6.  PhantomReference  vs WeakReference

PhantomReference  有两个好处, 其一, 它可以让我们准确地知道对象何时被从内存中删除, 这个特性可以被用于一些特殊的需求中(例如 Distributed GC,  XWork 和 google-guice 中也使用 PhantomReference 做了一些清理性工作).

其二, 它可以避免 finalization 带来的一些根本性问题, 上文提到 PhantomReference 的唯一作用就是跟踪 referent 何时被 enqueue 到 ReferenceQueue 中,  但是 WeakReference 也有对应的功能, 两者的区别到底在哪呢 ?
这就要说到 Object 的 finalize 方法, 此方法将在 gc 执行前被调用, 如果某个对象重载了 finalize 方法并故意在方法内创建本身的强引用,  这将导致这一轮的 GC 无法回收这个对象并有可能
引 起任意次 GC, 最后的结果就是明明 JVM 内有很多 Garbage 却 OutOfMemory, 使用 PhantomReference 就可以避免这个问题, 因为 PhantomReference 是在 finalize 方法执行后回收的,也就意味着此时已经不可能拿到原来的引用,  也就不会出现上述问题,  当然这是一个很极端的例子, 一般不会出现.

7. 对比

taken from http://mindprod.com/jgloss/phantom.html

Soft vs Weak vs Phantom References
Type Purpose Use When GCed Implementing Class
Strong Reference An ordinary reference. Keeps objects alive as long as they are referenced. normal reference. Any object not pointed to can be reclaimed. default
Soft Reference Keeps objects alive provided there’s enough memory. to keep objects alive even after clients have removed their references (memory-sensitive caches), in case clients start asking for them again by key. After a first gc pass, the JVM decides it still needs to reclaim more space. java.lang.ref.SoftReference
Weak Reference Keeps objects alive only while they’re in use (reachable) by clients. Containers that automatically delete objects no longer in use. After gc determines the object is only weakly reachable java.lang.ref.WeakReference 
java.util.WeakHashMap
Phantom Reference Lets you clean up after finalization but before the space is reclaimed (replaces or augments the use offinalize()) Special clean up processing After finalization. java.lang.ref.PhantomReference


8. 小结
       一般的应用程序不会涉及到 Reference 编程, 但是了解这些知识会对理解 GC 的工作原理以及性能调优有一定帮助,   在实现一些基础性设施比如缓存时也可能会用到, 希望本文能有所帮助.

        王政 于 2009,6,3

[转]application session request page

application:全局作用范围,整个应用程序共享,就是在部署文件中的同一个webApp共享,生命周期为:应用程序启动到停止。
session:会话作用域,当用户首次访问时,产生一个新的会话,以后服务器就可以记住这个会话状态。生命周期:会话超时,或者服务器端强制使会话失效。
request:请求作用域,就是客户端的一次请求。
page:一个JSP页面。
以上作用范围使越来越小, request和page的生命周期都是短暂的,他们之间的区别就是:一个request可以包含多个page页(include,forward以及filter)。

[转]浅析编写JSP Tag

编写一个JSP Tag涉及三个步骤:
(1)编写JSP
(2)编写JSP Tag的java程序
(3)编写JSP Tag库的描述文件tld(实际是一个XML文件)
这三个步骤之间没有顺序约束,下面是一个简单的例子:

1 编写HelloTag.jsp

  1. <%@page contentType="text/html"%>   
  2. <html>   
  3. <head><title>Hello Tags Page</title></head>   
  4. <body>   
  5. <%@ taglib uri="/WEB-INF/classes/tags/helloTag.tld" prefix="hello" %> 
  6. <hello:helloTag />   
  7. </body>   
  8. </html> 

2 编写JSP Tag

HelloTag.java

  1. package tags;   
  2. //注意:必须放在一个包中   
  3. import java.io.*;   
  4. import javax.servlet.jsp.*;   
  5. import javax.servlet.jsp.tagext.*;   
  6. public class HelloTag extends TagSupport {   
  7. public int doStartTag() {   
  8. try {   
  9. //使用JspWriter获得JSP的输出对象   
  10. JspWriter jspWriterOutput = pageContext.getOut(); 
  11. jspWriterOutput.print("Hello Tag!");   
  12. }   
  13. catch (IOException ioEx) {   
  14. System .out.println("IOException in HelloTag " + ioEx);   
  15. }   
  16. return (SKIP_BODY);   
  17. }   

3 编写helloTag.tld

这是Tag库的描述部分:

  1. <?xml version="1.0" encoding="UTF-8" ?> 
  2. <!DOCTYPE taglib  
  3. PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"  
  4. "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"> 
  5. <taglib> 
  6. <tlib-version>1.0</tlib-version> 
  7. <jsp-version>1.2</jsp-version> 
  8. <shorttag&#65279; -name>helloTag</short -name> 
  9. <uri>/WEB-INFtagshelloTag</uri> 
  10. <display-name>helloTag</display-name> 
  11. <small-icon></small-icon> 
  12. <large-icon></large-icon> 
  13. <description>simple hello tags tag  
  14. </description> 
  15. <tag> 
  16. <name>helloTag</name> 
  17. <tag-class >tags.HelloTag</tag-class > 
  18. <body-content>empty</body-content> 
  19. <small-icon></small-icon> 
  20. <large-icon></large-icon> 
  21. <description></description> 
  22. <example></example> 
  23. </tag> 
  24. </taglib>  

4 注意:

通常手工编写XML文件,但是Sun的教程建议使用IDE工具编写自定义tag,比如NetBeans
一般,直接把tld文件放到WEB-INF目录中。

2009年12月1日星期二

[note]URI与URL区别

url:统一资源定位符   
uri:统一资源标志符   
   
URI是URL的一部分

url定位客户端连接到服务器所需要的信息,如   
http://www.csdn.net   
http://tcc.com:8080/servlet/logon?name=zhangsan&addr=tttt   
完整构成   
<protocol>://<servername>[:port]/<url-path>[?query-string]   
   
uri是url组成的一部分,没有域名和查询字符串,
即域名之后查询字符串之前所有的信息,用于制定资源。   
    
例如,对于请求地址   
http://java.sun.com/products/servlet/index.html?id=09   
    
url--->http://java.sun.com/products/servlet/index.html?id=09   
uri--->/products/servlet/index.html  

[转]response.setContentType()的String参数及对应类型

response.setContentType()的String参数及对应类型

<option   value="image/bmp">BMP</option>  
<option   value="image/gif">GIF</option>  
<option   value="image/jpeg">JPEG</option>  
<option   value="image/tiff">TIFF</option>  
<option   value="image/x-dcx">DCX</option>  
<option   value="image/x-pcx">PCX</option>  
<option   value="text/html">HTML</option>  
<option   value="text/plain">TXT</option>  
<option   value="text/xml">XML</option>  
<option   value="application/afp">AFP</option>  
<option   value="application/pdf">PDF</option>  
<option   value="application/rtf">RTF</option>  
<option   value="application/msword">MSWORD</option>  
<option   value="application/vnd.ms-excel">MSEXCEL</option>  
<option   value="application/vnd.ms-powerpoint">MSPOWERPOINT</option>  
<option   value="application/wordperfect5.1">WORDPERFECT</option>  
<option   value="application/vnd.lotus-wordpro">WORDPRO</option>  
<option   value="application/vnd.visio">VISIO</option>  
<option   value="application/vnd.framemaker">FRAMEMAKER</option>  
<option   value="application/vnd.lotus-1-2-3">LOTUS123</option>