﻿<?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-【永恒的瞬间】  -文章分类-JAVAEE</title><link>http://www.blogjava.net/19851985lili/category/18368.html</link><description>☜Give me hapy ☞




</description><language>zh-cn</language><lastBuildDate>Sat, 31 May 2008 01:42:21 GMT</lastBuildDate><pubDate>Sat, 31 May 2008 01:42:21 GMT</pubDate><ttl>60</ttl><item><title>使用FileUpload组件上传文件</title><link>http://www.blogjava.net/19851985lili/articles/203816.html</link><dc:creator>☜♥☞MengChuChen</dc:creator><author>☜♥☞MengChuChen</author><pubDate>Thu, 29 May 2008 06:03:00 GMT</pubDate><guid>http://www.blogjava.net/19851985lili/articles/203816.html</guid><wfw:comment>http://www.blogjava.net/19851985lili/comments/203816.html</wfw:comment><comments>http://www.blogjava.net/19851985lili/articles/203816.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/19851985lili/comments/commentRss/203816.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/19851985lili/services/trackbacks/203816.html</trackback:ping><description><![CDATA[<p><font size="2">文件上传在web应用中非常普遍，要在jsp环境中实现文件上传功能是非常容易的，因为网上有许多用java开发的文件上传组件，本文以commons-fileupload组件为例，为jsp应用添加文件上传功能。</font></p>
<p><font size="2">common-fileupload组件是apache的一个开源项目之一，可以从<a href="http://jakarta.apache.org/commons/fileupload/">http://jakarta.apache.org/commons/fileupload/</a>下载。用该组件可实现一次上传一个或多个文件，并可限制文件大小。<br />
下载后解压zip包，将commons-fileupload-1.0.jar复制到tomcat的webapps\你的webapp\WEB-INF\lib\下，目录不存在请自建目录。</font></p>
<p><font size="2">新建一个servlet: Upload.java用于文件上传：</font></p>
<font size="2">
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="keyword">import</span><span>&nbsp;java.io.*; &nbsp;&nbsp;</span></span>
    <li class=""><span class="keyword">import</span><span>&nbsp;java.util.*; &nbsp;&nbsp;</span>
    <li class="alt"><span class="keyword">import</span><span>&nbsp;javax.servlet.*; &nbsp;&nbsp;</span>
    <li class=""><span class="keyword">import</span><span>&nbsp;javax.servlet.http.*; &nbsp;&nbsp;</span>
    <li class="alt"><span class="keyword">import</span><span>&nbsp;org.apache.commons.fileupload.*; &nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;</span>
    <li class="alt"><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;Upload&nbsp;</span><span class="keyword">extends</span><span>&nbsp;HttpServlet&nbsp;{ &nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">private</span><span>&nbsp;String&nbsp;uploadPath&nbsp;=&nbsp;</span><span class="string">"C:\\upload\\";&nbsp;//&nbsp;上传文件的目录 </span>&nbsp;
    <li class=""><span><span class="string">&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;String&nbsp;tempPath&nbsp;=&nbsp;"</span><span>C:\\upload\\tmp\\";&nbsp;</span><span class="comment">//&nbsp;临时文件目录 </span><span>&nbsp;&nbsp;</span></span>
    <li class="alt"><span>&nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;doPost(HttpServletRequest&nbsp;request, &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;HttpServletResponse&nbsp;response) &nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">throws</span><span>&nbsp;IOException,&nbsp;ServletException &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span>
    <li class="alt"><span>}&nbsp;&nbsp;</span> </li>
</ol>
</div>
<p>在doPost()方法中，当servlet收到浏览器发出的Post请求后，实现文件上传。以下是示例代码：<br />
</p>
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;doPost(HttpServletRequest&nbsp;request, &nbsp;&nbsp;</span></span>
    <li class=""><span>HttpServletResponse&nbsp;response) &nbsp;&nbsp;</span>
    <li class="alt"><span class="keyword">throws</span><span>&nbsp;IOException,&nbsp;ServletException &nbsp;&nbsp;</span>
    <li class=""><span>{ &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">try</span><span>&nbsp;{ &nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DiskFileUpload&nbsp;fu&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;DiskFileUpload(); &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//&nbsp;设置最大文件尺寸，这里是4MB </span><span>&nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fu.setSizeMax(</span><span class="number">4194304</span><span>); &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//&nbsp;设置缓冲区大小，这里是4kb </span><span>&nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fu.setSizeThreshold(</span><span class="number">4096</span><span>); &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//&nbsp;设置临时目录： </span><span>&nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fu.setRepositoryPath(tempPath); &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//&nbsp;得到所有的文件： </span><span>&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;List&nbsp;fileItems&nbsp;=&nbsp;fu.parseRequest(request); &nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Iterator&nbsp;i&nbsp;=&nbsp;fileItems.iterator(); &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//&nbsp;依次处理每一个文件： </span><span>&nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">while</span><span>(i.hasNext())&nbsp;{ &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FileItem&nbsp;fi&nbsp;=&nbsp;(FileItem)i.next(); &nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//&nbsp;获得文件名，这个文件名包括路径： </span><span>&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;fileName&nbsp;=&nbsp;fi.getName(); &nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//&nbsp;在这里可以记录用户和文件信息 </span><span>&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//&nbsp;... </span><span>&nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//&nbsp;写入文件，暂定文件名为a.txt，可以从fileName中提取文件名： </span><span>&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fi.write(</span><span class="keyword">new</span><span>&nbsp;File(uploadPath&nbsp;+&nbsp;</span><span class="string">"a.txt"</span><span>)); &nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">catch</span><span>(Exception&nbsp;e)&nbsp;{ &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//&nbsp;可以跳转出错页面 </span><span>&nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span>
    <li class="alt"><span>}&nbsp;&nbsp;</span> </li>
</ol>
</div>
<p>如果要在配置文件中读取指定的上传文件夹，可以在init()方法中执行：<br />
</p>
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;init()&nbsp;</span><span class="keyword">throws</span><span>&nbsp;ServletException&nbsp;{ &nbsp;&nbsp;</span></span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;uploadPath&nbsp;=&nbsp;.... &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;tempPath&nbsp;=&nbsp;.... &nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//&nbsp;文件夹不存在就自动创建： </span><span>&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span>(!</span><span class="keyword">new</span><span>&nbsp;File(uploadPath).isDirectory()) &nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">new</span><span>&nbsp;File(uploadPath).mkdirs(); &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span>(!</span><span class="keyword">new</span><span>&nbsp;File(tempPath).isDirectory()) &nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">new</span><span>&nbsp;File(tempPath).mkdirs(); &nbsp;&nbsp;</span>
    <li class="alt"><span>}&nbsp;&nbsp;</span> </li>
</ol>
</div>
<p>编译该servlet，注意要指定classpath，确保包含commons-upload-1.0.jar和tomcat\common\lib\servlet-api.jar。<br />
配置servlet，用记事本打开tomcat\webapps\你的webapp\WEB-INF\web.xml，没有的话新建一个。<br />
典型配置如下：<br />
</p>
<div class="code_title">xml 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-xml">
    <li class="alt"><span><span class="tag"><!--sp--><span class="tag-name">xml</span><span>&nbsp;</span><span class="attribute">version</span><span>=</span><span class="attribute-value">"1.0"</span><span>&nbsp;</span><span class="attribute">encoding</span><span>=</span><span class="attribute-value">"ISO-8859-1"</span><span class="tag">?&gt;</span><span>&nbsp;&nbsp;</span></span> </span>
    <li class="">
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;PUBLIC&nbsp;"-//Sun&nbsp;Microsystems,&nbsp;Inc.//DTD&nbsp;Web&nbsp;Application&nbsp;2.3//EN" &nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;"http://java.sun.com/dtd/web-app_2_3.dtd"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;</span>
    <li class=""><span class="tag">&lt;</span><span class="tag-name">web-app</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">servlet</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">servlet-name</span><span class="tag">&gt;</span><span>Upload</span><span class="tag"><span class="tag-name">servlet-name</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">servlet-class</span><span class="tag">&gt;</span><span>Upload</span><span class="tag"><span class="tag-name">servlet-class</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag"><span class="tag-name">servlet</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li class="alt"><span>&nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">servlet-mapping</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">servlet-name</span><span class="tag">&gt;</span><span>Upload</span><span class="tag"><span class="tag-name">servlet-name</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">url-pattern</span><span class="tag">&gt;</span><span>/fileupload</span><span class="tag"><span class="tag-name">url-pattern</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag"><span class="tag-name">servlet-mapping</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li class=""><span class="tag"><span class="tag-name">web-app</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span></li>
</ol>
</div>
<p>配置好servlet后，启动tomcat，写一个简单的jsp测试：</p>
<span><span><span>
<div class="code_title">jsp 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span>&amp;lt;form&nbsp;action=</span><span class="string">"fileupload"</span><span>&nbsp;method=</span><span class="string">"post"</span><span>&nbsp;enctype=</span><span class="string">"multipart/form-data"</span><span>&nbsp;name=</span><span class="string">"form1"</span><span>&gt; &nbsp;&nbsp;</span></span>
    <li class=""><span>&nbsp;&nbsp;<span><span>&amp;lt;</span></span>input&nbsp;type=</span><span class="string">"file"</span><span>&nbsp;name=</span><span class="string">"file"</span><span>&nbsp;/&gt; &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;<span><span>&amp;lt;</span></span>input&nbsp;type=</span><span class="string">"submit"</span><span>&nbsp;name=</span><span class="string">"submit"</span><span>&nbsp;value=</span><span class="string">"上传"</span><span>&nbsp;/&gt; &nbsp;&nbsp;</span>
    <li class=""><span><span><span>&amp;lt;</span></span>/form&gt;&nbsp;&nbsp;</span> </li>
</ol>
</div>
<p>注意：action="fileupload"其中fileupload是配置servlet时指定的url-pattern。<span><span></span></span></p>
</span></span></span></font>
<img src ="http://www.blogjava.net/19851985lili/aggbug/203816.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/19851985lili/" target="_blank">☜♥☞MengChuChen</a> 2008-05-29 14:03 <a href="http://www.blogjava.net/19851985lili/articles/203816.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用命名参数处理 CallableStatement</title><link>http://www.blogjava.net/19851985lili/articles/203809.html</link><dc:creator>☜♥☞MengChuChen</dc:creator><author>☜♥☞MengChuChen</author><pubDate>Thu, 29 May 2008 05:45:00 GMT</pubDate><guid>http://www.blogjava.net/19851985lili/articles/203809.html</guid><wfw:comment>http://www.blogjava.net/19851985lili/comments/203809.html</wfw:comment><comments>http://www.blogjava.net/19851985lili/articles/203809.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/19851985lili/comments/commentRss/203809.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/19851985lili/services/trackbacks/203809.html</trackback:ping><description><![CDATA[<p><a name="N10089"><span class="atitle">简介：JDBC 中的语句处理</span></a></p>
<p>在 JDBC 应用程序中，JDBC 语句对象用于将 SQL 语句发送到数据库服务器。一个语句对象与一个连接相关联，应用程序与数据库服务器之间的通信由语句对象来处理。</p>
<p>JDBC 中有三种类型的语句对象：</p>
<ol>
    <li><a href="http://www.ibm.com/developerworks/cn/db2/library/techarticles/dm-0802tiwary/#general" cmimpressionsent="1">常规语句（General statement）</a>
    <li><a href="http://www.ibm.com/developerworks/cn/db2/library/techarticles/dm-0802tiwary/#prepared" cmimpressionsent="1">预置语句（Prepared statement）</a>
    <li><a href="http://www.ibm.com/developerworks/cn/db2/library/techarticles/dm-0802tiwary/#callable" cmimpressionsent="1">可调用语句（Callable statement）</a> </li>
</ol>
<p>语句对象与一个连接相关联，所以要创建一个语句对象，首先应该建立一个数据库连接。</p>
<p><a name="N100B1"><span class="smalltitle">创建连接</span></a></p>
<p>清单 1 中的代码示例演示了如何创建连接：</p>
<br />
<a name="listing1"><strong>清单 1.装载 Informix 驱动程序并创建一个连接的代码示例</strong></a><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">
            Connection con = null;
            try {
            Class.forName("com.informix.jdbc.IfxDriver");
            String url = "jdbc:informix-sqli://hostname:port_number/dbname:
            informixserver=servername; userid=userid;password=pwd;";
            con = DriverManager.getConnection(url);
            }
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>现在逐个考察这三种类型的语句对象。</p>
<br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
            <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td>
        </tr>
    </tbody>
</table>
<table class="no-print" cellspacing="0" cellpadding="0" align="right">
    <tbody>
        <tr align="right">
            <td><br />
            </td>
        </tr>
    </tbody>
</table>
<br />
<br />
<p><a name="general"><span class="atitle">常规语句</span></a></p>
<p>可以使用连接的 <code>createStatement</code> 方法创建这种语句。这种语句专用于不需要传递任何值作为参数的 SQL 语句。</p>
<br />
<a name="listing2"><strong>清单 2. 演示创建语句的示例代码</strong></a><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">
            Statement stmt = con.createStatement();
            cmd = "create database testDB;";
            rc = stmt.executeUpdate(cmd);
            stmt.close();
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
            <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td>
        </tr>
    </tbody>
</table>
<table class="no-print" cellspacing="0" cellpadding="0" align="right">
    <tbody>
        <tr align="right">
            <td><img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /><br />
            </td>
        </tr>
    </tbody>
</table>
<br />
<br />
<p><a name="prepared"><span class="atitle">预置语句</span></a></p>
<p>预置语句是 statement 类的一个子类。预置语句与 statement 类的主要区别在于，前者可以只编译和优化一次，然后通过设置不同的参数值多次使用。所以，如果想多次执行一条语句，那么预置语句是更好的选择。由于已经预先编译好，所以减少了执行时间。因此，预置语句的优点是，它不仅包含一条 SQL 语句，而且还是一条预先编译好的 SQL 语句。另一个区别是，SQL 语句在创建后就被提供给预置语句。</p>
<br />
<a name="listing3"><strong>清单 3. 解释预置语句的示例代码</strong></a><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">
            PreparedStatement pstmt = con.prepareStatement("UPDATE tab1 "+
            "set col1 = ? where key = 1");
            pstmt.setShort(1, (short)2);
            int rowcount = pstmt.executeUpdate();
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>在此，同一个预置语句可用于不同的 col1 值。参数一旦设定，它的值将保持不变，直到被重新设置或者 <code>clearParameters</code> 被调用。这项特性使得预置语句可以用于批量处理 <code>INSERT</code>/<code>UPDATE</code>。</p>
<p><a name="N10101"><span class="smalltitle">批量更新</span></a></p>
<p>通过设置多个值，批量更新特性提高了需要多次执行的语句的性能。这样可以将多个更新操作提交到一个数据源并进行一次性处理。语句对象也可以使用批量更新。但语句对象提交不同的 SQL 语句进行批处理，而预置语句提交的是一组参数。</p>
<p>清单 4 显示了如何使用预置语句进行批量插入：</p>
<br />
<a name="listing4"><strong>清单 4. 演示批量更新的示例代码</strong></a><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">
            PreparedStatement pst = conn.prepareStatement("insert into tab1 values (?)");
            for loop....
            {
            pst.setInt (1, i);
            pst.addBatch();
            }
            pst.executeBatch();
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p><code>addBatch</code> 方法将语句添加到一个缓存中，然后使用 <code>executeBatch()</code> 方法转储到数据库中。所以它节省了语句的编译/优化，因为它只编译一次（对于预置语句），而且还节省了与服务器之间的往返，因为它一次性发送了批量插入。</p>
<br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
            <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td>
        </tr>
    </tbody>
</table>
<br />
<br />
<p><a name="callable"><span class="atitle">可调用语句</span></a></p>
<p>这是调用 SQL 语句的第三种方法，它提供了一种从 Java&#8482; 程序中调用服务器上的存储过程的方式。可调用语句也需要先作准备，然后使用 set 方法设置它们的参数。可以通过以下两种方式设置参数值：</p>
<ol>
    <li>顺序位置
    <li>命名参数 </li>
</ol>
<p>顺序位置是传统的参数设置方式，它根据参数在 CallableStatements 中的位置来设置参数。但是，命名参数则提供了更大的灵活性，它允许根据名称而不是顺序位置来设置参数。在调用例程时，必须以名称或顺序格式指定 CallableStatement 的参数。例如，如果对一个参数使用了参数名称，那么对所有其他参数也必须使用参数名称。</p>
<p>在调用具有许多参数，而且其中一些参数有默认值的存储过程时，命名参数特别有用。如果过程是惟一的，那么可以省略有默认值的参数，并且可以按任意顺序输入参数。命名参数使应用程序更加健壮，所以，即使存储过程中参数的顺序发生了改变，也不必修改应用程序。</p>
<p>JDBC 驱动程序提供了 <code>DatabaseMetaData.supportsNamedParameters()</code> 方法来确认驱动程序和 RDMS 是否支持 CallableStatement 中的命名参数。如果支持命名参数，则系统返回 true。例如：</p>
<br />
<a name="listing5"><strong>清单 5. supportsNamedParameters() 的使用</strong></a><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">
            Connection myConn = . . .   // connection to the RDBMS for Database
            DatabaseMetaData dbmd = myConn.getMetaData();
            if (dbmd.supportsNamedParameters() == true)
            {
            System.out.println("NAMED PARAMETERS FOR CALLABLE"
            + "STATEMENTS IS SUPPORTED");
            }
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p><a name="N1014E"><span class="smalltitle">获取存储过程的参数名称</span></a></p>
<p>可以使用 <code>DatabaseMetaData</code> 的 <code>getprocedureColumns</code> 获取存储过程的参数名称，该方法的定义如清单 6 所示：</p>
<br />
<a name="listing6"><strong>清单 6. getProcedureColumn() 方法的使用</strong></a><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">
            Connection myConn = . . .   // connection to the RDBMS for Database
            . .
            DatabaseMetaData dbmd = myConn.getMetaData();
            ResultSet rs = dbmd.getProcedureColumns(
            "myDB", schemaPattern, procedureNamePattern, columnNamePattern);
            rs.next() {
            String parameterName = rs.getString(4);
            - - - or - - -
            String parameterName = rs.getString("COLUMN_NAME");
            - - -
            System.out.println("Column Name: " + parameterName);
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>与 <code>getProcedureColumns()</code> 方法的参数相匹配的所有列的名称都将被显示。</p>
<p>清单 7 显示了 CallableStatements 中的命名参数的使用。</p>
<p><strong>创建存储过程</strong> </p>
<br />
<a name="listing7"><strong>清单 7. 可调用 OUT 参数的使用</strong></a><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">
            create procedure createProductDef(productname   varchar(64),
            productdesc  varchar(64),
            listprice    float,
            minprice     float,
            out prod_id      float);
            . . .
            let prod_id="value for prod_id";
            end procedure;
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p><a href="http://www.ibm.com/developerworks/cn/db2/library/techarticles/dm-0802tiwary/#listing8" cmimpressionsent="1">清单 8</a> 中的 Java 代码首先创建一个有 5 个参数的 CallableStatement，这 5 个参数与存储过程中的参数相对应。JDBC 调用的括号中的问号字符 (?) 对参数进行引用。设置或注册所有的参数。使用格式 <em>cstmt.setString("arg", name);</em> 命名参数，其中 <em>arg</em> 是相应的存储过程中的参数名称。这里不需要按照存储过程中的参数顺序来命名参数。</p>
<br />
<a name="listing8"><strong>清单 8. 可调用命名参数的使用</strong></a><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">
            String sqlCall = "{call CreateProductDef(?,?,?,?,?)}";
            CallableStatement cstmt = conn.prepareCall(sqlCall);
            cstmt.setString("productname", name);     // Set Product Name.
            cstmt.setString("productdesc", desc);     // Set Product Description.
            cstmt.setFloat("listprice", listprice);   // Set Product ListPrice.
            cstmt.setFloat("minprice", minprice);     // Set Product MinPrice.
            // Register out parameter which should return the product is created.
            cstmt.registerOutParameter("prod_id", Types.FLOAT);
            // Execute the call.
            cstmt.execute();
            // Get the value of the id from the OUT parameter: prod_id
            float id = cstmt.getFloat("prod_id");
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>如果 CallableStatement 中的参数数量少于存储过程中的参数数量，那么剩下的参数必须有默认值。不需要为有默认值的参数设置值，因为服务器会自动使用默认值。例如，如果一个存储过程有 10 个参数，其中 4 个参数没有默认值，6 个参数有默认值，那么在 CallableStatement 中必须至少有 4 个问号。也可以使用 5 个、6 个或至多 10 个问号。在下面这个惟一的存储过程中，参数 <code>listprice</code> 和 <code>minprice</code> 有默认值：</p>
<br />
<a name="listing9"><strong>清单 9. 创建包括具有默认值的参数的过程</strong></a><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">
            create procedure createProductDef(productname   varchar(64),
            productdesc  varchar(64),
            listprice    float default 100.00,
            minprice     float default  90.00,
            out prod_id      float);
            . . .
            let prod_id = value for prod_id;
            end procedure;</pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>清单 10 中的 Java 代码使用少于存储过程中参数数量的参数（存储过程中有 5 个参数，而代码中只使用 4 个参数）调用存储过程。由于 <code>listprice</code> 有一个默认值，因此可以在 CallableStatement 中省略它。</p>
<br />
<a name="listing10"><strong>清单 10. 默认参数的使用</strong></a><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">
            String sqlCall = "{call CreateProductDef(?,?,?,?)}";
            // 4 params for 5 args
            CallableStatement cstmt = conn.prepareCall(sqlCall);
            cstmt.setString("productname", name);   // Set Product Name.
            cstmt.setString("productdesc", desc);   // Set Product Description.
            cstmt.setFloat("minprice", minprice);   // Set Product MinPrice.
            // Register out parameter which should return the product id created.
            cstmt.registerOutParameter("prod_id", Types.FLOAT);
            // Execute the call.
            cstmt.execute();
            // Get the value of the id from the OUT parameter: prod_id
            float id = cstmt.getFloat("prod_id");
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>如果可调用语句包含 <code>OUT</code> 或 <code>INOUT</code> 参数，那么需要使用 CallableStatement 的 <code>registerOutParameter</code> 注册这些参数。清单 11 使用 <code>out</code> 参数 <code>prod_id</code> 创建一个具有 <code>OUT</code> 参数的存储过程。类似地，可以使用关键字 <code>INOUT</code> 创建 <code>INOUT</code> 参数。</p>
<br />
<a name="listing11"><strong>清单 11. INOUT 和 OUT 参数的使用</strong></a><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">
            create procedure createProductDef(productname   varchar(64),
            productdesc  varchar(64),
            inout    listprice    float default 100.00,
            minprice     float default  90.00,
            out prod_id      float);     </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>清单 12 使用 CallableStatements <code>registerOutparameter</code> 方法注册 CallableStatement 的 <code>out</code> 参数。 </p>
<br />
<a name="listing12"><strong>清单 12. 使用 CallableStatement 注册 OUT 参数</strong></a><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">
            cstmt.registerOutParameter("prod_id", Types.FLOAT);
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>清单 13 将使用命名参数特性的所有语句合并在一起：</p>
<br />
<a name="listing13"><strong>清单 13. 演示命名参数功能的程序</strong></a><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">
            package Callable;
            import java.sql.CallableStatement;
            import java.sql.Connection;
            import java.sql.DriverManager;
            import java.sql.ResultSet;
            import java.sql.SQLException;
            import java.sql.Statement;
            import java.sql.Types;
            public class out1 {
            static Connection conn;
            public static void main(String[] args) {
            getConnect();
            System.out.println("Connection Established");
            createProc();
            runthis();
            System.out.println("\n=============Finished=============");
            System.exit(0);
            }
            private static void getConnect() {
            try
            {
            Class.forName("com.informix.jdbc.IfxDriver");
            String url = "jdbc:informix-sqli://host name or ip :porn number/database
            name:informixserver=dbservername;";
            System.out.println("URL: "+url);
            conn = DriverManager.getConnection(url);
            }
            catch( Exception e )
            {
            e.printStackTrace();
            System.exit(1);
            }
            }
            private static void createProc() {
            String str=null;
            Statement stmt = null;
            try
            {
            stmt = conn.createStatement();
            }
            catch (SQLException e2)
            {
            e2.printStackTrace();
            }
            str="drop function c_out_proc";
            try
            {
            stmt.executeUpdate (str);
            }
            catch (SQLException e1)
            {	}
            str = "create function  c_out_proc ( i int, OUT d varchar(20) ) \n" +
            "returning float; \n" +
            "define f float; \n" +
            "let d= \"Hello OUT\"; \n" +
            "let f=i*2; \n" +
            "return f; \n" +
            "end function; \n";
            try
            {
            stmt.executeUpdate (str);
            System.out.println("Function created \n");
            }
            catch (SQLException e)
            {
            System.out.println("Error on creating function: " + e.toString());
            System.exit(1);
            }
            }
            private static void runthis()
            {
            CallableStatement cstmt = null;
            String command = "{? = call c_out_proc(?, ?)}  ";
            try
            {
            cstmt = conn.prepareCall (command);
            cstmt.setInt(1, 2);
            cstmt.registerOutParameter(2, Types.VARCHAR);
            ResultSet rs = cstmt.executeQuery();
            if (rs == null)
            {
            System.out.println("rs is null *** this is BAD.");
            System.exit(0);
            }
            else
            {
            rs.next();
            System.out.println(rs.getFloat(1));
            System.out.println(cstmt.getString(2));
            }
            }
            catch (SQLException e)
            {
            e.printStackTrace();
            }
            }
            }</pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<br />
<img src ="http://www.blogjava.net/19851985lili/aggbug/203809.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/19851985lili/" target="_blank">☜♥☞MengChuChen</a> 2008-05-29 13:45 <a href="http://www.blogjava.net/19851985lili/articles/203809.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>各类Http请求状态(status)及其含义</title><link>http://www.blogjava.net/19851985lili/articles/203791.html</link><dc:creator>☜♥☞MengChuChen</dc:creator><author>☜♥☞MengChuChen</author><pubDate>Thu, 29 May 2008 04:41:00 GMT</pubDate><guid>http://www.blogjava.net/19851985lili/articles/203791.html</guid><wfw:comment>http://www.blogjava.net/19851985lili/comments/203791.html</wfw:comment><comments>http://www.blogjava.net/19851985lili/articles/203791.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/19851985lili/comments/commentRss/203791.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/19851985lili/services/trackbacks/203791.html</trackback:ping><description><![CDATA[<p>AJAX中请求远端文件、或在检测远端文件是否掉链时，都需要了解到远端服务器反馈的状态以确定文件的存在与否。<br />
<br />
当然，在我们平常浏览网页时，也会发现一些文件不存在时显示为&#8220;404错误&#8221;，这就是常见的Http请求状态（status）<br />
<br />
文章来自：<a class="blog_content" href="http://www.linuxmine.com/48146.html" target="_blank"><a class="blog_content" href="http://www.linuxmine.com/48146.html" target="_blank">http://www.linuxmine.com/48146.html</a> </a>和<a class="blog_content" href="http://www.51windows.net/data/?url=/data/files/file_266.asp" target="_blank"><a class="blog_content" href="http://www.51windows.net/data/?url=/data/files/file_266.asp" target="_blank">http://www.51windows.net/data/?url=/data/files/file_266.asp</a> </a><br />
<br />
Web服务器响应浏览器或<a href="http://www.phpchina.com/12834/javascrīpt:;" target="_self" nclick="javascrīpt:tagshow(event, '%C6%E4%CB%FB');"  ō><u><strong>其他</strong></u></a>客户程序的请求时，其应答一般由以下几个部分组成：一个状态行，几个应答头，一个空行，内容文档。下面是一个最简单的应答：<br />
<br />
状态行包含HTTP版本、状态<a href="http://www.phpchina.com/12834/javascrīpt:;" target="_self" nclick="javascrīpt:tagshow(event, '%B4%FA%C2%EB');"  ō><u><strong>代码</strong></u></a>、与状态代码对应的简短说明信息。在大多数情况下，除了Content-Type之外的所有应答头都是可选的。但Content-Type是必需的，它描述的是后面文档的MIME类型。虽然大多数应答都包含一个文档，但也有一些不包含，例如对HEAD请求的应答永远不会附带文档。有许多状态代码实际上用来标识一次失败的请求，这些应答也不包含文档（或只包含一个简短的错误信息说明）。 <br />
<br />
当用户试图通过 HTTP 访问一台正在运行 <a href="http://www.phpchina.com/12834/javascrīpt:;" target="_self" nclick="javascrīpt:tagshow(event, 'Internet');"  ō><u><strong>Internet</strong></u></a> 信息服务 (IIS) 的服务器上的内容时，IIS 返回一个表示该请求的状态的数字代码。状态代码可以指明具体请求是否已成功，还可以揭示请求失败的确切原因。<br />
<br />
<strong>1xx - 信息提示</strong><br />
<br />
这些状态代码表示临时的响应。客户端在收到常规响应之前，应准备接收一个或多个 1xx 响应。 <br />
&#183; 100 - Continue 初始的请求已经接受，客户应当继续发送请求的其余部分。（HTTP 1.1新） <br />
&#183; 101 - Switching Protocols 服务器将遵从客户的请求转换到另外一种协议（HTTP 1.1新） <br />
<br />
<strong>2xx - 成功</strong><br />
<br />
这类状态代码表明服务器成功地接受了客户端请求。<br />
&#183; 200 - OK 一切正常，对GET和POST请求的应答文档跟在后面。 <br />
&#183; 201 - Created 服务器已经创建了文档，Location头给出了它的URL。 <br />
&#183; 202 - Accepted 已经接受请求，但处理尚未完成。 <br />
&#183; 203 - Non-Authoritative Information 文档已经正常地返回，但一些应答头可能不正确，因为使用的是文档的拷贝，非权威性信息（HTTP 1.1新）。<br />
&#183; 204 - No Content 没有新文档，浏览器应该继续显示原来的文档。如果用户定期地刷新页面，而Servlet可以确定用户文档足够新，这个状态代码是很有用的。 <br />
&#183; 205 - Reset Content 没有新的内容，但浏览器应该重置它所显示的内容。用来强制浏览器清除表单输入内容（HTTP 1.1新）。 <br />
&#183; 206 - Partial Content 客户发送了一个带有Range头的GET请求，服务器完成了它（HTTP 1.1新）。 <br />
<br />
<strong>3xx - 重定向</strong><br />
<br />
客户端浏览器必须采取更多操作来实现请求。例如，浏览器可能不得不请求服务器上的不同的页面，或通过代理服务器重复该请求。<br />
&#183; 300 - Multiple Choices 客户请求的文档可以在多个位置找到，这些位置已经在返回的文档内列出。如果服务器要提出优先选择，则应该在Location应答头指明。 <br />
&#183; 301 - Moved Permanently 客户请求的文档在其他地方，新的URL在Location头中给出，浏览器应该自动地访问新的URL。 <br />
&#183; 302 - Found 类似于301，但新的URL应该被视为临时性的替代，而不是永久性的。注意，在HTTP1.0中对应的状态信息是&#8220;Moved Temporatily&#8221;。出现该状态代码时，浏览器能够自动访问新的URL，因此它是一个很有用的状态代码。注意这个状态代码有时候可以和301替换使用。例如，如果浏览器错误地请求 <a class="blog_content" href="http://host/~user" target="_blank"><a class="blog_content" href="http://host/~user" target="_blank">http://host/~user</a> </a>（缺少了后面的斜杠），有的服务器返回301，有的则返回302。严格地说，我们只能假定只有当原来的请求是GET时浏览器才会自动重定向。请参见307。 <br />
&#183; 303 - See Other 类似于301/302，不同之处在于，如果原来的请求是POST，Location头指定的重定向目标文档应该通过GET提取（HTTP 1.1新）。 <br />
&#183; 304 - Not Modified 客户端有缓冲的文档并发出了一个条件性的请求（一般是提供If-Modified-Since头表示客户只想比指定日期更新的文档）。服务器告诉客户，原来缓冲的文档还可以继续使用。<br />
&#183; 305 - Use Proxy 客户请求的文档应该通过Location头所指明的代理服务器提取（HTTP 1.1新）。 <br />
&#183; 307 - Temporary Redirect 和302（Found）相同。许多浏览器会错误地响应302应答进行重定向，即使原来的请求是POST，即使它实际上只能在POST请求的应答是303时才能重定向。由于这个原因，HTTP 1.1新增了307，以便更加清除地区分几个状态代码：当出现303应答时，浏览器可以跟随重定向的GET和POST请求；如果是307应答，则浏览器只能跟随对GET请求的重定向。（HTTP 1.1新） <br />
<br />
<strong>4xx - 客户端错误</strong><br />
<br />
发生错误，客户端似乎有问题。例如，客户端请求不存在的页面，客户端未提供有效的身份验证信息。<br />
<br />
&#183; 400 - Bad Request 请求出现语法错误。 <br />
<br />
&#183; 401 - Unauthorized 访问被拒绝，客户试图未经授权访问受密码保护的页面。应答中会包含一个WWW-Authenticate头，浏览器据此显示用户名字/密码对话框，然后在填写合适的Authorization头后再次发出请求。IIS 定义了许多不同的 401 错误，它们指明更为具体的错误原因。这些具体的错误代码在浏览器中显示，但不在 IIS <a href="http://www.phpchina.com/12834/javascrīpt:;" target="_self" nclick="javascrīpt:tagshow(event, '%C8%D5%D6%BE');"  ō><u><strong>日志</strong></u></a>中显示：<br />
　&#183; 401.1 - 登录失败。<br />
　&#183; 401.2 - 服务器配置导致登录失败。<br />
　&#183; 401.3 - 由于 ACL 对资源的限制而未获得授权。<br />
　&#183; 401.4 - 筛选器授权失败。<br />
　&#183; 401.5 - ISAPI/CGI 应用程序授权失败。<br />
　&#183; 401.7 &#8211; 访问被 Web 服务器上的 URL 授权策略拒绝。这个错误代码为 IIS 6.0 所专用。<br />
<br />
&#183; 403 - Forbidden 资源不可用。服务器理解客户的请求，但拒绝处理它。通常由于服务器上文件或目录的权限设置导致。禁止访问：IIS 定义了许多不同的 403 错误，它们指明更为具体的错误原因：<br />
　&#183; 403.1 - 执行访问被禁止。<br />
　&#183; 403.2 - 读访问被禁止。<br />
　&#183; 403.3 - 写访问被禁止。<br />
　&#183; 403.4 - 要求 SSL。<br />
　&#183; 403.5 - 要求 SSL 128。<br />
　&#183; 403.6 - IP 地址被拒绝。<br />
　&#183; 403.7 - 要求客户端证书。<br />
　&#183; 403.8 - 站点访问被拒绝。<br />
　&#183; 403.9 - 用户数过多。<br />
　&#183; 403.10 - 配置无效。<br />
　&#183; 403.11 - 密码更改。<br />
　&#183; 403.12 - 拒绝访问映射表。<br />
　&#183; 403.13 - 客户端证书被吊销。<br />
　&#183; 403.14 - 拒绝目录列表。<br />
　&#183; 403.15 - 超出客户端访问许可。<br />
　&#183; 403.16 - 客户端证书不受信任或无效。<br />
　&#183; 403.17 - 客户端证书已过期或尚未生效。<br />
　&#183; 403.18 - 在当前的应用程序池中不能执行所请求的 URL。这个错误代码为 IIS 6.0 所专用。<br />
　&#183; 403.19 - 不能为这个应用程序池中的客户端执行 CGI。这个错误代码为 IIS 6.0 所专用。<br />
　&#183; 403.20 - Passport 登录失败。这个错误代码为 IIS 6.0 所专用。<br />
<br />
&#183; 404 - Not Found 无法找到指定位置的资源。这也是一个常用的应答。 <br />
　&#183; 404.0 -（无） &#8211; 没有找到文件或目录。<br />
　&#183; 404.1 - 无法在所请求的端口上访问 Web 站点。<br />
　&#183; 404.2 - Web 服务扩展锁定策略阻止本请求。<br />
　&#183; 404.3 - MIME 映射策略阻止本请求。<br />
<br />
&#183; 405 - Method Not Allowed 请求<a href="http://www.phpchina.com/12834/javascrīpt:;" target="_self" nclick="javascrīpt:tagshow(event, '%B7%BD%B7%A8');"  ō><u><strong>方法</strong></u></a>（GET、POST、HEAD、DELETE、PUT、TRACE等）对指定的资源不适用，用来访问本页面的 HTTP 谓词不被允许（方法不被允许）（HTTP 1.1新） <br />
&#183; 406 - Not Acceptable 指定的资源已经找到，但它的MIME类型和客户在Accpet头中所指定的不兼容，客户端浏览器不接受所请求页面的 MIME 类型（HTTP 1.1新）。 <br />
&#183; 407 - Proxy Authentication Required 要求进行代理身份验证，类似于401，表示客户必须先经过代理服务器的授权。（HTTP 1.1新） <br />
&#183; 408 - Request Timeout 在服务器许可的等待时间内，客户一直没有发出任何请求。客户可以在以后重复同一请求。（HTTP 1.1新）<br />
&#183; 409 - Conflict 通常和PUT请求有关。由于请求和资源的当前状态相冲突，因此请求不能成功。（HTTP 1.1新） <br />
&#183; 410 - Gone 所请求的文档已经不再可用，而且服务器不知道应该重定向到哪一个地址。它和404的不同在于，返回407表示文档永久地离开了指定的位置，而404表示由于未知的原因文档不可用。（HTTP 1.1新） <br />
&#183; 411 - Length Required 服务器不能处理请求，除非客户发送一个Content-Length头。（HTTP 1.1新） <br />
&#183; 412 - Precondition Failed 请求头中指定的一些前提条件失败（HTTP 1.1新）。<br />
&#183; 413 &#8211; Request Entity Too Large 目标文档的大小超过服务器当前愿意处理的大小。如果服务器认为自己能够稍后再处理该请求，则应该提供一个Retry-After头（HTTP 1.1新）。 <br />
&#183; 414 - Request URI Too Long URI太长（HTTP 1.1新）。 <br />
&#183; 415 &#8211; 不支持的媒体类型。<br />
&#183; 416 &#8211; Requested Range Not Satisfiable 服务器不能满足客户在请求中指定的Range头。（HTTP 1.1新） <br />
&#183; 417 &#8211; 执行失败。<br />
&#183; 423 &#8211; 锁定的错误。<br />
<br />
<strong>5xx - 服务器错误</strong><br />
<br />
服务器由于遇到错误而不能完成该请求。<br />
<br />
&#183; 500 - Internal Server Error 服务器遇到了意料不到的情况，不能完成客户的请求。 <br />
<br />
　&#183; 500.12 - 应用程序正忙于在 Web 服务器上重新启动。<br />
　&#183; 500.13 - Web 服务器太忙。<br />
　&#183; 500.15 - 不允许直接请求 Global.asa。<br />
　&#183; 500.16 &#8211; UNC 授权凭据不正确。这个错误代码为 IIS 6.0 所专用。<br />
　&#183; 500.18 &#8211; URL 授权存储不能打开。这个错误代码为 IIS 6.0 所专用。<br />
　&#183; 500.100 - 内部 ASP 错误。<br />
<br />
&#183; 501 - Not Implemented 服务器不支持实现请求所需要的功能，页眉值指定了未实现的配置。例如，客户发出了一个服务器不支持的PUT请求。<br />
<br />
&#183; 502 - Bad Gateway 服务器作为网关或者代理时，为了完成请求访问下一个服务器，但该服务器返回了非法的应答。 亦说Web 服务器用作网关或代理服务器时收到了无效响应。<br />
<br />
　&#183; 502.1 - CGI 应用程序超时。<br />
　&#183; 502.2 - CGI 应用程序出错。<br />
<br />
&#183; 503 - Service Unavailable 服务不可用，服务器由于维护或者负载过重未能应答。例如，Servlet可能在数据库连接池已满的情况下返回503。服务器返回503时可以提供一个Retry-After头。这个错误代码为 IIS 6.0 所专用。<br />
<br />
&#183; 504 - Gateway Timeout 网关超时，由作为代理或网关的服务器使用，表示不能及时地从远程服务器获得应答。（HTTP 1.1新） 。<br />
<br />
&#183; 505 - HTTP Version Not Supported 服务器不支持请求中所指明的HTTP版本。（HTTP 1.1新）。<br />
<br />
===================================<br />
<br />
以下是CSDN的JnKc写的&#8220;利用XMLHTTP检测网址及探测服务器类型&#8221;<br />
</p>
<p>&nbsp;</p>
<p>&lt;html&gt;&nbsp; <br />
&nbsp;&lt;head&gt;&nbsp; <br />
&nbsp;&lt;title&gt;利用XMLHTTP检测网址及探测服务器类型&lt;/title&gt;&nbsp; <br />
&nbsp;&lt;META http-equiv=Content-Type content="text/html; charset=gb2312"&gt;&nbsp; <br />
&nbsp;&lt;meta name="Generator" content="EditPlus"&gt;&nbsp; <br />
&nbsp;&lt;meta name="Author" content="JnKc"&gt;<br />
&nbsp;&lt;meta name="Keywords" content=""&gt;<br />
&nbsp;&lt;/head&gt;&nbsp; <br />
&nbsp;&lt;body&gt;&nbsp; <br />
&nbsp;&lt;input type="text" id="jnkcInput" value="<a href="http://www.cnbruce.com/">http://www.cnbruce.com</a>" size="50"&gt;&lt;button id="chk"&gt;检测&lt;/button&gt;&nbsp; <br />
&nbsp;&lt;div id="jnkc_show"&gt;&lt;/div&gt;&nbsp; <br />
&nbsp;&lt;scrīpt LANGUAGE="VBscrīpt"&gt;&nbsp; <br />
&nbsp;Dim i,jnkcUrl,jnkcHTML,jnkcStatus,jnkcServer&nbsp; <br />
&nbsp;Function chk_onClick()&nbsp; <br />
&nbsp;jnkcUrl = jnkcInput.value&nbsp; <br />
&nbsp;Call GetDetail&nbsp; <br />
&nbsp;i = i+1&nbsp; <br />
&nbsp;jnkc_show.innerHTML = "&lt;hr&gt;&lt;pre&gt;&lt;font color=red&gt;" &amp; i &amp; "、" &amp; jnkcUrl &amp; "&lt;/font&gt;&lt;br&gt;" &amp; jnkcStatus &amp; "&lt;/pre&gt;" &amp; jnkc_show.innerHTML&nbsp; <br />
&nbsp;End Function&nbsp; <br />
&nbsp;Dim jnkcXMLHTTP&nbsp; <br />
&nbsp;Sub GetDetail&nbsp; <br />
&nbsp;&nbsp;&nbsp; Set jnkcXMLHTTP = CreateObject("Msxml2.XMLHTTP")&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jnkcXMLHTTP.OnReadyStateChange = GetRef("GetStatus")&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jnkcXMLHTTP.Open "GET", jnkcUrl, False&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; On Error Resume Next&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jnkcXMLHTTP.Send&nbsp; <br />
&nbsp;&nbsp;&nbsp; Set jnkcXMLHTTP = Nothing&nbsp; <br />
&nbsp;End Sub&nbsp; <br />
&nbsp;Sub GetStatus&nbsp; <br />
&nbsp;&nbsp;&nbsp; If jnkcXMLHTTP.ReadyState &lt;&gt; 4 Then<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Exit Sub&nbsp; <br />
&nbsp;&nbsp;&nbsp; End If&nbsp; <br />
&nbsp;&nbsp;&nbsp; If jnkcXMLHTTP.Status = 404 Then<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jnkcStatus = "该网页不存在！"&nbsp; <br />
&nbsp;&nbsp;&nbsp; ElseIf jnkcXMLHTTP.Status &lt; 200 Then<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jnkcStatus = "客户端错误，信息：" &amp; CStr(jnkcXMLHTTP.Status) &amp; " " &amp; jnkcXMLHTTP.StatusText&nbsp; <br />
&nbsp;&nbsp;&nbsp; ElseIf jnkcXMLHTTP.Status &lt; 300 Then&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jnkcStatus = "成功，该网页能访问。"&nbsp; <br />
&nbsp;&nbsp;&nbsp; ElseIf jnkcXMLHTTP.Status &lt; 400 Then<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jnkcStatus = "重定向，信息：" &amp; CStr(jnkcXMLHTTP.Status) &amp; " " &amp; jnkcXMLHTTP.StatusText&nbsp; <br />
&nbsp;&nbsp;&nbsp; ElseIf jnkcXMLHTTP.Status &lt; 500 Then<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jnkcStatus = "客户端错误，信息：" &amp; CStr(jnkcXMLHTTP.Status) &amp; " " &amp; jnkcXMLHTTP.StatusText&nbsp; <br />
&nbsp;&nbsp;&nbsp; ElseIf jnkcXMLHTTP.Status &lt; 600 Then<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jnkcStatus = "服务器错误，信息：" &amp; CStr(jnkcXMLHTTP.Status) &amp; " " &amp; jnkcXMLHTTP.StatusText&nbsp; <br />
&nbsp;&nbsp;&nbsp; Else&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jnkcStatus = "域名不可用或网络连接错误，信息：" &amp; CStr(jnkcXMLHTTP.Status) &amp; " " &amp; jnkcXMLHTTP.StatusText&nbsp; <br />
&nbsp;&nbsp;&nbsp; End If&nbsp; <br />
&nbsp;&nbsp;&nbsp; If jnkcXMLHTTP.Status &lt; 600 Then Call GetServer&nbsp; <br />
&nbsp;End Sub <br />
&nbsp;<br />
&nbsp;Sub GetServer<br />
&nbsp;&nbsp;&nbsp; jnkcServer = jnkcXMLHTTP.GetResponseHeader("Server")&nbsp; <br />
&nbsp;&nbsp;&nbsp; If jnkcServer &lt;&gt; "" Then&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jnkcStatus = jnkcStatus &amp; "&lt;br&gt;HTTP服务器：" &amp; jnkcServer&nbsp; <br />
&nbsp;&nbsp;&nbsp; End If&nbsp; <br />
&nbsp;&nbsp;&nbsp; jnkcStatus = "&lt;b&gt;" &amp; jnkcStatus &amp; "&lt;/b&gt;&lt;br&gt;所有反馈信息：&lt;br&gt;"&amp; jnkcXMLHTTP.GetAllResponseHeaders&nbsp; <br />
&nbsp;End Sub&nbsp; <br />
&nbsp;&lt;/scrīpt&gt;&nbsp; <br />
&nbsp;&lt;/body&gt;&nbsp; <br />
&nbsp;&lt;/html&gt;&nbsp; <br />
</p>
<img src ="http://www.blogjava.net/19851985lili/aggbug/203791.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/19851985lili/" target="_blank">☜♥☞MengChuChen</a> 2008-05-29 12:41 <a href="http://www.blogjava.net/19851985lili/articles/203791.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JSP几种跳转方式 </title><link>http://www.blogjava.net/19851985lili/articles/203780.html</link><dc:creator>☜♥☞MengChuChen</dc:creator><author>☜♥☞MengChuChen</author><pubDate>Thu, 29 May 2008 04:02:00 GMT</pubDate><guid>http://www.blogjava.net/19851985lili/articles/203780.html</guid><wfw:comment>http://www.blogjava.net/19851985lili/comments/203780.html</wfw:comment><comments>http://www.blogjava.net/19851985lili/articles/203780.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/19851985lili/comments/commentRss/203780.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/19851985lili/services/trackbacks/203780.html</trackback:ping><description><![CDATA[<p>1.RequestDispatcher.forward()</p>
<p>　　 是在服务器端起作用,当使用forward()时,Servlet engine传递HTTP请求从当前的Servlet or JSP到另外一个Servlet,JSP 或普通HTML文件,也即你的form提交至a.jsp,在a.jsp用到了forward()重定向至b.jsp,此时form提交的所有信息在 b.jsp都可以获得,参数自动传递.</p>
<p>　　但forward()无法重定向至有frame的jsp文件,可以重定向至有frame的html文件,同时forward()无法在后面带参数传递,比如servlet?name=frank,这样不行,可以程序内通过response.setAttribute("name",name)来传至下一个页面.</p>
<p>　　重定向后浏览器地址栏URL不变.</p>
<p>　　例:在servlet中进行重定向<br />
<br />
public void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException<br />
{<br />
　 response.setContentType("text/html; charset=gb2312");<br />
　 ServletContext sc = getServletContext();<br />
　 RequestDispatcher rd = null;<br />
　 rd = sc.getRequestDispatcher("/index.jsp"); //定向的页面<br />
　 rd.forward(request, response);<br />
}</p>
<p>　　通常在servlet中使用，不在jsp中使用。</p>
<p>　　 2.response.sendRedirect()</p>
<p>　　是在用户的浏览器端工作,sendRedirect()可以带参数传递,比如servlet?name=frank传至下个页面,同时它可以重定向至不同的主机上,sendRedirect()可以重定向有frame.的jsp文件.</p>
<p>　　重定向后在浏览器地址栏上会出现重定向页面的URL</p>
<p>　　例:在servlet中重定向</p>
<p>public void doPost(HttpServletRequest request,HttpServletResponse response)<br />
throws ServletException,IOException<br />
{<br />
　 response.setContentType("text/html; charset=gb2312");<br />
　 response.sendRedirect("/index.jsp");<br />
}</p>
<p>　　由于response是jsp页面中的隐含对象，故在jsp页面中可以用response.sendRedirect()直接实现重定位。</p>
<p>　　注意：</p>
<p>　　 (1) 使用response.sendRedirect时，前面不能有HTML输出</p>
<p>　　这并不是绝对的，不能有HTML输出其实是指不能有HTML被送到了浏览器。事实上现在的server都有cache机制，一般在8K（我是说 JSP　SERVER），这就意味着，除非你关闭了cache，或者你使用了out.flush()强制刷新，那么在使用sendRedirect之前，有少量的HTML输出也是允许的。</p>
<p>　　 (2) response.sendRedirect之后，应该紧跟一句return;</p>
<p>　　我们已经知道response.sendRedirect是通过浏览器来做转向的，所以只有在页面处理完成后，才会有实际的动作。既然你已经要做转向了，那么后的输出还有什么意义呢？而且有可能会因为后面的输出导致转向失败。</p>
<p>　　比较：</p>
<p>　　 (1) Dispatcher.forward()是容器中控制权的转向，在客户端浏览器地址栏中不会显示出转向后的地址；</p>
<p>　　 (2) response.sendRedirect()则是完全的跳转，浏览器将会得到跳转的地址，并重新发送请求链接。这样，从浏览器的地址栏中可以看到跳转后的链接地址。</p>
<p>　　前者更加高效，在前者可以满足需要时，尽量使用RequestDispatcher.forward()方法.</p>
<p>　　注：在有些情况下，比如，需要跳转到一个其它服务器上的资源，则必须使用HttpServletResponse.sendRequest()方法。</p>
<p>　　 3.&lt;jsp:forward page="" /&gt;</p>
<p>　　它的底层部分是由RequestDispatcher来实现的，因此它带有RequestDispatcher.forward()方法的印记。</p>
<p>　　如果在&lt;jsp:forward&gt;之前有很多输出,前面的输出已使缓冲区满,将自动输出到客户端,那么该语句将不起作用,这一点应该特别注意。</p>
<p>　　另外要注意：它不能改变浏览器地址，刷新的话会导致重复提交</p>
<p>　　 4.修改HTTP header的Location属性来重定向</p>
<p>　　通过设置直接修改地址栏来实现页面的重定向。</p>
<p>　　 jsp文件代码如下：</p>
<p>&lt;%<br />
response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);<br />
String newLocn = "/newpath/jsa.jsp";<br />
response.setHeader("Location",newLocn);<br />
%&gt;</p>
<p>　　 5.JSP中实现在某页面停留若干秒后,自动重定向到另一页面</p>
<p>　　在html文件中，下面的代码：</p>
<p>&lt;meta http-equiv="refresh" content="300; url=target.jsp"&gt;</p>
<p>　　它的含义：在5分钟之后正在浏览的页面将会自动变为target.html这一页。代码中300为刷新的延迟时间，以秒为单位。targer.html为你想转向的目标页,若为本页则为自动刷新本页。</p>
<p>　　由上可知，可以通过setHeader来实现某页面停留若干秒后,自动重定向到另一页面。</p>
<p>　　关键代码：</p>
<p>String content=stayTime+";URL="+URL;<br />
response.setHeader("REFRESH",content);</p>
<img src ="http://www.blogjava.net/19851985lili/aggbug/203780.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/19851985lili/" target="_blank">☜♥☞MengChuChen</a> 2008-05-29 12:02 <a href="http://www.blogjava.net/19851985lili/articles/203780.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JDBC3.0的特性</title><link>http://www.blogjava.net/19851985lili/articles/203779.html</link><dc:creator>☜♥☞MengChuChen</dc:creator><author>☜♥☞MengChuChen</author><pubDate>Thu, 29 May 2008 03:59:00 GMT</pubDate><guid>http://www.blogjava.net/19851985lili/articles/203779.html</guid><wfw:comment>http://www.blogjava.net/19851985lili/comments/203779.html</wfw:comment><comments>http://www.blogjava.net/19851985lili/articles/203779.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/19851985lili/comments/commentRss/203779.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/19851985lili/services/trackbacks/203779.html</trackback:ping><description><![CDATA[<p><strong>1、JDBC3.0规范中数据库连接池框架<br />
</strong>　　JDBC3.0规范中通过提供了一个支持数据库连接池的框架，这个框架仅仅规定了如何支持连接池的实现，而连接池的具体实现JDBC 3.0规范并没有做相关的规定。通过这个框架可以让不同角色的开发人员共同实现数据库连接池。</p>
<p>　　通过JDBC3.0规范可以知道具体数据库连接池的实现可以分为JDBC Driver级和Application Server级。在JDBC Driver级的实现中任何相关的工作均由特定数据库厂商的JDBC Drvier的开发人员来具体实现，即JDBC Driver既需要提供对数据库连接池的支持同时也必须对数据库连接池进行具体实现。而在Application Server级中数据库连接池的实现中特定数据库厂商的JDBC Driver开发人员和Application Server开发人员来共同实现数据库连接池的实现（但是现在大多数Application Server厂商实现的连接池的机制和规范中提到有差异），其中特定数据库厂商的JDBC Driver提供数据库连接池的支持而特定的Application Server厂商提供数据库连接池的具体实现。</p>
<p>　　JDBC3.0规范规定了如下的类和接口来支持数据库连接池的实现。</p>
<pre class="code">javax.sql.ConnectionEvent
javax.sql.ConnectionPoolDataSource
javax.sql.PooledConnection
javax.sql.ConnectionEventListener
</pre>
<p>　　其中除javax.sql.ConnectionEvent是类，其它的均为接口。</p>
<p align="center">　　<img height="398" src="http://dev2dev.bea.com.cn/images/image060112002.jpg" width="319"  alt="" /></p>
<p align="center"><strong>JDBC3.0连接池框架的关系图</strong></p>
<p>　　通过此图可以大概的了解相关接口在一个典型的三层环境中应用程序的位置。</p>
<p><strong>2、检索自动产生的关键字<br />
</strong>　　为了解决对获取自动产生的或自动增加的关键字的值的需求，JDBC 3.0 API 现在将获取这种值变得很轻松。要确定任何所产生的关键字的值，只要简单地在语句的 execute() 方法中指定一个可选的标记，表示您有兴趣获取产生的值。您感兴趣的程度可以是 Statement.RETURN_GENERATED_KEYS，也可以是 Statement.NO_GENERATED_KEYS。在执行这条语句后，所产生的关键字的值就会通过从 Statement 的实例方法 getGeneratedKeys() 来检索 ResultSet 而获得，ResultSet 包含了每个所产生的关键字的列，下面的示例创建一个新的作者并返回对应的自动产生的关键字。</p>
<pre class="code">&#8230;&#8230;
Statement stmt = conn.createStatement();
// Obtain the generated key that results from the query.
stmt.executeUpdate("INSERT INTO authors " +
"(first_name, last_name) " +
"VALUES (&#8216;Ghq&#8217;, &#8216;Wxl&#8217;)",
Statement.RETURN_GENERATED_KEYS);
ResultSet rs = stmt.getGeneratedKeys();
if ( rs.next() ) {
// Retrieve the auto generated key(s).
int key = rs.getInt();
}
&#8230;&#8230;
</pre>
<p><strong>3、返回多重结果<br />
</strong>　　JDBC 2 规范的一个局限是，在任意时刻，返回多重结果的语句只能打开一个ResultSet。作为 JDBC 3.0 规范中改变的一个部分，规范将允许 Statement 接口支持多重打开的 ResultSets。然而，重要的是 execute() 方法仍然会关闭任何以前 execute() 调用中打开的 ResultSet。所以，要支持多重打开的结果，Statement 接口就要加上一个重载的 getMoreResults() 方法。新式的方法会做一个整数标记，在 getResultSet() 方法被调用时指定前一次打开的 ResultSet 的行为。接口将按如下所示定义标记：</p>
<p>　　CLOSE_ALL_RESULTS：当调用 getMoreResults() 时，所有以前打开的 ResultSet 对象都将被关闭。</p>
<p>　　CLOSE_CURRENT_RESULT：当调用 getMoreResults() 时，当前的 ResultSet 对象将被关闭。</p>
<p>　　KEEP_CURRENT_RESULT：当调用 getMoreResults() 时，当前的 ResultSet 对象将不会被关闭。</p>
<p>　　下面展示的是一个处理多重打开结果的示例。</p>
<pre class="code">&#8230;&#8230;
String procCall;
// Set the value of procCall to call a stored procedure.
// &#8230;
CallableStatement cstmt = connection.prepareCall(procCall);
int retval = cstmt.execute();
if (retval == false) {
// The statement returned an update count, so handle it.
// &#8230;
} else { // ResultSet
ResultSet rs1 = cstmt.getResultSet();
// &#8230;
retval = cstmt.getMoreResults(Statement.KEEP_CURRENT_RESULT);
if (retval == true) {
ResultSet rs2 = cstmt.getResultSet();
// Both ResultSets are open and ready for use.
rs2.next();
rs1.next();
// &#8230;
}
}
&#8230;&#8230;
</pre>
<strong>4、在事务中使用 Savepoint</strong><br />
　　也许在 JDBC 3.0 中最令人兴奋的附加特点就是 Savepoint 了。JDBC 2 中的事务支持让开发人员可以控制对数据的并发访问，从而保证持续数据总是保持一致的状态。可惜的是，有时候需要的是对事务多一点的控制，而不是在当前的事务中简单地对每一个改变进行回滚。在JDBC 3.0 下，可以通过 Savepoint 获得这种控制。Savepoint 接口允许您将事务分割为各个逻辑断点，以控制有多少事务需要回滚。下图将说明如何在事务中运用 Savepoint。</strong>
<p align="center">　　<img height="198" src="http://dev2dev.bea.com.cn/images/image060112004.jpg" width="513"  alt="" /></p>
<p><strong>Savepoint 的直观表示<br />
</strong>　　你或许不是经常需要使用 Savepoint。然而，在一种普遍的情况下 Savepoint 会发挥作用，那就是您需要作一系列的改变，但是在知道所有的结果之前不能确定应该保留这些改变的哪一部分。下面的代码示例说明了如何使用 Savepoint 接口。</p>
<pre class="code">......
conn.setAutoCommit(false);
// Set a conservative transaction isolation level.
conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
Statement stmt = conn.createStatement();
int rows = stmt.executeUpdate( "INSERT INTO authors " +
" (first_name, last_name) VALUES " +
" ('Ghq', 'Wxl')");
// Set a named savepoint.
Savepoint svpt = conn.setSavepoint("NewAuthor");
// &#8230;
rows = stmt.executeUpdate( "UPDATE authors set type = 'fiction' " +
"WHERE last_name = 'Wxl'");
// &#8230;
conn.rollback(svpt);
// &#8230;
// The author has been added, but not updated.
conn.commit();
......
</pre>
<p><strong>5、其他的特性<br />
</strong>　　<strong>1）元数据 API<br />
</strong>　　元数据 API 已经得到更新，DatabaseMetaData 接口现在可以检索 SQL 类型的层次结构，一种新的 ParameterMetaData 接口可以描述 PreparedStatement 对象中参数的类型和属性。</p>
<p>　　<strong>2）CallableStatements 中已命名的参数<br />
</strong>　　在 JDBC 3.0 之前，设置一个存储过程中的一个参数要指定它的索引值，而不是它的名称。 CallableStatement 接口已经被更新了，现在您可以用名称来指定参数。</p>
<p>　　<strong>3）数据类型的改变<br />
</strong>　　JDBC 所支持的数据类型作了几个改变，其中之一是增加了两种新的数据类型。</p>
<p>　　为了便于修改 CLOB（Character Large OBject，字符型巨对象）、BLOB（Binary Large OBject，二进制巨对象）和 REF（SQL 结构）类型的值，同名的数据类型接口都被更新了。接下来的是，因为我们现在能够更新这些数据类型的值，所以 ResultSet 接口也被修改了，以支持对这些数据类型的列的更新，也包括对 ARRAY 类型的更新。增加的两种新的数据类型是 java.sql.Types.DATALINK 和 java.sql.Types.BOOLEAN。新增的数据类型指的是同名的 SQL 类型。DATALINK 提供对外部资源的访问或 URL，而 BOOLEAN 类型在逻辑上和 BIT 类型是等同的，只是增加了在语义上的含义。DATALINK 列值是通过使用新的 getURL() 方法从 ResultSet 的一个实例中检索到的，而 BOOLEAN 类型是通过使用 getBoolean() 来检索的。</p>
<p><strong>二进制大对象Blob<br />
</strong>　　Blob对象是SQL Blob的Java语言映射。SQL Blob是一个内置类型，它可以将一个二进制大对象保存在数据库中。接口ResultSet、CallableStatement和PreparedStatement中的方法允许程序员使用与访问SQL 92内置类型同样的方式来访问SQL 99类型BLOB。</p>
<p>　　在标准实现中，JDBC驱动程序在后台使用SQL类型LOCATOR(BLOB)来实现Blob接口。LOCATOR(BLOB)指向保存在数据库服务器上的SQL BLOB值，而且这些操作作用在这个LOCATOR（定位器）上与作用在BLOB值本身有同样的结果。这意味着用户可以在一个Blob实例上执行操作而不必将这个BLOB数据物化到用户上，这将显著的提高性能。因为驱动程序在后台使用LOCATOR(BLOB),所以它的使用对程序员是完全透明的。</p>
<p>　　Blob实例的标准行为一直保持有效，直到这个事务（创建一个Blob的事务）执行了提交或者回滚操作。</p>
<ol>
    <li>创建Blob对象<br />
    　　下面的代码说明了如何创建一个Blob对象，其中stmt是一个Statement对象：
    <pre class="code">Statement stmt = con..createStatement(ResultSet.TYPE_INSENSITIVE,
    ResultSet.CONCUR_READ_ONLY);
    ResultSet rs = stmt.excuteQuery(&#8220;SELECT DATA  FROM  TABLE	1&#8221;);
    If (rs.next()){
    rs.first();
    Blob blob=rs.getBlob(&#8220;DATA&#8221;);
    }
    变量blob包含一个指向BLOB值的逻辑指针，该BLOB值保存在结果集rs的第一行的DATA列中。即使变量blob实际上并不包含BLOB值中的数值，应用程序在blob上执行操作仍然像在实际的数据上执行一样。即应用程序在blob上所作的任何操作都会对表中的BLOB值起作用。</pre>
    <li>物化BLOB数据<br />
    　　开发人员可以在Blob对象上调用JDBC API中的方法，就像这些方法直接<br />
    　　在该对象所指向的SQL BLOB上执行操作一样。然而，如果想在BLOB数据上执行操作，就必须首先将BLOB数据物化到客户。Blob接口提供了两个方法来物化BLOB数据：getBinaryStream，这个方法将BLOB数据物化为一个输入流；getBytes，这个方法将BLOB值得一部分或者全部物化为一个字节数组。下面的代码说明了如何将Blob所指向的BLOB值得全部物化为一个输入流：
    <pre class="code"> java.io.InputStream in = blob.getBinaryStream();
    byte b;
    while((b = in.read()) &gt;-1){
    System.out.println(b);
    }
    </pre>
    接下来的代码同样物化了blob所指向的BLOB值得所有数据，但是它产生的是字节数组而不是输入流。
    <pre class="code"> long len = blob.length();
    byte [] data = blob.getBytes(1,len);
    for(int i=0;i&lt;len;i++){
    byte b = data[i];
    System.out.println(b);
    }
    </pre>
    　　变量data复制了blob所指向的BLOB值的所有字节。这是因为传递给方法getBytes的参数值说明了整个BLOB值：第一个参数表示从第一个字节开始返回字节，第二个参数说明它返回的字节长度是BLOB值的长度。 <br />
    　　需要说明的是，因为SQL和Java语言之间的不同，一个BLOB值得第一个字节在位置1，而Java数组的第一个元素的索引是0。
    <li>存储Blob值<br />
    　　若要在数据库中存储Blob值，应用程序可以把它作为一个参数传递给<br />
    　　PreparedStatement的方法setBlob。下面的代码就实现了这个功能：
    <pre class="code">PreparedStatement的方法setBlob。下面的代码就实现了这个功能：
    Blob stats = rs.getBlob(&#8220;STATS&#8221;);
    PreparedStatement pstmt= con.preparedStatement(
    &#8220;UPDATE SIGHTINGS SET MEAS= ? WHERE  AREA = &#8216;BEIJING&#8217; &#8221;);
    pstmt.setBlob(1,stats);
    pstmt.excuteUpdate();
    </pre>
    <li>发现Blob对象中的模式<br />
    　　如果一个Blob对象包含一个给定的字节集合，应用程序可以使用方法<br />
    　　position的两个方法来找到它。其中一个方法搜索一个给定的字节数组，而另一个在一个Blob对象中搜索一个给定的Blob对象。如果发现一个匹配的结果，则返回该模式字节的起始位置。
    <li>修改Blob对象的方法<br />
    　　JDBC 3.0 API中新增的方法setBytes和setBinaryStream允许应用程序对<br />
    　　Blob对象进行修改。<br />
    　　方法setBytes有两个方法来向Blob对象添加数据。其中一个方法增加给定的字节数组的全部内容，而另一个方法增加给定字节数组的特定部分。两个方法都使用一个参数说明向Blob对象插入数据的起始位置。例如，下面的代码段在一个Blob对象blob1的第一个字节处写入整个字节数组bytes。在这种情况下，bytes包含了Blob对象blob的所有字节，因此执行的结果是blob2被写入了blob1的起始处。需要注意的是如果blob2的长度是1024字节，那么blob2的1024各字节将覆盖blob1的开头的1024各字节。
    <pre class="code">byte [] bytes = blob2.getBytes(1,blob2.length());
    blob.setBytes(1,bytes,0,512);
    </pre>
    　　下面的代码段说明如何仅仅向Blob对象加入一个字节数组的特定部分。在这种情况下，方法setBytes接受两个附加的参数来说明需要增加字节数组的哪一个部分。其中一个参数指明了这个字节数组的起始偏移量，另一个参数说明这个字节数组包含多少个连续的字节。
    <pre class="code">byte [] bytes={&#8230;&#8230;};
    blob.setBytes(1,bytes,0,512);
    </pre>
    　　除了可以向Blob对象增加字节之外，Blob接口还提供了删除字节的方法。方法truncate接受一个字节数目作为一个参数并且根据这个数目来缩短Blob对象。
    <li>定位器和更新<br />
    　　在标准实现中，指向SQL BLOB的Blob对象使用了SQL LOCATOR类型。定位器(locator)是一个指向保存在数据库中的BLOB值的指针，而DBMS如何更新一个作为定位器实现的对象则依赖于具体的数据库。某些DBMS会更新表中的BLOB值，而另一些则仅仅更新BLOB值的一个副本，并不改变数据库中的值。在后一种情况下，应用程序必须直接更新BLOb值。<br />
    　　为了发现DBMS是如何更新BLOB值的，应用程序可以调用DatabaseMetaData的方法locatorsUpdateCopy。如果这个方法返回true，则应用程序必须自己更新数据库中的BLOB值。下面的代码显示了这个过程：首先从rs取回Blob对象，然后把它的值改为字节数据val的值。如果方法locatorsUpdateCopy返回true，那么它随后执行一个PreparedStatement对象来更新数据库中的值。如果方法locatorsUpdateCopy返回false，代码什么也不用做，因为数据库中的值已经被更新过了。
    <pre class="code">byte [] val ={0,1,2,3,4};
    Blob data =rs.getBlob(&#8220;DATA&#8221;);
    int numWritten = data.setBytes(1,val);
    if (dbmd.locatorUpdateCopy() == true){
    PreparedStatement pstmt= con . preparedStatement(
    &#8220;UPDATE statistics SET DATA = ? WHERE REGION = &#8216;BEIJING&#8217; &#8220;);
    pstmt.setBlob(&#8220;DATA&#8221;,data);
    pstmt.executeUpdate();
    }
    </pre>
    </li>
</ol>
<p><strong>字符大对象Clob</strong></p>
<ol>
    <li>创建Blob对象<br />
    　　Clob clob = rs.getClob(1);<br />
    　　变量clob现在可以被用于在CLOB值上执行操作，而假设这CLOB值保存在结果集rs的第一列中。
    <p>&nbsp;</p>
    <li>物化Clob数据<br />
    　　和物化Blob的方式一样。不过Clob接口提供了三种方法达到将CLOB作为一个Java对象的形式保存在客户的内存中。
    <pre class="code">使用getAsiiStream把CLOB值物化为一个包含Ascii字节的字符流。
    ① 使用getAsiiStream把CLOB值物化为一个包含Ascii字节的字符流。
    Clob notes = rs.getClob(&#8220;NOTES&#8221;);
    java.io.InputStream in = notes.getAsciiStream();
    byte b = in.read();
    ② 使用getCharacterStream把CLOB值物化为一个Unicode字符流。
    Clob notes = rs.getClob(&#8220;NOTES&#8221;);
    java.io.Reader reader = notes.getCharacterStream();
    int c = reader.read();
    //
    ③	使用getSubString将CLOB值的全部或者部分化为一个String对象。
    Clob notes = rs.getClob(4);
    String substring= notes.getSubString(10,5);
    或者
    long len =notes.length();
    String substring = notes.getSubString(1,(int)len);</pre>
    <li>存储、更新Clob对象<br />
    　　和存储、更新Blob对象类似。</li>
</ol>
<p><strong>元数据接口使用详解<br />
</strong>　　三个元数据接口DatabaseMetaData、ResultSetMetaData和ParameterMetaData接口是三个常用的元数据接口。DatabaseMetaData提供与数据库或者DBMS相关的信息；ResultSetMetaData对象提供与特定ResultSet实例中与列相关的信息；ParameterMetaData对象提供与PreparedStatement对象的参数有关的信息。本文讨论的内容并不仅限于JDBC的某个版本，而是基于1.0—3.0的规范进行学习。</p>
<ul>
    <li>ResultSetMetaData对象<br />
    　　当在JDBC应用程序中发送select语句时，该操作会返回一个ResultSet对象，这个ResultSet对象包含满足条件的数据。通过创建ResultMetaData对象和调用该对象的方法，可以获取与这个ResultSet对象中的列有关的信息。下面的代码段将创建ResultSet对象rs，然后使用rs来创建ResultSetMetaData对象，所创建的ResultSetMetaData对象包含与rs中的列有关的信息。
    <pre class="code">     Statement stmt= con . createStatement();
    ResultSet rs = stmt.executeQuery(&#8220;select * from sales&#8221;);
    ResultSetMetaData rsmd = rs.getMetaData();
    </pre>
    　　现在可以使用rsmd调用ResultSetMetaData的方法来访问与rs中的列有关的信息。除了方法getColumnCount给出结果集中总的列数外，所有的ResultSetMetaData方法都返回与单个列有关的信息，并都接受一个表示对应列号的参数。
    <ol>
        <li>getColumnCount方法<br />
        　　 这也许是ResultSetMetaData中使用最多的方法，该方法返回结果集中列数目　：
        <pre class="code">ResultSet rs = stmt.executeQuery(&#8220;select * from sales&#8221;);
        ResultSetMetaData rsmd = rs.getMetaData();
        int numberOfColumns = rsmd.getColumnCount();
        while(rs.next()){
        for(int i=1;i&lt;=numberOfColumn;i++){
        String s = rs.getString(i);
        System.out.println(&#8220;Column &#8221; +i +&#8221;:   &#8221; +s +&#8221;  &#8221;);
        }
        }
        </pre>
        　　需要注意的是，用于检索所有列值的ResultSet方法是getString。当不知道每一列的类型，这是比较容易的方法；如果希望能检索所有的数据类型（包括SQL 99数据型），则可以使用方法getObject，这是保证能够检索所有列值得唯一方法。
        <li>获取列类型信息<br />
        　　有两个ResultSetMetaData方法可以获取与结果集列的类型有关的信息。这
        <p>&nbsp;</p>
        两个方法是getColumnType和getColumnTypeName。getColumnType方法用于确定存储在指定列中的值的JDBC类型。该方法以一个int值来返回JDBC类型。如下面的代码获得rs第二列的JDBC类型：
        <pre class="code">    ResultSetMetaData rsmd = rs.getMetaData();
        int jdbcType = rsmd.getColumnType(2);
        </pre>
        <li>获取其他信息<br />
        　　另外有几个方法用来提供与存储数值类型的列有关的信息。
        <pre class="code">isAutoIncrement
        isCurrency
        isSigned
        getPrecision
        getScale
        isNullable
        getColumnDisplaySize</pre>
        </li>
    </ol>
    <ol>
        <li>使用DatabaseMetaData对象<br />
        　　接口DatabaseMetaData提供了大量的方法取得与数据库相关的信息。一旦获得了打开的连接，就可以创建包含与数据库系统有关的信息的DatabaseMetaData对象。
        <li>DatabaseMetaData方法的类别<br />
        　　按照返回值的类型对DatabaseMetaData的方法进行分类，可以分为4种。<br />
        　　有三种类型返回单一的值，另外一种返回一个结果集，这个结果集包含1～18列的数据。 ① 返回String的方法<br />
        　　最小的类别是指返回String对象的DatabaseMetaData方法。这些方法中的一些方法可以获取与DBMS有关的总体信息，包括数据库的URL、username、产品名称、驱动程序信息等等。<br />
        ② 返回int的方法<br />
        ③ 返回boolean的方法<br />
        ④返回ResultSet对象的方法<br />
        　　这些方法可以返回ResultSet对象，所返回的ResultSet对象可以包含1到最多18列。
        <li>获取与主外键有关的信息<br />
        　　返回与主外键有关信息的方法主要有getPrimaryKeys、getImportedKeys、getExportedKeys以及getCrossReference等。<br />
        　　下面的代码段显示了如果在定义表时指定了主键，则可以调用方法getPrimaryKeys开获取对于表中主键列的描述。
        <pre class="code"> import java.sql.*;
        public class static PrimaryKeysExample{
        public static void main(String args[]){
        String url =&#8221;jdbc:mySubprotocol:myDataSource&#8221;;
        Connection con;
        String createString =&#8221;create table supplierspk&#8221;+
        &#8220;(sup_id integer not null,&#8221;+
        &#8220;sup_name varchar(40),&#8221;+
        &#8220;street varchar(40),&#8221;+
        &#8220;city varchar(20)&#8221;+
        &#8220;state char(10),&#8221;+
        &#8220;zip char(10),&#8221;+
        &#8220;primary key(sup_id))&#8221;;
        Statement stmt;
        try{
        Class.forName(&#8220;myDriver.className&#8221;);
        }catch(java.lang.ClassNotFoundException e){
        System.err.println(&#8220;ClassNotFoundException: &#8221;);
        System.err.println(&#8220;e.getMessage()&#8221;);
        }
        try{
        con =DriverManager.getConnection(url,&#8221;username&#8221;,&#8221;pwd&#8221;);
        stmt=con.createStatement;
        stmt.executeUpdate(createString);
        DatabaseMetaData dbmd=con.getMetaData();
        ResultSet rs= dbmd.getPrimaryKey(null,null,&#8221;suplierspk&#8221;);
        While(rs.next()){
        String name =rs.getString(&#8220;table_name&#8221;);
        String columnName=rs.getString(&#8220;column_name&#8221;);
        String keySeq=rs.getString(&#8220;key_seq&#8221;);
        String pkName=rs.getString(&#8220;pk_name&#8221;);
        System.out.println(&#8220;table name :&#8221;+name);
        System.out.println(&#8220;column name: &#8221;+columnName);
        System.out.println(&#8220;sequence in key:&#8221;+keySeq);
        System.out.println(&#8220;primary key name:&#8221;+pkName);
        }
        rs.close();
        stmt.close();
        con.close();
        }catch(SQLException ex){
        System.err.println(&#8220;SQLException: &#8221;+ex.getMessage());
        }
        }
        }
        </pre>
        　　如果主键多余一列的话，那么方法getPrimaryKeys等将详细描述每一列。列key_seq中的值表示描述的是哪一列。</li>
    </ol>
    <li>使用ParameterMetaData对象<br />
    <p>　　可以使用ParameterMetaData对象来获取与PreparedStatement对象或者CallableStatement对象有关的信息。这些参数由&#8221;?&#8221;占位符表示，&#8221;?&#8221;占位符是提供给Connection方法prepareStatement和prepareCall的SQL语句。下面的代码行使用两个参数占位符来创建一个PreparedStatement对象。<br />
    　　PreparedStatement pstmt=con.prepareStatement(&#8220;select id from employees where dept=? and salary&gt;?&#8221;);<br />
    　　这些参数根据其序号来编号，因此第一个参数编号1，第二个参数编号2，依此类推。在上面的代码行中，参数1是列dept中的一个值，参数2是salary中的一个值。下面的代码段用于找出PreparedStatement pstmt有多少个参数。首先创建pstmt并用它来创建ParameterMetaData对象pmd，这个对象包含与pstmt中的参数有关的信息。接着调用pmd上的方法getColumnCount来找出pstmt有多少参数。 </p>
    <pre class="code">    PreparedStatement pstmt=con.prepareStatement(
    &#8220;update employees set salary =? Where level=?&#8221;);
    ParameterMetaData pmd = pstmt.getParameterMetaData();
    int count=pmd.getParameterCount();
    </pre>
    　　变量count的值应该等于2。方法getParameterCount不接受参数，因为它返回与PreparedStatement对象的所有参数有关的信息。ParameterMetaData接口中的所有其他方法都接受序号来表示作为要查询的信息的参数。<br />
    <li>JDBC 3.0API中新增的方法示例<br />
    　　JDBC 3.0 API引入了这样一种应用功能，即决定在已经调用commit方法来终止事务之后，ResultSet对象是否仍旧打开。这个功能即为结果集可保持性。ResultSet中加入了两个域HOLD_CURSORS_OVER_COMMIT和 CLOSE_CURSORS_AT_COMMIT，这些域可以用于指定ResultSet对象的可保持性，这些常量可以提供给创建Statement、PreparedStatement和CallableStatement对象的Connection方法，还可以作为提供给DataBaseMetaData方法supportResultSetHoldability的可能的参数值。
    <p>&nbsp;</p>
    <br />
    　　在下面的代码段中，首先判断驱动程序是否支持ResultSet可保持性，如果支持，则接着创建会生成带有可保持性游标的ResultSet对象的Statement对象，另外此代码还指定了stmt在执行查询时产生的ResultSet对象的类型和并发模式。
    <p>&nbsp;</p>
    <pre class="code">if (Boolean b =dbms.supportsResultSetHoldability(
    ResultSet. HOLD_CURSORS_OVER_COMMIT){
    Statement.stmt=con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
    ResultSet.CONCUR_UPDATABLE,
    ResultSet.HOLD_CURSORS_OVER_COMMIT);
    }
    </pre>
    　　参考《JDBC API Reference》 Maydene Fisher etc. 著</li>
</ul>
<p><strong>RowSet<br />
</strong>　　<strong></strong>RowSet对象是表格式数据的容器，封装了一组从数据源获取得数据行。在RowSet接口的基本实现中是从JDBC数据源中获取数据行。由于行集是可以定制的，所以行集中的数据可以来自电子数据表、flat文件（平面文件？）或者其他任何表格式样的数据源。RowSet对象是ResultSet接口的扩展，这就意味着RowSet对象是可滚动的、可更新的，并且能够执行ResultSet对象可以执行的任何操作。</p>
<p>　　RowSet对象不同于ResultSet对象，它是JavaBean组件，因此，该对象有JavaBean属性，并遵循其事件模型。另外RowSet对象的属性也允许该对象建立自己的数据库连接，执行自己的查询。此外，RowSet可以是disconnected的，也就是说使用行集的过程中，不必一直保持到数据源的打开连接。另外，行集可以串行化，所以可以通过网络把它发送到远程对象中去。</p>
<p>　　通常情况下，JDBC API可以分为两类：RowSet部分和驱动程序部分。RowSet以及支持它的接口使用其他JDBC API实现。从逻辑上来说，可以把实现RowSet接口的类看作是执行在JDBC驱动程序的上一层的软件。</p>
<p>　　现在的J2SE 5.0中，可以把JDBC API分为三种类别，除了上面的两类，还有RowSet接口的5种标准实现。这些实现提供了一组接口，以扩展基本的RowSet接口，通过在这些接口上建立application，可以确保在事件处理、游标控制以及其他操作方面的实现遵循JDBC API。</p>
<p>　　RowSet接口提供了一组基本方法，这些方法对于所有行集都是通用的。因为所有的RowSet对象都是JavaBean组件，因此，RowSet接口具有添加和删除event listener的方法，也有get/set RowSet对象所有属性的方法。RowSet对象的大多数属性都支持建立连接或者执行命令。为了执行查询、更新等SQL语句，并生成能够从中获取数据的结果集，行集会使用到数据源的连接。</p>
<p>　　若一个组件希望得到在RowSet对象上发生的事件的通知，它就应该实现RowSetListener接口，并向RowSet对象进行注册。这就是listener，一个GUI组件。这样每当行集产生事件时，listener每次都会得到事件的通知，这样就能够保持它的游标位置和数据与行集的内容一致。</p>
<p>　　RowSetInternal、RowSetReader、和RowSetWriter接口支持行集的reader/weiter工具。reader是一个实现RowSetReader接口的类的实例，用来读取数据并数据插入到行集中。writer是一个实现RowSetWriter接口的类的实例，用来将修改后的数据写回到数据源。reader和writer就像是listener一样，都向行集进行动态注册。</p>
<p>　　调用reader或者writer的RowSet对象必须是实现RowSetInternal接口的类的实例。这个接口为reader或者writer提供了附加的方法，用来操作行集的内部状态。例如行集可以跟踪它的初始值，RowSetInternal方法允许writer检测数据源中的相应数据是否已经被其他用户修改。另外，能够使用RowSetInternal方法来获取为行集的命令字符串设置的输入参数，也能够获取传递给行集的连接。最后，RowSetInternal方法允许reader设置新的RowSetMetaData对象，这个对象用来为行集描述reder将要插入到该行集中的数据行。</p>
<p>　　行集可以是connected的，也可以是disconnected的，一个连接的RowSet对象，在使用的整个过程中保持到数据源的连接，而一个未连接的行集，只有从数据源读取数据或者将数据写回数据源时才会连接到它的数据源。若行集是未连接的，它就不需要JDBC驱动或者JDBC API的完整实现。这使得它非常小巧，因此也成为发送一组数据到一个thin client的理想的容器。这个客户端可以选择更新数据，并将行集发送回应用服务器。在服务器端，未连接的RowSet对象使用它的reader来建立到数据源的连接，并把数据写回数据源。这一操作的具体实现依赖于reader的实现方式。通常reader将建立连接与读/写数据的操作委托给JDBC驱动。</p>
<p><strong>行集的事件模型<br />
</strong>　　行集事件模型使得Java对象或者组件能够收到RowSet对象产生的事件的通知。通知机制的建立包括被通知的组件，也包括RowSet对象自身。首先，每一个希望得到事件通知的组件都必须实现RowSetListener接口。然后，RowSet对象必须注册每一个组件，这通过在RowSet对象的事件通知组件列表中添加这些组件来完成。在这种情况下，这样的组件是一个listener，它是一个实现RowSetListener方法的类的实例，并已经向RowSet对象进行过注册。</p>
<p>　　在RowSet对象中可能发生三种事件：游标移动、数据行发生变化（ins、del、upd）或者该对象的整个内容发生变化。RowSetListener接口的cursorMoved、rowChanged和rowSetChanged方法分别对应与这些事件。当事件发生时，行集将创建一个RowSetEvent对象，使用这个对象将该行集标识为事件源。在每一个listener上调用适当的RowSetListender方法，并向此方法传递一个RowSetEvent对象作为输入参数，就将事件通知给行集所有的listener。</p>
<p><strong>RowSet属性<br />
</strong>　　RowSet接口提供了一组JavaBeans属性，可以配置RowSet实例以连接到数据源并获取数据行集合。有些属性可能并不需要，这取决于特定实现。如用URL或者数据源名来建立连接，但只要设置了其中一个属性，另一个属性就是可选的。如果设置了两个属性，就会使用最近设置的那个属性。若行集的数据是从不支持名命令的非SQL数据源中如电子表格中获取的，那么就不需要设置命令属性。</p>
<p><strong>几个接口的讲解</strong></p>
<ol>
    <li>WebRowSet<br />
    　　WebRowSet接口扩展了CacheRowSet接口。相比CacheRowSet接口，增加了读写XML格式行集的能力。WebRowSetImpl对象使用WebRowSetXmlReader对象来读取XML格式的行集，使用WebRowSetXmlWriter对象向XML格式的行集中写入数据。XML版本包含WebRowSetSetImpl对象的元数据，同时也包含它自己的数据。 　　WebRowSetImpl对象和CachedRowSetImpl相似点是二者都将瘦客户端连接到应用服务器。所以它们都适合为瘦客户提供数据；不同的地方是二者使用的协议。前者使用http/xml协议与中间层进行通信，而后者使用RMI/IIOP。　　<br />
    &nbsp;
    <li>JoinRowSet<br />
    　　JoinRowSet对象使得程序员能够从两个不同的RowSet对象合并数据。当相关联（p/f keys相关或者其他列唯一对应）的数据存储在不同的数据源中时，这种合并数据的功能很有用。任何RowSet实现都可以参与合并，但通常情况下，连接的双方是两个CachedRowSetImpl对象。将相关数据合并到一个JoinRowSetImpl对象中，应用程序就能够处理任何其他类型的RowSet对象一样来处理这些数据。<br />
    　　 假设有两个表：employees表和bonus_plan表，两表的第一个数据列都是ID，这个数据列是主键，现要将两表的信息进行匹配合并：
    <pre class="code">   JoinRowSetImpl jrs=new JoinRowSetImpl();
    ResultSet rs1 = stmt.executeQuery(&#8220;select * from employees&#8221;);
    CachedRowSetImpl empl=new CachedRowSetImpl();
    empl.populate(rs1);
    empl.setMatchColumn(1);
    jrs.addRowSet(empl);
    ResultSet rs2=stmt.executeQuery(&#8220;select * from bonum_plan&#8221;);
    CachedRowSetImpl bonums= new CachedRowSetImpl();
    bonus.populate(rs2);
    bonus.setMatchColumn(1);
    jrs.addRowSet(bonus);//已合并
    </pre>
    <p><strong>XAConnection 介绍<br />
    </strong>　　XAConnection对象是可以用于分布式事务的PooledConnection对象。它表示数据库的物理连接，多层结构中的服务器可以用它来创建返回给应用程序的Connection对象。因为是通过扩展PooledConnection接口得到的，所以继承了其所有的方法，另外添加了自己的方法 getXAResource。<br />
    　　分布式事务中的命令可以发送给多个DBMS服务器分布式事务是通过中间层应用服务器和外部的事务管理器以及JDBC服务器一同进行管理的，中间层的基础设施的这三个部分提供了plumbing。<br />
    　　分布式事务基础设施的首要元素是事务管理器，它可以是JTA的具体实现。事务管理器控制着事务边界以及两阶段提交过程。它启动和关闭与分布式事务 XAConnection对象相关的组件，并跟踪那些参与了分布式事务的DBMS服务器。事务管理器在每一个dbms中进行运行决定是否提交事务，仅当所有的dbms都同意提交时，事务管理器才提交事务，否则进行rollback。<br />
    　　分布式事务的另一个元素是支持jdbc api的jdbc驱动程序，而且这个驱动程序必须包含实现XADataSource和XAConnection接口的类。XADataResource接口和DataSource接口类似，但是它创建的对象是XAConnection对象而不是Connection对象。继承于 PooledConnection的XAConnection对象的特殊在于可以用它来获取XASource对象。事务管理器使用这个XARource对象开始和结束与分布式事务中的这个XAConnection相关的组件。<br />
    　　分布式事务基础设施中的第三个部分通常是一个连接池模块。XAConnection接口从PooledConnection接口继承而来，这表示分布式事务中的数据库连接可以来自连接池模块所管理的连接池。</p>
    <!--文章其他信息--></li>
</ol>
<img src ="http://www.blogjava.net/19851985lili/aggbug/203779.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/19851985lili/" target="_blank">☜♥☞MengChuChen</a> 2008-05-29 11:59 <a href="http://www.blogjava.net/19851985lili/articles/203779.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JSTL简介 ---Core标签库</title><link>http://www.blogjava.net/19851985lili/articles/203777.html</link><dc:creator>☜♥☞MengChuChen</dc:creator><author>☜♥☞MengChuChen</author><pubDate>Thu, 29 May 2008 03:53:00 GMT</pubDate><guid>http://www.blogjava.net/19851985lili/articles/203777.html</guid><wfw:comment>http://www.blogjava.net/19851985lili/comments/203777.html</wfw:comment><comments>http://www.blogjava.net/19851985lili/articles/203777.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/19851985lili/comments/commentRss/203777.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/19851985lili/services/trackbacks/203777.html</trackback:ping><description><![CDATA[<font size="4"><strong>1、 通用标签<br />
<br />
&lt;c:out&gt;</strong><br />
&lt;c:out&gt;标签用于在JSP中显示数据，它有如下属性 </font>
<table class="ubb" cellspacing="0">
    <tbody>
        <tr>
            <td class="ubb"><font size="4">属 性</font></td>
            <td class="ubb"><font size="4">描 述</font></td>
            <td class="ubb"><font size="4">是否必须</font></td>
            <td class="ubb"><font size="4">缺省值</font></td>
        </tr>
        <tr>
            <td class="ubb"><font size="4">value</font></td>
            <td class="ubb"><font size="4">输出的信息，可以是EL表达式或常量</font></td>
            <td class="ubb"><font size="4">是</font></td>
            <td class="ubb"><font size="4">无</font></td>
        </tr>
        <tr>
            <td class="ubb"><font size="4">default </font></td>
            <td class="ubb"><font size="4">value为空时显示信息</font></td>
            <td class="ubb"><font size="4">否</font></td>
            <td class="ubb"><font size="4">无</font></td>
        </tr>
        <tr>
            <td class="ubb"><font size="4">escapeXml</font></td>
            <td class="ubb"><font size="4">为true则避开特殊的xml字符集</font></td>
            <td class="ubb"><font size="4">否</font></td>
            <td class="ubb"><font size="4">true</font></td>
        </tr>
    </tbody>
</table>
<font size="4"><br />
<br />
<br />
例子: </font>
<table class="ubb" cellspacing="0">
    <tbody>
        <tr>
            <td class="ubb"><font size="4">您的用户名是: &lt;c:out value=&#8221;&#8221; default=&#8221;guest&#8221;/&gt;</font></td>
        </tr>
    </tbody>
</table>
<font size="4"><br />
显示用户的用户名，如为空则显示guest<br />
</font>
<table class="ubb" cellspacing="0">
    <tbody>
        <tr>
            <td class="ubb"><font size="4">&lt;c:out value=""/&gt;</font></td>
        </tr>
    </tbody>
</table>
<font size="4"><br />
指定从session中获取username的值显示；<br />
</font>
<table class="ubb" cellspacing="0">
    <tbody>
        <tr>
            <td class="ubb"><font size="4">&lt;c:out value="" /&gt;</font></td>
        </tr>
    </tbody>
</table>
<font size="4"><br />
显示username的值，默认是从request(page)中取，如果request中没有名为username的对象则从session中取， session中没有则从application(servletContext)中取，如果没有取到任何值则不显示。<br />
<br />
<strong>&lt;c:set&gt;</strong><br />
&lt;c:set&gt;标签用于保存数据，它有如下属性 </font>
<table class="ubb" cellspacing="0">
    <tbody>
        <tr>
            <td class="ubb"><font size="4">属 性</font></td>
            <td class="ubb"><font size="4">描 述</font></td>
            <td class="ubb"><font size="4">是否必须</font></td>
            <td class="ubb"><font size="4">缺省值</font></td>
        </tr>
        <tr>
            <td class="ubb"><font size="4">value</font></td>
            <td class="ubb"><font size="4">要保存的信息，可以是EL表达式或常量</font></td>
            <td class="ubb"><font size="4">否</font></td>
            <td class="ubb"><font size="4"><br />
            </font></td>
        </tr>
        <tr>
            <td class="ubb"><font size="4">target</font></td>
            <td class="ubb"><font size="4">需要修改属性的变量名，一般为javabean的实例</font></td>
            <td class="ubb"><font size="4">否</font></td>
            <td class="ubb"><font size="4">无</font></td>
        </tr>
        <tr>
            <td class="ubb"><font size="4">property</font></td>
            <td class="ubb"><font size="4">需要修改的javabean属性</font></td>
            <td class="ubb"><font size="4">否</font></td>
            <td class="ubb"><font size="4">无</font></td>
        </tr>
        <tr>
            <td class="ubb"><font size="4">var</font></td>
            <td class="ubb"><font size="4">需要保存信息的变量</font></td>
            <td class="ubb"><font size="4">否</font></td>
            <td class="ubb"><font size="4">无</font></td>
        </tr>
        <tr>
            <td class="ubb"><font size="4">scope</font></td>
            <td class="ubb"><font size="4">保存信息的变量的范围</font></td>
            <td class="ubb"><font size="4">否</font></td>
            <td class="ubb"><font size="4">page</font></td>
        </tr>
    </tbody>
</table>
<font size="4"><br />
如果指定了target属性, 那么property属性也必须指定。<br />
例子： </font>
<table class="ubb" cellspacing="0">
    <tbody>
        <tr>
            <td class="ubb"><font size="4">&lt;c:set value="" var="test2" scope=&#8221;session&#8221; /&gt;</font></td>
        </tr>
    </tbody>
</table>
<font size="4"><br />
将test.testinfo的值保存到session的test2中，其中test是一个javabean的实例，testinfo是test对象的属性。<br />
</font>
<table class="ubb" cellspacing="0">
    <tbody>
        <tr>
            <td class="ubb"><font size="4">&lt;c:set target="" property="city" value=""/&gt;</font></td>
        </tr>
    </tbody>
</table>
<font size="4"><br />
将对象cust.address的city属性值保存到变量city中<br />
<br />
<strong>&lt;c:remove&gt;</strong><br />
&lt;c:remove&gt;标签用于删除数据，它有如下属性 </font>
<table class="ubb" cellspacing="0">
    <tbody>
        <tr>
            <td class="ubb"><font size="4">属 性</font></td>
            <td class="ubb"><font size="4">描 述</font></td>
            <td class="ubb"><font size="4">是否必须</font></td>
            <td class="ubb"><font size="4">缺省值</font></td>
        </tr>
        <tr>
            <td class="ubb"><font size="4">var</font></td>
            <td class="ubb"><font size="4">要删除的变量</font></td>
            <td class="ubb"><font size="4">是</font></td>
            <td class="ubb"><font size="4">无</font></td>
        </tr>
        <tr>
            <td class="ubb"><font size="4">scope</font></td>
            <td class="ubb"><font size="4">被删除变量的范围</font></td>
            <td class="ubb"><font size="4">否</font></td>
            <td class="ubb"><font size="4">所有范围，包括page、request、session、application等</font></td>
        </tr>
    </tbody>
</table>
<font size="4"><br />
例子: </font>
<table class="ubb" cellspacing="0">
    <tbody>
        <tr>
            <td class="ubb"><font size="4">&lt;c:remove var="test2" scope="session"/&gt;</font></td>
        </tr>
    </tbody>
</table>
<font size="4"><br />
从session中删除test2变量。<br />
<br />
<strong>2、 流控制标签</strong><br />
<br />
<strong>&lt;c:if&gt;</strong><br />
<br />
&lt;c:if&gt;标签有如下属性 </font>
<table class="ubb" cellspacing="0">
    <tbody>
        <tr>
            <td class="ubb"><font size="4">属 性</font></td>
            <td class="ubb"><font size="4">描 述</font></td>
            <td class="ubb"><font size="4">是否必须</font></td>
            <td class="ubb"><font size="4">缺省值</font></td>
        </tr>
        <tr>
            <td class="ubb"><font size="4">test</font></td>
            <td class="ubb"><font size="4">需要评价的条件，相当于if (...){}语句中的条件</font></td>
            <td class="ubb"><font size="4">是</font></td>
            <td class="ubb"><font size="4">无</font></td>
        </tr>
        <tr>
            <td class="ubb"><font size="4">var</font></td>
            <td class="ubb"><font size="4">要求保存条件结果的变量名</font></td>
            <td class="ubb"><font size="4">否</font></td>
            <td class="ubb"><font size="4">无</font></td>
        </tr>
        <tr>
            <td class="ubb"><font size="4">scope</font></td>
            <td class="ubb"><font size="4">保存条件结果的变量范围</font></td>
            <td class="ubb"><font size="4">否</font></td>
            <td class="ubb"><font size="4">page</font></td>
        </tr>
    </tbody>
</table>
<font size="4"><br />
<br />
<strong>&lt;c:choose&gt;</strong><br />
这个标签不接受任何属性<br />
<br />
<strong>&lt;c:when&gt;</strong><br />
&lt;c:when&gt;标签有以下属性 </font>
<table class="ubb" cellspacing="0">
    <tbody>
        <tr>
            <td class="ubb"><font size="4">属 性</font></td>
            <td class="ubb"><font size="4">描 述</font></td>
            <td class="ubb"><font size="4">是否必须</font></td>
            <td class="ubb"><font size="4">缺省值</font></td>
        </tr>
        <tr>
            <td class="ubb"><font size="4">test</font></td>
            <td class="ubb"><font size="4">需要评价的条件</font></td>
            <td class="ubb"><font size="4">是</font></td>
            <td class="ubb"><font size="4">无</font></td>
        </tr>
    </tbody>
</table>
<font size="4"><br />
<br />
<strong>&lt;c:otherwise&gt;</strong><br />
这个标签同样不接受任何属性<br />
<br />
例子： </font>
<table class="ubb" cellspacing="0">
    <tbody>
        <tr>
            <td class="ubb"><font size="4">&lt;c:if test=""&gt;<br />
            user.wealthy is true.<br />
            &lt;/c:if&gt;</font></td>
        </tr>
    </tbody>
</table>
<font size="4"><br />
如果user.wealthy值true，则显示user.wealthy is true.<br />
<br />
</font>
<table class="ubb" cellspacing="0">
    <tbody>
        <tr>
            <td class="ubb"><font size="4">&lt;c:choose&gt;<br />
            &lt;c:when test=""&gt;<br />
            user.generous　is true.<br />
            &lt;/c:when&gt; <br />
            &lt;c:when test=""&gt;<br />
            user.stingy is true.<br />
            &lt;/c:when&gt;<br />
            &lt;c:otherwise&gt;<br />
            user.generous and user.stingy are false.<br />
            &lt;/c:otherwise&gt;<br />
            &lt;/c:choose&gt;</font></td>
        </tr>
    </tbody>
</table>
<font size="4"><br />
只有当条件user.generous返回值是true时，才显示user.generous　is true.<br />
只有当条件user.stingy返回值是true时，才显示user.stingy　is true.<br />
其它所有的情况（即user.generous和user.stingy的值都不为true）全部显示user.generous and user.stingy are false.<br />
<br />
由于JSTL没有形如if (){&#8230;} else {&#8230;}的条件语句，所以这种形式的语句只能用&lt;c:choose&gt;、&lt;c:when&gt;和&lt;c:otherwise&gt;标签共同来完成了。<br />
<br />
<strong>3、 循环控制标签</strong><br />
<br />
<strong>&lt;c:forEach&gt;</strong><br />
&lt;c:forEach&gt;标签用于通用数据，它有以下属性 </font>
<table class="ubb" cellspacing="0">
    <tbody>
        <tr>
            <td class="ubb"><font size="4">属 性</font></td>
            <td class="ubb"><font size="4">描 述</font></td>
            <td class="ubb"><font size="4">是否必须</font></td>
            <td class="ubb"><font size="4">缺省值</font></td>
        </tr>
        <tr>
            <td class="ubb"><font size="4">items</font></td>
            <td class="ubb"><font size="4">进行循环的项目</font></td>
            <td class="ubb"><font size="4">否</font></td>
            <td class="ubb"><font size="4">无</font></td>
        </tr>
        <tr>
            <td class="ubb"><font size="4">begin</font></td>
            <td class="ubb"><font size="4">开始条件</font></td>
            <td class="ubb"><font size="4">否</font></td>
            <td class="ubb"><font size="4">0</font></td>
        </tr>
        <tr>
            <td class="ubb"><font size="4">end</font></td>
            <td class="ubb"><font size="4">结束条件</font></td>
            <td class="ubb"><font size="4">否</font></td>
            <td class="ubb"><font size="4">集合中的最后一个项目</font></td>
        </tr>
        <tr>
            <td class="ubb"><font size="4">step</font></td>
            <td class="ubb"><font size="4">步长</font></td>
            <td class="ubb"><font size="4">否</font></td>
            <td class="ubb"><font size="4">1</font></td>
        </tr>
        <tr>
            <td class="ubb"><font size="4">var</font></td>
            <td class="ubb"><font size="4">代表当前项目的变量名</font></td>
            <td class="ubb"><font size="4">否</font></td>
            <td class="ubb"><font size="4">无</font></td>
        </tr>
        <tr>
            <td class="ubb"><font size="4">varStatus</font></td>
            <td class="ubb"><font size="4">显示循环状态的变量</font></td>
            <td class="ubb"><font size="4">否</font></td>
            <td class="ubb"><font size="4">无</font></td>
        </tr>
    </tbody>
</table>
<font size="4"><br />
<br />
例子： </font>
<table class="ubb" cellspacing="0">
    <tbody>
        <tr>
            <td class="ubb"><font size="4">&lt;c:forEach items="" var="vector"&gt;<br />
            &lt;c:out value=""/&gt;<br />
            &lt;/c:forEach&gt;</font></td>
        </tr>
    </tbody>
</table>
<font size="4"><br />
相当于java语句 </font>
<table class="ubb" cellspacing="0">
    <tbody>
        <tr>
            <td class="ubb"><font size="4">for (int i=0;i&lt;vectors.size();i++) {<br />
            out.println(vectors.get(i));<br />
            }</font></td>
        </tr>
    </tbody>
</table>
<font size="4"><br />
在这里vectors是一个java.util.Vector对象，里面存放的是String数据，vector是当前循环条件下String对象。实际上这里的vectors可以是任何实现了java.util. Collection接口的对象。 </font>
<table class="ubb" cellspacing="0">
    <tbody>
        <tr>
            <td class="ubb"><font size="4"><br />
            &lt;c:forEach begin="0" end="100" var="i" step="1"&gt;<br />
            count=&lt;c:out value=""/&gt;&lt;br&gt;<br />
            &lt;/c:forEach&gt;<br />
            </font></td>
        </tr>
    </tbody>
</table>
<font size="4"><br />
输出:<br />
count=0<br />
...<br />
count=100<br />
<br />
<strong>&lt;c:forTokens&gt;</strong><br />
&lt;c:forTokens&gt;标签有以下属性 </font>
<table class="ubb" cellspacing="0">
    <tbody>
        <tr>
            <td class="ubb"><font size="4">属 性</font></td>
            <td class="ubb"><font size="4">描 述</font></td>
            <td class="ubb"><font size="4">是否必须</font></td>
            <td class="ubb"><font size="4">缺省值</font></td>
        </tr>
        <tr>
            <td class="ubb"><font size="4">items</font></td>
            <td class="ubb"><font size="4">进行循环的项目</font></td>
            <td class="ubb"><font size="4">是</font></td>
            <td class="ubb"><font size="4">无</font></td>
        </tr>
        <tr>
            <td class="ubb"><font size="4">delims</font></td>
            <td class="ubb"><font size="4">分割符</font></td>
            <td class="ubb"><font size="4">是</font></td>
            <td class="ubb"><font size="4">无</font></td>
        </tr>
        <tr>
            <td class="ubb"><font size="4">begin</font></td>
            <td class="ubb"><font size="4">开始条件</font></td>
            <td class="ubb"><font size="4">否</font></td>
            <td class="ubb"><font size="4">0</font></td>
        </tr>
        <tr>
            <td class="ubb"><font size="4">end</font></td>
            <td class="ubb"><font size="4">结束条件</font></td>
            <td class="ubb"><font size="4">否</font></td>
            <td class="ubb"><font size="4">集合中的最后一个项目</font></td>
        </tr>
        <tr>
            <td class="ubb"><font size="4">step</font></td>
            <td class="ubb"><font size="4">步长</font></td>
            <td class="ubb"><font size="4">否</font></td>
            <td class="ubb"><font size="4">1</font></td>
        </tr>
        <tr>
            <td class="ubb"><font size="4">var</font></td>
            <td class="ubb"><font size="4">代表当前项目的变量名</font></td>
            <td class="ubb"><font size="4">否</font></td>
            <td class="ubb"><font size="4">无</font></td>
        </tr>
        <tr>
            <td class="ubb"><font size="4">varStatus</font></td>
            <td class="ubb"><font size="4">显示循环状态的变量</font></td>
            <td class="ubb"><font size="4">否</font></td>
            <td class="ubb"><font size="4">无</font></td>
        </tr>
    </tbody>
</table>
<font size="4"><br />
<br />
例子 </font>
<table class="ubb" cellspacing="0">
    <tbody>
        <tr>
            <td class="ubb"><font size="4"><br />
            &lt;c:forTokens items="a:b:c:d" delims=":" var="token"&gt;<br />
            &lt;c:out value=""/&gt;<br />
            &lt;/c:forTokens&gt;<br />
            </font></td>
        </tr>
    </tbody>
</table>
<font size="4"><br />
这个标签的使用相当于java.util.StringTokenizer类。在这里将字符串a:b:c:d以：分开循环四次，token是循环到当前分割到的字符串。<br />
<br />
<strong>4.导入文件和URL</strong><br />
<br />
JSTL核心标签库支持使用&lt;c:import&gt;来包含文件，使用&lt;c:url&gt;来打印和格式化URL,使用&lt;c:redirect&gt;来重定向URL。<br />
<br />
<strong>&lt;c:import&gt;</strong><br />
&lt;c:import&gt;标签包含另外一个页面代码到当前页，它有以下属性 </font>
<table class="ubb" cellspacing="0">
    <tbody>
        <tr>
            <td class="ubb"><font size="4">属 性</font></td>
            <td class="ubb"><font size="4">描 述</font></td>
            <td class="ubb"><font size="4">是否必须</font></td>
            <td class="ubb"><font size="4">缺省值</font></td>
        </tr>
        <tr>
            <td class="ubb"><font size="4">url</font></td>
            <td class="ubb"><font size="4">需要导入页面的url</font></td>
            <td class="ubb"><font size="4">是</font></td>
            <td class="ubb"><font size="4">无</font></td>
        </tr>
        <tr>
            <td class="ubb"><font size="4">context</font></td>
            <td class="ubb"><font size="4">/后跟本地web应用程序的名字</font></td>
            <td class="ubb"><font size="4">否</font></td>
            <td class="ubb"><font size="4">当前应用程序</font></td>
        </tr>
        <tr>
            <td class="ubb"><font size="4">charEncoding</font></td>
            <td class="ubb"><font size="4">用于导入数据的字符集</font></td>
            <td class="ubb"><font size="4">否</font></td>
            <td class="ubb"><font size="4">ISO-8859-1</font></td>
        </tr>
        <tr>
            <td class="ubb"><font size="4">var</font></td>
            <td class="ubb"><font size="4">接受导入文本的变量名</font></td>
            <td class="ubb"><font size="4">否</font></td>
            <td class="ubb"><font size="4">page</font></td>
        </tr>
        <tr>
            <td class="ubb"><font size="4">scope</font></td>
            <td class="ubb"><font size="4">接受导入文本的变量的变量范围</font></td>
            <td class="ubb"><font size="4">否</font></td>
            <td class="ubb"><font size="4">1</font></td>
        </tr>
        <tr>
            <td class="ubb"><font size="4">varReader</font></td>
            <td class="ubb"><font size="4">用于接受导入文本的java.io.Reader变量名</font></td>
            <td class="ubb"><font size="4">否</font></td>
            <td class="ubb"><font size="4">无</font></td>
        </tr>
        <tr>
            <td class="ubb"><font size="4">varStatus</font></td>
            <td class="ubb"><font size="4">显示循环状态的变量</font></td>
            <td class="ubb"><font size="4">否</font></td>
            <td class="ubb"><font size="4">无</font></td>
        </tr>
    </tbody>
</table>
<font size="4"><br />
<br />
<strong>&lt;c:url&gt;</strong><br />
&lt;c:url&gt;标签输出一个url地址，它有以下属性 </font>
<table class="ubb" cellspacing="0">
    <tbody>
        <tr>
            <td class="ubb"><font size="4">属 性</font></td>
            <td class="ubb"><font size="4">描 述</font></td>
            <td class="ubb"><font size="4">是否必须</font></td>
            <td class="ubb"><font size="4">缺省值</font></td>
        </tr>
        <tr>
            <td class="ubb"><font size="4">url</font></td>
            <td class="ubb"><font size="4">url地址</font></td>
            <td class="ubb"><font size="4">是</font></td>
            <td class="ubb"><font size="4">无</font></td>
        </tr>
        <tr>
            <td class="ubb"><font size="4">context</font></td>
            <td class="ubb"><font size="4">/后跟本地web应用程序的名字</font></td>
            <td class="ubb"><font size="4">否</font></td>
            <td class="ubb"><font size="4">当前应用程序</font></td>
        </tr>
        <tr>
            <td class="ubb"><font size="4">charEncoding</font></td>
            <td class="ubb"><font size="4">用于导入数据的字符集</font></td>
            <td class="ubb"><font size="4">否</font></td>
            <td class="ubb"><font size="4">ISO-8859-1</font></td>
        </tr>
        <tr>
            <td class="ubb"><font size="4">var</font></td>
            <td class="ubb"><font size="4">接受处理过的url变量名，该变量存储url</font></td>
            <td class="ubb"><font size="4">否</font></td>
            <td class="ubb"><font size="4">输出到页</font></td>
        </tr>
        <tr>
            <td class="ubb"><font size="4">scope</font></td>
            <td class="ubb"><font size="4">存储url的变量名的变量范围</font></td>
            <td class="ubb"><font size="4">否</font></td>
            <td class="ubb"><font size="4">page</font></td>
        </tr>
    </tbody>
</table>
<font size="4"><br />
<br />
例子： </font>
<table class="ubb" cellspacing="0">
    <tbody>
        <tr>
            <td class="ubb"><font size="4"><br />
            &lt;c:import url="http://www.url.com/edit.js" var="newsfeed"/&gt;<br />
            </font></td>
        </tr>
    </tbody>
</table>
<font size="4"><br />
将url http://www.url.com/edit.js包含到当前页的当前位置，并将url保存到newsfeed变量中 </font>
<table class="ubb" cellspacing="0">
    <tbody>
        <tr>
            <td class="ubb"><font size="4"><br />
            &lt;a href="&lt;c:url url="/index.jsp"/&gt;"/&gt;<br />
            </font></td>
        </tr>
    </tbody>
</table>
<font size="4"><br />
在当前页的当前位置输出&lt;a href="http://www.yourname.com/index.jsp"/&gt;，http://www.yourname.com是当前页的所在的位置。<br />
<br />
<br />
<strong>&lt;c:redirect&gt;</strong><br />
&lt;c:redirect&gt;标签将请求重新定向到另外一个页面，它有以下属性 </font>
<table class="ubb" cellspacing="0">
    <tbody>
        <tr>
            <td class="ubb"><font size="4">属 性</font></td>
            <td class="ubb"><font size="4">描 述</font></td>
            <td class="ubb"><font size="4">是否必须</font></td>
            <td class="ubb"><font size="4">缺省值</font></td>
        </tr>
        <tr>
            <td class="ubb"><font size="4">url</font></td>
            <td class="ubb"><font size="4">url地址</font></td>
            <td class="ubb"><font size="4">是</font></td>
            <td class="ubb"><font size="4">无</font></td>
        </tr>
        <tr>
            <td class="ubb"><font size="4">context</font></td>
            <td class="ubb"><font size="4">/后跟本地web应用程序的名字</font></td>
            <td class="ubb"><font size="4">否</font></td>
            <td class="ubb"><font size="4">当前应用程序</font></td>
        </tr>
    </tbody>
</table>
<font size="4"><br />
例子： </font>
<table class="ubb" cellspacing="0">
    <tbody>
        <tr>
            <td class="ubb"><font size="4"><br />
            &lt;c:redirect url="http://www.yourname.com/login.jsp"/&gt;<br />
            </font></td>
        </tr>
    </tbody>
</table>
<font size="4"><br />
将请求重新定向到http://www.yourname.com/login.jsp页，相当于response.setRedirect("http://www.yourname.com/login.jsp");<br />
<br />
<strong>&lt;c:param&gt;</strong><br />
&lt;c:param&gt;标签用来传递参数给一个重定向或包含页面，它有以下属性 </font>
<table class="ubb" cellspacing="0">
    <tbody>
        <tr>
            <td class="ubb"><font size="4">属 性</font></td>
            <td class="ubb"><font size="4">描 述</font></td>
            <td class="ubb"><font size="4">是否必须</font></td>
            <td class="ubb"><font size="4">缺省值</font></td>
        </tr>
        <tr>
            <td class="ubb"><font size="4">name</font></td>
            <td class="ubb"><font size="4">在request参数中设置的变量名</font></td>
            <td class="ubb"><font size="4">是</font></td>
            <td class="ubb"><font size="4">无</font></td>
        </tr>
        <tr>
            <td class="ubb"><font size="4">value</font></td>
            <td class="ubb"><font size="4">在request参数中设置的变量值</font></td>
            <td class="ubb"><font size="4">否</font></td>
            <td class="ubb"><font size="4">无</font></td>
        </tr>
    </tbody>
</table>
<font size="4"><br />
例子： </font>
<table class="ubb" cellspacing="0">
    <tbody>
        <tr>
            <td class="ubb"><font size="4"><br />
            &lt;c:redirect url="login.jsp"&gt;<br />
            &lt;c:param name="id" value="888"/&gt;<br />
            &lt;/c:redirect&gt;<br />
            </font></td>
        </tr>
    </tbody>
</table>
<img src ="http://www.blogjava.net/19851985lili/aggbug/203777.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/19851985lili/" target="_blank">☜♥☞MengChuChen</a> 2008-05-29 11:53 <a href="http://www.blogjava.net/19851985lili/articles/203777.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>jdk5.0的11个主要新特征</title><link>http://www.blogjava.net/19851985lili/articles/122932.html</link><dc:creator>☜♥☞MengChuChen</dc:creator><author>☜♥☞MengChuChen</author><pubDate>Fri, 08 Jun 2007 12:26:00 GMT</pubDate><guid>http://www.blogjava.net/19851985lili/articles/122932.html</guid><wfw:comment>http://www.blogjava.net/19851985lili/comments/122932.html</wfw:comment><comments>http://www.blogjava.net/19851985lili/articles/122932.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/19851985lili/comments/commentRss/122932.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/19851985lili/services/trackbacks/122932.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 泛型(Generic) 1.1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 说明 增强了java的类型安全，可以在编译期间对容器内的对象进行类型检查，在运行期不必进行类型的转换。而在j2se5之前必须在运...&nbsp;&nbsp;<a href='http://www.blogjava.net/19851985lili/articles/122932.html'>阅读全文</a><img src ="http://www.blogjava.net/19851985lili/aggbug/122932.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/19851985lili/" target="_blank">☜♥☞MengChuChen</a> 2007-06-08 20:26 <a href="http://www.blogjava.net/19851985lili/articles/122932.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>深入解析Java的新特性assertion</title><link>http://www.blogjava.net/19851985lili/articles/122920.html</link><dc:creator>☜♥☞MengChuChen</dc:creator><author>☜♥☞MengChuChen</author><pubDate>Fri, 08 Jun 2007 11:29:00 GMT</pubDate><guid>http://www.blogjava.net/19851985lili/articles/122920.html</guid><wfw:comment>http://www.blogjava.net/19851985lili/comments/122920.html</wfw:comment><comments>http://www.blogjava.net/19851985lili/articles/122920.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/19851985lili/comments/commentRss/122920.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/19851985lili/services/trackbacks/122920.html</trackback:ping><description><![CDATA[<p><a name=1><span class=atitle>assertion的语法和语义</span></a></p>
<p>
<p>J2SE 1.4在语言上提供了一个新特性，就是assertion(断言)功能，它是该版本在Java语言方面最大的革新。在软件开发中，assertion是一种经典的调试、测试方式，本文将深入解析assertion功能的使用以及其设计理念，并给出相关的例子 。</p>
<p>assertion(断言)在软件开发中是一种常用的调试方式，很多开发语言中都支持这种机制，如C，C++和Eiffel等，但是支持的形式不尽相同，有的是通过语言本身、有的是通过库函数等。另外，从理论上来说，通过assertion方式可以证明程序的正确性，但是这是一项相当复杂的工作，目前还没有太多的实践意义。</p>
<p>在实现中，assertion就是在程序中的一条语句，它对一个boolean表达式进行检查，一个正确程序必须保证这个boolean表达式的值为true；如果该值为false，说明程序已经处于不正确的状态下，系统将给出警告或退出。一般来说，assertion用于保证程序最基本、关键的正确性。assertion检查通常在开发和测试时开启。为了提高性能，在软件发布后，assertion检查通常是关闭的。下面简单介绍一下Java中assertion的实现。</p>
<p><a name=N1005D><span class=smalltitle><strong><font face=Arial>1．1) 语法表示</font></strong></span></a></p>
<p><strong><font face=Arial></font></strong>
<p>在语法上，为了支持assertion，Java增加了一个关键字assert。它包括两种表达式，分别如下：</p>
<ol>
    <li>assert expression1;
    <li>assert expression1: expression2; </li>
</ol>
<p>在两种表达式中，expression1表示一个boolean表达式，expression2表示一个基本类型或者是一个对象(Object) ，基本类型包括boolean,char,double,float,int和long。由于所有类都为Object的子类，因此这个参数可以用于所有对象。</p>
<p><a name=N10074><span class=smalltitle><strong><font face=Arial>1．2) 语义含义</font></strong></span></a></p>
<p><strong><font face=Arial></font></strong>
<p>在运行时，如果关闭了assertion功能，这些语句将不起任何作用。如果打开了assertion功能，那么expression1的值将被计算，如果它的值为false，该语句强抛出一个AssertionError对象。如果assertion语句包括expression2参数，程序将计算出expression2的结果，然后将这个结果作为AssertionError的构造函数的参数，来创建AssertionError对象，并抛出该对象；如果expression1值为true，expression2将不被计算。</p>
<p>一种特殊情况是，如果在计算表达式时，表达式本身抛出Exception，那么assert将停止运行，而抛出这个Exception。</p>
<p><a name=N10082><span class=smalltitle><strong><font face=Arial>1．3) 一些assertion例子</font></strong></span></a></p>
<p><strong><font face=Arial></font></strong>
<p>下面是一些Assert的例子。</p>
<ol>
    <li>assert　　0 &lt; value;
    <li>assert　　0 &lt; value:"value="+value;
    <li>assert　　ref != null:"ref doesn't equal null";
    <li>assert　　isBalanced(); </li>
</ol>
<p><a name=N1009C><span class=smalltitle><strong><font face=Arial>1．4) 编译</font></strong></span></a></p>
<p><strong><font face=Arial></font></strong>
<p>由于assert是一个新关键字，使用老版本的JDK是无法编译带有assert的源程序。因此，我们必须使用JDK1.4(或者更新)的Java编译器，在使用Javac命令时，我们必须加上-source 1.4作为参数。-source 1.4表示使用JDK 1.4版本的方式来编译源代码，否则编译就不能通过，因为缺省的Javac编译器使用JDK1.3的语法规则。</p>
<p>一个简单的例子如下：</p>
<p>javac -source 1.4 test.java</p>
<p><a name=N100AD><span class=smalltitle><strong><font face=Arial>1．5) 运行</font></strong></span></a></p>
<p><strong><font face=Arial></font></strong>
<p>由于带有assert语句的程序运行时，使用了新的ClassLoader和Class类，因此，这种程序必须在JDK1.4(或者更高版本)的JRE下运行，而不能在老版本的JRE下运行。</p>
<p>由于我们可以选择开启assertion功能，或者不开启，另外我们还可以开启一部分类或包的assertion功能，所以运行选项变得有些复杂。通过这些选项，我们可以过滤所有我们不关心的类，只选择我们关心的类或包来观察。下面介绍两类参数：</p>
<ol>
    <li>参数 <strong>-esa</strong>和 <strong>-dsa</strong>： <br>它们含义为开启(关闭)系统类的assertion功能。由于新版本的Java的系统类中，也使了assertion语句，因此如果用户需要观察它们的运行情况，就需要打开系统类的assertion功能 ，我们可使用-esa参数打开，使用 -dsa参数关闭。 -esa和-dsa的全名为-enablesystemassertions和-disenablesystemassertions，全名和缩写名有同样的功能。
    <li>参数 <strong>-ea</strong>和 <strong>-ea</strong>： <br>它们含义为开启(关闭)用户类的assertion功能：通过这个参数，用户可以打开某些类或包的assertion功能，同样用户也可以关闭某些类和包的assertion功能。打开assertion功能参数为-ea；如果不带任何参数，表示打开所有用户类；如果带有包名称或者类名称，表示打开这些类或包；如果包名称后面跟有三个点，代表这个包及其子包；如果只有三个点，代表无名包。关闭assertion功能参数为-da，使用方法与-ea类似。 <br>-ea和-da的全名为-enableassertions和-disenableassertions，全名和缩写名有同样的功能。 <br>下面表格表示了参数及其含义，并有例子说明如何使用。 <br>
    <table width="60%" border=1>
        <tbody>
            <tr>
                <td>参数</td>
                <td>例子</td>
                <td>说明</td>
            </tr>
            <tr>
                <td>-ea</td>
                <td>java -ea</td>
                <td>打开所有用户类的assertion</td>
            </tr>
            <tr>
                <td>-da</td>
                <td>java -da</td>
                <td>关闭所有用户类的assertion</td>
            </tr>
            <tr>
                <td>-ea:&lt;classname&gt;</td>
                <td>java -ea:MyClass1</td>
                <td>打开MyClass1的assertion</td>
            </tr>
            <tr>
                <td>-da:&lt;classname&gt;</td>
                <td>java -da: MyClass1</td>
                <td>关闭MyClass1的assertion</td>
            </tr>
            <tr>
                <td>-ea:&lt;packagename&gt;</td>
                <td>java -ea:pkg1</td>
                <td>打开pkg1包的assertion</td>
            </tr>
            <tr>
                <td>-da:&lt;packagename&gt;</td>
                <td>java -da:pkg1</td>
                <td>关闭pkg1包的assertion</td>
            </tr>
            <tr>
                <td>-ea:...</td>
                <td>java -ea:...</td>
                <td>打开缺省包(无名包)的assertion</td>
            </tr>
            <tr>
                <td>-da:...</td>
                <td>java -da:...</td>
                <td>关闭缺省包(无名包)的assertion</td>
            </tr>
            <tr>
                <td>-ea:&lt;packagename&gt;...</td>
                <td>java -ea:pkg1...</td>
                <td>打开pkg1包和其子包的assertion</td>
            </tr>
            <tr>
                <td>-da:&lt;packagename&gt;...</td>
                <td>java -da:pkg1...</td>
                <td>关闭pkg1包和其子包的assertion</td>
            </tr>
            <tr>
                <td>-esa</td>
                <td>java -esa</td>
                <td>打开系统类的assertion</td>
            </tr>
            <tr>
                <td>-dsa</td>
                <td>java -dsa</td>
                <td>关闭系统类的assertion</td>
            </tr>
            <tr>
                <td>综合使用</td>
                <td>java -dsa:MyClass1:pkg1</td>
                <td>关闭MyClass1和pkg1包的assertion</td>
            </tr>
        </tbody>
    </table>
    <br>其中...代表，此包和其子包的含义。例如我们有两个包为pkg1和pkg1.subpkg。那么pkg1...就代表pkg1和pkg1.subpkg两个包。 <br>另外，Java为了让程序也能够动态开启和关闭某些类和包的assertion功能，Java修该了Class和ClassLoader的实现，增加了几个用于操作assert的API。下面简单说明一下几个API的作用。 <br>ClassLoader类中的几个相关的API: <br>　　setDefaultAssertionStatus:用于开启/关闭assertion功能 <br>　　setPackageAssertionStatus:用于开启/关闭某些包的assertion功能 <br>　　setClassAssertionStatus: 用于开启/关闭某些类的assertion功能 <br>　　clearAssertionStatus：用于关闭assertion功能 </li>
</ol>
<p>
<table class=no-print cellSpacing=0 cellPadding=0 width=160 align=right border=0>
    <tbody>
        <tr>
            <td width=10><img height=1 alt="" src="http://www.ibm.com/i/c.gif" width=10></td>
            <td>
            <table cellSpacing=0 cellPadding=0 width=150 border=0>
                <tbody>
                    <tr>
                        <td class=v14-header-1-small>文档选项</td>
                    </tr>
                </tbody>
            </table>
            <table class=v14-gray-table-border cellSpacing=0 cellPadding=0 border=0>
                <tbody>
                    <tr>
                        <td class=no-padding width=150>
                        <table cellSpacing=0 cellPadding=0 width=143 border=0>
                            <img height=1 alt="" src="http://www.ibm.com/i/c.gif" width=8>
                            <form name=email action=https://www.ibm.com/developerworks/secure/email-it.jsp>
                                <input type=hidden value="J2SE 1.4在语言上提供了一个新特性，就是assertion(断言)功能，它是该版本在Java语言方面最大的革新。在软件开发中，assertion是一种经典的调试、测试方式，本文将深入解析assertion功能的使用以及其设计理念，并给出相关的例子 。" name=body><input type=hidden value=深入解析Java的新特性assertion name=subject><input type=hidden value=cn name=lang>
                                <script language=JavaScript type=text/javascript>
                                <!--
                                document.write('
                                <tr valign="top">
                                    <td width="8"><img src="//www.ibm.com/i/c.gif" width="8" height="1" alt=""/></td>
                                    <td width="16"><img src="//www.ibm.com/i/v14/icons/em.gif" height="16" width="16" vspace="3" alt="将此页作为电子邮件发送" /></td>
                                    <td width="122">
                                    <p><a class="smallplainlink" href="javascript:document.email.submit();"><strong>将此页作为电子邮件发送</strong></a></p>
                                    </td>
                                </tr>
                                ');
                                //-->
                                </script>
                                <tbody>
                                    <tr vAlign=top>
                                        <td width=8><img height=1 alt="" src="http://www.ibm.com/i/c.gif" width=8></td>
                                        <td width=16><img height=16 alt=将此页作为电子邮件发送 src="http://www.ibm.com/i/v14/icons/em.gif" width=16 vspace=3></td>
                                        <td width=122>
                                        <p><a class=smallplainlink href="javascript:document.email.submit();"><strong><font color=#5c81a7 size=2>将此页作为电子邮件发送</font></strong></a></p>
                                        </td>
                                    </tr>
                                    <noscript>
                                    <tr valign="top">
                                        <td width="8"><img alt="" height="1" width="8" src="//www.ibm.com/i/c.gif"/></td>
                                        <td width="16"><img alt="" width="16" height="16" src="//www.ibm.com/i/c.gif"/></td>
                                        <td class="small" width="122">
                                        <p><span class="ast">未显示需要 JavaScript 的文档选项</span></p>
                                        </td>
                                    </tr>
                                    </noscript>
                                </form>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <!--start RESERVED FOR FUTURE USE INCLUDE FILES--><!-- this content will be automatically generated across all content areas --><br><!--end RESERVED FOR FUTURE USE INCLUDE FILES--><br></td>
        </tr>
    </tbody>
</table>
</p>
<p>级别: 初级</p>
<p><a href="http://www.ibm.com/developerworks/cn/java/l-javaassertion/index.html#author"><font color=#996699>欧阳辰</font></a> (<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#121;&#101;&#101;&#107;&#101;&#101;&#64;&#115;&#105;&#110;&#97;&#46;&#99;&#111;&#109;&#63;&#115;&#117;&#98;&#106;&#101;&#99;&#116;&#61;&#28145;&#20837;&#35299;&#26512;&#74;&#97;&#118;&#97;&#30340;&#26032;&#29305;&#24615;&#97;&#115;&#115;&#101;&#114;&#116;&#105;&#111;&#110;&#38;&#97;&#109;&#112;&#59;&#99;&#99;&#61;&#121;&#101;&#101;&#107;&#101;&#101;&#64;&#115;&#105;&#110;&#97;&#46;&#99;&#111;&#109;"><font color=#5c81a7>yeekee@sina.com</font></a>), <br><a href="http://www.ibm.com/developerworks/cn/java/l-javaassertion/index.html#author"><font color=#996699>周欣</font></a> (<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#122;&#104;&#111;&#117;&#120;&#105;&#110;&#64;&#115;&#101;&#105;&#46;&#112;&#107;&#117;&#46;&#101;&#100;&#117;&#46;&#99;&#110;&#63;&#115;&#117;&#98;&#106;&#101;&#99;&#116;&#61;&#28145;&#20837;&#35299;&#26512;&#74;&#97;&#118;&#97;&#30340;&#26032;&#29305;&#24615;&#97;&#115;&#115;&#101;&#114;&#116;&#105;&#111;&#110;&#38;&#97;&#109;&#112;&#59;&#99;&#99;&#61;&#122;&#104;&#111;&#117;&#120;&#105;&#110;&#64;&#115;&#101;&#105;&#46;&#112;&#107;&#117;&#46;&#101;&#100;&#117;&#46;&#99;&#110;"><font color=#5c81a7>zhouxin@sei.pku.edu.cn</font></a>), <br></p>
<p>2002 年 6 月 12 日</p>
<blockquote>J2SE 1.4在语言上提供了一个新特性，就是assertion(断言)功能，它是该版本在Java语言方面最大的革新。在软件开发中，assertion是一种经典的调试、测试方式，本文将深入解析assertion功能的使用以及其设计理念，并给出相关的例子 。</blockquote><!--start RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters --><!--end RESERVED FOR FUTURE USE INCLUDE FILES-->
<p><a name=1><span class=atitle>assertion的语法和语义</span></a></p>
<p>
<p>J2SE 1.4在语言上提供了一个新特性，就是assertion(断言)功能，它是该版本在Java语言方面最大的革新。在软件开发中，assertion是一种经典的调试、测试方式，本文将深入解析assertion功能的使用以及其设计理念，并给出相关的例子 。</p>
<p>assertion(断言)在软件开发中是一种常用的调试方式，很多开发语言中都支持这种机制，如C，C++和Eiffel等，但是支持的形式不尽相同，有的是通过语言本身、有的是通过库函数等。另外，从理论上来说，通过assertion方式可以证明程序的正确性，但是这是一项相当复杂的工作，目前还没有太多的实践意义。</p>
<p>在实现中，assertion就是在程序中的一条语句，它对一个boolean表达式进行检查，一个正确程序必须保证这个boolean表达式的值为true；如果该值为false，说明程序已经处于不正确的状态下，系统将给出警告或退出。一般来说，assertion用于保证程序最基本、关键的正确性。assertion检查通常在开发和测试时开启。为了提高性能，在软件发布后，assertion检查通常是关闭的。下面简单介绍一下Java中assertion的实现。</p>
<p><a name=N1005D><span class=smalltitle><strong><font face=Arial>1．1) 语法表示</font></strong></span></a></p>
<p><strong><font face=Arial></font></strong>
<p>在语法上，为了支持assertion，Java增加了一个关键字assert。它包括两种表达式，分别如下：</p>
<ol>
    <li>assert expression1;
    <li>assert expression1: expression2; </li>
</ol>
<p>在两种表达式中，expression1表示一个boolean表达式，expression2表示一个基本类型或者是一个对象(Object) ，基本类型包括boolean,char,double,float,int和long。由于所有类都为Object的子类，因此这个参数可以用于所有对象。</p>
<p><a name=N10074><span class=smalltitle><strong><font face=Arial>1．2) 语义含义</font></strong></span></a></p>
<p><strong><font face=Arial></font></strong>
<p>在运行时，如果关闭了assertion功能，这些语句将不起任何作用。如果打开了assertion功能，那么expression1的值将被计算，如果它的值为false，该语句强抛出一个AssertionError对象。如果assertion语句包括expression2参数，程序将计算出expression2的结果，然后将这个结果作为AssertionError的构造函数的参数，来创建AssertionError对象，并抛出该对象；如果expression1值为true，expression2将不被计算。</p>
<p>一种特殊情况是，如果在计算表达式时，表达式本身抛出Exception，那么assert将停止运行，而抛出这个Exception。</p>
<p><a name=N10082><span class=smalltitle><strong><font face=Arial>1．3) 一些assertion例子</font></strong></span></a></p>
<p><strong><font face=Arial></font></strong>
<p>下面是一些Assert的例子。</p>
<ol>
    <li>assert　　0 &lt; value;
    <li>assert　　0 &lt; value:"value="+value;
    <li>assert　　ref != null:"ref doesn't equal null";
    <li>assert　　isBalanced(); </li>
</ol>
<p><a name=N1009C><span class=smalltitle><strong><font face=Arial>1．4) 编译</font></strong></span></a></p>
<p><strong><font face=Arial></font></strong>
<p>由于assert是一个新关键字，使用老版本的JDK是无法编译带有assert的源程序。因此，我们必须使用JDK1.4(或者更新)的Java编译器，在使用Javac命令时，我们必须加上-source 1.4作为参数。-source 1.4表示使用JDK 1.4版本的方式来编译源代码，否则编译就不能通过，因为缺省的Javac编译器使用JDK1.3的语法规则。</p>
<p>一个简单的例子如下：</p>
<p>javac -source 1.4 test.java</p>
<p><a name=N100AD><span class=smalltitle><strong><font face=Arial>1．5) 运行</font></strong></span></a></p>
<p><strong><font face=Arial></font></strong>
<p>由于带有assert语句的程序运行时，使用了新的ClassLoader和Class类，因此，这种程序必须在JDK1.4(或者更高版本)的JRE下运行，而不能在老版本的JRE下运行。</p>
<p>由于我们可以选择开启assertion功能，或者不开启，另外我们还可以开启一部分类或包的assertion功能，所以运行选项变得有些复杂。通过这些选项，我们可以过滤所有我们不关心的类，只选择我们关心的类或包来观察。下面介绍两类参数：</p>
<ol>
    <li>参数 <strong>-esa</strong>和 <strong>-dsa</strong>： <br>它们含义为开启(关闭)系统类的assertion功能。由于新版本的Java的系统类中，也使了assertion语句，因此如果用户需要观察它们的运行情况，就需要打开系统类的assertion功能 ，我们可使用-esa参数打开，使用 -dsa参数关闭。 -esa和-dsa的全名为-enablesystemassertions和-disenablesystemassertions，全名和缩写名有同样的功能。
    <li>参数 <strong>-ea</strong>和 <strong>-ea</strong>： <br>它们含义为开启(关闭)用户类的assertion功能：通过这个参数，用户可以打开某些类或包的assertion功能，同样用户也可以关闭某些类和包的assertion功能。打开assertion功能参数为-ea；如果不带任何参数，表示打开所有用户类；如果带有包名称或者类名称，表示打开这些类或包；如果包名称后面跟有三个点，代表这个包及其子包；如果只有三个点，代表无名包。关闭assertion功能参数为-da，使用方法与-ea类似。 <br>-ea和-da的全名为-enableassertions和-disenableassertions，全名和缩写名有同样的功能。 <br>下面表格表示了参数及其含义，并有例子说明如何使用。 <br>
    <table width="60%" border=1>
        <tbody>
            <tr>
                <td>参数</td>
                <td>例子</td>
                <td>说明</td>
            </tr>
            <tr>
                <td>-ea</td>
                <td>java -ea</td>
                <td>打开所有用户类的assertion</td>
            </tr>
            <tr>
                <td>-da</td>
                <td>java -da</td>
                <td>关闭所有用户类的assertion</td>
            </tr>
            <tr>
                <td>-ea:&lt;classname&gt;</td>
                <td>java -ea:MyClass1</td>
                <td>打开MyClass1的assertion</td>
            </tr>
            <tr>
                <td>-da:&lt;classname&gt;</td>
                <td>java -da: MyClass1</td>
                <td>关闭MyClass1的assertion</td>
            </tr>
            <tr>
                <td>-ea:&lt;packagename&gt;</td>
                <td>java -ea:pkg1</td>
                <td>打开pkg1包的assertion</td>
            </tr>
            <tr>
                <td>-da:&lt;packagename&gt;</td>
                <td>java -da:pkg1</td>
                <td>关闭pkg1包的assertion</td>
            </tr>
            <tr>
                <td>-ea:...</td>
                <td>java -ea:...</td>
                <td>打开缺省包(无名包)的assertion</td>
            </tr>
            <tr>
                <td>-da:...</td>
                <td>java -da:...</td>
                <td>关闭缺省包(无名包)的assertion</td>
            </tr>
            <tr>
                <td>-ea:&lt;packagename&gt;...</td>
                <td>java -ea:pkg1...</td>
                <td>打开pkg1包和其子包的assertion</td>
            </tr>
            <tr>
                <td>-da:&lt;packagename&gt;...</td>
                <td>java -da:pkg1...</td>
                <td>关闭pkg1包和其子包的assertion</td>
            </tr>
            <tr>
                <td>-esa</td>
                <td>java -esa</td>
                <td>打开系统类的assertion</td>
            </tr>
            <tr>
                <td>-dsa</td>
                <td>java -dsa</td>
                <td>关闭系统类的assertion</td>
            </tr>
            <tr>
                <td>综合使用</td>
                <td>java -dsa:MyClass1:pkg1</td>
                <td>关闭MyClass1和pkg1包的assertion</td>
            </tr>
        </tbody>
    </table>
    <br>其中...代表，此包和其子包的含义。例如我们有两个包为pkg1和pkg1.subpkg。那么pkg1...就代表pkg1和pkg1.subpkg两个包。 <br>另外，Java为了让程序也能够动态开启和关闭某些类和包的assertion功能，Java修该了Class和ClassLoader的实现，增加了几个用于操作assert的API。下面简单说明一下几个API的作用。 <br>ClassLoader类中的几个相关的API: <br>　　setDefaultAssertionStatus:用于开启/关闭assertion功能 <br>　　setPackageAssertionStatus:用于开启/关闭某些包的assertion功能 <br>　　setClassAssertionStatus: 用于开启/关闭某些类的assertion功能 <br>　　clearAssertionStatus：用于关闭assertion功能 </li>
</ol>
<p><br>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td><img height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"><br><img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=8 border=0></td>
        </tr>
    </tbody>
</table>
<table class=no-print cellSpacing=0 cellPadding=0 align=right>
    <tbody>
        <tr align=right>
            <td><img height=4 alt="" src="http://www.ibm.com/i/c.gif" width="100%"><br>
            <table cellSpacing=0 cellPadding=0 border=0>
                <tbody>
                    <tr>
                        <td vAlign=center><img height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><br></td>
                        <td vAlign=top align=right><a class=fbox href="http://www.ibm.com/developerworks/cn/java/l-javaassertion/index.html#main"><strong><font color=#996699>回页首</font></strong></a></td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<br><br></p>
<p><a name=2><span class=atitle>assertion的设计问题</span></a></p>
<p>
<p>首先，我们认为assertion是必要的。因为，如果没有统一的assertion机制，Java程序通常使用if-then-else或者switch-case语句进行assertion检查，而且检查的数据类型也不完全相同。assertion机制让Java程序员用统一的方式处理assertion问题，而不是按自己的方式处理。另外，如果用户使用自己的方式进行检查，那么这些代码在发布以后仍然将起作用，这可能会影响程序的性能。而从语言言层次支持assertion功能，这将把assertion对性能带来的负面影响降到最小。</p>
<p>Java是通过增强一个关键字assert实现支持assertion，而不是使用一个库函数支持，这说明Java认为assertion对于语言本身来说是非常重要的。实际上，在Java的早期的规范中，Java是能够支持assert的，但是由于一些实现的限制，这些特性从规范中除去了。因此，assert的再次引入应该是恢复了Java对assert的支持。C语言就是通过Assert.h函数库实现断言的支持。</p>
<p>Java的assertion的开启也和C语言不太一样，我们都知道在C语言中，assertion的开启是在编译时候决定的。当我们使用debug方式编译程序时候，assertion被开启，而使用release方式编译时候，assertion自动被关闭。而Java的assertion却是在运行的时候进行决定的。其实，这两种方式是各有优缺点。如果采用编译时决定方式，开发人员将处理两种类型的目标码，debug版本和release版本，这加大了文档管理的难度，但是提高了代码的运行效率。Java采用运行时决定的方式，这样所有的assertion信息将置于目标代码中，同一目标代码可以选择不同方式运行，增强目标代码的灵活性，但是它将牺牲因为assertion而引起一部分性能损失。Java专家小组认为，所牺牲的性能相当小，因此java采用了运行时决定方式。</p>
<p>另外，我们注意到AssertionError作为Error的一个子类，而不是RuntimeException。关于这一点，专家组也进行了长期的讨论。Error代表一些异常的错误，通常是不可以恢复的，而RuntimeException强调该错误在运行时才发生的特点。AssertionError通常为非常关键的错误，这些错误往往是不容易恢复的，而且assertion机制也不鼓励程序员对这种错误进行恢复。因此，为了强调assertion的含义，Java专家小组选择了让AssertError为Error的子类。</p>
<p><a name=3><span class=atitle>assertion与继承</span></a></p>
<p>
<p>在本节，我们将考虑assertion与继承的关系，研究assert是如何定位的。如果开启一个子类的assertion，那么它的父类的assertion是否执行？</p>
<p>下面的例子将显示如果一个assert语句在父类，而当它的子类调用它时，该assert为false。我们看看在不同的情况下，该assertion是否被处理。</p>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>class Base
            {
            public void baseMethod()
            {
            assert      false : "Assertion failed:This is base ";// 总是assertion失败
            System.out.println("Base Method");
            }
            }
            class Derived
            extends Base
            {
            public void derivedMethod()
            {
            assert false: "Assertion failed:This is derive";// 总是assertion失败
            System.out.println( "Derived Method" );
            }
            public static void main( String[] args )
            {
            try
            {
            Derived derived = new Derived();
            derived.baseMethod(  );
            derived.derivedMethod();
            }
            catch( AssertionError ae )
            {
            System.out.println(ae);
            }
            }
            }</pre>
            </td>
        </tr>
    </tbody>
</table>
<p><a name=4><span class=atitle>assertion的使用</span></a></p>
<p>
<p>assertion的使用是一个复杂的问题，因为这将涉及到程序的风格，assertion运用的目标，程序的性质等问题。通常来说，assertion用于检查一些关键的值，并且这些值对整个程序，或者局部功能的完成有很大的影响，并且这种错误不容易恢复的。assertion表达式应该短小、易懂，如果需要评估复杂的表达式，应该使用函数计算。以下是一些使用assertion的情况的例子，这些方式可以让java程序的可靠性更高。</p>
<ol>
    <li>检查控制流； 在if-then-else和swith-case语句中，我们可以在不应该发生的控制支流上加上assert false语句。如果这种情况发生了，assert能够检查出来。例如：x取值只能使1,2,3，我们的程序可以如下表示
    <table cellSpacing=0 cellPadding=0 width="100%" border=0>
        <tbody>
            <tr>
                <td class=code-outline>
                <pre class=displaycode>	switch (x)
                { case 1: &#8230;;
                case 2: &#8230;;
                case 3: &#8230;
                default: assert false:"x value is invalid: "+x;
                }
                </pre>
                </td>
            </tr>
        </tbody>
    </table>
    <br><br>
    <li>在私有函数计算前，检查输入参数是否有效；对于一私有些函数，要求输入满足一些特定的条件，那么我们可以在函数开始处使用assert进行参数检查。对于公共函数，我们通常不使用assertion检查，因为一般来说，公共函数必须对无效的参数进行检查和处理。而私有函数往往是直接使用的。 <br>例如：某函数可能要求输入的参数必须不为null。那么我们可以在函数的一开始加上 <code>assert parameter1!=null : "paramerter is null in test method";</code> <br>
    <li>在函数计算后，检查函数结果是否有效；对于一些计算函数，函数运行完成后，某些值需要保证一定的性质，因此我们可以通过assert检查该值。例如，我们有一个计算绝对值的函数，那么我们就可以在函数的结果处，加上一个语句：
    <table cellSpacing=0 cellPadding=0 width="100%" border=0>
        <tbody>
            <tr>
                <td class=code-outline>
                <pre class=displaycode>assert  value&gt;=0:"Value should be bigger than 0:"+value;</pre>
                </td>
            </tr>
        </tbody>
    </table>
    <br><br>通过这种方式，我们可以对函数计算完的结果进行检查。
    <li>检查程序不变量；有些程序中，存在一些不变量，在程序的运行生命周期，这些不变量的值都是不变的。这些不变量可能是一个简单表达式，也可能是一个复杂的表达式。对于一些关键的不变量，我们可以通过assert进行检查。例如，在一个财会系统中，公司的支出和收入必须保持一定的平衡关系，因此我们可以编写一个表达式检查这种平衡关系，如下表示。
    <table cellSpacing=0 cellPadding=0 width="100%" border=0>
        <tbody>
            <tr>
                <td class=code-outline>
                <pre class=displaycode>      private boolean isBalance() {
                &#8230;&#8230;
                }
                </pre>
                </td>
            </tr>
        </tbody>
    </table>
    <br><br>在这个系统中，在一些可能影响这种平衡关系的方法的前后，我们都可以加上assert验证： <code>assert isBalance():"balance is destoried"; </code></li>
</ol>
<p><a name=5><span class=atitle>结论</span></a></p>
<p>
<p>assertion为开发人员提供了一种灵活地调试和测试机制，它的使用也非常简单、方便。但是，如何规范、系统地使用assertion(特别是在Java语言中)仍然是一个亟待研究的问题。<br>
<table width="60%" border=1>
    <tbody>
        <tr>
            <td>运行命令</td>
            <td>含义</td>
            <td>结果</td>
        </tr>
        <tr>
            <td>Java Derived</td>
            <td>不启用assertion</td>
            <td>Base MethodDerived Method</td>
        </tr>
        <tr>
            <td>Java -ea Derived</td>
            <td>开启所有assertion</td>
            <td>Java.lang.AssertionError:Assertion Failed:This is base</td>
        </tr>
        <tr>
            <td>Java -da Derived</td>
            <td>关闭所有assertion</td>
            <td>Base MethodDerived Method</td>
        </tr>
        <tr>
            <td>Java -ea:Base Derived</td>
            <td>仅打开Base的assertion</td>
            <td>Java.lang.AssertionError:Assertion Failed:This is base</td>
        </tr>
        <tr>
            <td>Java -ea:Derived Derived</td>
            <td>仅打开Derived的assertion</td>
            <td>Base MethodJava.lang.AssertionError:Assertion Failed:This is derived</td>
        </tr>
    </tbody>
</table>
</p>
<p>从这个例子我们可以看出，父类的assert语句将只有在父类的assert开启才起作用，如果仅仅开启子类的assert，父类的assert仍然不运行。例如，我们执行java -ea:Derived Derived的时候，Base类的assert语句并不执行。因此，我们可以认为，assert语句不具有继承功能。</p>
<br>
<img src ="http://www.blogjava.net/19851985lili/aggbug/122920.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/19851985lili/" target="_blank">☜♥☞MengChuChen</a> 2007-06-08 19:29 <a href="http://www.blogjava.net/19851985lili/articles/122920.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>面向Web的JMS应用系统</title><link>http://www.blogjava.net/19851985lili/articles/119725.html</link><dc:creator>☜♥☞MengChuChen</dc:creator><author>☜♥☞MengChuChen</author><pubDate>Thu, 24 May 2007 07:06:00 GMT</pubDate><guid>http://www.blogjava.net/19851985lili/articles/119725.html</guid><wfw:comment>http://www.blogjava.net/19851985lili/comments/119725.html</wfw:comment><comments>http://www.blogjava.net/19851985lili/articles/119725.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/19851985lili/comments/commentRss/119725.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/19851985lili/services/trackbacks/119725.html</trackback:ping><description><![CDATA[<p>JMS面向Web的应用与面向桌面的应用相比，有特殊的用户环境要求：同一个消息必须能被若干未知的用户消费，因此在消息接收方必须有"接收而不确认"的提交机制；本文以CWNF校务系统为实现案例，讨论面向Web的JMS应用系统消息提交原理及采用的关键技术。</p>
<p>消息传递是一种在软件组件或应用之间进行分布式通信的松散耦合方法，与各种紧密耦合通信技术（如CORBA、Java RMI、COM/DCOM）相比，不同之处在于：①消息系统是一种对等实施，通信双方即消息的发送者和接受者都是该系统中的客户端，彼此不呈C/S关系；②通信双方的工作是异步的；③基于消息格式一致，通信双方只需一个中介来存储并管理消息就可以实现通信，而紧密耦合技术则需要知道远程方法在本地的接口。因自身特点，消息传递技术在企业中和企业间有较广泛的应用需求。</p>
<p>JMS（Java Message Service）是J2EE企业平台的Java消息服务，目前主流J2EE产品的JMS都实现了存储功能，JMS客户端通过JMS API创建，彼此间通过目的地（Destination）对象进行通信；可是JMS消息系统多见于桌面应用，而Web应用鲜见，本文以笔者开发的CWNF校务系统为案例，讨论面向Web的JMS应用系统的实现原理及采用的关键技术。</p>
<h4>1&nbsp;&nbsp;面向Web的JMS应用系统实现原理</h4>
<h4>1.1&nbsp;&nbsp;JMS应用系统消息传递原理</h4>
<br>
<p>JMS应用系统有4个部分：①JMS提供者（JMS Provider），是一个逻辑数据存储体，并提供管理工具和控制特性；②JMS客户端，是用Java语言编写的发送或接收消息的组件或应用；③消息，是JMS客户端间被传递的承载信息的对象；④被管理对象，是系统管理员为客户端预置的JMS对象，包括目的地对象和连接工厂对象，其中目的地对象是客户端间的消息中介。这4个部分通过JNDI相关联：管理员通过管理工具把目的地对象和连接工厂对象绑定到一个JNDI API命名空间中，JMS客户端就可以在命名空间中查找这些对象，并通过JMS提供者建立与这些对象的逻辑连接，从而彼此之间实现通信（图1）。JMS支持2种消息传递域：点到点、发布/订阅，与之相对应的消息目的地对象也有2种：队列、主题。</p>
<p><img alt="" src="http://gceclub.sun.com.cn/yuanchuang/2004_Q4/jms01.jpg" border=0></p>
<h4>1.2&nbsp;&nbsp;Web应用的消息提交机制</h4>
<br>
<p>通常，无论是消息发送方还是接收方，桌面应用都不容许消息丢失或重复，JMS消息提交机制是基于这个要求的，它们从不同方面保证该要求的实现：①在接收方控制消息的确认。通过确认保证一个接收者对一个消息只消费一次，在非事务性的会话中，消息确认方式取决于create&#215;&#215;&#215;Session方法第二个参数的值；在事务性会话中，无论由Bean管理事务还是由Bean容器管理事务，消息确认都由Bean容器自动完成。②在发送方指定消息的提交模式和生存期。提交模式有两种：PERSISTENT(稳定存储)和NON_PERSISTENT(非稳定存储)，稳定存储保证在故障情况下消息不会丢失；生存期决定一个消息在存储中介中的存在寿命，JMS提供者会自动摧毁到期的消息。③创建持久定阅的接收方。在发布/订阅系统中，持久订阅者可以接收到在订阅者关闭阶段消息发送方发布的消息。</p>
<p>但是Web应用系统在消息接收方有Web特有的用户环境要求：①若干个用户共用一个JMS客户端组件，因此消息就应向一个消息接收者提交而不需确认，具有容器自动确认功能的Bean是无法实现这一要求的；在一个组件内如果把会话设置成事务性的，而这个组件的容器又不具有事务管理能力，则这个组件就能做到"接收而不确认"，在Web应用系统中只有Servlet组件符合这一要求。②JMS客户端的消息接收者经常关闭，为了接收在关闭期间发送来的消息，消息接收者必定是基于主题的持久定阅者，所以面向Web的JMS应用系统必定采用发布/订阅消息传递域。</p>
<h4>2&nbsp;&nbsp;CWNF校务系统模型</h4>
<br>
<p>CWNF是一个面向Web的JMS校务系统，用于校园发布通知及征求意见等校务工作，通知分为2类：普通通知和征求意见性通知。</p>
<p>该系统用户分成3类，用户不同，处理模型也不同，基本情况如下：①发布用户，拥有通知发布权，向主题发布通知；②署名用户，查阅通知，也可发表对征求意见性通知的反馈意见；③匿名用户，只查阅通知。</p>
<h4>2.1&nbsp;&nbsp;数据与数据流模型</h4>
<br>
<p>系统中的数据因此有2类：通知、反馈。接收方接收的数据将形成一个XML文档对象，以便发往Web浏览器显示；基于这样的要求，考察下面2个问题：①系统中各方之间的数据关系，②各方数据的形式。</p>
<p>主要的数据关系有3个：①通知发送方与通知接收方的数据关系，②反馈发送方与反馈接收方的数据关系，③通知接收方与反馈接收方的数据关系。（如图2）在发送方，数据（通知或反馈）是一件一件的发送，在接收方，数据（通知或反馈）则是批接收，是对应发送方数据的集合，因此在发送方没有必要把数据直接加工成XML文档对象形式，只要生成能构成XML文档对象的元素对象即可；而通知接收方与反馈接收方的数据关系则是：每一条征求意见性通知都有相关的一个反馈集合。</p>
<p><img height=224 alt="" src="http://gceclub.sun.com.cn/yuanchuang/2004_Q4/jms02.jpg" width=450 border=0></p>
<p>系统的数据流模型如下：<br>①通知发送方：表单数据&#8594;XML元素（通知）&#8594;主题(存储)<br>②通知接收方：主题(存储)&#8594;XML元素（通知）&#8594;XML文档（通知）&#8594;XSL显示（含表单）<br>③通知接收方到反馈接收方: XSL显示（含表单）&#8594;主题（存储）<br>④反馈接收方：主题(存储)&#8594;XML元素（反馈）&#8594;XML文档（反馈）&#8594;XSL显示（含表单）<br>⑤反馈发送方：表单数据&#8594;XML元素（反馈）&#8594;主题(存储)</p>
<h4>2.2&nbsp;&nbsp;组件模型</h4>
<br>
<p>系统组件模型如图3：主题CWNFTopic是消息传递中介，NoticerServlet组件向发布用户发送表单，并从表单接收数据，然后生成XML元素对象，该元素对象和其它一些数据被作为参数调用PublisherBean组件方法，向主题发送以该元素对象为消息体的消息；ReaderServlet组件处理署名用户和匿名用户查阅通知的业务，它从表单获得用户将查阅什么方面通知的有关信息后，便使用receive方法限时阻塞地从主题接收消息并对消息进行筛选，把筛选出的若干消息的消息体取出，然后加工成XML文档对象（根元素是通知集），最后输出。FeedbackerPubServlet用于反馈发送方的业务处理，功能与NoticerServlet相似；FeedbackerSubServlet用于反馈接收方的业务处理，功能与ReaderServlet相似；PublisherBean组件被NoticerServlet组件和FeedbackerPubServlet组件调用，用于发送消息，容器管理发送事务，具有很高的可靠性。</p>
<p><img height=383 alt="" src="http://gceclub.sun.com.cn/yuanchuang/2004_Q4/jms03.jpg" width=609 border=0></p>
<h4>3&nbsp;&nbsp;关键的实现技术</h4>
<h4>3.1&nbsp;&nbsp;JDOM建立、输出XML文档</h4>
<br>
<p>JDOM是一个开放源代码的纯Java树式API，用于分析、建立、处理和序列化XML文档。在数据流模型中，XML元素和XML文档都由JDOM API建立，在发送方，通过用户提交的表单取得名/值对若干，这些数据经过JDOM方法处理生成XML元素对象，元素对象被作为消息的消息体发往主题存储；在接收方，持久订阅者接收到若干XML元素对象后，继续通过JDOM方法建立XML文档对象。且XML文档向Web浏览器输出也依赖于JDOM的XMLOutputte对象方法：</p>
<table class=grey4 cellSpacing=0 cellPadding=10 border=0>
    <tbody>
        <tr>
            <td>
            <pre>XMLOutputter serializer=new XMLOutputter();
            ...
            PrintWriter out=response.getWriter();	// out 是ServletResponse的输出流对象
            serializer.output(xmldoc,out);			//通过out把XML文档输出到页面
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<h4>3.2&nbsp;&nbsp;XSL定义XML文档显示样式</h4>
<br>
<p>XSL是可扩展的样式单语言，通知集的XML文档和反馈集的XML文档都有相关的XSL文档决定其页面显示，如通知集XML文档的XSL样式定义如下：</p>
<table class=grey4 cellSpacing=0 cellPadding=10 border=0>
    <tbody>
        <tr>
            <td>
            <pre>&lt;?xml version="1.0" encoding="GBK"?&gt;
            &lt;xsl:stylesheet&gt;
            &lt;xsl:template match="/"&gt;
            &lt;HTML&gt;
            &lt;BODY&gt;
            ...
            &lt;DIV&gt;&lt;xsl:apply-templates select="通知集"/&gt;&lt;/DIV&gt;
            &lt;/BODY&gt;
            &lt;/HTML&gt;
            &lt;/xsl:template&gt;
            &lt;xsl:template match="通知集"&gt;
            &lt;xsl:for-each select="通知"&gt;
            ...
            &lt;/xsl:for-each&gt;
            &lt;/xsl:template&gt;
            &lt;/xsl:stylesheet&gt;
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<h4>3.3&nbsp;&nbsp;Servlet间数据的传递</h4>
<h4>3.3.1&nbsp;&nbsp;注册/登录</h4>
<br>
<p>用户的一些处理工作需要注册/登录后才能进行，因此注册/登录的获准信息必须能在有关Servlet组件之间传递。ServletContext 对象可设置和读取属性，使不同Servlet之间相互通信，在系统中被用于有关组件对用户身份的验证。</p>
<h4>3.3.2&nbsp;&nbsp;通知与反馈的数据关联</h4>
<br>
<p>每一条征求意见性通知都有一个相关联的反馈集合，关联可通过设置消息属性实现。JMS消息（包括通知类消息）都有系统级JMSMessageID属性，其值是唯一的，可用于表征每一条征求意见性通知，因此对任何反馈消息也可以设置一个应用级属性（CWNF中是FeedbackSN），让它取与之相关联的征求意见性通知的JMSMessageID属性值。这样就建立了两者间的数据关联。</p>
<p>因此数据流模型"③通知接收方到反馈接收方: XSL显示（含表单）&#8594;主题（存储）"的实现流程如下：用户在页面上选择一条征求意见性通知后，该通知的JMSMessageID属性值将被传递给FeedbackerSubServlet组件，该组件将使用这个属性值去匹配从主题取出的反馈消息的FeedbackSN属性，从而筛选出相关联的反馈消息。</p>
<p>那么一条征求意见性通知的JMSMessageID属性值又如何传递给FeedbackerSubServlet组件呢？通过ServletContext对象只能传递可预知信息，CWNF的做法是：由XSL为每一条征求意见性通知设置一个独立的表单，并把该通知的JMSMessageID属性值写在表单的TEXTAREA元素框内，这样用户在表单上选择一条征求意见性通知后，该通知的JMSMessageID属性值就随表单一起提交给FeedbackerSubServlet组件。XSL有关代码如下：</p>
<table class=grey4 cellSpacing=0 cellPadding=10 border=0>
    <tbody>
        <tr>
            <td>
            <pre>&lt;xsl:if test="string(意见反馈)='on'"&gt;
            &lt;FORM method="post" action="http://localhost:6888/Feedbacker/servlet
            /FeedbackerSubServlet"&gt;
            &lt;BUTTON type="submit"&gt;意见反馈&lt;/BUTTON&gt;
            &lt;TEXTAREA name="序列号" rows="1" cols="40"&gt;
            &lt;xsl:value-of select="序列号"/&gt;
            &lt;/TEXTAREA&gt;
            &lt;/FORM&gt;
            &lt;/xsl:if&gt;
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<h4>4&nbsp;&nbsp;结束语</h4>
<br>
<p>JMS应用系统与数据库系统有相似性，从数据方面看，JMS消息体的数据类型支持文本和对象，所以JMS更灵活，与XML集成应用的空间更大；但从管理上看，JMS Provider向管理员提供的管理功能远远低于DBMS提供的管理功能，因此在面向Web的应用中，JMS宜作为中小流量、管理员参与度较低的信息系统解决方案。</p>
<p>CWNF校务系统经校园网实验性运行，效果良好，验证了面向Web的JMS应用是可行的。</p>
<img src ="http://www.blogjava.net/19851985lili/aggbug/119725.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/19851985lili/" target="_blank">☜♥☞MengChuChen</a> 2007-05-24 15:06 <a href="http://www.blogjava.net/19851985lili/articles/119725.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>简明 XHTML 1.0 参考手册</title><link>http://www.blogjava.net/19851985lili/articles/116583.html</link><dc:creator>☜♥☞MengChuChen</dc:creator><author>☜♥☞MengChuChen</author><pubDate>Thu, 10 May 2007 12:43:00 GMT</pubDate><guid>http://www.blogjava.net/19851985lili/articles/116583.html</guid><wfw:comment>http://www.blogjava.net/19851985lili/comments/116583.html</wfw:comment><comments>http://www.blogjava.net/19851985lili/articles/116583.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/19851985lili/comments/commentRss/116583.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/19851985lili/services/trackbacks/116583.html</trackback:ping><description><![CDATA[<h2>过渡型XHTML文档头与文档结构</h2>
<div id=过渡型XHTML文档头与文档结构><samp>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;<br>&lt;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh-CN"&gt;<br>&lt;head&gt;<br>&lt;meta http-equiv="Content-Type" content="text/html; charset=gb2312" /&gt;<br>&lt;meta http-equiv="Content-Language" content="zh-CN" /&gt;<br>&lt;style type="text/css" media="all"&gt;<br>&lt;/style&gt;<br>&lt;!-- 其他文档头元素 --&gt;<br>&lt;title&gt;文档标题&lt;/title&gt;<br>&lt;/head&gt;<br>&lt;body&gt;<br>&lt;/body&gt;<br>&lt;/html&gt;<br></samp></div>
<!-- ======== 通用字符实体 =============-->
<hr>
<h2>通用字符实体</h2>
<div id=通用字符实体>
<table id=通用字符实体表>
    <tbody>
        <tr>
            <th width=60>实体</th>
            <th width=60>含义</th>
        </tr>
        <tr>
            <td>&amp;quot;</td>
            <td>"</td>
        </tr>
        <tr>
            <td>&amp;amp;</td>
            <td>&amp;</td>
        </tr>
        <tr>
            <td>&amp;lt;</td>
            <td>&lt;</td>
        </tr>
        <tr>
            <td>&amp;gt;</td>
            <td>&gt;</td>
        </tr>
    </tbody>
</table>
</div>
<!-- ======== 属性值的数据类型 =============-->
<hr>
<h2>属性值的数据类型</h2>
<div id=属性值的数据类型>
<p>[注意]所有属性值编码后的长度都不能超过<strong>1024</strong>字节。</p>
<p>[释疑] 一段被 <samp>&lt;![CDATA[</samp> 和 <samp>]]&gt;</samp>括起来的<dfn><font face="Courier New">CDATA节</font></dfn>表示一段不被解析的字符数据，其中可以直接使用 " &amp; &lt; &gt; 字符。<br><dfn><font face="Courier New">CDATA节</font></dfn>只能出现在元素的内容中，它与属性声明中的<dfn><font face="Courier New">CDATA</font></dfn>数据类型并无任何关系。</p>
<table id=属性值的基本类型>
    <caption>属性值的基本类型</caption>
    <tbody>
        <tr>
            <th width=70>数据类型</th>
            <th>解释</th>
        </tr>
        <tr>
            <td>ID</td>
            <td>整个文档范围内的唯一标识符</td>
        </tr>
        <tr>
            <td>IDREF</td>
            <td>在文档其他位置已定义的ID类型的值</td>
        </tr>
        <tr>
            <td>IDREFS</td>
            <td>空格分割的已定义的ID类型的值列表</td>
        </tr>
        <tr>
            <td>NMTOKEN</td>
            <td>面向处理程序的XML名称(记号)</td>
        </tr>
        <tr>
            <td>CDATA</td>
            <td>字符数据，必须对 &amp; &lt; 和 " 使用实体，多个空白符等价于单个空格。</td>
        </tr>
    </tbody>
</table>
<table id=NMTOKEN的派生类型>
    <caption>NMTOKEN的派生类型</caption>
    <tbody>
        <tr>
            <th width=70>数据类型</th>
            <th>解释</th>
        </tr>
        <tr>
            <td>语言代码</td>
            <td>比如："zh" "zh-CN" "zh-TW" "en-US"</td>
        </tr>
        <tr>
            <td>框架名</td>
            <td>预定义名称："_blank"(新窗口) "_self"(自身) "_parent"(父窗口) "_top"(顶层窗口) ；自定义的名称不能以下划线开头。</td>
        </tr>
    </tbody>
</table>
<table id=CDATA的派生类型>
    <caption>CDATA的派生类型</caption>
    <tbody>
        <tr>
            <th width=70>数据类型</th>
            <th>解释</th>
        </tr>
        <tr>
            <td>MIME类型</td>
            <td>比如："text/css" "image/gif" "application/rss+xml"</td>
        </tr>
        <tr>
            <td>MIME列表</td>
            <td>逗号分隔的MIME类型列表。比如："text/*" "image/*,*/*"</td>
        </tr>
        <tr>
            <td>设备列表</td>
            <td>逗号分隔的设备类型列表。比如："all"(所有) "screen"(屏幕) "print"(打印机)</td>
        </tr>
        <tr>
            <td>字符编码</td>
            <td>比如："gb2312" "utf-8"</td>
        </tr>
        <tr>
            <td>关系列表</td>
            <td>空格分隔的连接关系列表。比如："Shortcut Icon"(图标,仅用于link) "Next"(下一个) "Prev"(上一个) "Parent"(上一级) "Start"(起点) "Contents Index"(目录 索引) "Alternate"(可替代文档) "Chapter"(章) "Section"(节) "Subsection"(子节) "Copyright"(版权) "Glossary"(词汇表) "Help"(帮助) "Appendix"(附录)</td>
        </tr>
        <tr>
            <td>URL</td>
            <td>比如："/new%20pricing.php?id=678" "mailto:rcpt@host?subject=sub&amp;cc=copy@net" "javascript:fun('cc');"</td>
        </tr>
        <tr>
            <td>URL列表</td>
            <td>空格分割的URL列表。比如："../index.html /test.html#frag #price"</td>
        </tr>
        <tr>
            <td>js脚本</td>
            <td>一段JavaScript脚本。比如："window.alert("XX公司主页");"</td>
        </tr>
        <tr>
            <td>简介</td>
            <td>对元素内容的摘要介绍。比如："XX公司简介"</td>
        </tr>
        <tr>
            <td>唯一字母</td>
            <td>整个文档范围内的唯一小写字母。比如："a"</td>
        </tr>
        <tr>
            <td>正整数</td>
            <td>一个大于零的正整数。比如："1"</td>
        </tr>
        <tr>
            <td>像素</td>
            <td>以像素为单位的长度。比如："2" "523" "0"</td>
        </tr>
        <tr>
            <td>长度</td>
            <td>"nn"表示像素长度，"nn%"表示百分比长度(相对于包含块的高度或宽度)。比如："3" "30%"</td>
        </tr>
        <tr>
            <td>混合长度</td>
            <td>"nn"表示像素长度，"nn%"表示百分比长度，"n*"表示剩余空间内的相对长度。比如："3*" "*" "5*"</td>
        </tr>
        <tr>
            <td>坐标序列</td>
            <td>逗号分隔的坐标序列。规则：矩形[x1,y1,x2,y2]，圆[x,y,r]，多边形[x1,y1,x2,y3,x3,y3,...,xn,yn]</td>
        </tr>
    </tbody>
</table>
</div>
<!-- ======== 通用属性组 =============-->
<hr>
<h2>通用属性组</h2>
<div id=通用属性组>
<table id=方框含义>
    <caption>方框含义</caption>
    <tbody>
        <tr>
            <th width=94>模式</th>
            <th>解释</th>
        </tr>
        <tr>
            <td>[]</td>
            <td>无默认值的可选属性</td>
        </tr>
        <tr>
            <td>["???"]</td>
            <td>有默认值的可选属性</td>
        </tr>
        <tr>
            <td>[*]</td>
            <td>无默认值的必需属性</td>
        </tr>
        <tr>
            <td>[定值"???"]</td>
            <td>值固定的必需属性</td>
        </tr>
    </tbody>
</table>
<table id=通用属性组_核心>
    <caption>%Core;(核心)</caption>
    <tbody>
        <tr>
            <th width=94>属性名</th>
            <th width=59>数据类型</th>
            <th>解释</th>
        </tr>
        <tr>
            <td>id</td>
            <td>ID</td>
            <td>[]为元素定义一个唯一引用名，以供 超连接、样式表、小程序、其他元素 等引用。</td>
        </tr>
        <tr>
            <td>class</td>
            <td>CDATA</td>
            <td>[]指定元素内容的样式类。其值为用空格分隔的样式类名称列表。</td>
        </tr>
        <tr>
            <td>title</td>
            <td>简介</td>
            <td>[]为元素指定一个标题。鼠标停留时会显示其内容，常作为热点帮助。</td>
        </tr>
    </tbody>
</table>
<table id=通用属性组_语言>
    <caption>%Lang;(语言)</caption>
    <tbody>
        <tr>
            <th width=94>属性名</th>
            <th width=59>数据类型</th>
            <th>解释</th>
        </tr>
        <tr>
            <td>xml:lang</td>
            <td>语言代码</td>
            <td>[]指定元素内容的语言。</td>
        </tr>
    </tbody>
</table>
<table id=通用属性组_事件>
    <caption>%Event;(事件)</caption>
    <tbody>
        <tr>
            <th width=94>属性名</th>
            <th width=59>数据类型</th>
            <th>解释</th>
        </tr>
        <tr>
            <td>onclick</td>
            <td>js脚本</td>
            <td>[]单击事件</td>
        </tr>
        <tr>
            <td>ondblclick</td>
            <td>js脚本</td>
            <td>[]双击事件</td>
        </tr>
        <tr>
            <td>onmousedown</td>
            <td>js脚本</td>
            <td>[]按下左键事件</td>
        </tr>
        <tr>
            <td>onmouseup</td>
            <td>js脚本</td>
            <td>[]释放左键事件</td>
        </tr>
        <tr>
            <td>onmouseover</td>
            <td>js脚本</td>
            <td>[]进入元素区域事件</td>
        </tr>
        <tr>
            <td>onmousemove</td>
            <td>js脚本</td>
            <td>[]在元素内移动事件</td>
        </tr>
        <tr>
            <td>onmouseout</td>
            <td>js脚本</td>
            <td>[]离开元素区域事件</td>
        </tr>
    </tbody>
</table>
<table id=通用属性组_焦点>
    <caption>%Focus;(焦点)</caption>
    <tbody>
        <tr>
            <th width=94>属性名</th>
            <th width=59>数据类型</th>
            <th>解释</th>
        </tr>
        <tr>
            <td>accesskey</td>
            <td>唯一字母</td>
            <td>[]定义选中该元素的快捷键(Alt+字母)</td>
        </tr>
        <tr>
            <td>tabindex</td>
            <td>正整数</td>
            <td>[]使用Tab键切换焦点时的顺序</td>
        </tr>
        <tr>
            <td>onfocus</td>
            <td>js脚本</td>
            <td>[]获得焦点事件</td>
        </tr>
        <tr>
            <td>onblur</td>
            <td>js脚本</td>
            <td>[]失去焦点事件</td>
        </tr>
    </tbody>
</table>
<p><strong><font face="Courier New">%Attrs; ＝ %Core; ＋ %Lang; ＋ %Event;</font></strong></p>
</div>
<!-- ======== 通用元素组 =============--><font face="Courier New">
<hr>
</font>
<h2>通用元素组</h2>
<div id=通用元素组>
<dl>
<dt>%inline;
<dd>"a | br|span|object|img|map|iframe | em|strong|dfn|samp|kbd|code|var|cite|q|abbr|acronym | input|select|textarea|label|button"
<dt>%INLINE;
<dd>(#PCDATA | %inline; | script)*
<dt>%block;
<dd>"div | p | h1|h2|h3|h4|h5|h6 | ul|ol|dl | pre|blockquote|address | fieldset | table"
<dt>%BLOCK;
<dd>(%block; | form | script)*
<dt>%Flow;
<dd>(%INLINE; | %BLOCK;) </dd></dl>
<p class=说明>[说明]"#PCDATA" 表示文本数据，必须对其中的 &amp; 和 &lt; 字符使用实体。</p>
</div>
<!-- ======== 文档结构与头部元素 =============-->
<hr>
<h2>文档结构与头部元素</h2>
<div id=文档结构与头部元素>
<table>
    <tbody>
        <tr class=语法>
            <td width=72>界定文档</td>
            <td width=65>%Lang;</td>
            <td>&lt;html&gt; head, body &lt;/html&gt;</td>
        </tr>
        <tr>
            <td>xmlns</td>
            <td>URL</td>
            <td>[定值"http://www.w3.org/1999/xhtml"]本篇文档的XML命名空间</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=72>文档头</td>
            <td width=65>%Lang;</td>
            <td>&lt;head&gt; (meta|link|style|script|object)*, base?, title &lt;/head&gt;</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=72>文档标题</td>
            <td width=65>%Lang;</td>
            <td>&lt;title&gt; #PCDATA &lt;/title&gt;</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=72>文档基准</td>
            <td width=65>&nbsp;</td>
            <td>&lt;base ... /&gt;</td>
        </tr>
        <tr>
            <td>href</td>
            <td>URL</td>
            <td>[]基准URL。比如："/info/"</td>
        </tr>
        <tr>
            <td>target</td>
            <td>框架名</td>
            <td>["_self"]默认的目标框架或窗口名称</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=72>元信息</td>
            <td width=65>%Lang;</td>
            <td>&lt;meta ... /&gt;</td>
        </tr>
        <tr>
            <td>http-equiv</td>
            <td>CDATA</td>
            <td>[]等价HTTP头字段名称</td>
        </tr>
        <tr>
            <td>name</td>
            <td>CDATA</td>
            <td>[]元信息的名称</td>
        </tr>
        <tr>
            <td>content</td>
            <td>CDATA</td>
            <td>[*]名称对应的值</td>
        </tr>
        <tr>
            <td>补充说明</td>
            <td colSpan=2>http-equiv与name必需二选一。<br>http-equiv常用："Content-Type"(MIME类型,字符编码) "Content-Language"(语言) "Refresh"(自动刷新) "Expires"(失效时间) "Cache-Control"(缓存控制) "MSThemeCompatible"(XP主题) "imagetoolbar"(图像工具栏) "Page-Enter"(载入特效) "Page-Exit"(退出特效)<br>name常用："keywords"(关键字列表) "description"(网页描述) "author"(作者) "Copyright"(版权信息) "revisit"(重访) "robots"(机器人指令) "abstract"(摘要) "classification"(分类) "page-topic"(网页主题) "placename"(地名)</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=72>文档关系</td>
            <td width=65>%Attrs;</td>
            <td>&lt;link ... /&gt;</td>
        </tr>
        <tr>
            <td>href</td>
            <td>URL</td>
            <td>[*]目标文档</td>
        </tr>
        <tr>
            <td>rel</td>
            <td>关系列表</td>
            <td>[*]从源文档到目标文档的关系</td>
        </tr>
        <tr>
            <td>rev</td>
            <td>关系列表</td>
            <td>[]从目标文档到源文档的关系</td>
        </tr>
        <tr>
            <td>hreflang</td>
            <td>语言代码</td>
            <td>[]目标文档的语言</td>
        </tr>
        <tr>
            <td>charset</td>
            <td>字符编码</td>
            <td>[]目标文档的字符编码</td>
        </tr>
        <tr>
            <td>type</td>
            <td>MIME类型</td>
            <td>[]目标文档的MIME类型</td>
        </tr>
        <tr>
            <td>media</td>
            <td>设备列表</td>
            <td>[]目标文档所属设备类型</td>
        </tr>
        <tr>
            <td>补充说明</td>
            <td colSpan=2>rel与rev属性的通常用法：<br>a)在文档集中导航(start, contents, prev, next, index, end, help)<br>c)连接到该文档的可替代版本(rel="alternate")，如：另一语言版本、RSS版本、PDF版本、打印版本</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=72>样式表</td>
            <td width=65>%Lang;</td>
            <td>&lt;style&gt; #PCDATA &lt;/style&gt;</td>
        </tr>
        <tr>
            <td>type</td>
            <td>MIME类型</td>
            <td>[定值"text/css"]</td>
        </tr>
        <tr>
            <td>media</td>
            <td>设备列表</td>
            <td>["screen"]适用的媒体类型</td>
        </tr>
        <tr>
            <td>title</td>
            <td>简介</td>
            <td>[]样式说明</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=72>JS脚本</td>
            <td width=65>&nbsp;</td>
            <td>&lt;script&gt; #PCDATA &lt;/script&gt;</td>
        </tr>
        <tr>
            <td>type</td>
            <td>MIME类型</td>
            <td>[定值"text/javascript"]</td>
        </tr>
        <tr>
            <td>src</td>
            <td>URL</td>
            <td>[]引用的外部javascript代码(*.js)位置</td>
        </tr>
        <tr>
            <td>charset</td>
            <td>字符编码</td>
            <td>[]与src属性一起使用，指明外部js文件的字符集</td>
        </tr>
        <tr>
            <td>defer</td>
            <td>(defer)</td>
            <td>[]指明js脚本并不修改XHTML代码，从而可推迟脚本的执行</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=72>文档体</td>
            <td width=65>%Attrs;</td>
            <td>&lt;body&gt; %BLOCK; &lt;/body&gt;</td>
        </tr>
        <tr>
            <td>onload</td>
            <td>js脚本</td>
            <td>[]文档被完全载入完毕时的事件</td>
        </tr>
        <tr>
            <td>onunload</td>
            <td>js脚本</td>
            <td>[]文档被卸载前的事件</td>
        </tr>
    </tbody>
</table>
</div>
<!-- ======== 结构元素 =============-->
<hr>
<h2>结构元素</h2>
<div id=结构元素>
<table>
    <tbody>
        <tr class=语法>
            <td width=92>标题</td>
            <td width=70>%Attrs;</td>
            <td>&lt;h1|h2|h3|h4|h5|h6&gt; %INLINE; &lt;/h1|h2|h3|h4|h5|h6&gt;</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=92>水平分割线</td>
            <td width=70>%Attrs;</td>
            <td>&lt;hr ... /&gt;</td>
        </tr>
        <tr>
            <td>noshade</td>
            <td>(noshade)</td>
            <td>[]不显示阴影</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=92>通用结构容器</td>
            <td width=70>%Attrs;</td>
            <td>&lt;div&gt; %Flow; &lt;/div&gt;</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=92>段落</td>
            <td width=70>%Attrs;</td>
            <td>&lt;p&gt; %INLINE; &lt;/p&gt;</td>
        </tr>
    </tbody>
</table>
</div>
<!-- ======== 锚 =============-->
<hr>
<h2>锚</h2>
<div id=锚>
<table>
    <tbody>
        <tr class=语法>
            <td>锚</td>
            <td>%Attrs; %Focus;</td>
            <td>&lt;a&gt; (%INLINE; - a) &lt;/a&gt;</td>
        </tr>
        <tr>
            <td>name</td>
            <td>NMTOKEN</td>
            <td>[]锚的名称</td>
        </tr>
        <tr>
            <td>charset</td>
            <td>字符编码</td>
            <td>[]所引用资源的字符编码</td>
        </tr>
        <tr>
            <td>type</td>
            <td>MIME类型</td>
            <td>[]所引用资源的MIME类型</td>
        </tr>
        <tr>
            <td>href</td>
            <td>URL</td>
            <td>[]所引用资源的URL</td>
        </tr>
        <tr>
            <td>hreflang</td>
            <td>语言代码</td>
            <td>[]所引用资源的语言</td>
        </tr>
        <tr>
            <td>rel</td>
            <td>关系列表</td>
            <td>[]从源文档到目标文档的关系</td>
        </tr>
        <tr>
            <td>rev</td>
            <td>关系列表</td>
            <td>[]从目标文档到源文档的关系</td>
        </tr>
        <tr>
            <td>target</td>
            <td>框架名</td>
            <td>[base.target]目标框架或窗口名称</td>
        </tr>
        <tr>
            <td>补充说明</td>
            <td colSpan=2>一般放在多个元素的最内层</td>
        </tr>
    </tbody>
</table>
</div>
<!-- ======== 列表元素 =============-->
<hr>
<h2>列表元素</h2>
<div id=列表元素>
<table>
    <tbody>
        <tr class=语法>
            <td width=100>有序|无序列表</td>
            <td width=70>%Attrs;</td>
            <td>&lt;ol|ul&gt; (li)+ &lt;/ol|ul&gt;</td>
        </tr>
        <tr>
            <td>compact</td>
            <td>(compact)</td>
            <td>[]紧凑显示</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=100>列表项</td>
            <td width=70>%Attrs;</td>
            <td>&lt;li&gt; %Flow; &lt;/li&gt;</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=100>定义列表</td>
            <td width=70>%Attrs;</td>
            <td>&lt;dl&gt; (dt,dd*)+ &lt;/dl&gt;</td>
        </tr>
        <tr>
            <td>compact</td>
            <td>(compact)</td>
            <td>[]紧凑显示</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=100>术语</td>
            <td width=70>%Attrs;</td>
            <td>&lt;dt&gt; %INLINE; &lt;/dt&gt;</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=100>解释</td>
            <td width=70>%Attrs;</td>
            <td>&lt;dd&gt; %Flow; &lt;/dd&gt;</td>
        </tr>
    </tbody>
</table>
</div>
<!-- ======== 文本元素 =============-->
<hr>
<h2>文本元素</h2>
<div id=文本元素>
<table>
    <tbody>
        <tr class=语法>
            <td width=115>内联样式容器</td>
            <td width=59>%Attrs;</td>
            <td>&lt;span&gt; %INLINE; &lt;/span&gt;</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=115>地址</td>
            <td width=59>%Attrs;</td>
            <td>&lt;address&gt; %INLINE; &lt;/address&gt;</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=115>预格式化文本</td>
            <td width=59>%Attrs;</td>
            <td>&lt;pre&gt; (%INLINE; - "img|object") &lt;/pre&gt;</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=115>大块引用</td>
            <td width=59>%Attrs;</td>
            <td>&lt;blockquote&gt; %BLOCK; &lt;/blockquote&gt;</td>
        </tr>
        <tr>
            <td>cite</td>
            <td>URL</td>
            <td>[]引用内容的来源</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=115>长|短内联引用</td>
            <td width=59>%Attrs;</td>
            <td>&lt;cite|q&gt; %INLINE; &lt;/cite|q&gt;</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=115>换行</td>
            <td width=59>%Core;</td>
            <td>&lt;br ... /&gt;</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=115>一般|重点强调</td>
            <td width=59>%Attrs;</td>
            <td>&lt;em|strong&gt; %INLINE; &lt;/em|strong&gt;</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=115>首用术语</td>
            <td width=59>%Attrs;</td>
            <td>&lt;dfn&gt; %INLINE; &lt;/dfn&gt;</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=115>普通|首字母缩写</td>
            <td width=59>%Attrs;</td>
            <td>&lt;abbr|acronym&gt; %INLINE; &lt;/abbr|acronym&gt;</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=115>样例</td>
            <td width=59>%Attrs;</td>
            <td>&lt;samp&gt; %INLINE; &lt;/samp&gt;</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=115>键盘输入</td>
            <td width=59>%Attrs;</td>
            <td>&lt;kbd&gt; %INLINE; &lt;/kbd&gt;</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=115>代码|变量</td>
            <td width=59>%Attrs;</td>
            <td>&lt;code|var&gt; %INLINE; &lt;/code|var&gt;</td>
        </tr>
    </tbody>
</table>
</div>
<!-- ======== 替换元素 =============-->
<hr>
<h2>替换元素</h2>
<div id=替换元素>
<table>
    <tbody>
        <tr class=语法>
            <td width=108>图像</td>
            <td width=122>%Attrs;</td>
            <td>&lt;img ... /&gt;</td>
        </tr>
        <tr>
            <td>src</td>
            <td>URL</td>
            <td>[*]图像文件的位置</td>
        </tr>
        <tr>
            <td>alt</td>
            <td>简介</td>
            <td>[*]图像替代文本，鼠标停留时会显示其内容</td>
        </tr>
        <tr>
            <td>longdesc</td>
            <td>URL</td>
            <td>[]对图像进行详细描述的页面</td>
        </tr>
        <tr>
            <td>height</td>
            <td>长度</td>
            <td>[]高度</td>
        </tr>
        <tr>
            <td>width</td>
            <td>长度</td>
            <td>[]宽度</td>
        </tr>
        <tr>
            <td>usemap</td>
            <td>URL</td>
            <td>[]客户端图像映射，其值为期望的&lt;map&gt;元素的name属性值。</td>
        </tr>
        <tr>
            <td>ismap</td>
            <td>(ismap)</td>
            <td>[]服务端图像映射(位于&lt;a&gt;中)，将单击处x,y坐标发给&lt;a&gt;的href属性指定的处理程序。</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=108>客户端图像映射</td>
            <td width=122>%Attrs;</td>
            <td>&lt;map&gt; area+ &lt;/map&gt;</td>
        </tr>
        <tr>
            <td>id</td>
            <td>ID</td>
            <td>[*]此处id为必需属性</td>
        </tr>
        <tr>
            <td>name</td>
            <td>NMTOKEN</td>
            <td>[*]用来被usemap属性引用的唯一标识符</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=108>图像映射区域</td>
            <td width=122>%Attrs; %Focus;</td>
            <td>&lt;area ... /&gt;</td>
        </tr>
        <tr>
            <td>shape</td>
            <td>(rect|circle|poly)</td>
            <td>["rect"]区域形状(矩形|圆|多边形)</td>
        </tr>
        <tr>
            <td>coords</td>
            <td>坐标序列</td>
            <td>[]矩形:"x1,y1,x2,y2" 圆:"x,y,R" 多边形:"x1,y1,x2,y2,x3,y3,..."</td>
        </tr>
        <tr>
            <td>href</td>
            <td>URL</td>
            <td>[]该区域对应的URL</td>
        </tr>
        <tr>
            <td>nohref</td>
            <td>(nohref)</td>
            <td>[]表明没有文档与这个区域有关，单击此区域没有任何效果。</td>
        </tr>
        <tr>
            <td>alt</td>
            <td>简介</td>
            <td>[*]对该区域的简短描述，鼠标停留时会显示其内容</td>
        </tr>
        <tr>
            <td>target</td>
            <td>框架名</td>
            <td>[base.target]目标框架或窗口名称</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=108>内联框架</td>
            <td width=122>%Core;</td>
            <td>&lt;iframe&gt; %Flow; &lt;/iframe&gt;</td>
        </tr>
        <tr>
            <td>name</td>
            <td>NMTOKEN</td>
            <td>[]框架的名称，将成为target属性的目标</td>
        </tr>
        <tr>
            <td>src</td>
            <td>URL</td>
            <td>[]显示在该框架中的初始文档</td>
        </tr>
        <tr>
            <td>frameborder</td>
            <td>(1|0)</td>
            <td>["1"]边框：显示|不显示</td>
        </tr>
        <tr>
            <td>scrolling</td>
            <td>(auto|yes|no)</td>
            <td>["auto"]滚动条：自动|始终显示|禁止显示</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=108>嵌入对象</td>
            <td width=122>%Attrs;</td>
            <td>&lt;object&gt; param*, %Flow; &lt;/object&gt;</td>
        </tr>
        <tr>
            <td>declare</td>
            <td>(declare)</td>
            <td>[]仅声明该对象而不将其实例化</td>
        </tr>
        <tr>
            <td>classid</td>
            <td>URL</td>
            <td>[]对象的URL</td>
        </tr>
        <tr>
            <td>codebase</td>
            <td>URL</td>
            <td>[]对象源代码的URL</td>
        </tr>
        <tr>
            <td>data</td>
            <td>URL</td>
            <td>[]需要被对象处理的数据</td>
        </tr>
        <tr>
            <td>type</td>
            <td>MIME类型</td>
            <td>[]被处理的数据的MIME类型</td>
        </tr>
        <tr>
            <td>codetype</td>
            <td>MIME类型</td>
            <td>[]源代码的MIME类型</td>
        </tr>
        <tr>
            <td>archive</td>
            <td>URL列表</td>
            <td>[]对象所使用的资源的URL列表</td>
        </tr>
        <tr>
            <td>standby</td>
            <td>简介</td>
            <td>[]对象下载完毕前显示的消息</td>
        </tr>
        <tr>
            <td>height</td>
            <td>长度</td>
            <td>[]高度</td>
        </tr>
        <tr>
            <td>width</td>
            <td>长度</td>
            <td>[]宽度</td>
        </tr>
        <tr>
            <td>usemap</td>
            <td>URL</td>
            <td>[]与对象一起使用的图像映射</td>
        </tr>
        <tr>
            <td>name</td>
            <td>NMTOKEN</td>
            <td>[]定义对象的名字</td>
        </tr>
        <tr>
            <td>tabindex</td>
            <td>正整数</td>
            <td>[]使用Tab键切换焦点时的顺序</td>
        </tr>
        <tr>
            <td>补充说明</td>
            <td colSpan=2>嵌入Flash示例：<br>&lt;object width="宽度" height="高度" standby="对象下载完毕前显示的消息" data="swf路径" type="application/x-shockwave-flash" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,19,0"&gt;<br>&lt;param name="movie" value="swf路径" /&gt;<br>&lt;img src="替代GIF" /&gt;<br>&lt;/object&gt;</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=108>对象参数</td>
            <td width=122>&nbsp;</td>
            <td>&lt;param ... /&gt;</td>
        </tr>
        <tr>
            <td>name</td>
            <td>CDATA</td>
            <td>[*]参数名</td>
        </tr>
        <tr>
            <td>value</td>
            <td>CDATA</td>
            <td>[*]参数值</td>
        </tr>
        <tr>
            <td>valuetype</td>
            <td>(data|ref|object)</td>
            <td>["data"]参数值的数据类型(数据|引用|对象)</td>
        </tr>
        <tr>
            <td>type</td>
            <td>MIME类型</td>
            <td>[]参数的MIME类型</td>
        </tr>
    </tbody>
</table>
</div>
<!-- ======== 表单元素 =============-->
<hr>
<h2>表单元素</h2>
<div id=表单元素>
<table>
    <tbody>
        <tr class=语法>
            <td width=116>表单</td>
            <td width=150>%Attrs;</td>
            <td>&lt;form&gt; (%block; | script)* &lt;/form&gt;</td>
        </tr>
        <tr>
            <td>action</td>
            <td>URL</td>
            <td>[*]接收表单数据的程序</td>
        </tr>
        <tr>
            <td>method</td>
            <td>(get|post)</td>
            <td>["get"]提交数据的方法，get能传递的数据长度(编码后)不超过1024字符且不能上传文件，post无此限制。</td>
        </tr>
        <tr>
            <td>enctype</td>
            <td>MIME类型</td>
            <td>["application/x-www-form-urlencoded"]另一值"multipart/form-data"仅在上传文件时使用，且此时必须用post方法。</td>
        </tr>
        <tr>
            <td>onsubmit</td>
            <td>js脚本</td>
            <td>[]提交数据前执行的js脚本</td>
        </tr>
        <tr>
            <td>onreset</td>
            <td>js脚本</td>
            <td>[]重置数据前执行的js脚本</td>
        </tr>
        <tr>
            <td>target</td>
            <td>框架名</td>
            <td>[base.target]将表单结果重定向到目标框架或窗口名称</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=116>字段组</td>
            <td width=150>%Attrs;</td>
            <td>&lt;fieldset&gt; legend?, %Flow; &lt;/fieldset&gt;</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=116>字段组标签</td>
            <td width=150>%Attrs;</td>
            <td>&lt;legend&gt; %INLINE; &lt;/legend&gt;</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=116>字段标签</td>
            <td width=150>%Attrs;</td>
            <td>&lt;label&gt; %INLINE; &lt;/label&gt;</td>
        </tr>
        <tr>
            <td>for</td>
            <td>IDREF</td>
            <td>[*]目标字段的id属性值</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=116>单行文本|密码框</td>
            <td width=150>%Attrs; %Focus;</td>
            <td>&lt;input type="text|password" ... /&gt;</td>
        </tr>
        <tr>
            <td>name</td>
            <td>CDATA</td>
            <td>[*]字段名</td>
        </tr>
        <tr>
            <td>value</td>
            <td>CDATA</td>
            <td>[*]字段默认值</td>
        </tr>
        <tr>
            <td>disabled</td>
            <td>(disabled)</td>
            <td>[]禁用该控件(灰显)，其值不会提交给服务器</td>
        </tr>
        <tr>
            <td>readonly</td>
            <td>(readonly)</td>
            <td>[]其值不能被用户修改，但是其值会提交给服务器</td>
        </tr>
        <tr>
            <td>size</td>
            <td>正整数</td>
            <td>[]控件长度(按字符数计算)</td>
        </tr>
        <tr>
            <td>maxlength</td>
            <td>正整数</td>
            <td>[]允许输入的最大字符数</td>
        </tr>
        <tr>
            <td>onselect</td>
            <td>js脚本</td>
            <td>[]选中事件</td>
        </tr>
        <tr>
            <td>onchange</td>
            <td>js脚本</td>
            <td>[]改变字段值事件</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=116>隐藏文本</td>
            <td width=150>%Core;</td>
            <td>&lt;input type="hidden" ... /&gt;</td>
        </tr>
        <tr>
            <td>name</td>
            <td>CDATA</td>
            <td>[*]字段名</td>
        </tr>
        <tr>
            <td>value</td>
            <td>CDATA</td>
            <td>[*]字段值</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=116>文件上传</td>
            <td width=150>%Attrs; %Focus;</td>
            <td>&lt;input type="file" ... /&gt;</td>
        </tr>
        <tr>
            <td>name</td>
            <td>CDATA</td>
            <td>[*]字段名</td>
        </tr>
        <tr>
            <td>value</td>
            <td>CDATA</td>
            <td>[]文件名(含路径)默认值</td>
        </tr>
        <tr>
            <td>disabled</td>
            <td>(disabled)</td>
            <td>[]禁用该控件(灰显)，其值不会提交给服务器</td>
        </tr>
        <tr>
            <td>readonly</td>
            <td>(readonly)</td>
            <td>[]其值不能被用户修改，但是其值会提交给服务器</td>
        </tr>
        <tr>
            <td>size</td>
            <td>正整数</td>
            <td>[]控件长度(按字符数计算)</td>
        </tr>
        <tr>
            <td>onchange</td>
            <td>js脚本</td>
            <td>[]改变字段值事件</td>
        </tr>
        <tr>
            <td>accept</td>
            <td>MIME列表</td>
            <td>[]限制用户可选择的文件类型</td>
        </tr>
        <tr>
            <td>补充说明</td>
            <td colSpan=2>必须有 form.method="post" 和 form.enctype="multipart/form-data"</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=116>单选|复选</td>
            <td width=150>%Attrs; %Focus;</td>
            <td>&lt;input type="radio|checkbox" ... /&gt;</td>
        </tr>
        <tr>
            <td>name</td>
            <td>CDATA</td>
            <td>[*]字段名(单选按钮使用它进行分组)</td>
        </tr>
        <tr>
            <td>value</td>
            <td>CDATA</td>
            <td>[*]字段值</td>
        </tr>
        <tr>
            <td>checked</td>
            <td>(checked)</td>
            <td>[]表示默认选中</td>
        </tr>
        <tr>
            <td>disabled</td>
            <td>(disabled)</td>
            <td>[]禁用该控件(灰显)，其值不会提交给服务器</td>
        </tr>
        <tr>
            <td>readonly</td>
            <td>(readonly)</td>
            <td>[]其值不能被用户修改，但是其值会提交给服务器</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=116>图像提交按钮</td>
            <td width=150>%Attrs; %Focus;</td>
            <td>&lt;input type="image" ... /&gt;</td>
        </tr>
        <tr>
            <td>name</td>
            <td>CDATA</td>
            <td>[]字段名，浏览器会将单击处的 name.x, name.y 坐标发送给服务器</td>
        </tr>
        <tr>
            <td>disabled</td>
            <td>(disabled)</td>
            <td>[]禁用该控件(灰显)，其值不会提交给服务器</td>
        </tr>
        <tr>
            <td>src</td>
            <td>URL</td>
            <td>[*]图像的URL</td>
        </tr>
        <tr>
            <td>alt</td>
            <td>CDATA</td>
            <td>[*]替代文字</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=116>通用按钮</td>
            <td width=150>%Attrs; %Focus;</td>
            <td>&lt;button&gt; (%Flow - a,表单元素) &lt;/button&gt;</td>
        </tr>
        <tr>
            <td>name</td>
            <td>CDATA</td>
            <td>[]字段名</td>
        </tr>
        <tr>
            <td>value</td>
            <td>CDATA</td>
            <td>[]字段值(并不显示在按钮上)</td>
        </tr>
        <tr>
            <td>type</td>
            <td>(button|submit|reset)</td>
            <td>["submit"]按钮类型(单击|提交|重置)</td>
        </tr>
        <tr>
            <td>disabled</td>
            <td>(disabled)</td>
            <td>[]禁用该控件(灰显)，其值不会提交给服务器</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=116>选择列表</td>
            <td width=150>%Attrs; %Focus;</td>
            <td>&lt;select&gt; (optgroup|option)+ &lt;/select&gt;</td>
        </tr>
        <tr>
            <td>name</td>
            <td>CDATA</td>
            <td>[*]字段名</td>
        </tr>
        <tr>
            <td>size</td>
            <td>正整数</td>
            <td>["1|4"]同时显示的项数，不设multiple时默认为1，反之为4</td>
        </tr>
        <tr>
            <td>multiple</td>
            <td>(multiple)</td>
            <td>[]允许多选，不设置则为单选</td>
        </tr>
        <tr>
            <td>disabled</td>
            <td>(disabled)</td>
            <td>[]禁用该控件(灰显)，其值不会提交给服务器</td>
        </tr>
        <tr>
            <td>onchange</td>
            <td>js脚本</td>
            <td>[]改变字段值事件</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=116>选项组</td>
            <td width=150>%Attrs;</td>
            <td>&lt;optgroup&gt; (option)+ &lt;/optgroup&gt;</td>
        </tr>
        <tr>
            <td>label</td>
            <td>简介</td>
            <td>[*]该组的标签(名称)，将会显示在每组首部</td>
        </tr>
        <tr>
            <td>disabled</td>
            <td>(disabled)</td>
            <td>[]禁用该控件(灰显)，其值不会提交给服务器</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=116>选项</td>
            <td width=150>%Attrs;</td>
            <td>&lt;option&gt; #PCDATA &lt;/option&gt;</td>
        </tr>
        <tr>
            <td>value</td>
            <td>CDATA</td>
            <td>[#PCDATA]条目的值，默认为元素包含的文本</td>
        </tr>
        <tr>
            <td>selected</td>
            <td>(selected)</td>
            <td>[]表示默认选中</td>
        </tr>
        <tr>
            <td>disabled</td>
            <td>(disabled)</td>
            <td>[]禁用该控件(灰显)，其值不会提交给服务器</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=116>多行文本</td>
            <td width=150>%Attrs; %Focus;</td>
            <td>&lt;textarea&gt; #PCDATA &lt;/textarea&gt;</td>
        </tr>
        <tr>
            <td>name</td>
            <td>CDATA</td>
            <td>[*]字段名</td>
        </tr>
        <tr>
            <td>rows</td>
            <td>正整数</td>
            <td>[*]输入区域的行数</td>
        </tr>
        <tr>
            <td>cols</td>
            <td>正整数</td>
            <td>[*]输入区域的列数</td>
        </tr>
        <tr>
            <td>disabled</td>
            <td>(disabled)</td>
            <td>[]禁用该控件(灰显)，其值不会提交给服务器</td>
        </tr>
        <tr>
            <td>readonly</td>
            <td>(readonly)</td>
            <td>[]其值不能被用户修改，但是其值会提交给服务器</td>
        </tr>
        <tr>
            <td>onselect</td>
            <td>js脚本</td>
            <td>[]选中事件</td>
        </tr>
        <tr>
            <td>onchange</td>
            <td>js脚本</td>
            <td>[]改变字段值事件</td>
        </tr>
    </tbody>
</table>
</div>
<!-- ======== 表格元素 =============-->
<hr>
<h2>表格元素</h2>
<div id=表格元素>
<table>
    <tbody>
        <tr class=语法>
            <td width=125>表格</td>
            <td width=198>%Attrs;</td>
            <td>&lt;table&gt; caption?, (col*|colgroup*), thead?, tfoot?, (tbody+|tr+) &lt;/table&gt;</td>
        </tr>
        <tr>
            <td>summary</td>
            <td>简介</td>
            <td>[]对表格内容的摘要描述</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=125>表格标题</td>
            <td width=198>%Attrs;</td>
            <td>&lt;caption&gt; %INLINE; &lt;/caption&gt;</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=125>列组</td>
            <td width=198>%Attrs;</td>
            <td>&lt;colgroup&gt; (col)* &lt;/colgroup&gt;</td>
        </tr>
        <tr>
            <td>span</td>
            <td>正整数</td>
            <td>["1"]该组的列数(紧接上一个列组)</td>
        </tr>
        <tr>
            <td>width</td>
            <td>混合长度</td>
            <td>[]宽度</td>
        </tr>
        <tr>
            <td>align</td>
            <td>(left|center|right)</td>
            <td>[]水平对齐</td>
        </tr>
        <tr>
            <td>valign</td>
            <td>(top|middle|bottom|baseline)</td>
            <td>[]垂直对齐</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=125>列</td>
            <td width=198>%Attrs;</td>
            <td>&lt;col ... /&gt;</td>
        </tr>
        <tr>
            <td>span</td>
            <td>正整数</td>
            <td>["1"]影响的列数(紧接上一个列)</td>
        </tr>
        <tr>
            <td>width</td>
            <td>混合长度</td>
            <td>[]宽度</td>
        </tr>
        <tr>
            <td>align</td>
            <td>(left|center|right)</td>
            <td>[]水平对齐</td>
        </tr>
        <tr>
            <td>valign</td>
            <td>(top|middle|bottom|baseline)</td>
            <td>[]垂直对齐</td>
        </tr>
        <tr>
            <td>补充说明</td>
            <td colSpan=2>仅用于不含span属性的&lt;colgroup&gt;元素中</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=125>表头|表脚|表正文</td>
            <td width=198>%Attrs;</td>
            <td>&lt;thead|tfoot|tbody&gt; (tr)+ &lt;/thead|tfoot|tbody&gt;</td>
        </tr>
        <tr>
            <td>align</td>
            <td>(left|center|right)</td>
            <td>[]水平对齐</td>
        </tr>
        <tr>
            <td>valign</td>
            <td>(top|middle|bottom|baseline)</td>
            <td>[]垂直对齐</td>
        </tr>
        <tr>
            <td>补充说明</td>
            <td colSpan=2>必需保持 头 -&gt; 脚 -&gt; 正文 的顺序</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=125>表格行</td>
            <td width=198>%Attrs;</td>
            <td>&lt;tr&gt; (th|td)+ &lt;/tr&gt;</td>
        </tr>
        <tr>
            <td>align</td>
            <td>(left|center|right)</td>
            <td>[]水平对齐</td>
        </tr>
        <tr>
            <td>valign</td>
            <td>(top|middle|bottom|baseline)</td>
            <td>[]垂直对齐</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr class=语法>
            <td width=125>表头|数据单元格</td>
            <td width=198>%Attrs;</td>
            <td>&lt;th|td&gt; %Flow; &lt;/th|td&gt;</td>
        </tr>
        <tr>
            <td>abbr</td>
            <td>简介</td>
            <td>[]单元格内容缩写</td>
        </tr>
        <tr>
            <td>axis</td>
            <td>CDATA</td>
            <td>[]一系列空格分割关键字列表，用于形成一个查询，而单元格的内容就是查询的结果</td>
        </tr>
        <tr>
            <td>scope</td>
            <td>(row|col|rowgroup|colgroup)</td>
            <td>[](仅&lt;th&gt;)关联到&lt;td&gt;：所在行|所在列|行组|列组</td>
        </tr>
        <tr>
            <td>rowspan</td>
            <td>正整数</td>
            <td>["1"]跨行数</td>
        </tr>
        <tr>
            <td>colspan</td>
            <td>正整数</td>
            <td>["1"]跨列数</td>
        </tr>
        <tr>
            <td>nowrap</td>
            <td>(nowrap)</td>
            <td>[]禁止换行</td>
        </tr>
        <tr>
            <td>align</td>
            <td>(left|center|right)</td>
            <td>[]水平对齐</td>
        </tr>
        <tr>
            <td>valign</td>
            <td>(top|middle|bottom|baseline)</td>
            <td>[]垂直对齐</td>
        </tr>
        <tr>
            <td>height</td>
            <td>长度</td>
            <td>[]高度</td>
        </tr>
        <tr>
            <td>width</td>
            <td>长度</td>
            <td>[]宽度</td>
        </tr>
    </tbody>
</table>
</div>
<hr>
<img src ="http://www.blogjava.net/19851985lili/aggbug/116583.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/19851985lili/" target="_blank">☜♥☞MengChuChen</a> 2007-05-10 20:43 <a href="http://www.blogjava.net/19851985lili/articles/116583.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>简明 CSS2.1 参考手册</title><link>http://www.blogjava.net/19851985lili/articles/116580.html</link><dc:creator>☜♥☞MengChuChen</dc:creator><author>☜♥☞MengChuChen</author><pubDate>Thu, 10 May 2007 12:40:00 GMT</pubDate><guid>http://www.blogjava.net/19851985lili/articles/116580.html</guid><wfw:comment>http://www.blogjava.net/19851985lili/comments/116580.html</wfw:comment><comments>http://www.blogjava.net/19851985lili/articles/116580.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/19851985lili/comments/commentRss/116580.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/19851985lili/services/trackbacks/116580.html</trackback:ping><description><![CDATA[<h2>导入样式表的方法(示范)</h2>
<div id=导入样式表的方法><samp>&lt;style type="text/css" media="all" title="应用于所有媒体的样式"&gt;<br>&nbsp; &nbsp; @import url(/style/css/global.css); /*全局样式*/<br>&nbsp; &nbsp; @import url(/style/css/skyblue.css); /*个性化样式*/<br>&nbsp; &nbsp; body { background: url(img/body_bg.gif); } /*文档级样式*/<br>&lt;/style&gt; </samp>
<ul>
    <li>目前受浏览器支持的设备类型仅有：<dfn><font face="Courier New">all</font></dfn>(所有)、<dfn><font face="Courier New">print</font></dfn>(打印机)、<dfn><font face="Courier New">screen</font></dfn>(计算机显示器)
    <li>必须在外部样式文件开头使用形如 <samp>@charset "gb2312";</samp> 的<dfn><font face="Courier New">At规则</font></dfn>来指定其自身使用的字符集。
    <li><dfn><font face="Courier New">@import</font></dfn> 必须放置在常规样式之前，不管是在&lt;style&gt;中还是在外部样式表中。 </li>
</ul>
</div>
<!-- ================================== 术语 ========================================================== -->
<hr>
<h2>术语</h2>
<div id=术语>
<dl>
<dt>替换元素
<dd>超出 CSS 格式器范围的元素。
<dd>HTML中的 img, input, textarea, select, object 都是替换元素。
<dd>所有的替换元素且仅有替换元素才具有固有尺寸。
<dt>块级元素
<dd>在视觉上被格式化为块的元素。浮动元素以及<dfn class=非继承属性><strong><font color=#0000bb>display</font></strong></dfn>属性等于<dfn><font face="Courier New">block</font></dfn>或<dfn><font face="Courier New">list-item</font></dfn>的元素都是块级元素。
<dt>内联元素
<dd>不形成新内容块的元素。<dfn class=非继承属性><strong><font color=#0000bb>display</font></strong></dfn>属性等于<dfn class=默认值><font color=#ff6600>inline</font></dfn>的元素都是内联元素。
<dt>已定位元素
<dd><dfn class=非继承属性><strong><font color=#0000bb>position</font></strong></dfn>属性不等于<dfn class=默认值><font color=#ff6600>static</font></dfn>的元素。 </dd></dl></div>
<!-- ========================================= 选择符 =================================================== -->
<hr>
<h2>选择符</h2>
<div id=选择符>
<dl>
<dt>简单选择符
<dd class=语法>[<var>E</var>|*][#<var>id</var>](.<var>class</var>)*[:<dfn><font face="Courier New">link</font></dfn>][:<dfn><font face="Courier New">visited</font></dfn>][:<dfn><font face="Courier New">hover</font></dfn>][:<dfn><font face="Courier New">active</font></dfn>]
<dt>伪元素
<dd class=语法><var>S</var>[:<dfn><font face="Courier New">first-letter</font></dfn>][:<dfn><font face="Courier New">first-line</font></dfn>]
<dt>嵌套
<dd class=语法><var>S1</var> <var>S2</var> ... <var>O</var>
<dt>群组
<dd class=语法><var>A1</var>, <var>A2</var>, ... <var>An</var> </dd></dl>
<ul>
    <li>符号含义：<var>E</var>(元素)、<var>S</var>(简单选择符)、<var>O</var>(简单选择符|伪元素)、<var>A</var>(简单选择符|伪元素|嵌套)
    <li>竖线"|"表示或关系，方括号"[]"表示可选，圆括号"()"用于正则分组。
    <li>所有标识符(元素名、类、ID)，都不能以 数字、连字符、下划线 开头，但是可以使用汉字。
    <li>伪类仅可用于超连接。伪元素仅可用于块元素。嵌套顺序中可以夹杂其他元素。
    <li>允许用于伪元素的属性仅有：字体属性、文本属性、前景背景属性。此外首字还可用：盒模型属性与<dfn class=非继承属性><strong><font color=#0000bb>float</font></strong></dfn>属性
    <li>层叠权重：<dfn><font face="Courier New">!important</font></dfn> &gt; ID &gt; (伪)类 &gt; (伪)元素 &gt; * </li>
</ul>
</div>
<!-- ================================== 属性值的数据类型 ========================================================== -->
<hr>
<h2>属性值的数据类型</h2>
<div id=属性值的数据类型>
<dl>
<dt>长度
<dd>绝对长度以 <dfn><font face="Courier New">mm</font></dfn> 或 <dfn><font face="Courier New">pt</font></dfn> 为单位(1<dfn><font face="Courier New">pt</font></dfn>=0.353<dfn><font face="Courier New">mm</font></dfn>)。
<dd>像素长度以 <dfn><font face="Courier New">px</font></dfn> 为单位(以96dpi为标准)，只能取整数值。
<dd>相对长度以 <dfn><font face="Courier New">em</font></dfn> 为单位(等于当前<dfn class=继承属性><strong><font color=#bb0000>font-size</font></strong></dfn>计算值)，继承时使用计算值。
<dt>百分比
<dd>使用 <span class=语法>nn%</span> 表示，是相对于另一个值的值，继承时使用计算值。
<dt>URL
<dd>使用 <span class=语法>url(URL)</span> 表示，必须使用"%XX"编码特殊字符(括号/逗号/引号等)，相对URL是指相对于样式表的URL。
<dt>颜色
<dd>使用 <span class=语法>#rrggbb</span> 或 <span class=语法>#rgb</span> 十六进制法表示，其值基于sRGB色彩空间，并且gamma值为2.2。
<dt>字体列表
<dd>用逗号分割的字体名称优先级列表(次序：英文&#8594;中文&#8594;系列)，字体名称含有空格时必须用引号界定。
<dd>安全英文serif(有衬线)系列字体：<span style="FONT-FAMILY: Georgia">Georgia</span> &nbsp; <span style="FONT-FAMILY: 'Palatino Linotype'">"Palatino Linotype"</span> &nbsp; <span style="FONT-FAMILY: 'Times New Roman'">"Times New Roman"</span>
<dd>安全英文sans-serif(无衬线)系列字体：<span style="FONT-FAMILY: Arial">Arial</span> &nbsp; <span style="FONT-FAMILY: Tahoma">Tahoma</span> &nbsp; <span style="FONT-FAMILY: 'Trebuchet MS'">"Trebuchet MS"</span> &nbsp; <span style="FONT-FAMILY: Verdana">Verdana</span>
<dd>安全英文monospace(等宽)系列字体：<span style="FONT-FAMILY: 'Courier New'">"Courier New"</span> &nbsp; <span style="FONT-FAMILY: 'Lucida Console'">"Lucida Console"</span>
<dd>安全英文cursive(模拟笔迹)系列字体：<span style="FONT-FAMILY: 'Comic Sans MS'">"Comic Sans MS"</span>
<dd>安全中文字体：<span style="FONT-FAMILY: 宋体">宋体</span> &nbsp; <span style="FONT-FAMILY: 仿宋_GB2312">仿宋_GB2312</span> &nbsp; <span style="FONT-FAMILY: 黑体">黑体</span> &nbsp; <span style="FONT-FAMILY: 楷体_GB2312">楷体_GB2312</span>
<dt>边框样式
<dd>枚举值：<dfn class=默认值 style="BORDER-TOP-STYLE: none; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none"><font color=#ff6600>none</font></dfn>(默认) | <dfn style="BORDER-TOP-STYLE: dotted; BORDER-RIGHT-STYLE: dotted; BORDER-LEFT-STYLE: dotted; BORDER-BOTTOM-STYLE: dotted"><font face="Courier New">dotted</font></dfn> | <dfn style="BORDER-TOP-STYLE: dashed; BORDER-RIGHT-STYLE: dashed; BORDER-LEFT-STYLE: dashed; BORDER-BOTTOM-STYLE: dashed"><font face="Courier New">dashed</font></dfn> | <dfn style="BORDER-TOP-STYLE: solid; BORDER-RIGHT-STYLE: solid; BORDER-LEFT-STYLE: solid; BORDER-BOTTOM-STYLE: solid"><font face="Courier New">solid</font></dfn> | <dfn style="BORDER-TOP-STYLE: double; BORDER-RIGHT-STYLE: double; BORDER-LEFT-STYLE: double; BORDER-BOTTOM-STYLE: double"><font face="Courier New">double</font></dfn> | <dfn style="BORDER-TOP-STYLE: groove; BORDER-RIGHT-STYLE: groove; BORDER-LEFT-STYLE: groove; BORDER-BOTTOM-STYLE: groove"><font face="Courier New">groove</font></dfn> | <dfn style="BORDER-TOP-STYLE: inset; BORDER-RIGHT-STYLE: inset; BORDER-LEFT-STYLE: inset; BORDER-BOTTOM-STYLE: inset"><font face="Courier New">inset</font></dfn> | <dfn style="BORDER-TOP-STYLE: outset; BORDER-RIGHT-STYLE: outset; BORDER-LEFT-STYLE: outset; BORDER-BOTTOM-STYLE: outset"><font face="Courier New">outset</font></dfn>
<dt>内置列表项图标
<dd>枚举值：<dfn class=默认值><font color=#ff6600>disc</font></dfn>(实心圆)|<dfn><font face="Courier New">circle</font></dfn>(空心圆)|<dfn><font face="Courier New">square</font></dfn>(方块)|<dfn><font face="Courier New">decimal</font></dfn>(数字)|<dfn><font face="Courier New">lower-roman</font></dfn>(小写罗马数字)|<dfn><font face="Courier New">upper-roman</font></dfn>(大写罗马数字)|<dfn><font face="Courier New">lower-alpha</font></dfn>(小写字母)|<dfn><font face="Courier New">upper-alpha</font></dfn>(大写字母)|<dfn><font face="Courier New">none</font></dfn>(无)
<dt>指针样式
<dd>枚举值：<dfn class=默认值 style="CURSOR: auto"><font color=#ff6600>auto</font></dfn>|<dfn style="CURSOR: crosshair"><font face="Courier New">crosshair</font></dfn>|<dfn style="CURSOR: default"><font face="Courier New">default</font></dfn>|<dfn style="CURSOR: pointer"><font face="Courier New">pointer</font></dfn>|<dfn style="CURSOR: move"><font face="Courier New">move</font></dfn>|<dfn style="CURSOR: wait"><font face="Courier New">wait</font></dfn>|<dfn style="CURSOR: help"><font face="Courier New">help</font></dfn>|<dfn style="CURSOR: progress"><font face="Courier New">progress</font></dfn>|<dfn style="CURSOR: not-allowed"><font face="Courier New">not-allowed</font></dfn> </dd></dl>
<p>[注意]对于速记属性，未指定的部分视为指定了<em>默认值</em>。</p>
</div>
<!-- =====================================字体属性============================================== -->
<hr>
<h2>字体属性</h2>
<div id=字体属性>
<table>
    <tbody>
        <tr>
            <th width=60>字体速记</th>
            <td class=语法><dfn class=继承属性><strong><font color=#bb0000>font</font></strong></dfn> : <dfn class=继承属性><strong><font color=#bb0000>font-style</font></strong></dfn> <dfn class=继承属性><strong><font color=#bb0000>font-weight</font></strong></dfn> <dfn class=继承属性><strong><font color=#bb0000>font-size</font></strong></dfn> <dfn class=继承属性><strong><font color=#bb0000>font-family</font></strong></dfn></td>
        </tr>
        <tr>
            <td>继承</td>
            <td>适用：所有元素</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr>
            <th width=60>字体倾斜</th>
            <td class=语法><dfn class=继承属性><strong><font color=#bb0000>font-style</font></strong></dfn> : <dfn class=默认值><font color=#ff6600>normal</font></dfn>|<dfn><font face="Courier New">italic</font></dfn></td>
        </tr>
        <tr>
            <td>继承</td>
            <td>适用：所有元素</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr>
            <th width=60>字体粗细</th>
            <td class=语法><dfn class=继承属性><strong><font color=#bb0000>font-weight</font></strong></dfn> : <dfn class=默认值><font color=#ff6600>normal</font></dfn>|<dfn><font face="Courier New">bold</font></dfn></td>
        </tr>
        <tr>
            <td>继承</td>
            <td>适用：所有元素</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr>
            <th width=60>字体大小</th>
            <td class=语法><dfn class=继承属性><strong><font color=#bb0000>font-size</font></strong></dfn> : <dfn><font face="Courier New">长度</font></dfn></td>
        </tr>
        <tr>
            <td>继承</td>
            <td>适用：所有元素</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr>
            <th width=60>字体族</th>
            <td class=语法><dfn class=继承属性><strong><font color=#bb0000>font-family</font></strong></dfn> : <dfn><font face="Courier New">字体列表</font></dfn></td>
        </tr>
        <tr>
            <td>继承</td>
            <td>适用：所有元素</td>
        </tr>
    </tbody>
</table>
</div>
<!-- =====================================文本属性=========================================== -->
<hr>
<h2>文本属性</h2>
<div id=文本属性>
<table>
    <tbody>
        <tr>
            <th width=75>文本划线</th>
            <td class=语法><dfn class=非继承属性><strong><font color=#0000bb>text-decoration</font></strong></dfn> : <dfn class=默认值><font color=#ff6600>none</font></dfn>|(<dfn><font face="Courier New">underline</font></dfn>‖<dfn><font face="Courier New">overline</font></dfn>‖<dfn><font face="Courier New">line-through</font></dfn>)</td>
        </tr>
        <tr>
            <td>非继承</td>
            <td>适用：所有元素</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr>
            <th width=75>字符间距</th>
            <td class=语法><dfn class=继承属性><strong><font color=#bb0000>letter-spacing</font></strong></dfn> : <dfn class=默认值><font color=#ff6600>normal</font></dfn>|<dfn><font face="Courier New">长度</font></dfn></td>
        </tr>
        <tr>
            <td>继承</td>
            <td>适用：所有元素</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr>
            <th width=75>大小写转换</th>
            <td class=语法><dfn class=继承属性><strong><font color=#bb0000>text-transform</font></strong></dfn> : <dfn class=默认值><font color=#ff6600>none</font></dfn>|<dfn><font face="Courier New">capitalize</font></dfn>|<dfn><font face="Courier New">uppercase</font></dfn>|<dfn><font face="Courier New">lowercase</font></dfn></td>
        </tr>
        <tr>
            <td>继承</td>
            <td>适用：所有元素</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr>
            <th width=75>首行缩进量</th>
            <td class=语法><dfn class=继承属性><strong><font color=#bb0000>text-indent</font></strong></dfn> : <dfn class=默认值><font color=#ff6600>0</font></dfn>|<dfn><font face="Courier New">长度</font></dfn></td>
        </tr>
        <tr>
            <td>继承</td>
            <td>适用：块元素/表格单元格/内联块</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr>
            <th width=75>行高</th>
            <td class=语法><dfn class=继承属性><strong><font color=#bb0000>line-height</font></strong></dfn> : <dfn class=默认值><font color=#ff6600>normal</font></dfn>|<dfn><font face="Courier New">缩放系数</font></dfn>|<dfn><font face="Courier New">长度</font></dfn>|<dfn><font face="Courier New">百分比</font></dfn></td>
        </tr>
        <tr>
            <td>继承</td>
            <td>适用：所有元素</td>
        </tr>
        <tr>
            <td colSpan=2>缩放系数按指定值继承</td>
        </tr>
        <tr>
            <td colSpan=2>百分比：相对于自身的<dfn class=继承属性><strong><font color=#bb0000>font-size</font></strong></dfn>属性值</td>
        </tr>
        <tr>
            <td colSpan=2>行高=文本高度+上下空白；<dfn class=默认值><font color=#ff6600>normal</font></dfn>大约相当于1.1～1.2的缩放系数。</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr>
            <th width=75>水平对齐</th>
            <td class=语法><dfn class=继承属性><strong><font color=#bb0000>text-align</font></strong></dfn> : <dfn class=默认值><font color=#ff6600>left</font></dfn>|<dfn><font face="Courier New">right</font></dfn>|<dfn><font face="Courier New">center</font></dfn></td>
        </tr>
        <tr>
            <td>继承</td>
            <td>适用：块元素/表格单元格/内联块</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr>
            <th width=75>垂直对齐</th>
            <td class=语法><dfn class=非继承属性><strong><font color=#0000bb>vertical-align</font></strong></dfn> : <dfn class=默认值><font color=#ff6600>baseline</font></dfn>|<dfn><font face="Courier New">sub</font></dfn>|<dfn><font face="Courier New">super</font></dfn>|<dfn><font face="Courier New">top</font></dfn>|<dfn><font face="Courier New">text-top</font></dfn>|<dfn><font face="Courier New">middle</font></dfn>|<dfn><font face="Courier New">bottom</font></dfn>|<dfn><font face="Courier New">text-bottom</font></dfn>|<dfn><font face="Courier New">长度</font></dfn>|<dfn><font face="Courier New">百分比</font></dfn></td>
        </tr>
        <tr>
            <td>非继承</td>
            <td>适用：内联元素/表格单元格</td>
        </tr>
        <tr>
            <td colSpan=2>百分比：相对于自身的<dfn class=继承属性><strong><font color=#bb0000>line-height</font></strong></dfn>属性值</td>
        </tr>
        <tr>
            <td colSpan=2>长度和百分比表示当前元素的基线相对于父元素基线的偏移量(上为正下为负，没有基线则使用底线)。</td>
        </tr>
    </tbody>
</table>
</div>
<!-- =================================前景和背景属性======================================= -->
<hr>
<h2>前景和背景属性</h2>
<div id=前景和背景属性>
<p>前景：内容+边框。背景：背景图+背景色。背景面积：内容+补白+边框。透明：补白/边框空隙/边界。</p>
<table>
    <tbody>
        <tr>
            <th width=60>前景色</th>
            <td class=语法><dfn class=继承属性><strong><font color=#bb0000>color</font></strong></dfn> : <dfn><font face="Courier New">颜色</font></dfn></td>
        </tr>
        <tr>
            <td>继承</td>
            <td>适用：所有元素</td>
        </tr>
        <tr>
            <td colSpan=2>hr 元素默认不执行继承。由于IE的错误，表格与图片的边框也不执行继承。</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr>
            <th width=60>背景速记</th>
            <td class=语法><dfn class=非继承属性><strong><font color=#0000bb>background</font></strong></dfn> : (<dfn class=默认值><font color=#ff6600>transparent</font></dfn>|<dfn><font face="Courier New">颜色</font></dfn>) (<dfn class=默认值><font color=#ff6600>none</font></dfn>|<dfn><font face="Courier New">URL</font></dfn>)? (<dfn class=默认值><font color=#ff6600>0% 0%</font></dfn>|(<dfn><font face="Courier New">长度</font></dfn>|<dfn><font face="Courier New">百分比</font></dfn>){2})? (<dfn class=默认值><font color=#ff6600>repeat</font></dfn>|<dfn><font face="Courier New">repeat-x</font></dfn>|<dfn><font face="Courier New">repeat-y</font></dfn>|<dfn><font face="Courier New">no-repeat</font></dfn>)? (<dfn class=默认值><font color=#ff6600>scroll</font></dfn>|<dfn><font face="Courier New">fixed</font></dfn>)?</td>
        </tr>
        <tr>
            <td>非继承</td>
            <td>适用：所有元素</td>
        </tr>
        <tr>
            <td colSpan=2>速记含义：背景色 背景图 背景图位置 背景图平铺 背景图滚动</td>
        </tr>
        <tr>
            <td colSpan=2>百分比：相对于盒子自身内容+补白区域的尺寸，将背景图与背景区域各自相同偏移量的点对齐。</td>
        </tr>
    </tbody>
</table>
</div>
<!-- =================================列表属性======================================= -->
<hr>
<h2>列表属性</h2>
<div id=列表属性>
<table>
    <tbody>
        <tr>
            <th width=72>列表项样式</th>
            <td class=语法><dfn class=继承属性><strong><font color=#bb0000>list-style</font></strong></dfn> : <dfn><font face="Courier New">内置列表项图标</font></dfn> (<dfn class=默认值><font color=#ff6600>none</font></dfn>|<dfn><font face="Courier New">URL</font></dfn>) (<dfn class=默认值><font color=#ff6600>outside</font></dfn>|<dfn><font face="Courier New">inside</font></dfn>)</td>
        </tr>
        <tr>
            <td>继承</td>
            <td>适用：列表项元素</td>
        </tr>
        <tr>
            <td colSpan=2>速记含义：内置列表项图标 自定义列表项图标 图标位置</td>
        </tr>
    </tbody>
</table>
</div>
<!-- =================================表格属性======================================= -->
<hr>
<h2>表格属性</h2>
<div id=表格属性>
<table>
    <tbody>
        <tr>
            <th width=100>表格布局算法</th>
            <td class=语法><dfn class=非继承属性><strong><font color=#0000bb>table-layout</font></strong></dfn> : <dfn class=默认值><font color=#ff6600>auto</font></dfn>|<dfn><font face="Courier New">fixed</font></dfn></td>
        </tr>
        <tr>
            <td>非继承</td>
            <td>适用：table 元素</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr>
            <th width=100>单元格边框模型</th>
            <td class=语法><dfn class=继承属性><strong><font color=#bb0000>border-collapse</font></strong></dfn> : <dfn class=默认值><font color=#ff6600>separate</font></dfn>|<dfn><font face="Courier New">collapse</font></dfn></td>
        </tr>
        <tr>
            <td>继承</td>
            <td>适用：表格元素</td>
        </tr>
    </tbody>
</table>
</div>
<!-- =================================指针属性======================================= -->
<hr>
<h2>指针属性</h2>
<div id=指针属性>
<table>
    <tbody>
        <tr>
            <th width=60>指针样式</th>
            <td class=语法><dfn class=继承属性><strong><font color=#bb0000>cursor</font></strong></dfn> : <dfn><font face="Courier New">指针样式</font></dfn></td>
        </tr>
        <tr>
            <td>继承</td>
            <td>适用：所有元素</td>
        </tr>
    </tbody>
</table>
</div>
<!-- ==============================盒模型属性=========================================== -->
<hr>
<h2>盒模型属性</h2>
<div id=盒模型属性>
<ul>
    <li>由内到外的层次：内容 &#8594; 补白 &#8594; 边框 &#8594; 边界
    <li>由上到下的层次：边框 &#8594; 内容+补白 &#8594; 背景图 &#8594; 背景色 &#8594; 边界 </li>
</ul>
<table>
    <tbody>
        <tr>
            <th width=95>内容宽度|高度</th>
            <td class=语法><dfn class=非继承属性><strong><font color=#0000bb>width</font></strong></dfn>|<dfn class=非继承属性><strong><font color=#0000bb>height</font></strong></dfn> : <dfn class=默认值><font color=#ff6600>auto</font></dfn>|<dfn><font face="Courier New">长度</font></dfn>|<dfn><font face="Courier New">百分比</font></dfn></td>
        </tr>
        <tr>
            <td>非继承</td>
            <td>适用：块元素/替换元素</td>
        </tr>
        <tr>
            <td colSpan=2>百分比：相对于包含框的<dfn class=非继承属性><strong><font color=#0000bb>width</font></strong></dfn>|<dfn class=非继承属性><strong><font color=#0000bb>height</font></strong></dfn>属性值</td>
        </tr>
        <tr>
            <td colSpan=2>内联盒子的高度与<dfn class=非继承属性><strong><font color=#0000bb>height</font></strong></dfn>属性无关</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr>
            <th width=95>补白宽度</th>
            <td class=语法><dfn class=非继承属性><strong><font color=#0000bb>padding</font></strong></dfn> : <dfn class=默认值><font color=#ff6600>0</font></dfn>|(<dfn><font face="Courier New">长度</font></dfn>|<dfn><font face="Courier New">百分比</font></dfn>){1,4}</td>
        </tr>
        <tr>
            <td>非继承</td>
            <td>适用：<dfn class=非继承属性><strong><font color=#0000bb>display</font></strong></dfn>不等于<dfn><font face="Courier New">table-*</font></dfn>的所有元素</td>
        </tr>
        <tr>
            <td colSpan=2>百分比：相对于包含框的<dfn class=非继承属性><strong><font color=#0000bb>width</font></strong></dfn>属性值</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr>
            <th width=95>边界宽度</th>
            <td class=语法><dfn class=非继承属性><strong><font color=#0000bb>margin</font></strong></dfn> : <dfn class=默认值><font color=#ff6600>0</font></dfn>|(<dfn><font face="Courier New">长度</font></dfn>|<dfn><font face="Courier New">百分比</font></dfn>|<dfn><font face="Courier New">auto</font></dfn>){1,4}</td>
        </tr>
        <tr>
            <td>非继承</td>
            <td>适用：<dfn class=非继承属性><strong><font color=#0000bb>display</font></strong></dfn>不等于<dfn><font face="Courier New">table-*</font></dfn>的所有元素</td>
        </tr>
        <tr>
            <td colSpan=2>百分比：相对于包含框的<dfn class=非继承属性><strong><font color=#0000bb>width</font></strong></dfn>属性值</td>
        </tr>
        <tr>
            <td colSpan=2>上下边界宽度对非替换内联元素无效。将左右边界设为<dfn><font face="Courier New">auto</font></dfn>是将块元素居中的正确做法。</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr>
            <th width=95>边框速记</th>
            <td class=语法><dfn class=非继承属性><strong><font color=#0000bb>border</font></strong></dfn>|<dfn class=非继承属性><strong><font color=#0000bb>border-top</font></strong></dfn>|<dfn class=非继承属性><strong><font color=#0000bb>border-bottom</font></strong></dfn>|<dfn class=非继承属性><strong><font color=#0000bb>border-left</font></strong></dfn>|<dfn class=非继承属性><strong><font color=#0000bb>border-right</font></strong></dfn> : <dfn><font face="Courier New">边框样式</font></dfn> <dfn><font face="Courier New">长度</font></dfn> (<dfn><font face="Courier New">颜色</font></dfn>|<dfn><font face="Courier New">transparent</font></dfn>)?</td>
        </tr>
        <tr>
            <td>非继承</td>
            <td>适用：所有元素</td>
        </tr>
        <tr>
            <td colSpan=2>速记含义：边框样式 边框宽度 边框颜色</td>
        </tr>
        <tr>
            <td colSpan=2>当边框样式样式为<dfn><font face="Courier New">none</font></dfn>时，边框宽度自动强制为零。</td>
        </tr>
    </tbody>
</table>
<h3>边界重叠</h3>
<p><dfn><font face="Courier New">边界重叠</font></dfn>是指两个或多个盒子(可能相邻也可能嵌套)的相邻边界(其间没有任何非空内容、补白、边框)重合在一起而形成一个单一边界。</p>
<p>常规流中两个或多个块级盒子的垂直相邻边界会重合。结果的边界宽度是相邻边界宽度中最大的值。如果出现负边界，则在最大的正边界中减去绝对值最大的负边界。如果没有正边界，则从零中减去绝对值最大的负边界。注意：相邻的盒子可能并非是由父子关系或同胞关系的元素生成。</p>
<p>但是边界的重叠也有例外情况：</p>
<ul>
    <li>水平边界永远不会重叠。
    <li>浮动盒子、绝对定位盒子、内联块盒子、根盒子的边界永不重叠。
    <li><dfn class=非继承属性><strong><font color=#0000bb>overflow</font></strong></dfn>属性不等于<dfn class=默认值><font color=#ff6600>visible</font></dfn>的元素与它的非浮动子元素之间边界不发生重叠。 </li>
</ul>
</div>
<!-- ==================================显示属性===================================== -->
<hr>
<h2>显示属性</h2>
<div id=显示属性>
<table>
    <tbody>
        <tr>
            <th width=60>显示类型</th>
            <td class=语法><dfn class=非继承属性><strong><font color=#0000bb>display</font></strong></dfn> : <dfn class=默认值><font color=#ff6600>inline</font></dfn>|<dfn><font face="Courier New">block</font></dfn>|<dfn><font face="Courier New">list-item</font></dfn>|<dfn><font face="Courier New">table-header-group</font></dfn>|<dfn><font face="Courier New">table-footer-group</font></dfn>|<dfn><font face="Courier New">none</font></dfn></td>
        </tr>
        <tr>
            <td>非继承</td>
            <td>适用：所有元素</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr>
            <th width=60>可见性</th>
            <td class=语法><dfn class=继承属性><strong><font color=#bb0000>visibility</font></strong></dfn> : <dfn class=默认值><font color=#ff6600>visible</font></dfn>|<dfn><font face="Courier New">hidden</font></dfn></td>
        </tr>
        <tr>
            <td>继承</td>
            <td>适用：所有元素</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr>
            <th width=60>溢出模式</th>
            <td class=语法><dfn class=非继承属性><strong><font color=#0000bb>overflow</font></strong></dfn> : <dfn class=默认值><font color=#ff6600>visible</font></dfn>|<dfn><font face="Courier New">hidden</font></dfn>|<dfn><font face="Courier New">scroll</font></dfn>|<dfn><font face="Courier New">auto</font></dfn></td>
        </tr>
        <tr>
            <td>非继承</td>
            <td>适用：非替换块元素/表格单元格/内联块</td>
        </tr>
    </tbody>
</table>
</div>
<!-- ===============================定位与布局属性================================ -->
<hr>
<h2>定位与布局属性</h2>
<div id=定位与布局属性>
<table>
    <tbody>
        <tr>
            <th width=72>定位方式</th>
            <td class=语法><dfn class=非继承属性><strong><font color=#0000bb>position</font></strong></dfn> : <dfn class=默认值><font color=#ff6600>static</font></dfn>|<dfn><font face="Courier New">relative</font></dfn>|<dfn><font face="Courier New">absolute</font></dfn></td>
        </tr>
        <tr>
            <td>非继承</td>
            <td>适用：所有元素</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr>
            <th width=72>边界偏移量</th>
            <td class=语法><dfn class=非继承属性><strong><font color=#0000bb>top</font></strong></dfn>|<dfn class=非继承属性><strong><font color=#0000bb>bottom</font></strong></dfn>|<dfn class=非继承属性><strong><font color=#0000bb>left</font></strong></dfn>|<dfn class=非继承属性><strong><font color=#0000bb>right</font></strong></dfn> : <dfn><font face="Courier New">长度</font></dfn>|<dfn><font face="Courier New">百分比</font></dfn>|<dfn class=默认值><font color=#ff6600>auto</font></dfn></td>
        </tr>
        <tr>
            <td>非继承</td>
            <td>适用：已定位元素</td>
        </tr>
        <tr>
            <td colSpan=2>百分比：垂直|水平相对于包含框的<dfn class=非继承属性><strong><font color=#0000bb>height</font></strong></dfn>|<dfn class=非继承属性><strong><font color=#0000bb>width</font></strong></dfn>属性值</td>
        </tr>
        <tr>
            <td colSpan=2>绝对定位偏移量相对于上一级已定位盒子的内容边沿，相对定位偏移量相对于原始的位置。</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr>
            <th width=72>浮动</th>
            <td class=语法><dfn class=非继承属性><strong><font color=#0000bb>float</font></strong></dfn> : <dfn class=默认值><font color=#ff6600>none</font></dfn>|<dfn><font face="Courier New">left</font></dfn>|<dfn><font face="Courier New">right</font></dfn></td>
        </tr>
        <tr>
            <td>非继承</td>
            <td>适用：所有元素</td>
        </tr>
        <tr>
            <td colSpan=2>浮动的盒子必须有一个显式的宽度(通过<dfn class=非继承属性><strong><font color=#0000bb>width</font></strong></dfn>属性指定，或对于替换元素具有固有宽度)，任何浮动盒子都成为一个块盒子。</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr>
            <th width=72>避让浮动</th>
            <td class=语法><dfn class=非继承属性><strong><font color=#0000bb>clear</font></strong></dfn> : <dfn class=默认值><font color=#ff6600>none</font></dfn>|<dfn><font face="Courier New">left</font></dfn>|<dfn><font face="Courier New">right</font></dfn>|<dfn><font face="Courier New">both</font></dfn></td>
        </tr>
        <tr>
            <td>非继承</td>
            <td>适用：块元素</td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr>
            <th width=72>Z轴顺序</th>
            <td class=语法><dfn class=非继承属性><strong><font color=#0000bb>z-index</font></strong></dfn> : <dfn class=默认值><font color=#ff6600>auto</font></dfn>|<dfn><font face="Courier New">整数</font></dfn></td>
        </tr>
        <tr>
            <td>非继承</td>
            <td>适用：已定位元素</td>
        </tr>
    </tbody>
</table>
<h3><dfn class=非继承属性><font color=#0000bb>display</font></dfn>, <dfn class=非继承属性><font color=#0000bb>position</font></dfn>, <dfn class=非继承属性><font color=#0000bb>float</font></dfn> 之间的相互关系：</h3>
<ol>
    <li>如果<dfn class=非继承属性><strong><font color=#0000bb>display</font></strong></dfn>等于<dfn><font face="Courier New">none</font></dfn>，则用户端必须忽略<dfn class=非继承属性><strong><font color=#0000bb>position</font></strong></dfn>和<dfn class=非继承属性><strong><font color=#0000bb>float</font></strong></dfn>。在这种情况下，元素不产生盒子。
    <li>否则，如果<dfn class=非继承属性><strong><font color=#0000bb>position</font></strong></dfn>等于<dfn><font face="Courier New">absolute</font></dfn>，则<dfn class=非继承属性><strong><font color=#0000bb>display</font></strong></dfn>与<dfn class=非继承属性><strong><font color=#0000bb>float</font></strong></dfn>皆强制为<dfn><font face="Courier New">none</font></dfn>(<dfn><font face="Courier New">list-item</font></dfn>保持不变)。盒子的位置由边界偏移量确定。
    <li>否则，如果<dfn class=非继承属性><strong><font color=#0000bb>float</font></strong></dfn>不等于<dfn class=默认值><font color=#ff6600>none</font></dfn>或该元素是根元素，则<dfn class=非继承属性><strong><font color=#0000bb>display</font></strong></dfn>强制为<dfn><font face="Courier New">block</font></dfn>(<dfn><font face="Courier New">list-item</font></dfn>保持不变)。
    <li>否则，使用指定的<dfn class=非继承属性><strong><font color=#0000bb>display</font></strong></dfn>属性。 </li>
</ol>
</div>
<!-- =============================== HTML默认样式 ================================ -->
<hr>
<h2>HTML默认样式</h2>
<div id=HTML默认样式>
<pre style="COLOR: #c0c">html,body,div,  h1,h2,h3,h4,h5,h6,p,  ol,ul,dl,dt,dd,
form,fieldset,  blockquote,address,hr,pre { <span style="COLOR: #009">display</span>: <span style="COLOR: #00f">block</span> }
input,select { <span style="COLOR: #009">display</span>: <span style="COLOR: #00f">inline-block</span> }
li           { <span style="COLOR: #009">display</span>: <span style="COLOR: #00f">list-item</span> }
head         { <span style="COLOR: #009">display</span>: <span style="COLOR: #00f">none</span> }
table        { <span style="COLOR: #009">display</span>: <span style="COLOR: #00f">table</span> }
caption      { <span style="COLOR: #009">display</span>: <span style="COLOR: #00f">table-caption</span> }
thead        { <span style="COLOR: #009">display</span>: <span style="COLOR: #00f">table-header-group</span> }
tbody        { <span style="COLOR: #009">display</span>: <span style="COLOR: #00f">table-row-group</span> }
tfoot        { <span style="COLOR: #009">display</span>: <span style="COLOR: #00f">table-footer-group</span> }
tr           { <span style="COLOR: #009">display</span>: <span style="COLOR: #00f">table-row</span> }
col          { <span style="COLOR: #009">display</span>: <span style="COLOR: #00f">table-column</span> }
colgroup     { <span style="COLOR: #009">display</span>: <span style="COLOR: #00f">table-column-group</span> }
td, th       { <span style="COLOR: #009">display</span>: <span style="COLOR: #00f">table-cell</span> }
caption     { <span style="COLOR: #009">text-align</span>: <span style="COLOR: #00f">center</span> }
th          { <span style="COLOR: #009">font-weight</span>: <span style="COLOR: #00f">bolder</span>; <span style="COLOR: #009">text-align</span>: <span style="COLOR: #00f">center</span> }
body     { <span style="COLOR: #009">margin</span>: <span style="COLOR: #00f">8px</span> }
blockquote      { <span style="COLOR: #009">margin-left</span>: <span style="COLOR: #00f">40px</span>; <span style="COLOR: #009">margin-right</span>: <span style="COLOR: #00f">40px</span> }
h4,p,blockquote,ul,fieldset,form,ol,dl { <span style="COLOR: #009">margin</span>: <span style="COLOR: #00f">1.12em 0</span> }
h1       { <span style="COLOR: #009">font-size</span>: <span style="COLOR: #00f">2em</span>;    <span style="COLOR: #009">margin</span>: <span style="COLOR: #00f">0.67em 0</span> }
h2       { <span style="COLOR: #009">font-size</span>: <span style="COLOR: #00f">1.5em</span>;  <span style="COLOR: #009">margin</span>: <span style="COLOR: #00f">0.75em 0</span> }
h3       { <span style="COLOR: #009">font-size</span>: <span style="COLOR: #00f">1.17em</span>; <span style="COLOR: #009">margin</span>: <span style="COLOR: #00f">0.83em 0</span> }
h5       { <span style="COLOR: #009">font-size</span>: <span style="COLOR: #00f">0.83em</span>; <span style="COLOR: #009">margin</span>: <span style="COLOR: #00f">1.5em  0</span> }
h6       { <span style="COLOR: #009">font-size</span>: <span style="COLOR: #00f">0.75em</span>; <span style="COLOR: #009">margin</span>: <span style="COLOR: #00f">1.67em 0</span> }
pre  { <span style="COLOR: #009">white-space</span>: <span style="COLOR: #00f">pre</span> }
h1,h2,h3,h4,h5,h6,strong  { <span style="COLOR: #009">font-weight</span>: <span style="COLOR: #00f">bolder</span> }
cite,em,var,address { <span style="COLOR: #009">font-style</span>: <span style="COLOR: #00f">italic</span> }
pre,code,kbd,samp   { <span style="COLOR: #009">font-family</span>: <span style="COLOR: #00f">monospace</span> }
button, textarea,table      { <span style="COLOR: #009">border-spacing</span>: <span style="COLOR: #00f">2px</span>; }
thead,tbody,tfoot           { <span style="COLOR: #009">vertical-align</span>: <span style="COLOR: #00f">middle</span> }
td, th          { <span style="COLOR: #009">vertical-align</span>: <span style="COLOR: #00f">inherit</span> }
hr              { <span style="COLOR: #009">border</span>: <span style="COLOR: #00f">1px inset</span> }
ol, ul, dir, menu, dd        { <span style="COLOR: #009">margin-left</span>: <span style="COLOR: #00f">40px</span> }
ol              { <span style="COLOR: #009">list-style-type</span>: <span style="COLOR: #00f">decimal</span> }
ol ul, ul ol, ul ul, ol ol    { <span style="COLOR: #009">margin-top</span>: <span style="COLOR: #00f">0</span>; <span style="COLOR: #009">margin-bottom</span>: <span style="COLOR: #00f">0</span> }
:link, :visited { <span style="COLOR: #009">text-decoration</span>: <span style="COLOR: #00f">underline</span> }
</pre>
</div>
<img src ="http://www.blogjava.net/19851985lili/aggbug/116580.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/19851985lili/" target="_blank">☜♥☞MengChuChen</a> 2007-05-10 20:40 <a href="http://www.blogjava.net/19851985lili/articles/116580.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JRun4.0与Apache的整合</title><link>http://www.blogjava.net/19851985lili/articles/109398.html</link><dc:creator>☜♥☞MengChuChen</dc:creator><author>☜♥☞MengChuChen</author><pubDate>Mon, 09 Apr 2007 06:59:00 GMT</pubDate><guid>http://www.blogjava.net/19851985lili/articles/109398.html</guid><wfw:comment>http://www.blogjava.net/19851985lili/comments/109398.html</wfw:comment><comments>http://www.blogjava.net/19851985lili/articles/109398.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/19851985lili/comments/commentRss/109398.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/19851985lili/services/trackbacks/109398.html</trackback:ping><description><![CDATA[<p><span>序：</span></p>
<p><span>JRun3.1下，与Apache的整合配置非常方便，直接在JRun Management Console界面中，配置一下Admin Server的External Web Server即可；动态加载Servlet也可以直接通过点击{server_name}－&gt; Web Applications &gt; {application_name}－&gt; Servlet Definitions进行配置。</span></p>
<p><span>JRun4.0下还真有点不习惯，在配置上也走了不少弯路，在此粗略写下基本操作步骤，希望对配置JRun4.0的新手们有点帮助。第一次写东西，还望各路朋友多多捧场，多多指教。MSN:chinawdn@hotmail.com</span></p>
<p><span>言归正传，<span>Window与Linux系统环境下，JRun和Apache整合步骤基本相似，本文以Linux下的配置为例。</span></span></p>
<p>&nbsp;</p>
<p><span>1．<span>&nbsp;&nbsp; </span></span><span>准备工作：</span></p>
<p><span>(1)<span>&nbsp;&nbsp; </span></span><span>建立文件目录：</span></p>
<p><span>/home/httpd/html/sdsms<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>存放jsp文件</span></p>
<p><span>/home/httpd/np/com/np/sdsms&nbsp;存放java程序</span></p>
<p>&nbsp;</p>
<p><span>(2)<span>&nbsp;&nbsp; </span></span><span>安装相关软件：</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;<img alt=相关软件及相应安装目录 hspace=0 src="http://blog.csdn.net/Develop/ArticleImages/18/18440/CSDN_Dev_Image_2003-5-151835460.gif" align=baseline border=0></span></span></p>
<p>&#160;</p>
<p>&nbsp;</p>
<p><span>2．<span>&nbsp;&nbsp; </span></span><span>初步使用配置：</span></p>
<p><span>(1)<span>&nbsp;&nbsp; </span></span><span>配置<span>JDK的CLASSPATH：</span></span></p>
<p>&nbsp;</p>
<p><span>(2)<span>&nbsp;&nbsp; </span></span><span>配置<span>Apache的httpd.conf文件并重启：</span></span></p>
<p><span>DocumentRoot "/home/httpd/html"</span></p>
<p>&nbsp;</p>
<p><span>(3)<span>&nbsp;&nbsp; </span></span><span>配置并重启<span>JRun：</span></span></p>
<p><span>a．添加虚拟目录： </span></p>
<p><span>{JRun_Root}/servers/{server name}/default-ear/default-war/WEB-INF/jrun-web.xml 添加</span></p>
<p>&nbsp;</p>
<p><span>&lt;virtual-mapping&gt;</span></p>
<p><span>&nbsp;&lt;resource-path&gt;/sdhero&lt;/resource-path&gt;</span></p>
<p><span>&nbsp;&lt;system-path&gt;/home/httpd/html/sdsms&lt;/system-path&gt;</span></p>
<p><span>&lt;/virtual-mapping&gt;</span></p>
<p>&nbsp;</p>
<p><span>b．动态加载相关Servlet：</span></p>
<p><span>{JRun_Root}/servers/{server_name}/default-ear/default-war/WEB-INF/web.xml 添加</span></p>
<p>&nbsp;</p>
<p><span>&lt;web-app&gt; </span></p>
<p><span>&nbsp;&#8230;</span></p>
<p><span>&lt;servlet&gt;</span></p>
<p><span>&nbsp;<span>&nbsp;&nbsp;</span>&lt;servlet-name&gt;SDTest&lt;/servlet-name&gt;</span></p>
<p><span>&lt;servlet-class&gt;com.np.sdsms.TextIO&lt;/servlet-class&gt;</span></p>
<p><span>&lt;init-param&gt;</span></p>
<p><span>&nbsp;&lt;param-name&gt;name&lt;/param-name&gt;</span></p>
<p><span>&nbsp;&lt;param-value&gt;Jane Xu&lt;/param-value&gt;</span></p>
<p><span>&lt;/init-param&gt;</span></p>
<p><span>&nbsp;<span>&nbsp;&nbsp;</span>&lt;load-on-startup&gt;<font color=#ff0000>1</font>&lt;/load-on-startup&gt;</span></p>
<p><span>&nbsp;&nbsp;&lt;/servlet&gt;</span></p>
<p><span>&nbsp;&#8230;</span></p>
<p><span>&lt;/web-app&gt;</span></p>
<p>&nbsp;</p>
<p><span>c．优化JSP：</span></p>
<p><span>{JRun_Root}/servers/{server name}/SERVER-INF/default-web.xml 更新JSPServlet：</span></p>
<p>&nbsp;</p>
<p><span>&lt;servlet&gt;</span></p>
<p><span>&nbsp;&lt;servlet-name&gt;JSPServlet&lt;/servlet-name&gt;</span></p>
<p><span>&nbsp;&lt;servlet-class&gt;jrun.jsp.JSPServlet&lt;/servlet-class&gt;</span></p>
<p><span>&nbsp;&#8230;</span></p>
<p><span>&nbsp;&lt;init-param&gt;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>&lt;param-name&gt;translationDisabled&lt;/param-name&gt;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>&lt;param-value&gt;<span>true</span>&lt;/param-value&gt;</span></p>
<p><span>&nbsp;&lt;/init-param&gt;&nbsp;</span></p>
<p><span>&lt;/servlet&gt;</span></p>
<p>&nbsp;</p>
<span>
<p><span>d．配置一个空的web应用(web appalication，*.war)</span></p>
<p>&nbsp;</p>
<p><span>cd /home/httpd/html/</span></p>
<p><span>mkdir jane</span></p>
<p><span>cd jane</span></p>
<p><span>mkdir WEB-INF</span></p>
<p><span>cp {jrun_root}/{app_server_name}/default-ear/default-war/WEB-INF/web.xml WEB-INF/</span></p>
<p><span>从控制台<span>/后台启动admin server 和准备该web应用的目标app server(设port=8100)</span></span></p>
<p><span>点击该<span>server，再点击web application下的add按钮</span></span></p>
<p><span>在<span>Source File Path&nbsp;填入/home/httpd/html/jane，点击Deploy按钮</span></span></p>
<p><span>在<span>Overview页面，可以修改Context Path名称，继续点击Apply按钮</span></span></p>
<p><span>好了，在<span>jane目录下建一个test.jsp文件，试试访问 http://localhost:8100/jane/test.jsp</span></span><span><span>J</span></span></p>
<p>&nbsp;</p>
<p></span><span>e．相关server添加必要的classpath</span></p>
<p><span>启动<span>JRun Admin Server，运行JRun Management Console界面，(<a href="http://localhost:8000/">http://localhost:8000</a>)</span></span></p>
<p><span>设置：点击<span>{server_name}－&gt;settings－&gt;add Classpaths for Java VM添加相关classpath</span></span></p>
<p>&nbsp;</p>
<p><span>3．<span>&nbsp;&nbsp; </span></span><span>整合配置：</span></p>
<p><span>(1)<span>&nbsp;&nbsp; </span></span><span>JRun 整合Apache，运行命令：</span></p>
<p><span>{jrun_root}/lib/java -jar wsconfig.jar<span>&nbsp;<span>&#8211;ws apache</span></span> -dir {apache_root/conf} -server {server_name}也可直接</span></p>
<p><span>{jrun_root}/lib/java -jar wsconfig.jar<span>&nbsp;<span>&#8211;ws apache</span></span> -dir {apache_root/conf}，将Apachedefault与Jrun的default server整合(默认的JRun server)</span></p>
<p>&nbsp;</p>
<p><span>(2)<span>&nbsp;&nbsp; </span></span><span>如果需要删除与<span>Apache的整合，运行命令：</span></span></p>
<p><span>{jrun_root}/lib/java -jar wsconfig.jar<span>&nbsp;<span>&#8211;ws apache</span></span> &#8211;dir {apache_root/conf} &#8211;r</span></p>
<p>&nbsp;</p>
<p><span>注：<span>Windows下使用方法：开始菜单－&gt;JRun程序组－&gt;Web Server Configuration Tool</span></span></p>
<p>&nbsp;</p>
<p><span>4．<span>&nbsp;&nbsp; </span></span><span>测试：</span></p>
<p><span>(1)<span>&nbsp;&nbsp; </span></span><span>测试相关目录：</span></p>
<p><span>/home/httpd/html/ 下新建文件test.jsp：</span></p>
<p><span>测试代码：<span>&lt;% out.print(&#8220;Apache DocumentRoot&#8221;); %&gt;</span></span></p>
<p><span>/home/httpd/html/sdsms/下新建文件test.jsp：</span></p>
<p><span>测试代码：<span>&lt;% out.print(&#8220;JRun Default Server&#8217;s Virtual Root named \&#8221;sdhero\&#8221;&#8221;); %&gt;</span></span></p>
<p>&nbsp;</p>
<p><span>(2)<span>&nbsp;&nbsp; </span></span><span>现在分别重启一下<span>Apache和JRun，在浏览器中分别输入：</span></span></p>
<p><span><a href="http://localhost/test.jsp">http://localhost/test.jsp</a></span></p>
<p><span><a href="http://localhost/sdhero/test.jsp">http://localhost/sdhero/test.jsp</a></span></p>
<p><span>附，后台启jrun命令：./jrun -start {servername} 1&gt;{JRun.rootdir}/logs/{servername}-out.log 2&gt;{JRun.rootdir}/logs/{servername}-error.log &amp;</span></p>
<p><span>(3)<span>&nbsp;&nbsp; </span></span><span>运行命令：<span>tail -f access_log | grep test，可以通过apache的日记文件监控了吧，到这里基本就OK啦！^_^</span></span></p>
<p><span>参考：</span></p>
<p><span>JRun4.0自带文档 {jrun_root}/docs/dochome.html</span></p>
<img src ="http://www.blogjava.net/19851985lili/aggbug/109398.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/19851985lili/" target="_blank">☜♥☞MengChuChen</a> 2007-04-09 14:59 <a href="http://www.blogjava.net/19851985lili/articles/109398.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java Web Service技术</title><link>http://www.blogjava.net/19851985lili/articles/97655.html</link><dc:creator>☜♥☞MengChuChen</dc:creator><author>☜♥☞MengChuChen</author><pubDate>Fri, 02 Feb 2007 12:41:00 GMT</pubDate><guid>http://www.blogjava.net/19851985lili/articles/97655.html</guid><wfw:comment>http://www.blogjava.net/19851985lili/comments/97655.html</wfw:comment><comments>http://www.blogjava.net/19851985lili/articles/97655.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/19851985lili/comments/commentRss/97655.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/19851985lili/services/trackbacks/97655.html</trackback:ping><description><![CDATA[
		<li class="entrylistitem">
				<a class="entrylisttitle" id="CategoryEntryList.ascx_EntryStoryList_Entries__ctl1_TitleUrl" href="http://blog.csdn.net/superalans/archive/2006/05/21/747947.aspx">Java Servlet API说明文档 3</a>
				<p>
						<font color="#333399" size="3">Java Servlet API说明文档（2.1a版）3 <br />软件包：javax.servlet.http <br />所包含的接口：HttpServletRequest；HttpServletResponse；HttpSession；HttpSessionBindingListener；HttpSessionContext。 <br />所包含的类：Cookie；HttpServlet；HttpSessionBindingEvent；HttpUtils。 </font>
				</p>
				<p>
						<font color="#333399" size="3">一、HttpServletRequest接口 <br />定义 <br />public interface HttpServletRequest extends ServletRequest; <br />用来处理一个对Servlet的HTTP格式的请求信息。 <br />方法 <br />1、getAuthType <br />public String getAuthType(); <br />返回这个请求的身份验证模式。 <br />2、getCookies <br />public Cookie[] getCookies(); <br />返回一个数组，该数组包含这个请求中当前的所有cookie。如果这个请求中没有cookie，返回一个空数组。 <br />3、getDateHeader <br />public long getDateHeader(String name); <br />返回指定的请求头域的值，这个值被转换成一个反映自1970-1-1日（GMT）以来的精确到毫秒的长整数。 <br />如果头域不能转换，抛出一个IllegalArgumentException。如果这个请求头域不存在，这个方法返回-1。 <br />4、getHeader <br />public String getHeader(String name); <br />返回一个请求头域的值。（译者注：与上一个方法不同的是，该方法返回一个字符串） <br />如果这个请求头域不存在，这个方法返回-1。 <br />5、getHeaderNames <br />public Enumeration getHeaderNames(); <br />该方法返回一个String对象的列表，该列表反映请求的所有头域名。 <br />有的引擎可能不允许通过这种方法访问头域，在这种情况下，这个方法返回一个空的列表。 <br />6、getIntHeader <br />public int getIntHeader(String name); <br />返回指定的请求头域的值，这个值被转换成一个整数。 <br />如果头域不能转换，抛出一个IllegalArgumentException。如果这个请求头域不存在，这个方法返回-1。 <br />7、getMethod <br />public String getMethod(); <br />返回这个请求使用的HTTP方法（例如：GET、POST、PUT） <br />8、getPathInfo <br />public String getPathInfo(); <br />这个方法返回在这个请求的URL的Servlet路径之后的请求URL的额外的路径信息。如果这个请求URL包括一个查询字符串，在返回值内将不包括这个查询字符串。这个路径在返回之前必须经过URL解码。如果在这个请求的URL的Servlet路径之后没有路径信息。这个方法返回空值。 <br />9、getPathTranslated <br />public String getPathTranslated(); <br />这个方法获得这个请求的URL的Servlet路径之后的额外的路径信息，并将它转换成一个真实的路径。在进行转换前，这个请求的URL必须经过URL解码。如果在这个URL的Servlet路径之后没有附加路径信息。这个方法返回空值。 <br />10、getQueryString <br />public String getQueryString(); <br />返回这个请求URL所包含的查询字符串。一个查询字串符在一个URL中由一个“？”引出。如果没有查询字符串，这个方法返回空值。 <br />11、getRemoteUser <br />public String getRemoteUser <br />返回作了请求的用户名，这个信息用来作HTTP用户论证。 <br />如果在请求中没有用户名信息，这个方法返回空值。 <br />12、getRequestedSessionId <br />public String getRequestedSessionId(); <br />返回这个请求相应的session id。如果由于某种原因客户端提供的session id是无效的，这个session id将与在当前session中的session id不同，与此同时，将建立一个新的session。 <br />如果这个请求没与一个session关联，这个方法返回空值。 <br />13、getRequestURI <br />public String getRequestURI(); <br />从HTTP请求的第一行返回请求的URL中定义被请求的资源的部分。如果有一个查询字符串存在，这个查询字符串将不包括在返回值当中。例如，一个请求通过/catalog/books?id=1这样的URL路径访问，这个方法将返回/catalog/books。这个方法的返回值包括了Servlet路径和路径信息。 <br />如果这个URL路径中的的一部分经过了URL编码，这个方法的返回值在返回之前必须经过解码。 <br />14、getServletPath <br />public String getServletPath(); <br />这个方法返回请求URL反映调用Servlet的部分。例如，一个Servlet被映射到/catalog/summer这个URL路径，而一个请求使用了/catalog/summer/casual这样的路径。所谓的反映调用Servlet的部分就是指/catalog/summer。 <br />如果这个Servlet不是通过路径匹配来调用。这个方法将返回一个空值。 <br />15、getSession <br />public HttpSession getSession(); <br />public HttpSession getSession(boolean create); <br />返回与这个请求关联的当前的有效的session。如果调用这个方法时没带参数，那么在没有session与这个请求关联的情况下，将会新建一个session。如果调用这个方法时带入了一个布尔型的参数，只有当这个参数为真时，session才会被建立。 <br />为了确保session能够被完全维持。Servlet开发者必须在响应被提交之前调用该方法。 <br />如果带入的参数为假，而且没有session与这个请求关联。这个方法会返回空值。 <br />16、isRequestedSessionIdValid <br />public boolean isRequestedSessionIdValid(); <br />这个方法检查与此请求关联的session当前是不是有效。如果当前请求中使用的session无效，它将不能通过getSession方法返回。 <br />17、isRequestedSessionIdFromCookie <br />public boolean isRequestedSessionIdFromCookie(); <br />如果这个请求的session id是通过客户端的一个cookie提供的，该方法返回真，否则返回假。 <br />18、isRequestedSessionIdFromURL <br />public boolean isRequestedSessionIdFromURL(); <br />如果这个请求的session id是通过客户端的URL的一部分提供的，该方法返回真，否则返回假。请注意此方法与isRequestedSessionIdFromUrl在URL的拼写上不同。 <br />以下方法将被取消</font>
				</p>
				<p>
						<font color="#333399" size="3">19、isRequestedSessionIdFromUrl <br />public boolean isRequestedSessionIdFromUrl(); <br />该方法被isRequestedSessionIdFromURL代替。 </font>
				</p>
				<p>
						<font color="#333399" size="3">二、HttpServletResponse接口 <br />定义</font>
				</p>
				<p>
						<font color="#333399" size="3">public interface HttpServletResponse extends ServletResponse <br />描述一个返回到客户端的HTTP回应。这个接口允许Servlet程序员利用HTTP协议规定的头信息。 <br />成员变量 <br />public static final int SC_CONTINUE = 100; <br />public static final int SC_SWITCHING_PROTOCOLS = 101; <br />public static final int SC_OK = 200; <br />public static final int SC_CREATED = 201; <br />public static final int SC_ACCEPTED = 202; <br />public static final int SC_NON_AUTHORITATIVE_INFORMATION = 203; <br />public static final int SC_NO_CONTENT = 204; <br />public static final int SC_RESET_CONTENT = 205; <br />public static final int SC_PARTIAL_CONTENT = 206; <br />public static final int SC_MULTIPLE_CHOICES = 300; <br />public static final int SC_MOVED_PERMANENTLY = 301; <br />public static final int SC_MOVED_TEMPORARILY = 302; <br />public static final int SC_SEE_OTHER = 303; <br />public static final int SC_NOT_MODIFIED = 304; <br />public static final int SC_USE_PROXY = 305; <br />public static final int SC_BAD_REQUEST = 400; <br />public static final int SC_UNAUTHORIZED = 401; <br />public static final int SC_PAYMENT_REQUIRED = 402; <br />public static final int SC_FORBIDDEN = 403; <br />public static final int SC_NOT_FOUND = 404; <br />public static final int SC_METHOD_NOT_ALLOWED = 405; <br />public static final int SC_NOT_ACCEPTABLE = 406; <br />public static final int SC_PROXY_AUTHENTICATION_REQUIRED = 407; <br />public static final int SC_REQUEST_TIMEOUT = 408; <br />public static final int SC_CONFLICT = 409; <br />public static final int SC_GONE = 410; <br />public static final int SC_LENGTH_REQUIRED = 411; <br />public static final int SC_PRECONDITION_FAILED = 412; <br />public static final int SC_REQUEST_ENTITY_TOO_LARGE = 413; <br />public static final int SC_REQUEST_URI_TOO_LONG = 414; <br />public static final int SC_UNSUPPORTED_MEDIA_TYPE = 415; <br />public static final int SC_INTERNAL_SERVER_ERROR = 500; <br />public static final int SC_NOT_IMPLEMENTED = 501; <br />public static final int SC_BAD_GATEWAY = 502; <br />public static final int SC_SERVICE_UNAVAILABLE = 503; <br />public static final int SC_GATEWAY_TIMEOUT = 504; <br />public static final int SC_HTTP_VERSION_NOT_SUPPORTED = 505; <br />以上HTTP产状态码是由HTTP/1.1定义的。 <br />方法 <br />1、addCookie <br />public void addCookie(Cookie cookie); <br />在响应中增加一个指定的cookie。可多次调用该方法以定义多个cookie。为了设置适当的头域，该方法应该在响应被提交之前调用。 <br />2、containsHeader <br />public boolean containsHeader(String name); <br />检查是否设置了指定的响应头。 <br />3、encodeRedirectURL <br />public String encodeRedirectURL(String url); <br />对sendRedirect方法使用的指定URL进行编码。如果不需要编码，就直接返回这个URL。之所以提供这个附加的编码方法，是因为在redirect的情况下，决定是否对URL进行编码的规则和一般情况有所不同。所给的URL必须是一个绝对URL。相对URL不能被接收，会抛出一个IllegalArgumentException。 <br />所有提供给sendRedirect方法的URL都应通过这个方法运行，这样才能确保会话跟踪能够在所有浏览器中正常运行。 <br />4、encodeURL <br />public String encodeURL(String url); <br />对包含session ID的URL进行编码。如果不需要编码，就直接返回这个URL。Servlet引擎必须提供URL编码方法，因为在有些情况下，我们将不得不重写URL，例如，在响应对应的请求中包含一个有效的session，但是这个session不能被非URL的（例如cookie）的手段来维持。 <br />所有提供给Servlet的URL都应通过这个方法运行，这样才能确保会话跟踪能够在所有浏览器中正常运行。 <br />5、sendError <br />public void sendError(int statusCode) throws IOException; <br />public void sendError(int statusCode, String message) throws <br />IOException; <br />用给定的状态码发给客户端一个错误响应。如果提供了一个message参数，这将作为响应体的一部分被发出，否则，服务器会返回错误代码所对应的标准信息。 <br />调用这个方法后，响应立即被提交。在调用这个方法后，Servlet不会再有更多的输出。 <br />6、sendRedirect <br />public void sendRedirect(String location) throws IOException; <br />使用给定的路径，给客户端发出一个临时转向的响应（SC_MOVED_TEMPORARILY）。给定的路径必须是绝对URL。相对URL将不能被接收，会抛出一个IllegalArgumentException。 <br />这个方法必须在响应被提交之前调用。调用这个方法后，响应立即被提交。在调用这个方法后，Servlet不会再有更多的输出。 <br />7、setDateHeader <br />public void setDateHeader(String name, long date); <br />用一个给定的名称和日期值设置响应头，这里的日期值应该是反映自1970-1-1日（GMT）以来的精确到毫秒的长整数。如果响应头已经被设置，新的值将覆盖当前的值。 <br />8、setHeader <br />public void setHeader(String name, String value); <br />用一个给定的名称和域设置响应头。如果响应头已经被设置，新的值将覆盖当前的值。 <br />9、setIntHeader <br />public void setIntHeader(String name, int value); <br />用一个给定的名称和整形值设置响应头。如果响应头已经被设置，新的值将覆盖当前的值。 <br />10、setStatus <br />public void setStatus(int statusCode); <br />这个方法设置了响应的状态码，如果状态码已经被设置，新的值将覆盖当前的值。 <br />以下的几个方法将被取消 <br />11、encodeRedirectUrl <br />public String encodeRedirectUrl(String url); <br />该方法被encodeRedirectURL取代。 <br />12、encodeUrl <br />public String encodeUrl(String url); <br />该方法被encodeURL取代。 <br />13、setStatus <br />public void setStatus(int statusCode, String message); <br />这个方法设置了响应的状态码，如果状态码已经被设置，新的值将覆盖当前的值。如果提供了一个message，它也将会被作为响应体的一部分被发送。 </font>
				</p>
				<p>
						<font color="#333399" size="3">三、HttpSession接口 <br />定义 <br />public interface HttpSession <br />这个接口被Servlet引擎用来实现在HTTP客户端和HTTP会话两者的关联。这种关联可能在多外连接和请求中持续一段给定的时间。session用来在无状态的HTTP协议下越过多个请求页面来维持状态和识别用户。 <br />一个session可以通过cookie或重写URL来维持。 <br />方法 <br />1、getCreationTime <br />public long getCreationTime(); <br />返回建立session的时间，这个时间表示为自1970-1-1日（GMT）以来的毫秒数。 <br />2、getId <br />public String getId(); <br />返回分配给这个session的标识符。一个HTTP session的标识符是一个由服务器来建立和维持的唯一的字符串。 <br />3、getLastAccessedTime <br />public long getLastAccessedTime(); <br />返回客户端最后一次发出与这个session有关的请求的时间，如果这个session是新建立的，返回-1。这个时间表示为自1970-1-1日（GMT）以来的毫秒数。 <br />4、getMaxInactiveInterval <br />public int getMaxInactiveInterval(); <br />返加一个秒数，这个秒数表示客户端在不发出请求时，session被Servlet引擎维持的最长时间。在这个时间之后，Servlet引擎可能被Servlet引擎终止。如果这个session不会被终止，这个方法返回-1。 <br />当session无效后再调用这个方法会抛出一个IllegalStateException。 <br />5、getValue <br />public Object getValue(String name); <br />返回一个以给定的名字绑定到session上的对象。如果不存在这样的绑定，返回空值。 <br />当session无效后再调用这个方法会抛出一个IllegalStateException。 <br />6、getValueNames <br />public String[] getValueNames(); <br />以一个数组返回绑定到session上的所有数据的名称。 <br />当session无效后再调用这个方法会抛出一个IllegalStateException。 <br />7、invalidate <br />public void invalidate(); <br />这个方法会终止这个session。所有绑定在这个session上的数据都会被清除。并通过HttpSessionBindingListener接口的valueUnbound方法发出通告。 <br />8、isNew <br />public boolean isNew(); <br />返回一个布尔值以判断这个session是不是新的。如果一个session已经被服务器建立但是还没有收到相应的客户端的请求，这个session将被认为是新的。这意味着，这个客户端还没有加入会话或没有被会话公认。在他发出下一个请求时还不能返回适当的session认证信息。 <br />当session无效后再调用这个方法会抛出一个IllegalStateException。 <br />9、putValue <br />public void putValue(String name, Object value); <br />以给定的名字，绑定给定的对象到session中。已存在的同名的绑定会被重置。这时会调用HttpSessionBindingListener接口的valueBound方法。 <br />当session无效后再调用这个方法会抛出一个IllegalStateException。 <br />10、removeValue <br />public void removeValue(String name); <br />取消给定名字的对象在session上的绑定。如果未找到给定名字的绑定的对象，这个方法什么也不做。 这时会调用HttpSessionBindingListener接口的valueUnbound方法。 <br />当session无效后再调用这个方法会抛出一个IllegalStateException。 <br />11、setMaxInactiveInterval <br />public int setMaxInactiveInterval(int interval); <br />设置一个秒数，这个秒数表示客户端在不发出请求时，session被Servlet引擎维持的最长时间。 <br />以下这个方法将被取消 <br />12、getSessionContext <br />public HttpSessionContext getSessionContext(); <br />返回session在其中得以保持的环境变量。这个方法和其他所有HttpSessionContext的方法一样被取消了。 </font>
				</p>
				<p>
						<font color="#333399" size="3">四、HttpSessionBindingListener接口 <br />定义 <br />public interface HttpSessionBindingListener <br />这个对象被加入到HTTP的session中，执行这个接口会通告有没有什么对象被绑定到这个HTTP session中或被从这个HTTP session中取消绑定。 <br />方法 <br />1、valueBound <br />public void valueBound(HttpSessionBindingEvent event); <br />当一个对象被绑定到session中，调用此方法。HttpSession.putValue方法被调用时，Servlet引擎应该调用此方法。 <br />2、valueUnbound <br />public void valueUnbound(HttpSessionBindingEvent event); <br />当一个对象被从session中取消绑定，调用此方法。HttpSession.removeValue方法被调用时，Servlet引擎应该调用此方法。 </font>
				</p>
				<p>
						<font color="#333399" size="3">五、HttpSessionContext接口 <br />定义 <br />此接口将被取消 <br />public interface HttpSessionContext <br />这个对象是与一组HTTP session关联的单一的实体。 <br />这个接口由于安全的原因被取消，它出现在目前的版本中仅仅是为了兼容性的原因。这个接口的方法将模拟以前的版本的定义返回相应的值。 <br />方法 <br />1、getSession <br />public HttpSession getSession(String sessionId); <br />当初用来返回与这个session id相关的session。现在返回空值。 <br />2、getIds <br />public Enumeration getIds(); <br />当初用来返回这个环境下所有session id的列表。现在返回空的列表。 </font>
				</p>
				<p>
						<font color="#333399" size="3">六、Cookie类 <br />定义 <br />public class Cookie implements Cloneable <br />这个类描述了一个cookie，有关cookie的定义你可以参照Netscape Communications Corporation的说明，也可以参照RFC 2109。 <br />构造函数 <br />public Cookie(String name, String value); <br />用一个name-value对定义一个cookie。这个name必须能被HTTP/1.1所接受。 <br />以字符$开头的name被RFC 2109保留。 <br />给定的name如果不能被HTTP/1.1所接受，该方法抛出一个IllegalArgumentException。 <br />方法 <br />1、getComment <br />public String getComment(); <br />返回描述这个cookie目的的说明，如果未定义这个说明，返回空值。 <br />2、getDomain <br />public String getDomain(); <br />返回这个cookie可以出现的区域，如果未定义区域，返回空值。 <br />3、getMaxAge <br />public int getMaxAge(); <br />这个方法返回这个cookie指定的最长存活时期。如果未定义这个最长存活时期，该方法返回-1。 <br />4、getName <br />public String getName(); <br />该方法返回cookie名。 <br />5、getPath <br />public String getPath(); <br />返回这个cookie有效的所有URL路径的前缀，如果未定义，返回空值。 <br />6、getSecure <br />public boolean getSecure(); <br />如果这个cookie只通过安全通道传输返回真，否则返回假。 <br />7、getValue <br />public String getValue(); <br />该方法返回cookie的值。 <br />8、getVersion <br />public int getVersion(); <br />返回cookie的版本。版本1由RFC 2109解释。版本0由Netscape Communications Corporation的说明解释。新构造的cookie默认使用版本0。 <br />9、setComment <br />public void setComment(String purpose); <br />如果一个用户将这个cookie提交给另一个用户，必须通过这个说明描述这个cookie的目的。版本0不支持这个属性。 <br />10、setDomain <br />public void setDomain(String pattern); <br />这个方法设置cookie的有效域的属性。这个属性指定了cookie可以出现的区域。一个有效域以一个点开头（.foo.com），这意味着在指定的域名解析系统的区域中（可能是</font>
						<a href="http://www.foo.com/">
								<font color="#333399" size="3">www.foo.com</font>
						</a>
						<font color="#333399" size="3">但不是a.b.foo.com）的主机可以看到这个cookie。默认情况是，cookie只能返回保存它的主机。 <br />11、setMaxAge <br />public void setMaxAge(int expiry); <br />这个方法设定这个cookie的最长存活时期。在该存活时期之后，cookie会被终目。负数表示这个cookie不会生效，0将从客户端删除这个cookie。 <br />12、setPath <br />public void setPath(String uri); <br />这个方法设置cookie的路径属性。客户端只能向以这个给定的路径String开头的路径返回cookie。 <br />13、setSecure <br />public void setSecure(boolean flag); <br />指出这个cookie只能通过安全通道（例如HTTPS）发送。只有当产生这个cookie的服务器使用安全协议发送这个cookie值时才能这样设置。 <br />14、setValue <br />public void setValue(String newValue); <br />设置这个cookie的值，对于二进制数据采用BASE64编码。 <br />版本0不能使用空格、{}、()、=、，、“”、/、?、@、：以及；。 <br />15、setVersion <br />public void setVersion(int v); <br />设置cookie的版本号 </font>
				</p>
				<p>
						<font color="#333399" size="3">七、HttpServlet类 <br />定义 <br />public class HttpServlet extends GenericServlet implements <br />Serializable <br />这是一个抽象类，用来简化HTTP Servlet写作的过程。它是GenericServlet类的扩充，提供了一个处理HTTP协议的框架。 <br />在这个类中的service方法支持例如GET、POST这样的标准的HTTP方法。这一支持过程是通过分配他们到适当的方法（例如doGet、doPost）来实现的。 <br />方法 <br />1、doDelete <br />protected void doDelete(HttpServletRequest request, <br />HttpServletResponse response) throws ServletException, <br />IOException; <br />被这个类的service方法调用，用来处理一个HTTP DELETE操作。这个操作允许客户端请求从服务器上删除URL。这一操作可能有负面影响，对此用户就负起责任。 <br />这一方法的默认执行结果是返回一个HTTP BAD_REQUEST错误。当你要处理DELETE请求时，你必须重载这一方法。 <br />2、doGet <br />protected void doGet(HttpServletRequest request, <br />HttpServletResponse response) throws ServletException, <br />IOException; <br />被这个类的service方法调用，用来处理一个HTTP GET操作。这个操作允许客户端简单地从一个HTTP服务器“获得”资源。对这个方法的重载将自动地支持HEAD方法。 <br />GET操作应该是安全而且没有负面影响的。这个操作也应该可以安全地重复。 <br />这一方法的默认执行结果是返回一个HTTP BAD_REQUEST错误。 <br />3、doHead <br />protected void doHead(HttpServletRequest request, <br />HttpServletResponse response) throws ServletException, <br />IOException; <br />被这个类的service方法调用，用来处理一个HTTP HEAD操作。默认的情况是，这个操作会按照一个无条件的GET方法来执行，该操作不向客户端返回任何数据，而仅仅是返回包含内容长度的头信息。 <br />与GET操作一样，这个操作应该是安全而且没有负面影响的。这个操作也应该可以安全地重复。 <br />这个方法的默认执行结果是自动处理HTTP HEAD操作，这个方法不需要被一个子类执行。 <br />4、doOptions <br />protected void doOptions(HttpServletRequest request, <br />HttpServletResponse response) throws ServletException, <br />IOException; <br />被这个类的service方法调用，用来处理一个HTTP OPTION操作。这个操作自动地决定支持哪一种HTTP方法。例如，一个Servlet写了一个HttpServlet的子类并重载了doGet方法，doOption会返回下面的头： <br />Allow: GET,HEAD,TRACE,OPTIONS <br />你一般不需要重载这个方法。 <br />5、doPost <br />protected void doPost(HttpServletRequest request, <br />HttpServletResponse response) throws ServletException, <br />IOException; <br />被这个类的service方法调用，用来处理一个HTTP POST操作。这个操作包含请求体的数据，Servlet应该按照他行事。 <br />这个操作可能有负面影响。例如更新存储的数据或在线购物。 <br />这一方法的默认执行结果是返回一个HTTP BAD_REQUEST错误。当你要处理POST操作时，你必须在HttpServlet的子类中重载这一方法。 <br />6、doPut <br />protected void doPut(HttpServletRequest request, <br />HttpServletResponse response) throws ServletException, <br />IOException; <br />被这个类的service方法调用，用来处理一个HTTP PUT操作。这个操作类似于通过FTP发送文件。 <br />这个操作可能有负面影响。例如更新存储的数据或在线购物。 <br />这一方法的默认执行结果是返回一个HTTP BAD_REQUEST错误。当你要处理PUT操作时，你必须在HttpServlet的子类中重载这一方法。 <br />7、doTrace <br />protected void doTrace(HttpServletRequest request, <br />HttpServletResponse response) throws ServletException, <br />IOException; <br />被这个类的service方法调用，用来处理一个HTTP TRACE操作。这个操作的默认执行结果是产生一个响应，这个响应包含一个反映trace请求中发送的所有头域的信息。 <br />当你开发Servlet时，在多数情况下你需要重载这个方法。 <br />8、getLastModified <br />protected long getLastModified(HttpServletRequest request); <br />返回这个请求实体的最后修改时间。为了支持GET操作，你必须重载这一方法，以精确地反映最后修改的时间。这将有助于浏览器和代理服务器减少装载服务器和网络资源，从而更加有效地工作。返回的数值是自1970-1-1日（GMT）以来的毫秒数。 <br />默认的执行结果是返回一个负数，这标志着最后修改时间未知，它也不能被一个有条件的GET操作使用。 <br />9、service <br />protected void service(HttpServletRequest request, <br />HttpServletResponse response) throws ServletException, <br />IOException; <br />public void service(ServletRequest request, ServletResponse response) <br />throws ServletException, IOException; <br />这是一个Servlet的HTTP-specific方案，它分配请求到这个类的支持这个请求的其他方法。 <br />当你开发Servlet时，在多数情况下你不必重载这个方法。 </font>
				</p>
				<p>
						<font color="#333399" size="3">八、HttpSessionBindingEvent类 <br />定义 <br />public class HttpSessionBindingEvent extends EventObject <br />这个事件是在监听到HttpSession发生绑定和取消绑定的情况时连通HttpSessionBindingListener的。这可能是一个session被终止或被认定无效的结果。 <br />事件源是HttpSession.putValue或HttpSession.removeValue。 <br />构造函数 <br />public HttpSessionBindingEvent(HttpSession session, String name); <br />通过引起这个事件的Session和发生绑定或取消绑定的对象名构造一个新的HttpSessionBindingEvent。 <br />方法 <br />1、getName <br />public String getName(); <br />返回发生绑定和取消绑定的对象的名字。 <br />2、getSession <br />public HttpSession getSession(); <br />返回发生绑定和取消绑定的session的名字。 </font>
				</p>
				<p>
						<font color="#333399" size="3">九、HttpUtils类 <br />定义 <br />public class HttpUtils <br />收集HTTP Servlet使用的静态的有效的方法。 <br />方法 <br />1、getRequestURL <br />public static StringBuffer getRequestURL(HttpServletRequest <br />request); <br />在服务器上重建客户端用来建立请求的URL。这个方法反映了不同的协议（例如http和https）和端口，但不包含查询字符串。 <br />这个方法返回一个StringBuffer而不是一个String，这样URL可以被Servlet开发者有效地修改。 <br />2、parsePostData <br />public static Hashtable parsePostData(int len, <br />ServletInputstream in); <br />解析一个包含MIME类型application/x-www-form-urlencoded的数据的流，并创建一个具有关键值-数据对的hash table。这里的关键值是字符串，数据是该字符串所对应的值的列表。一个关键值可以在POST的数据中出现一次或多次。这个关键值每出现一次，它的相应的值就被加入到hash table中的字符串所对应的值的列表中。 <br />从POST数据读出的数据将经过URL解码，+将被转换为空格以十六进制传送的数据（例如%xx）将被转换成字符。 <br />当POST数据无效时，该方法抛出一个IllegalArgumentException。 <br />3、parseQueryString <br />public static Hashtable parseQueryString(String s); <br />解析一个查询字符串，并创建一个具有关键值-数据对的hash table。这里的数据是该字符串所对应的值的列表。一个关键值可以出现一次或多次。这个关键值每出现一次，它的相应的值就被加入到hash table中的字符串所对应的值的列表中。 <br />从查询字符串读出的数据将经过URL解码，+将被转换为空格以十六进制传送的数据（例如%xx）将被转换成字符。 <br />当查询字符串无效时，该方法抛出一个IllegalArgumentException。 </font>
				</p>
				<p>
						<font color="#333399" size="3">Java Servlet API说明文档（2.1a版）（四） <br />术语表<br />bytecode <br />字节码：由Java编译器和Java解释程序生成的机器代码。 <br />cookie <br />由Web服务器建立的数据，该数据存储在用户的计算机上，提供了一个Web站点跟踪用户的参数并存储在用户自己硬盘上的方法。 <br />HTTP <br />超文本传输协议。一个请求响应协议用来连接WWW服务器向客户端浏览器传输HTML页面。 <br />输入流对象<br />一个对象，由ServletInputStream类定义，被Servlet用来从客户端读取请求。 <br />映射<br />由Servlet实例和Servlet返回数据的URL组成的一对，例如，HelloServlet和/hello/index.html。 <br />输出流对象<br />一个对象，由ServletOutputStream class类定义，被Servlet用来向客户端返回数据。 <br />request dispatcher object <br />由RequestDispatcher接口定义的一个对象，用来从客户端接收请求，并将其发送到Web服务器上可用的其他资源（例如Servlet、CGI、HTML文件或JSP文件）。 <br />sandboxed servlet <br />在一个安全性约束下运行的Servlet。 <br />servlet <br />一个小的，具有平台无关性的，没有图形用户界面的Java程序。它可以在许多方面扩充Web服务的功能。 <br />servlet configuration object <br />ServletConfig接口定义的一个对象，用来配置一个Servlet。 <br />servlet context object <br />ServletContext接口定义的一个对象。给予Servlet有关Servlet引擎的信息。 <br />servlet引擎<br />由Web服务器提供商制作的一个环境，可以允许Servlet在具体的Web服务器上运行。 <br />servlet请求对象 <br />由ServletRequest接口定义的一个对象，允许Servlet获得用关客户端请求的数据。 <br />servlet response object <br />由ServletResponse接口定义的一个对象，允许Servlet作出响应。 <br />servlet runner <br />Java Servlet Developer’s Kit (JSDK)中的sun.servlet.http.HttpServer过程，它使得Servlet得以运行。 <br />会话跟踪 <br />在一个Web应用程序中，识别一个从同一个客户端发出的连续的唯一的请求的能力。 <br />SSL <br />加密套接字协议层。一个安全协议，用来在Iternet上的客户端浏览器和服务器交换密钥和加密数据。 <br />URI <br />统一资源标识。定义一个Internet地址，它是一个URL的超集。 <br />URL <br />统一资源路径。这个地址定义了到达一个WWW上的文件的路线，通常由协议前缀、域名、目录名和文件名组成。 <br /></font>
				</p>
				<div class="itemdesc">发表于 @ <a title="permalink" href="http://blog.csdn.net/superalans/archive/2006/05/21/747947.aspx">2006年05月21日 5:30 PM</a> | <a title="comments, pingbacks, trackbacks" href="http://blog.csdn.net/superalans/archive/2006/05/21/747947.aspx#FeedBack">评论 (0)</a></div>
		</li>
		<li class="entrylistitem">
				<a class="entrylisttitle" id="CategoryEntryList.ascx_EntryStoryList_Entries__ctl2_TitleUrl" href="http://blog.csdn.net/superalans/archive/2006/05/21/747941.aspx">Java Servlet API说明文档 2</a>
				<p>
						<font color="#333399" size="3">Java Servlet API说明文档（2.1a版）2<br />API对象的说明<br />这一部分包含了对Java Servlet API的全部类和接口的详细说明。这个说明与Javadoc API差不多，但是这份文档提供了更多的信息。 <br />API包含了两个软件包，十二个接口和九个类。 <br />软件包：javax.servlet <br />所包含的接口：RequestDispatcher；Servlet；ServletConfig；ServletContext；ServletRequest；ServletResponse；SingleThreadModel。 <br />所包含的类：GenericServlet；ServletInputStream；ServletOutputStream；ServletException；UnavailableException。 </font>
				</p>
				<p>
						<font color="#333399" size="3">一、RequestDispatcher接口： <br />定义： <br />public interface RequestDispatcher; <br />定义一个对象，从客户端接收请求，然后将它发给服务器的可用资源（例如Servlet、CGI、HTML文件、JSP文件）。Servlet引擎创建request dispatcher对象，用于封装由一个特定的URL定义的服务器资源。 <br />这个接口是专用于封装Servlet的，但是一个Servlet引擎可以创建request dispatcher对象用于封装任何类型的资源。 <br />request dispatcher对象是由Servlet引擎建立的，而不是由Servlet开发者建立的。 <br />方法 <br />1、forward <br />public void forward(ServletRequest request, ServletResponse response) <br />throws ServletException, IOException; <br />被用来从这个Servlet向其它服务器资源传递请求。当一个Servlet对响应作了初步的处理，并要求其它的对象对此做出响应时，可以使用这个方法。 <br />当request对象被传递到目标对象时，请求的URL路径和其他路径参数会被调整为反映目标对象的目标URL路径。 <br />如果已经通过响应返回了一个ServletOutputStream对象或PrintWriter对象，这个方法将不能使用，否则，这个方法会抛出一个IllegalStateException。 <br />2、include <br />public void include(ServletRequest request, ServletResponse response) <br />throws ServletException, IOException <br />用来包括发送给其他服务器资源的响应的内容。本质上来说，这个方法反映了服务器端的内容。 <br />请求对象传到目标对象后会反映调用请求的请求URL路径和路径信息。这个响应对象只能调用这个Servlet的ServletOutputStream对象和PrintWriter对象。 <br />一个调用include的Servlet不能设置头域，如果这个Servlet调用了必须设置头域的方法（例如cookie），这个方法将不能保证正常使用。作为一个Servlet开发者，你必须妥善地解决那些可能直接存储头域的方法。例如，即使你使用会话跟踪，为了保证session的正常工作，你必须在一个调用include的Servlet之外开始你的session </font>
				</p>
				<p>
						<font color="#333399" size="3">二、Servlet接口。 <br />定义<br />public interface Servlet <br />这个接口定义了一个Servlet：一个在Web服务器上继承了这个功能的Java类。 <br />方法 <br />1、init <br />public void init(ServletConfig config) throws ServletException; <br />Servlet引擎会在Servlet实例化之后，置入服务之前精确地调用init方法。在调用service方法之前，init方法必须成功退出。 <br />如果init方法抛出一个ServletException，你不能将这个Servlet置入服务中，如果init方法在超时范围内没完成，我们也可以假定这个Servlet是不具备功能的，也不能置入服务中。 <br />2、service <br />public void service(ServletRequest request, ServletResponse response) <br />throws ServletException, IOException; <br />Servlet引擎调用这个方法以允许Servlet响应请求。这个方法在Servlet未成功初始化之前无法调用。在Servlet被初始化之前，Servlet引擎能够封锁未决的请求。 <br />在一个Servlet对象被卸载后，直到一个新的Servlet被初始化，Servlet引擎不能调用这个方法 <br />3、destroy <br />public void destroy(); <br />当一个Servlet被从服务中去除时，Servlet引擎调用这个方法。在这个对象的service方法所有线程未全部退出或者没被引擎认为发生超时操作时，destroy方法不能被调用。 <br />4、getServletConfig <br />public ServletConfig getServletConfig(); <br />返回一个ServletConfig对象，作为一个Servlet的开发者，你应该通过init方法存储ServletConfig对象以便这个方法能返回这个对象。为了你的便利，GenericServlet在执行这个接口时，已经这样做了。 <br />5、getServletInfo <br />public String getServletInfo(); <br />允许Servlet向主机的Servlet运行者提供有关它本身的信息。返回的字符串应该是纯文本格式而不应有任何标志（例如HTML，XML等）。 </font>
				</p>
				<p>
						<font color="#333399" size="3">三、ServletConfig接口 <br />定义<br />public interface ServletConfig <br />这个接口定义了一个对象，通过这个对象，Servlet引擎配置一个Servlet并且允许Servlet获得一个有关它的ServletContext接口的说明。每一个ServletConfig对象对应着一个唯一的Servlet。 <br />方法 <br />1、getInitParameter <br />public String getInitParameter(String name); <br />这个方法返回一个包含Servlet指定的初始化参数的String。如果这个参数不存在，返加空值。 <br />2、getInitParameterNames <br />public Enumeration getInitParameterNames(); <br />这个方法返回一个列表String对象，该对象包括Servlet的所有初始化参数名。如果Servlet没有初始化参数，getInitParameterNames返回一个空的列表。 <br />3、getServletContext <br />public ServletContext getServletContext(); <br />返回这个Servlet的ServletContext对象。 </font>
				</p>
				<p>
						<font color="#333399" size="3">四、ServletContext接口 <br />定义<br />public interface ServletContext <br />定义了一个Servlet的环境对象，通过这个对象，Servlet引擎向Servlet提供环境信息。 <br />一个Servlet的环境对象必须至少与它所驻留的主机是一一对应的。在一个处理多个虚拟主机的Servlet引擎中（例如，使用了HTTP1.1的主机头域），每一个虚拟主机必须被视为一个单独的环境。此外，Servlet引擎还可以创建对应于一组Servlet的环境对象。 <br />方法 <br />1、getAttribute <br />public Object getAttribute(String name); <br />返回Servlet环境对象中指定的属性对象。如果该属性对象不存在，返回空值。这个方法允许访问有关这个Servlet引擎的在该接口的其他方法中尚未提供的附加信息。 <br />2、getAttributeNames <br />public Enumeration getAttributeNames(); <br />返回一个Servlet环境对象中可用的属性名的列表。 <br />3、getContext <br />public ServletContext getContext(String uripath); <br />返回一个Servlet环境对象，这个对象包括了特定URI路径的Servlets和资源，如果该路径不存在，则返回一个空值。URI路径格式是/dir/dir/filename.ext。 <br />为了安全，如果通过这个方法访问一个受限制的Servlet的环境对象，会返回一个空值。 <br />4、getMajorVersion <br />public int getMajorVersion(); <br />返回Servlet引擎支持的Servlet API的主版本号。例如对于2.1版，这个方法会返回一个整数2。 <br />5、getMinorVersion <br />public int getMinorVersion(); <br />返回Servlet引擎支持的Servlet API的次版本号。例如对于2.1版，这个方法会返回一个整数2。 <br />6、getMimeType <br />public String getMimeType(String file); <br />返回指定文件的MIME类型，如果这种MIME类型未知，则返回一个空值。MIME类型是由Servlet引擎的配置决定的。 <br />7、getRealPath <br />public String getRealPath(String path); <br />一个符合URL路径格式的指定的虚拟路径的格式是：/dir/dir/filename.ext。用这个方法，可以返回与一个符合该格式的虚拟路径相对应的真实路径的String。这个真实路径的格式应该适合于运行这个Servlet引擎的计算机（包括其相应的路径解析器）。 <br />不管是什么原因，如果这一从虚拟路径转换成实际路径的过程不能执行，该方法将会返回一个空值。 <br />8、getResource <br />public URL getResource(String uripath); <br />返回一个URL对象，该对象反映位于给定的URL地址（格式：/dir/dir/filename.ext）的Servlet环境对象已知的资源。无论URLStreamHandlers对于访问给定的环境是不是必须的，Servlet引擎都必须执行。如果给定的路径的Servlet环境没有已知的资源，该方法会返回一个空值。 <br />这个方法和java.lang.Class的getResource方法不完全相同。java.lang.Class的getResource方法通过装载类来寻找资源。而这个方法允许服务器产生环境变量给任何资源的任何Servlet，而不必依赖于装载类、特定区域等等。 <br />9、getResourceAsStream <br />public InputStream getResourceAsStream(String uripath); <br />返回一个InputStream对象，该对象引用指定的URL的Servlet环境对象的内容。如果没找到Servlet环境变量，就会返回空值，URL路径应该具有这种格式：/dir/dir/filename.ext。 <br />这个方法是一个通过getResource方法获得URL对象的方便的途径。请注意，当你使用这个方法时，meta-information（例如内容长度、内容类型）会丢失。 <br />10、getRequestDispatcher <br />public RequestDispatcher getRequestDispatcher(String uripath); <br />如果这个指定的路径下能够找到活动的资源(例如一个Servlet，JSP页面，CGI等等)就返回一个特定URL的RequestDispatcher对象，否则，就返回一个空值，Servlet引擎负责用一个request dispatcher对象封装目标路径。这个request dispatcher对象可以用来完全请求的传送。 <br />11、getServerInfo <br />public String getServerInfo(); <br />返回一个String对象，该对象至少包括Servlet引擎的名字和版本号。 <br />12、log <br />public void log(String msg); <br />public void log(String msg, Throwable t); <br />public void log(Exception exception, String msg); // 这种用法将被取消<br />写指定的信息到一个Servlet环境对象的log文件中。被写入的log文件由Servlet引擎指定，但是通常这是一个事件log。当这个方法被一个异常调用时，log中将包括堆栈跟踪。 <br />13、setAttribute <br />public void setAttribute(String name, Object o); <br />给予Servlet环境对象中你所指定的对象一个名称。 <br />14、removeAttribute <br />public void removeAttribute(String name); <br />从指定的Servlet环境对象中删除一个属性。 <br />注：以下几个方法将被取消<br />15、getServlet <br />public Servlet getServlet(String name) throws ServletException; <br />最初用来返回一个指定名称的Servlet，如果没找到就返回一个空值。如果这个Servlet能够返回，这就意味着它已经被初始化，而且已经可以接受service请求。这是一个危险的方法。当调用这个方法时，可能并不知道Servlet的状态，这就可能导致有关服务器状态的问题。而允许一个Servlet访问其他Servlet的这个方法也同样的危险。 <br />现在这个方法返回一个空值，为了保持和以前版本的兼容性，现在这个方法还没有被取消。在以后的API版本中，该方法将被取消。 <br />16、getServletNames <br />public Enumeration getServletNames(); <br />最初用来返回一个String对象的列表，该列表表示了在这个Servlet环境下所有已知的Servlet对象名。这个列表总是包含这个Servlet自身。 <br />基于与上一个方法同样的理由，这也是一个危险的方法。 <br />现在这个方法返回一个空的列表。为了保持和以前版本的兼容性，现在这个方法还没有被取消。在以后的API版本中，该方法将被取消。 <br />17、getServlets <br />public Enumeration getServlets(); <br />最初用来返回在这个Servelet环境下所有已知的Servlet对象的列表。这个列表总是包含这个Servlet自身。 <br />基于与getServlet方法同样的理由，这也是一个危险的方法。 <br />现在这个方法返回一个空的列表。为了保持和以前版本的兼容性，现在这个方法还没有被取消。在以后的API版本中，该方法将被取消。 </font>
				</p>
				<p>
						<font color="#333399" size="3">五、ServletRequest接口 <br />定义<br />public interface ServletRequest <br />定义一个Servlet引擎产生的对象，通过这个对象，Servlet可以获得客户端请求的数据。这个对象通过读取请求体的数据提供包括参数的名称、值和属性以及输入流的所有数据。 <br />方法 <br />1、getAttribute <br />public Object getAttribute(String name); <br />返回请求中指定属性的值，如果这个属性不存在，就返回一个空值。这个方法允许访问一些不提供给这个接口中其他方法的请求信息以及其他Servlet放置在这个请求对象内的数据。 <br />2、getAttributeNames <br />public Enumeration getAttributeNames(); <br />返回包含在这个请求中的所有属性名的列表。 <br />3、getCharacterEncoding <br />public String getCharacterEncoding(); <br />返回请求中输入内容的字符编码类型，如果没有定义字符编码类型就返回空值。 <br />4、getContentLength <br />public int getContentLength(); <br />请求内容的长度，如果长度未知就返回-1。 <br />5、getContentType <br />public String getContentType(); <br />返回请求数据体的MIME类型，如果类型未知返回空值。 <br />6、getInputStream <br />public ServletInputStream getInputStream() throws IOException; <br />返回一个输入流用来从请求体读取二进制数据。如果在此之前已经通过getReader方法获得了要读取的结果，这个方法会抛出一个IllegalStateException。 <br />7、getParameter <br />public String getParameter(String name); <br />以一个String返回指定的参数的值，如果这个参数不存在返回空值。例如，在一个HTTP Servlet中，这个方法会返回一个指定的查询语句产生的参数的值或一个被提交的表单中的参数值。如果一个参数名对应着几个参数值，这个方法只能返回通过getParameterValues方法返回的数组中的第一个值。因此，如果这个参数有（或者可能有）多个值，你只能使用getParameterValues方法。 <br />8、getParameterNames <br />public Enumeration getParameterNames(); <br />返回所有参数名的String对象列表，如果没有输入参数，该方法返回一个空值。 <br />9、getParameterValues <br />public String[] getParameterValues(String name); <br />通过一个String对象的数组返回指定参数的值，如果这个参数不存在，该方法返回一个空值。 <br />10、getProtocol <br />public String getProtocol(); <br />返回这个请求所用的协议，其形式是协议/主版本号.次版本号。例如对于一个HTTP1.0的请求，该方法返回HTTP/1.0。 <br />11、getReader <br />public BufferedReader getReader() throws IOException; <br />这个方法返回一个buffered reader用来读取请求体的实体，其编码方式依照请求数据的编码方式。如果这个请求的输入流已经被getInputStream调用获得，这个方法会抛出一个IllegalStateException。 <br />12、getRemoteAddr <br />public String getRemoteAddr(); <br />返回发送请求者的IP地址。 <br />13、getRemoteHost <br />public String getRemoteHost(); <br />返回发送请求者的主机名称。如果引擎不能或者选择不解析主机名（为了改善性能），这个方法会直接返回IP地址。 <br />14、getScheme <br />public String getScheme(); <br />返回请求所使用的URL的模式。例如，对于一个HTTP请求，这个模式就是http。 <br />15、getServerName <br />public String getServerName(); <br />返回接收请求的服务器的主机名。 <br />16、getServerPort <br />public int getServerPort(); <br />返回接收请求的端口号。 <br />17、setAttribute <br />public void setAttribute(String name, Object object); <br />这个方法在请求中添加一个属性，这个属性可以被其他可以访问这个请求对象的对象（例如一个嵌套的Servlet）使用。 <br />注：以下方法将被取消<br />getRealPath <br />public String getRealPath(String path); <br />返回与虚拟路径相对应的真实路径，如果因为某种原因，这一过程不能进行，该方法将返回一个空值。 <br />这个方法和ServletContext接口中的getRealPath方法重复。在2.1版中，ServletContext接口将阐明一个Servlet所能用的所有的路径的映射。该方法执行的结果将会与ServletContext中getRealPath方法的结果完全一样。 </font>
				</p>
				<p>
						<font color="#333399" size="3">六、ServletResponse接口 <br />定义<br />public interface ServletResponse <br />定义一个Servlet引擎产生的对象，通过这个对象，Servlet对客户端的请求作出响应。这个响应应该是一个MIME实体，可能是一个HTML页、图象数据或其他MIME的格式。 <br />方法 <br />1、getCharacterEncoding <br />public String getCharacterEncoding(); <br />返回MIME实体的字符编码。这个字符编码可以是指定的类型，也可以是与请求头域所反映的客户端所能接受的字符编码最匹配的类型。在HTTP协议中，这个信息被通过Accept-Charset传送到Servlet引擎。 <br />有关字符编码和MIME的更多信息请参看RFC 2047。 <br />2、getOutputStream <br />public ServletOutputStream getOutputStream() throws IOException; <br />返回一个记录二进制的响应数据的输出流。 <br />如果这个响应对象已经调用getWriter，将会抛出IllegalStateException。 <br />3、getWriter <br />public PrintWriter getWriter throws IOException; <br />这个方法返回一个PrintWriter对象用来记录格式化的响应实体。如果要反映使用的字符编码，必须修改响应的MIME类型。在调用这个方法之前，必须设定响应的content类型。 <br />如果没有提供这样的编码类型，会抛出一个UnsupportedEncodingException，如果这个响应对象已调用getOutputStream，会抛出一个getOutputStream。 <br />4、setContentLength <br />public void setContentLength(int length); <br />设置响应的内容的长度，这个方法会覆盖以前对内容长度的设定。 <br />为了保证成功地设定响应头的内容长度，在响应被提交到输出流之前必须调用这个方法。 <br />5、setContentType <br />public void setContentType(String type); <br />这个方法用来设定响应的content类型。这个类型以后可能会在另外的一些情况下被隐式地修改，这里所说的另外的情况可能当服务器发现有必要的情况下对MIME的字符设置。 <br />为了保证成功地设定响应头的content类型，在响应被提交到输出流之前必须调用这个方法。 </font>
				</p>
				<p>
						<font color="#333399" size="3">七、SingleThreadModel接口 <br />定义<br />public interface SingleThreadModel; <br />这是一个空接口，它指定了系统如何处理对同一个Servlet的调用。如果一个Servlet被这个接口指定，那么在这个Servlet中的service方法中将不会有两个线程被同时执行。 <br />Servlet可以通过维持一个各自独立的Servlet实例池，或者通过只让Servlet的service中只有一个线程的方法来实现这个保证。 </font>
				</p>
				<p>
						<font color="#333399" size="3">八、GenericServlet类<br />public abstract class GenericServlet implements Servlet, <br />ServletConfig, Serializable; <br />这个类的存在使得编写Servlet更加方便。它提供了一个简单的方案，这个方案用来执行有关Servlet生命周期的方法以及在初始化时对ServletConfig对象和ServletContext对象进行说明。 <br />方法 <br />1、destroy <br />public void destroy(); <br />在这里destroy方法不做任何其他的工作。 <br />2、getInitParameter <br />public String getInitParameter(String name); <br />这是一个简便的途径，它将会调用ServletConfig对象的同名的方法。 <br />3、getInitParameterNames <br />public Enumeration getInitParameterNames(); <br />这是一个简便的途径，它将会调用ServletConfig对象的同名的方法。 <br />4、getServletConfig <br />public ServletConfig getServletConfig(); <br />返回一个通过这个类的init方法产生的ServletConfig对象的说明。 <br />5、getServletContext <br />public ServletContext getServletContext(); <br />这是一个简便的途径，它将会调用ServletConfig对象的同名的方法。 <br />6、getServletInfo <br />public String getServletInfo(); <br />返回一个反映Servlet版本的String。 <br />7、init <br />public void init() throws ServletException; <br />public void init(ServletConfig config) throws ServletException; <br />init(ServletConfig config)方法是一个对这个Servlet的生命周期进行初始化的简便的途径。 <br />init()方法是用来让你对GenericServlet类进行扩充的，使用这个方法时，你不需要存储config对象，也不需要调用super.init(config)。 <br />init(ServletConfig config)方法会存储config对象然后调用init()。如果你重载了这个方法，你必须调用super.init(config)，这样GenericServlet类的其他方法才能正常工作。 <br />8、log <br />public void log(String msg); <br />public void log(String msg, Throwable cause); <br />通过Servlet content对象将Servlet的类名和给定的信息写入log文件中。 <br />9、service <br />public abstract void service(ServletRequest request, ServletResponse <br />response) throws ServletException, IOException; <br />这是一个抽象的方法，当你扩展这个类时，为了执行网络请求，你必须执行它。 </font>
				</p>
				<p>
						<font color="#333399" size="3">九、ServletInputStream类<br />定义<br />public abstract class ServletInputStream extends InputStream <br />这个类定义了一个用来读取客户端的请求信息的输入流。这是一个Servlet引擎提供的抽象类。一个Servlet通过使用ServletRequest接口获得了对一个ServletInputStream对象的说明。 <br />这个类的子类必须提供一个从InputStream接口读取有关信息的方法。 <br />方法 <br />1、readLine <br />public int readLine(byte[] b, int off, int len) throws IOException; <br />从输入流的指定的偏移量开始将指定长度的字节读入到指定的数组中。如果该行所有请求的内容都已被读取，这个读取的过程将结束。如果是遇到了新的一行，新的一行的首个字符也将被读入到数组中。 </font>
				</p>
				<p>
						<font color="#333399" size="3">十、ServletOutputStream类<br />定义<br />public abstract class ServletOutputStream extends OutputStream <br />这是一个由Servlet引擎使用的抽象类。Servlet通过使用ServletResponse接口的使用获得了对一个这种类型的对象的说明。利用这个输出流可以将数据返回到客户端。 <br />这个类的子类必须提供一个向OutputStream接口写入有关信息的方法。 <br />在这个接口中，当一个刷新或关闭的方法被调用时。所有数据缓冲区的信息将会被发送到客户端，也就是说响应被提交了。请注意，关闭这种类型的对象时不一定要关闭隐含的socket流。 <br />方法 <br />1、print <br />public void print(String s) throws IOException; <br />public void print(boolean b) throws IOException; <br />public void print(char c) throws IOException; <br />public void print(int i) throws IOException; <br />public void print(long l) throws IOException; <br />public void print(float f) throws IOException; <br />public void print(double d) throws IOException; <br />输出变量到输出流中 <br />2、println <br />public void println() throws IOException; <br />public void println(String s) throws IOException; <br />public void println(boolean b) throws IOException; <br />public void println(char c) throws IOException; <br />public void println(int i) throws IOException; <br />public void println(long l) throws IOException; <br />public void println(float f) throws IOException; <br />public void println(double d) throws IOException; <br />输出变量到输出流中，并增加一个回车换行符</font>
				</p>
				<p>
						<font color="#333399" size="3">十一、ServletException类<br />定义<br />public class ServletException extends Exception <br />当Servlet遇到问题时抛出的一个异常。 <br />构造函数 <br />public ServletException(); <br />public ServletException(String message); <br />public ServletException(String message, Throwable cause); <br />public ServletException(Throwable cause); <br />构造一个新的ServletException，如果这个构造函数包括一个Throwable参数，这个Throwable对象将被作为可能抛出这个异常的原因。 <br />方法 <br />1、getRootCause <br />public Throwable getRootCause(); <br />如果配置了抛出这个异常的原因，这个方法将返回这个原因，否则返回一个空值。 </font>
				</p>
				<p>
						<font color="#333399" size="3">十二、UnavailableException类<br />定义<br />public class UnavailableException extends ServletException <br />不论一个Servlet是永久地还是临时地无效，都会抛出这个异常。Servlet会记录这个异常以及Servlet引擎所要采取的相应措施。 <br />临时的无效是指Servlet在某一时间由于一个临时的问题而不能处理请求。例如，在另一个不同的应用层的服务（可能是数据库）无法使用。这个问题可能会自行纠正或者需要采取其他的纠正措施。 <br />永久的无效是指除非管理员采取措施，这个Servlet将不能处理客户端的请求。例如，这个Servlet配置信息丢失或Servlet的状态被破坏。 <br />Servlet引擎可以安全地处理包括永久无效在内的这两种异常，但是对临时无效的正常处理可以使得Servlet引擎更健壮。特别的，这时对Servlet的请求只是被阻止（或者是被延期）一段时间，这显然要比在service自己重新启动前完全拒绝请求更为科学。 <br />构造函数 <br />public UnavailableException(Servlet servlet, String message); <br />public UnavailableException(int seconds, Servlet servlet, <br />String message); <br />构造一个包含指定的描述信息的新的异常。如果这个构造函数有一个关于秒数的参数，这将给出Servlet发生临时无效后，能够重新处理请求的估计时间。如果不包含这个参数，这意味着这个Servlet永久无效。 <br />方法 <br />1、getServlet <br />public Servlet getServlet(); <br />返回报告无效的Servlet。这被Servlet引擎用来识别受到影响的Servlet。 <br />2、getUnavailableSeconds <br />public int getUnavailableSeconds(); <br />返回Servlet预期的无效时间，如果这个Servlet是永久无效，返回-1。 <br />3、isPermanent <br />public boolean isPermanent(); <br />如果这个Servlet永久无效，返回布尔值true，指示必须采取一些管理行动以使得这个Servlet可用。 <br /></font>
				</p>
				<div class="itemdesc">发表于 @ <a title="permalink" href="http://blog.csdn.net/superalans/archive/2006/05/21/747941.aspx">2006年05月21日 5:26 PM</a> | <a title="comments, pingbacks, trackbacks" href="http://blog.csdn.net/superalans/archive/2006/05/21/747941.aspx#FeedBack">评论 (0)</a></div>
		</li>
		<li class="entrylistitem">
				<a class="entrylisttitle" id="CategoryEntryList.ascx_EntryStoryList_Entries__ctl3_TitleUrl" href="http://blog.csdn.net/superalans/archive/2006/05/21/747935.aspx">Java Servlet API说明文档 1</a>
				<font color="#333399" size="3">Java Servlet API说明文档（2.1a版） 1<br />译者前言： <br />近来在整理有关Servlet资料时发现，在网上竟然找不到一份中文的Java Servlet API的说明文档，而在有一本有关JSP的书后面附的Java Servlet API说明竟然不全，而这份文档的2.1a版在1998年的11月份就已定稿。所以我决定翻译一份中文的文档（其中一些与技术关系不大的部分已被略去），有兴趣的读者可以从http://java.sun.com/products/servlet/2.1/servletspec-2.1.zip下载原文阅读。 <br /><br /><br />Java Servlet API说明文档（2.1a版） <br />1998年11月 <br /><br /><br />绪言 <br />这是一份关于2.1版Java Servlet API的说明文档，作为对这本文档的补充，你可以到http://java.sun.com/products/servlet/index.html下面下载Javadoc格式的文档。 <br /><br />谁需要读这份文档 <br />这份文档描述了Java Servlet API的最新版本2.1版。所以，这本书对于Servlet的开发者及servlet引擎的开发者同样适用。 <br /><br />Java Servlet API的组成 <br />Java Servlet API由两个软件包组成：一个是对应HTTP的软件包，另一个是不对应HTTP的通用的软件包。这两个软件包的同时存在使得Java Servlet API能够适应将来的其他请求-响应的协议。 <br />这份文档以及刚才提及的Javadoc格式的文档都描述了这两个软件包，Javadoc格式的文档还描述了你应该如何使用这两个软件包中的所有方法。 <br /><br />有关规范 <br />你也许对下面的这些Internet规范感兴趣，这些规范将直接影响到Servlet API的发展和执行。你可以从http://info.internet.isi.edu/7c/in-notes/rfc/.cache 找到下面提到的所有这些RFC规范。 <br />RFC 1738 统一资源定位器(URL) <br />RFC 1808 相关统一资源定位器 <br />RFC 1945 超文本传输协议--HTTP/1.0 <br />RFC 2045 多用途Internet邮件扩展(多用途网际邮件扩充协议(MIME))第一部分:Internet信息体格式 <br />RFC 2046 多用途Internet邮件扩展(多用途网际邮件扩充协议(MIME))第二部分:媒体类型 <br />RFC 2047 多用途网际邮件扩充协议(MIME)(多用途Internet邮件扩展)第三部分:信息标题扩展用于非ASCII文本 <br />RFC 2048 多用途Internet邮件扩展(多用途网际邮件扩充协议(MIME))第四部分: 注册步骤 <br />RFC 2049 多用途Internet邮件扩展(多用途网际邮件扩充协议(MIME))第五部分:一致性标准和例子 <br />RFC 2068 超文本传输协议 -- HTTP/1.1 <br />RFC 2069 一个扩展HTTP:摘要访问鉴定 <br />RFC 2109 HTTP状态管理机制 <br />RFC 2145 HTTP 版本号的使用和解释 <br />RFC 2324 超文本Coffee Pot控制协议 (HTCPCP/1.0) <br />万维网协会（http://www.w3.org）管理着这些协议的规范和执行。 <br /><br /><br />有关Java Servlets <br />JavaTM servlets是一个不受平台约束的Java小程序，它可以被用来通过多种方法扩充一个Web服务器的功能。你可以把Servlet理解成Server上的applets，它被编译成字节码，这样它就可以被动态地载入并用效地扩展主机的处理能力。 <br />Servlet与applets不同的地方是，它不运行在Web浏览器或其他图形化的用户界面上。Servlet通过servlet引擎运行在Web服务器中，以执行请求和响应，请求、响应的典型范例是HTTP协议。 <br />一个客户端程序，可以是一个Web浏览器，或者是非其他的可以连接上Internet的程序，它会访问Web服务器并发出请求。这个请求被运行在Web服务器上的Servlet引擎处理，并返回响应到Servlet。Servlet通过HTTP将这个响应转发到客户端。 <br />在功能上，Servlet与CGI、NSAPI有点类似，但是，与他们不同的是：Servlet具有平台无关性。 <br /><br />Java Servlet概论 <br />Servlet与其他普通的server扩展机制有以下进步： <br />因为它采用了不同的进程处理模式，所以它比CGI更快。 <br />它使用了许多Web服务器都支持的标准的API。 <br />它继承了Java的所有优势，包括易升级以及平台无关性。 <br />它可以调用Java所提供的大量的API的功能模块。 <br />这份文档说明了Java Servlet API的类和接口的方法。有关更多的信息，请参看下面的API说明。 <br /><br />Servlet的生命周期 <br />一个Java servlet具有一个生命周期，这个生命周期定义了一个Servlet如何被载入并被初始化，如何接收请求并作出对请求的响应，如何被从服务中清除。Servlet的生命周期被javax.servlet.Servlet这个接口所定义。 <br />所有的Java Servlet都会直接地或间接地执行javax.servlet.Servlet接口，这样它才能在一个Servlet引擎中运行。Servlet引擎是Web 服务器按照Java Servlet API定制的扩展。Servlet引擎提供网络服务，能够理解MIME请求，并提供一个运行Servlet的容器。 <br />javax.servlet.Servlet接口定义了在Servlet的生命周期中特定时间以及特定顺序被调用的方法。 <br /><br />Servlet的解析和载入\r <br />Servlet引擎解析并载入一个Servlet，这个过程可以发生在引擎启动时，需要一个Servlet去响应请求时，以及在此之间的任何时候。 <br />Servlet引擎利用Java类载入工具载入一个Servlet，Servlet引擎可以从一个本地的文件系统、一个远程的文件系统以及网络载入Servlet。 <br /><br />Servlet的初始化 <br />Servlet引擎载入Servlet后，Servlet引擎必须对Servlet进行初始化，在这一过程中，你可以读取一些固定存储的数据、初始化JDBC的连接以及建立与其他资源的连接。 <br />在初始化过程中，javax.servlet.Servlet接口的init()方法提供了Servlet的初始化信息。这样，Servlet可以对自己进行配置。 <br />init()方法获得了一个Servlet配置对象（ServletConfig）。这个对象在Servlet引擎中执行，并允许Servlet通过它获处相关参数。这个对象使得Servlet能够访问ServletContext对象。 <br /><br />Servlet处理请求\r <br />Servlet被初始化之后，它已经可以处理来自客户端的请求，每一个来自客户端的请求都被描述成一个ServletRequest对象，Servlet的响应被描述成一个ServletResponse对象。 <br />当客户端发出请求时，Servlet引擎传递给Servlet一个ServletRequest对象和一个ServletResponse对象，这两个对象作为参数传递到service()方法中。 <br />Servlet也可以执行ServletRequest接口和ServletResponse接口。ServletRequest接口使得Servlet有权使用客户端发出的请求。Servlet可以通过ServletInputStream对象读取请求信息。 <br />ServletResponse接口允许Servlet建立响应头和状态代码。通过执行这个接口，Servlet有权使用ServletOutputStream类来向客户端返回数据。 <br /><br />多线程和映射\r <br />在多线程的环境下，Servlet必须能处理许多同时发生的请求。例外的情况是这个Servlet执行了SingleThreadModel接口，如果是那样的话，Servlet只能同时处理一个请求。 <br />Servlet依照Servlet引擎的映射来响应客户端的请求。一个映射对包括一个Servlet实例以及一个Servlet返回数据的URL，例如：HelloServlet with /hello/index.html。 <br />然而，一个映射可能是由一个URL和许多Servlet实例组成，例如：一个分布式的Servlet引擎可能运行在不止一个的服务器中，这样的话，每一个服务器中都可能有一个Servlet实例，以平衡进程的载入。作为一个Servlet的开发者，你不能假定一个Servlet只有一个实例。 <br /><br />Servlet的卸载 <br />Servlet引擎并不必需保证一个Servlet在任何时候或在服务开启的任何时候都被载入。Servlet引擎可以自由的在任何时候使用或清除一个Servlet。因此，我们不能依赖一个类或实例来存储重要的信息。 <br />当Servlet引擎决定卸载一个Servlet时（例如，如果这个引擎被关闭或者需要让资源），这个引擎必须允许Servlet释放正在使用的资源并存储有关资料。为了完成以上工作，引擎会调用Servlet的destroy()方法。 <br />在卸载一个Servlet之前，Servlet引擎必须等待所有的service()方法完成或超时结束（Servlet引擎会对超时作出定义）。当一个Servlet被卸载时，引擎将不能给Servlet发送任何请求。引擎必须释放Servlet并完成无用存储单元的收集 <br /><br />Servlet映射技术\r <br />作为一个Servlet引擎的开发者，你必须对于如何映射客户端的请求到Servlet有大量的适应性。这份说明文档不规定映射如何发生。但是，你必须能够自由地运用下面的所有技术： <br /><br />映射一个Servlet到一个URL <br />例如，你可以指定一个特殊的Servlet它仅被来自/feedback/index.html的请求调用。 <br /><br />映射一个Servlet到以一个指定的目录名开始的所有URL <br />例如，你可以映射一个Servlet到/catalog，这样来自/catalog/、 /catalog/garden和/catalog/housewares/index.html的请求都会被映射到这个Servlet。但是来自/catalogtwo 或/catalog.html的请求没被映射。 <br /><br />映射一个Servlet到所有以一个特定的字段结尾的所有URL <br />例如，你可以映射一个来自于所有以in.thtml结尾的请求到一个特定的Servlet。 <br /><br />映射一个Servlet到一个特殊的URL /servlet/servlet_name。 <br />例如，如果你建立了一个名叫listattributes的Servlet，你可以通过使用/servlet/listattributes来访问这个Servlet。 <br /><br />通过类名调用Servlet <br />例如，如果Servlet引擎接收了来自/servlet/com.foo.servlet.MailServlet的请求，Servlet引擎会载入这个com.foo.servlet.MailServlet类，建立实例，并通过这个Servlet来处理请求。 <br /><br />Servlet环境 <br />ServletContext接口定义了一个Servlet环境对象，这个对象定义了一个在Servlet引擎上的Servlet的视图。通过使用这个对象，Servlet可以记录事件、得到资源并得到来自Servlet引擎的类（例如RequestDispatcher对象）。一个Servlet只能运行在一个Servlet环境中，但是不同的Servlet可以在Servlet引擎上有不同的视图。 <br />如果Servlet引擎支持虚拟主机，每个虚拟主机有一个Servlet环境。一个Servlet环境不能在虚拟主机之间共享。 <br />Servlet引擎能够允许一个Servlet环境有它自己的活动范围。 <br />例如，一个Servlet环境是属于bank应用的，它将被映射到/bank目录下。在这种情况下，一个对getContext方法的调用会返回/bank的Servlet环境。 <br /><br />HTTP会话 <br />HTTP是一个没有状态的协议。要建立一个有效的Web服务应用，你必须能够识别一个连续的来自远端的客户机的唯一的请求。随着时间的过去，发展了许多会话跟踪的技术，但是使用起来都比较麻烦。 <br />Java Servlet API提供了一个简单的接口，通过这个接口，Servlet引擎可以有效地跟踪用户的会话。 <br /><br />建立Session <br />因为HTTP是一个请求-响应协议，一个会话在客户机加入之前会被认为是一个新的会话。加入的意思是返回会话跟踪信息到服务器中，指出会话已被建立。在客户端加入之前，我们不能判断下一个客户端请求是目前会话的一部分。 <br />在下面的情况下，Session会被认为是新的Session。 <br />客户端的Session在此之前还不知道 <br />客户端选择不加入Session，例如，如果客户端拒绝接收来自服务器的cookie <br />作为一个Servlet的开发者，你必须决定你的Web应用是否处理客户机不加入或不能加入Session。服务器会在Web服务器或Servlet规定的时间内维持一个Session对象。当Session终止时，服务器会释放Session对象以及所有绑定在Session上的对象。 <br />绑定对象到Session中 <br />如果有助于你处理应用的数据需求，你也许需要绑定对象到Session中，你可以通过一个唯一的名字绑定任何的对象到Session中，这时，你需要使用HttpSession对象。任何绑定到Session上的对象都可以被处理同一会话的Servlet调用。 <br />有些对象可能需要你知道什么时候会被放置到Session中或从Session中移开。你可以通过使用HttpSessionBindingListener接口获得这些信息。当你的应用存储数据到Session中，或从Session中清除数据，Servlet都会通过HttpSessionBindingListener检杳什么类被绑定或被取消绑定。这个接口的方法会通报被绑定或被取消绑定的对象</font>
		</li>
<img src ="http://www.blogjava.net/19851985lili/aggbug/97655.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/19851985lili/" target="_blank">☜♥☞MengChuChen</a> 2007-02-02 20:41 <a href="http://www.blogjava.net/19851985lili/articles/97655.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JSP/Servlet的重定向技术综述 </title><link>http://www.blogjava.net/19851985lili/articles/97617.html</link><dc:creator>☜♥☞MengChuChen</dc:creator><author>☜♥☞MengChuChen</author><pubDate>Fri, 02 Feb 2007 11:35:00 GMT</pubDate><guid>http://www.blogjava.net/19851985lili/articles/97617.html</guid><wfw:comment>http://www.blogjava.net/19851985lili/comments/97617.html</wfw:comment><comments>http://www.blogjava.net/19851985lili/articles/97617.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/19851985lili/comments/commentRss/97617.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/19851985lili/services/trackbacks/97617.html</trackback:ping><description><![CDATA[
		<p>有关JSP/Servlet的重定向技术综述如下</p>
		<p>1.RequestDispatcher.forward()<br />  是在服务器端起作用,当使用forward()时,Servlet engine传递HTTP请求从当前的Servlet or JSP到另外一个Servlet,JSP 或普通HTML文件,也即你的form提交至a.jsp,在a.jsp用到了forward()重定向至b.jsp,此时form提交的所有信息在b.jsp都可以获得,参数自动传递.<br />  但forward()无法重定向至有frame的jsp文件,可以重定向至有frame的html文件,同时forward()无法在后面带参数传递,比如servlet?name=frank,这样不行,可以程序内通过response.setAttribute("name",name)来传至下一个页面.</p>
		<p>   重定向后浏览器地址栏URL不变.</p>
		<p>例:在servlet中进行重定向<br />public void doPost(HttpServletRequest request,HttpServletResponse response)<br /> throws ServletException,IOException<br />{</p>
		<p>        response.setContentType("text/html; charset=gb2312");</p>
		<p>        ServletContext sc = getServletContext();</p>
		<p>        RequestDispatcher rd = null;</p>
		<p>        rd = sc.getRequestDispatcher("/index.jsp");     //定向的页面</p>
		<p>        rd.forward(request, response);</p>
		<p>}<br />通常在servlet中使用，不在jsp中使用。</p>
		<p>2.response.sendRedirect()<br />    是在用户的浏览器端工作,sendRedirect()可以带参数传递,比如servlet?name=frank传至下个页面,同时它可以重定向至不同的主机上,sendRedirect()可以重定向有frame.的jsp文件.<br />   重定向后在浏览器地址栏上会出现重定向页面的URL<br />例:在servlet中重定向<br />public void doPost(HttpServletRequest request,HttpServletResponse response)</p>
		<p>        throws ServletException,IOException</p>
		<p>{</p>
		<p>        response.setContentType("text/html; charset=gb2312");</p>
		<p>        response.sendRedirect("/index.jsp");</p>
		<p>}<br />由于response是jsp页面中的隐含对象，故在jsp页面中可以用response.sendRedirect()直接实现重定位。<br />注意：<br />(1).使用response.sendRedirect时，前面不能有HTML输出。<br />这并不是绝对的，不能有HTML输出其实是指不能有HTML被送到了浏览器。事实上现在的server都有cache机制，一般在8K（我是说JSP　SERVER），这就意味着，除非你关闭了cache，或者你使用了out.flush()强制刷新，那么在使用sendRedirect之前，有少量的HTML输出也是允许的。<br />(2).response.sendRedirect之后，应该紧跟一句return;<br />我们已经知道response.sendRedirect是通过浏览器来做转向的，所以只有在页面处理完成后，才会有实际的动作。既然你已经要做转向了，那么后的输出还有什么意义呢？而且有可能会因为后面的输出导致转向失败。<br />比较：<br />(1).Request Dispatcher.forward()是容器中控制权的转向，在客户端浏览器地址栏中不会显示出转向后的地址；<br />(2).response.sendRedirect()则是完全的跳转，浏览器将会得到跳转的地址，并重新发送请求链接。这样，从浏览器的地址栏中可以看到跳转后的链接地址。<br />前者更加高效，在前者可以满足需要时，尽量使用RequestDispatcher.forward()方法.</p>
		<p> 注：在有些情况下，比如，需要跳转到一个其它服务器上的资源，则必须使用HttpServletResponse.sendRequest()方法。<br /> <br />3.&lt;jsp:forward page="" /&gt; </p>
		<p>它的底层部分是由RequestDispatcher来实现的，因此它带有RequestDispatcher.forward()方法的印记。<br /></p>
		<p>如果在&lt;jsp:forward&gt;之前有很多输出,前面的输出已使缓冲区满,将自动输出到客户端,那么该语句将不起作用,这一点应该特别注意。<br /> 另外要注意：它不能改变浏览器地址，刷新的话会导致重复提交</p>
		<p>4.修改HTTP header的Location属性来重定向<br />   通过设置直接修改地址栏来实现页面的重定向。<br />jsp文件代码如下：</p>
		<p>＜%<br />response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);<br />String newLocn = "/newpath/jsa.jsp";<br />response.setHeader("Location",newLocn);<br />%＞</p>
		<p>5.JSP中实现在某页面停留若干秒后,自动重定向到另一页面<br />  在html文件中，下面的代码：<br />    &lt;meta http-equiv="refresh" content="300; url=target.jsp"&gt;<br />    它的含义：在5分钟之后正在浏览的页面将会自动变为target.html这一页。代码中300为刷新的延迟时间，以秒为单位。targer.html为你想转向的目标页,若为本页则为自动刷新本页。<br />    由上可知，可以通过setHeader来实现某页面停留若干秒后,自动重定向到另一页面。<br />    关键代码：<br />          String content=stayTime+";URL="+URL;<br />          response.setHeader("REFRESH",content);<br /></p>
		<p>
				<u>
						<font color="#0000ff">requestDispatcher.forward()与response.sendRedirect()的区别</font>
				</u>
		</p>
		<div class="postText">
				<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo1; tab-stops: list 18.0pt">
						<span lang="EN-US" style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体">
								<span style="mso-list: Ignore">
										<font size="3">A．</font>
										<span style="FONT: 7pt 'Times New Roman'">  </span>
								</span>
						</span>
						<font size="3">
								<strong style="mso-bidi-font-weight: normal">
										<span lang="EN-US" style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt">request Dispatcher.forward()</span>
								</strong>
								<strong style="mso-bidi-font-weight: normal">
										<span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt">是容器中控制权的转向</span>
								</strong>
								<span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt">，在客户端浏览器地址栏中不会显示出转向后的地址；<span lang="EN-US"><?XML:NAMESPACE PREFIX = O /?><o:p></o:p></span></span>
						</font>
				</p>
				<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo1; tab-stops: list 18.0pt">
						<span lang="EN-US" style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体">
								<span style="mso-list: Ignore">
										<font size="3">B．</font>
										<span style="FONT: 7pt 'Times New Roman'">  </span>
								</span>
						</span>
						<font size="3">
								<strong style="mso-bidi-font-weight: normal">
										<span lang="EN-US" style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt">response.sendRedirect()</span>
								</strong>
								<strong style="mso-bidi-font-weight: normal">
										<span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt">则是完全的跳转</span>
								</strong>
						</font>
						<span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt">
								<font size="3">，浏览器将会得到跳转的地址，并重新发送请求链接。这样，从浏览器的地址栏中可以看到跳转后的链接地址。</font>
								<span lang="EN-US">
										<br />
								</span>
								<font size="3">前者更加高效；<span lang="EN-US"><o:p></o:p></span></font>
						</span>
				</p>
				<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo1; tab-stops: list 18.0pt">
						<span lang="EN-US" style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体">
								<span style="mso-list: Ignore">
										<font size="3">C．</font>
										<span style="FONT: 7pt 'Times New Roman'">  </span>
								</span>
						</span>
						<font size="3">
								<strong style="mso-bidi-font-weight: normal">
										<span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt">在前者可以满足需要时，尽量使用<span lang="EN-US">RequestDispatcher.forward()</span>方法</span>
								</strong>
								<span lang="EN-US" style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt">.</span>
								<span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt">在有些情况下，比如，需要跳转到一个其它服务器上的资源，则必须使用<span lang="EN-US">HttpServletResponse.sendRequest()</span>方法。<br /><br /><br /><font face="Times New Roman">由于response是jsp页面中的隐含对象，故在jsp页面中可以用response.sendRedirect()直接实现重定位。<br />　　注意：<br />　　 (1).使用response.sendRedirect时，前面不能有HTML输出。<br />这并不是绝对的，不能有HTML输出其实是指不能有HTML被送到了浏览器。事实上现在的server都有cache机制，一般在8K（我是说JSP　SERVER），这就意味着，除非你关闭了cache，或者你使用了out.flush()强制刷新，那么在使用sendRedirect之前，有少量的HTML输出也是允许的。<br />　　 (2).response.sendRedirect之后，应该紧跟一句return;<br />　　我们已经知道response.sendRedirect是通过浏览器来做转向的，所以只有在页面处理完成后，才会有实际的动作。既然你已经要做转向了，那么后的输出还有什么意义呢？而且有可能会因为后面的输出导致转向失败。 <br />　　补充<br />　　 1.RequestDispatcher.forward()<br />　　是在服务器端起作用,当使用forward()时,Servlet engine传递HTTP请求从当前的Servlet or JSP到另外一个Servlet,JSP 或普通HTML文件,也即你的form提交至a.jsp,在a.jsp用到了forward()重定向至b.jsp,此时form提交的所有信息在b.jsp都可以获得,参数自动传递.<br />　　但forward()无法重定向至有frame的jsp文件,可以重定向至有frame的html文件,同时forward()无法在后面带参数传递,比如servlet?name=frank,这样不行,可以程序内通过response.setAttribute("name",name)来传至下一个页面.<br />　　重定向后浏览器地址栏URL不变.<br />　　例:在servlet中进行重定向<br />public void doPost(HttpServletRequest request,HttpServletResponse response)<br />throws ServletException,IOException<br />{<br />　 response.setContentType("text/html; charset=gb2312");<br />　 ServletContext sc = getServletContext();<br />　 RequestDispatcher rd = null;<br />　 rd = sc.getRequestDispatcher("/index.jsp"); //定向的页面<br />　 rd.forward(request, response);<br />} <br />　　通常在servlet中使用，不在jsp中使用。<br />　　 2.response.sendRedirect()<br />　　是在用户的浏览器端工作,sendRedirect()可以带参数传递,比如servlet?name=frank传至下个页面,同时它可以重定向至不同的主机上,sendRedirect()可以重定向有frame.的jsp文件.<br />　　重定向后在浏览器地址栏上会出现重定向页面的URL</font><br /><br /></span>
						</font>使用Response Buffering <br /><br />　　通过打开“response buffering”可以缓冲一个值得输出的整个页面内容，这将最小化输出到浏览器的数据量，从而提高了整体性能。每一次输出都耗费许多，所以写得越少，效果越好。TCP/IP在发送少量大的数据包时，要比发送大量小的数据包工作效率高，因为它是慢速启动并不断发送的。 <br /><br />　　有2种方法打开Response Buffering。首先，可以使用Internet Services Manager为整个应用程序打开response buffering，这是推荐的方式，而且在IIS4.0和IIS5.0中，默认状态下，response buffering是打开的。其次，在每一页面上，可以在头部放置如下代码开打开response buffering： <br /><br />&lt; % Response.Buffer = True % &gt; <br /><br />　　这段代码必须在任何数据输出到浏览器前被执行（就是说，在任何html内容显示前和在任何cookie被设置前）。通常情况下，为整个应用程序打开response buffering是很好的方案，这么做后就不用在每个页面头部设置如上的代码。 <br /><br />　　关于打开response buffering的一个通用问题是：用户必须要等待整个页面全部产生后，才能看到内容。对于一个长时间运行的页面来说，可以设置Response.Buffer=False关闭缓冲。然后，好的策略是利用Response.Flush方法，它将输出所有已被ASP描述的HTML内容到浏览器。比如，在描述了一个1，000行表格的100行后，ASP就可以使用Response.Flush来强迫输出这100行的内容到浏览器，这时用户就可以看到前100行数据，同时其余的行数据正在准备生成。 <br /><br />　　注意，关于上面的1，000行表格输出的例子，对于一些浏览器器来说，除非遇到&lt; /table &gt;标记，它们不会输出表格的任何内容。如果这样，可以将表格分割成许多含有少量行的多个表格，然后在每一个表格产生后，调用Response.Flush输出。新版的Internet Explorer在整个表格下载后才显示内容，并且，如果定义了表格的列宽度，生成表格的速度将特别快。 <br /><br />关于打开response buffering的另外一个问题是：当生成非常大的页面时，将消耗非常大的服务器内存<br /><br /><br />如果总结得不够全面，请各位发表自己的意见或经验。</p>
		</div>
<img src ="http://www.blogjava.net/19851985lili/aggbug/97617.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/19851985lili/" target="_blank">☜♥☞MengChuChen</a> 2007-02-02 19:35 <a href="http://www.blogjava.net/19851985lili/articles/97617.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>APACHE服务器是什么服务器:</title><link>http://www.blogjava.net/19851985lili/articles/94172.html</link><dc:creator>☜♥☞MengChuChen</dc:creator><author>☜♥☞MengChuChen</author><pubDate>Tue, 16 Jan 2007 03:25:00 GMT</pubDate><guid>http://www.blogjava.net/19851985lili/articles/94172.html</guid><wfw:comment>http://www.blogjava.net/19851985lili/comments/94172.html</wfw:comment><comments>http://www.blogjava.net/19851985lili/articles/94172.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/19851985lili/comments/commentRss/94172.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/19851985lili/services/trackbacks/94172.html</trackback:ping><description><![CDATA[
		<strong>
				<font style="BACKGROUND-COLOR: #ffff66">Apache</font>
		</strong>音译为阿帕奇，是北美印弟安人的一个部落，叫阿帕奇族，在美国的西南部。相传阿帕奇是一个武士，他英勇善战，且战无不胜，被印弟安人奉为勇敢和胜利的代表，因此后人便用他的名字为印弟安部落命名，而阿帕奇族在印第安史上也以强悍著称。 <br /><br /><b style="COLOR: black; BACKGROUND-COLOR: #ffff66">Apache</b>是世界使用排名第一的Web服务器。它可以运行在几乎所有广泛使用的计算机平台上。 <br /><br /><b style="COLOR: black; BACKGROUND-COLOR: #ffff66">Apache</b>源于NCSAhttpd服务器，经过多次修改，成为世界上最流行的Web服务器软件之一。<b style="COLOR: black; BACKGROUND-COLOR: #ffff66">Apache</b>取自“a patchy server”的读音，意思是充满补丁的服务器，因为它是自由软件，所以不断有人来为它开发新的功能、新的特性、修改原来的缺陷。<b style="COLOR: black; BACKGROUND-COLOR: #ffff66">Apache</b>的特点是简单、速度快、性能稳定，并可做代理服务器来使用。 <br /><br />本来它只用于小型或试验Internet网络，后来逐步扩充到各种Unix系统中，尤其对Linux的支持相当完美。<b style="COLOR: black; BACKGROUND-COLOR: #ffff66">Apache</b>有多种产品，可以支持SSL技术，支持多个虚拟主机。<b style="COLOR: black; BACKGROUND-COLOR: #ffff66">Apache</b>是以进程为基础的结构，进程要比线程消耗更多的系统开支，不太适合于多处理器环境，因此，在一个<b style="COLOR: black; BACKGROUND-COLOR: #ffff66">Apache</b> Web站点扩容时，通常是增加服务器或扩充群集节点而不是增加处理器。到目前为止<b style="COLOR: black; BACKGROUND-COLOR: #ffff66">Apache</b>仍然是世界上用的最多的Web服务器，市场占有率达60%左右。世界上很多著名的网站如Amazon.com、Yahoo!、W3 Consortium、Financial Times等都是<b style="COLOR: black; BACKGROUND-COLOR: #ffff66">Apache</b>的产物，它的成功之处主要在于它的源代码开放、有一支开放的开发队伍、支持跨平台的应用（可以运行在几乎所有的Unix、Windows、Linux系统平台上）以及它的可移植性等方面。 <br /><br /><b style="COLOR: black; BACKGROUND-COLOR: #ffff66">Apache</b>的诞生极富有戏剧性。当NCSA WWW服务器项目停顿后，那些使用NCSA WWW服务器的人们开始交换他们用于该服务器的补丁程序，他们也很快认识到成立管理这些补丁程序的论坛是必要的。就这样，诞生了<b style="COLOR: black; BACKGROUND-COLOR: #ffff66">Apache</b> Group，后来这个团体在NCSA的基础上创建了<b style="COLOR: black; BACKGROUND-COLOR: #ffff66">Apache</b>。 <br /><br /><b style="COLOR: black; BACKGROUND-COLOR: #ffff66">Apache</b>服务器拥有以下特性： <br /><br />支持最新的HTTP/1.1通信协议 <br /><br />拥有简单而强有力的基于文件的配置过程 <br /><br />支持通用网关接口 <br /><br />支持基于IP和基于域名的虚拟主机 <br /><br />支持多种方式的HTTP认证 <br /><br />集成Perl处理模块 <br /><br />集成代理服务器模块 <br /><br />支持实时监视服务器状态和定制服务器日志 <br /><br />支持服务器端包含指令(SSI) <br /><br />支持安全Socket层(SSL) <br /><br />提供用户会话过程的跟踪 <br /><br />支持FastCGI <br /><br />通过第三方模块可以支持Java Servlets <br /><br />如果你准备选择Web服务器，毫无疑问<b style="COLOR: black; BACKGROUND-COLOR: #ffff66">Apache</b>是你的最佳选择。 <br /><img src ="http://www.blogjava.net/19851985lili/aggbug/94172.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/19851985lili/" target="_blank">☜♥☞MengChuChen</a> 2007-01-16 11:25 <a href="http://www.blogjava.net/19851985lili/articles/94172.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>web服务器和应用服务器的区别:</title><link>http://www.blogjava.net/19851985lili/articles/94112.html</link><dc:creator>☜♥☞MengChuChen</dc:creator><author>☜♥☞MengChuChen</author><pubDate>Tue, 16 Jan 2007 01:51:00 GMT</pubDate><guid>http://www.blogjava.net/19851985lili/articles/94112.html</guid><wfw:comment>http://www.blogjava.net/19851985lili/comments/94112.html</wfw:comment><comments>http://www.blogjava.net/19851985lili/articles/94112.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/19851985lili/comments/commentRss/94112.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/19851985lili/services/trackbacks/94112.html</trackback:ping><description><![CDATA[web服务器和应用服务器的区别!<div class="wr"><span class="gray"><font color="#666666"></font></span> </div><div class="f14 wr"><cd>其中应用服务器是基于C/S结构，web服务器是基于B/S结构的，
<div class="f14 wr"></div></cd></div><div class="b3 bcr mb12"><div class="p90"><div class="f14 wr"><ca>通俗的讲: <br />               Web服务器传送(serves)页面使浏览器可以浏览，然而应用程序服务器提供的是客户端应用程序可以调用(call)的方法(methods)。确切一点，你可以说：Web服务器专门处理HTTP请求(request)，但是应用程序服务器是通过很多协议来为应用程序提供(serves)商业逻辑(business logic)。 <br /><br />下面让我们来细细道来： <br /><br />Web服务器(Web Server) :<br />          Web服务器可以解析(handles)HTTP协议。当Web服务器接收到一个HTTP请求(request)，会返回一个HTTP响应(response)，例如送回一个HTML页面。为了处理一个请求(request)，Web服务器可以响应(response)一个静态页面或图片，进行页面跳转(redirect)，或者把动态响应(dynamic response)的产生委托(delegate)给一些其它的程序例如CGI脚本，JSP(JavaServer Pages)脚本，servlets，ASP(Active Server Pages)脚本，服务器端(server-side)JavaScript，或者一些其它的服务器端(server-side)技术。无论它们(译者注：脚本)的目的如何，这些服务器端(server-side)的程序通常产生一个HTML的响应(response)来让浏览器可以浏览。 <br /><br />           要知道，Web服务器的代理模型(delegation model)非常简单。当一个请求(request)被送到Web服务器里来时，它只单纯的把请求(request)传递给可以很好的处理请求(request)的程序(译者注：服务器端脚本)。Web服务器仅仅提供一个可以执行服务器端(server-side)程序和返回(程序所产生的)响应(response)的环境，而不会超出职能范围。服务器端(server-side)程序通常具有事务处理(transaction processing)，数据库连接(database connectivity)和消息(messaging)等功能。 <br /><br />       虽然Web服务器不支持事务处理或数据库连接池，但它可以配置(employ)各种策略(strategies)来实现容错性(fault tolerance)和可扩展性(scalability)，例如负载平衡(load balancing)，缓冲(caching)。集群特征(clustering—features)经常被误认为仅仅是应用程序服务器专有的特征。 <br /><br />应用程序服务器(The Application Server) :<br /><br />      根据我们的定义，作为应用程序服务器，它通过各种协议，可以包括HTTP，把商业逻辑暴露给(expose)客户端应用程序。Web服务器主要是处理向浏览器发送HTML以供浏览，而应用程序服务器提供访问商业逻辑的途径以供客户端应用程序使用。应用程序使用此商业逻辑就象你调用对象的一个方法(或过程语言中的一个函数)一样。 <br /><br />     应用程序服务器的客户端(包含有图形用户界面(GUI)的)可能会运行在一台PC、一个Web服务器或者甚至是其它的应用程序服务器上。在应用程序服务器与其客户端之间来回穿梭(traveling)的信息不仅仅局限于简单的显示标记。相反，这种信息就是程序逻辑(program logic)。 正是由于这种逻辑取得了(takes)数据和方法调用(calls)的形式而不是静态HTML，所以客户端才可以随心所欲的使用这种被暴露的商业逻辑。 <br /><br />在大多数情形下，应用程序服务器是通过组件(component)的应用程序接口(API)把商业逻辑暴露(expose)(给客户端应用程序)的，例如基于J2EE(Java 2 Platform, Enterprise Edition)应用程序服务器的EJB(Enterprise JavaBean)组件模型。此外，应用程序服务器可以管理自己的资源，例如看大门的工作(gate-keeping duties)包括安全(security)，事务处理(transaction processing)，资源池(resource pooling)， 和消息(messaging)。就象Web服务器一样，应用程序服务器配置了多种可扩展(scalability)和容错(fault tolerance)技术。 <br /><br />一个例子 <br />例如，设想一个在线商店(网站)提供实时定价(real-time pricing)和有效性(availability)信息。这个站点(site)很可能会提供一个表单(form)让你来选择产品。当你提交查询(query)后，网站会进行查找(lookup)并把结果内嵌在HTML页面中返回。网站可以有很多种方式来实现这种功能。我要介绍一个不使用应用程序服务器的情景和一个使用应用程序服务器的情景。观察一下这两中情景的不同会有助于你了解应用程序服务器的功能。 <br /><br />情景1：不带应用程序服务器的Web服务器 <br /><br />在此种情景下，一个Web服务器独立提供在线商店的功能。Web服务器获得你的请求(request)，然后发送给服务器端(server-side)可以处理请求(request)的程序。此程序从数据库或文本文件(flat file，译者注：flat file是指没有特殊格式的非二进制的文件，如properties和XML文件等)中查找定价信息。一旦找到，服务器端(server-side)程序把结果信息表示成(formulate)HTML形式，最后Web服务器把会它发送到你的Web浏览器。 <br /><br />简而言之，Web服务器只是简单的通过响应(response)HTML页面来处理HTTP请求(request)。 <br /><br />情景2：带应用程序服务器的Web服务器 <br /><br />情景2和情景1相同的是Web服务器还是把响应(response)的产生委托(delegates)给脚本(译者注：服务器端(server-side)程序)。然而，你可以把查找定价的商业逻辑(business logic)放到应用程序服务器上。由于这种变化，此脚本只是简单的调用应用程序服务器的查找服务(lookup service)，而不是已经知道如何查找数据然后表示为(formulate)一个响应(response)。 这时当该脚本程序产生HTML响应(response)时就可以使用该服务的返回结果了。 <br /><br />在此情景中，应用程序服务器提供(serves)了用于查询产品的定价信息的商业逻辑。(服务器的)这种功能(functionality)没有指出有关显示和客户端如何使用此信息的细节，相反客户端和应用程序服务器只是来回传送数据。当有客户端调用应用程序服务器的查找服务(lookup service)时，此服务只是简单的查找并返回结果给客户端。 <br /><br />通过从响应产生(response-generating)HTML的代码中分离出来，在应用程序之中该定价(查找)逻辑的可重用性更强了。其他的客户端，例如收款机，也可以调用同样的服务(service)来作为一个店员给客户结帐。相反，在情景1中的定价查找服务是不可重用的因为信息内嵌在HTML页中了。 <br /><br />总而言之，在情景2的模型中，在Web服务器通过回应HTML页面来处理HTTP请求(request)，而应用程序服务器则是通过处理定价和有效性(availability)请求(request)来提供应用程序逻辑的。 <br /><br />警告(Caveats) <br />现在，XML Web Services已经使应用程序服务器和Web服务器的界线混淆了。通过传送一个XML有效载荷(payload)给服务器，Web服务器现在可以处理数据和响应(response)的能力与以前的应用程序服务器同样多了。 <br /><br />另外，现在大多数应用程序服务器也包含了Web服务器，这就意味着可以把Web服务器当作是应用程序服务器的一个子集(subset)。虽然应用程序服务器包含了Web服务器的功能，但是开发者很少把应用程序服务器部署(deploy)成这种功能(capacity)(译者注：这种功能是指既有应用程序服务器的功能又有Web服务器的功能)。相反，如果需要，他们通常会把Web服务器独立配置，和应用程序服务器一前一后。这种功能的分离有助于提高性能(简单的Web请求(request)就不会影响应用程序服务器了)，分开配置(专门的Web服务器，集群(clustering)等等)，而且给最佳产品的选取留有余地。</ca></div></div></div><img src ="http://www.blogjava.net/19851985lili/aggbug/94112.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/19851985lili/" target="_blank">☜♥☞MengChuChen</a> 2007-01-16 09:51 <a href="http://www.blogjava.net/19851985lili/articles/94112.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Eclipse 3.0 上配置JSP开发环境</title><link>http://www.blogjava.net/19851985lili/articles/93527.html</link><dc:creator>☜♥☞MengChuChen</dc:creator><author>☜♥☞MengChuChen</author><pubDate>Fri, 12 Jan 2007 12:37:00 GMT</pubDate><guid>http://www.blogjava.net/19851985lili/articles/93527.html</guid><wfw:comment>http://www.blogjava.net/19851985lili/comments/93527.html</wfw:comment><comments>http://www.blogjava.net/19851985lili/articles/93527.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/19851985lili/comments/commentRss/93527.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/19851985lili/services/trackbacks/93527.html</trackback:ping><description><![CDATA[
		<h4 class="TextColor1" id="subjcns!6FDD17E86EAABD69!116" style="MARGIN-BOTTOM: 0px">eclipse 平台入门</h4>
		<div id="msgcns!6FDD17E86EAABD69!116">
				<a href="http://www.eclipseworld.org/bbs/read.php?tid=842">http://www.eclipseworld.org/bbs/read.php?tid=842</a>
		</div>
		<table cellspacing="0" border="0">
				<tbody>
				</tbody>
		</table>
		<div class="footerLinks">5:46 | <nobr><a title="この記事にコメントを投稿する場合にクリックします" href="http://jorycen.spaces.live.com/blog/cns!6FDD17E86EAABD69!116.entry#post" bvitemtype="post">コメントの投稿</a></nobr> | <nobr><a title="クリックすると、この記事の固定リンクが表示されます" href="http://jorycen.spaces.live.com/blog/cns!6FDD17E86EAABD69!116.entry" bvitemtype="">固定リンク</a></nobr> | <nobr><a title="クリックすると、この記事のトラックバックが表示されます" href="http://jorycen.spaces.live.com/blog/cns!6FDD17E86EAABD69!116.entry#trackback" bvitemtype="trackback">トラックバック (0)</a></nobr> | <nobr><a title="この記事に関する記事を自分のスペースに投稿します" href="javascript:BlogIt('cns!6FDD17E86EAABD69!116');" bvitemtype="">この記事を引用</a></nobr></div>
		<div class="footer">
		</div>
		<div class="fixedTable bvEntry" id="entrycns!6FDD17E86EAABD69!114" bv:cat="" bv:ca="true" bv:cns="cns!6FDD17E86EAABD69!114">
				<h4 class="TextColor1" id="subjcns!6FDD17E86EAABD69!114" style="MARGIN-BOTTOM: 0px">Eclipse 3.0 上配置JSP开发环境</h4>
				<div id="msgcns!6FDD17E86EAABD69!114">
						<div>
								<p style="TEXT-INDENT: 2em">首先讲一下环境配置，注意我配置的环境是在win 2000 server下的，不是linux下的，配置的大致流程和操作系统无关，仅仅是在具体的安装上有差别。而配置成功与否，与操作系统无关。 </p>
								<p style="TEXT-INDENT: 2em">软件安装分为一下几个部分：</p>
								<p style="TEXT-INDENT: 2em">1、 java环境安装：</p>
								<p style="TEXT-INDENT: 2em">这里使用的是jdk1.4.1（jdk1.4.2也可以），这个可以到sun公司的网站去下载； </p>
								<p style="TEXT-INDENT: 2em">2、 tomcat环境安装：</p>
								<p style="TEXT-INDENT: 2em">tomcat的版本是4.1的，安装版或是解压版都是可以的；</p>
								<p style="TEXT-INDENT: 2em">3、 eclipse 3 安装：</p>
								<p style="TEXT-INDENT: 2em">可以去下列地址下载http://www.eclipse.org/downloads/index.php</p>
								<p style="TEXT-INDENT: 2em">我下载的是 3.1M4 版本，这个版本应该是比较新的。 4、 tomcat插件安装；</p>
								<p style="TEXT-INDENT: 2em">tomcat插件是要到下面地址下载http://www.sysdeo.com/eclipse/tomcatPlugin.html，下载之前需要查看插件是否适合eclipse的版本，我下载的是tomcatPluginV3.zip；</p>
								<p style="TEXT-INDENT: 2em">5、 lomboz插件安装；</p>
								<p style="TEXT-INDENT: 2em">lomboz插件需要下载两个部分，一个是emf环境，另一个是lomboz插件，分别到下列地方去找</p>
								<p style="TEXT-INDENT: 2em">http://forge.objectweb.org/project/showfiles.php?group_id=97</p>
								<p style="TEXT-INDENT: 2em">http://download.eclipse.org/tools/emf/scripts/downloads.php#goto2.1.0I</p>
								<p style="TEXT-INDENT: 2em">我下载的是emf-sdo-runtime-I200412160800.zip和org.objectweb.lomboz_3.1.0.N20050106.zip ；</p>
								<p style="TEXT-INDENT: 2em">这里主要是根据eclipse选择适当的lomboz插件，然后查看一下lomboz插件的 介绍，那里会介绍需要的emf插件的版本，然后再去下面的地址找emf插件。</p>
								<p style="TEXT-INDENT: 2em">好了，该下载的都有了，下面我介绍一下如何安装和配置。</p>
								<p style="TEXT-INDENT: 2em">一、 java环境安装</p>
								<p style="TEXT-INDENT: 2em">这个只要直接安装就可以了，不过最好能安装在系统盘以外的地方，这样可以更好理解jvm的配置；安装好了以后，需要配置环境变量，新建JAVA_HOME，并且配置path，把jdk的bin目录添加进去，这样就可以在命令行的任何路径使用jdk的命令了。</p>
								<p style="TEXT-INDENT: 2em">[测试] ：编写一个hello world程序，然后在dos下使用javac hello.java和java hello命令，如果可以正常执行，就证明jdk安装成功了。</p>
								<p style="TEXT-INDENT: 2em">二、 tomcat安装</p>
								<p style="TEXT-INDENT: 2em">解压版的直接解压就可以了，然后配置TOMCAT_HOME，安装版的要注意的两点，一个是安装完之后tomcat的服务就能够启动的了，但是还是要配置TOMCAT_HOME；第二个就是需要查看一下安装程序是不是把tomcat服务注册成为windows的启动服务，需要到“服务”里查看，如果有这个选项就把它设置为手动启动，并且先停止这个服务。</p>
								<p style="TEXT-INDENT: 2em">[测试]：使用startup.bat命令，服务正常启动之后，ie浏览器里输入</p>
								<p style="TEXT-INDENT: 2em">http://localhost:8080/ 如果出现正常的小猫页面，那就应该没有问题了。 </p>
								<p style="TEXT-INDENT: 2em">三、 eclipse 3安装</p>
								<p style="TEXT-INDENT: 2em">eclipse的安装倒是很简单，只要解压，然后把eclipse目录复制到盘符下就可以了，启动的时候，系统会自动寻找jvm，当然可以再以后配置，但是好像是必须先安装jdk。</p>
								<p style="TEXT-INDENT: 2em">四、 tomcat插件安装，emf插件安装，lomboz插件安装，</p>
								<p style="TEXT-INDENT: 2em">这几部分的步骤都是一样的，解压软件包，然后根据里面的目录结构，把目录文件分别复制到feature或plugins目录里，这样就行了，下面将详细讲述一下eclipse的配置。</p>
								<p style="TEXT-INDENT: 2em">五、 配置eclipse</p>
								<p style="TEXT-INDENT: 2em">1、 首先，打开配置界面 window-&gt;preferences。如果这几个插件安装成功，左边的列表里应该有lomboz和tomcat的选项。如果没有，检查上面的步骤是不是正确。</p>
								<p style="TEXT-INDENT: 2em">点击java-&gt;Installed JREs，然后显示如上，如果是初始安装的，只有显示第一个jre（不要问我什么是jre，自己查资料去），那是系统默认的安装在c盘的jre，如果系统当中安装了多个jdk，那么最好还是新建一个，点击add，然后选择你需要使用的jdk的位置，然后它会自动寻找其他的参数，点击ok。返回界面之后，不要忘记点选刚刚添加的jdk，要不然是没有用的。然后点击ok关闭这个窗口。</p>
								<p style="TEXT-INDENT: 2em">2、 再次打开配置界面，点击tomcat选项</p>
								<p style="TEXT-INDENT: 2em">这里是配置tomcat的参数，根据你安装的tomcat的版本，选择tomcat version，然户找到该tomcat的主目录，输入在tomcat home，下面的参数会自动配置，点击apply。 然后在左边选择advanced，同样把tomcat的主目录复制在tomcat base，点击apply。</p>
								<p style="TEXT-INDENT: 2em">最后在左边选择jvm setting，选择刚刚加入的jre，点击apply，点击ok。这样就可以了。回到界面，点击工具栏上的黄色小猫的图标，如果配置正确，在console里应该有启动tomcat的信息。如果有，就代表tomcat配置成功了。</p>
								<p style="TEXT-INDENT: 2em">1、 lomboz基本上不用什么配置，如果左边有那个lomboz选项，基本上就是成功了。点击lomboz，然后选择刚才配置的jdk里的tools.jar，这样配置就完成了。测试的方法是新建一个jsp文件，看看打开的时候是不是对script代码有特殊显示，并且建个测试类，看看jsp是不是能够自动引用类里的函数。</p>
						</div>
				</div>
				<table cellspacing="0" border="0">
						<tbody>
						</tbody>
				</table>
				<div class="footerLinks">5:36 | <nobr><a title="この記事にコメントを投稿する場合にクリックします" href="http://jorycen.spaces.live.com/blog/cns!6FDD17E86EAABD69!114.entry#post" bvitemtype="post">コメントの投稿</a></nobr> | <nobr><a title="クリックすると、この記事の固定リンクが表示されます" href="http://jorycen.spaces.live.com/blog/cns!6FDD17E86EAABD69!114.entry" bvitemtype="">固定リンク</a></nobr> | <nobr><a title="クリックすると、この記事のトラックバックが表示されます" href="http://jorycen.spaces.live.com/blog/cns!6FDD17E86EAABD69!114.entry#trackback" bvitemtype="trackback">トラックバック (0)</a></nobr> | <nobr><a title="この記事に関する記事を自分のスペースに投稿します" href="javascript:BlogIt('cns!6FDD17E86EAABD69!114');" bvitemtype="">この記事を引用</a></nobr></div>
				<div class="footer">
				</div>
		</div>
		<div class="fixedTable bvEntry" id="entrycns!6FDD17E86EAABD69!113" bv:cat="" bv:ca="true" bv:cns="cns!6FDD17E86EAABD69!113">
				<h4 class="TextColor1" id="subjcns!6FDD17E86EAABD69!113" style="MARGIN-BOTTOM: 0px">三步解决tomcat中administration web application 的安装问题</h4>
				<div id="msgcns!6FDD17E86EAABD69!113">
						<div>
								<div style="DISPLAY: block">
										<p>大家都知道Tomcat 5.5及以后的版本，都不带Tomcat Administration。安装完tomcat，如果打开在<a href="http://localhost:8080/"><font color="#b32302">http://localhost:8080</font></a>的页面，点击左上角的Tomcat Administration，或者用 <a href="http://localhost:8080/admin/"><font color="#b32302">Http://localhost:8080/admin/</font></a>  这个时候tomcat会告诉你“Tomcat's administration web application is no longer installed by default. Download and install the "admin" package to use it.”这个信息。</p>
										<p>也许你知道要安装administration web application，可是这个东西到底在那下载，或者下来后怎么安装，也许是个难题，在网上有很多人，写过此类的文章，但都不详细，或者根本行不通。在这里，我把我安装过程写出来，也许有一些是多余的步骤，如果有不同意见或者有不明白的地方可以在本页留言，或者qq249537688，认证信息：草不枯。</p>
										<p>转载请注明出处（<a href="http://kookl.bokee.com/"><font color="#b32302">http://kookl.bokee.com/</font></a>）</p>
										<p>我的环境：j2sdk1.5 ，<a href="http://apache.justdn.org/tomcat/tomcat-5/v5.5.12/bin/apache-tomcat-5.5.12.exe"><font color="#b32302">apache-tomcat-5.5.12.exe</font></a><br /></p>
										<p>第一步：下载</p>
										<p>
												<a href="http://apache.justdn.org/tomcat/tomcat-5/v5.5.12/bin/apache-tomcat-5.5.12-admin.zip">
														<font color="#b32302">http://apache.justdn.org/tomcat/tomcat-5/v5.5.12/bin/apache-tomcat-5.5.12-admin.zip</font>
												</a>
										</p>
										<p>以上直接下载</p>
										<p>或者到<a href="http://tomcat.apache.org/download-55.cgi"><font color="#b32302">http://tomcat.apache.org/download-55.cgi</font></a>下寻找</p>
										<p>第二步</p>
										<p>这一步很简单，<u><font color="#0000ff">apache-tomcat-5.5.12-admin.zip 解压后</font></u><br />把对应的文件copy到tomcat下，具体如下</p>
										<p>把\conf\Catalina\localhost下有admin.xml文件拷到 tomcat的安装目录下\conf\Catalina\localhost目录里面。</p>
										<p>然后再把server\webapps目录下的admin文件夹考到tomcat安转目录下的server\webapps的里面。（如果还不行，再在\Tomcat \webapps里也搞上一份）</p>
										<p>外面还有两个文件，你要不放心也copy 过去，其实没有什么用（个人意见）</p>
										<p>第三步：</p>
										<p>重起tomcai（好象是多余的步骤，各位自己研究以下）</p>
										<p>进入<a href="http://localhost:8080/"><font color="#b32302">http://localhost:8080/</font></a></p>
										<p>点击页面左上角的Status就进入了sever status</p>
										<p>点击左上角的<a href="http://localhost:8080/manager/html/list"><font color="#000000">List Applications</font></a></p>
										<p>你应该在list里能看到/admin.大家可以看到running 项是false。o.k，我们在后面的<font size="2">Commands项里点击start。</font></p>
										<p>
												<font size="2">就这样，好了，现在你可以用了。</font>
										</p>
								</div>
						</div>
				</div>
				<table cellspacing="0" border="0">
						<tbody>
						</tbody>
				</table>
				<div class="footerLinks">5:21 | <nobr><a title="この記事にコメントを投稿する場合にクリックします" href="http://jorycen.spaces.live.com/blog/cns!6FDD17E86EAABD69!113.entry#post" bvitemtype="post">コメントの投稿</a></nobr> | <nobr><a title="クリックすると、この記事の固定リンクが表示されます" href="http://jorycen.spaces.live.com/blog/cns!6FDD17E86EAABD69!113.entry" bvitemtype="">固定リンク</a></nobr> | <nobr><a title="クリックすると、この記事のトラックバックが表示されます" href="http://jorycen.spaces.live.com/blog/cns!6FDD17E86EAABD69!113.entry#trackback" bvitemtype="trackback">トラックバック (0)</a></nobr> | <nobr><a title="この記事に関する記事を自分のスペースに投稿します" href="javascript:BlogIt('cns!6FDD17E86EAABD69!113');" bvitemtype="">この記事を引用</a></nobr></div>
				<div class="footer">
				</div>
		</div>
		<div class="fixedTable bvEntry" id="entrycns!6FDD17E86EAABD69!111" bv:cat="" bv:ca="true" bv:cns="cns!6FDD17E86EAABD69!111">
				<h4 class="TextColor1" id="subjcns!6FDD17E86EAABD69!111" style="MARGIN-BOTTOM: 0px">tomcat 配置</h4>
				<div id="msgcns!6FDD17E86EAABD69!111">
						<div>
								<span>  
<div>2.修改jakarta-tomcat-5.5.x\conf\tomcat-users.xml.<br />添加管理员账号lizongbo，密码为lizongbopass.<br />新xml如下：<br />&lt;?xml version='1.0' encoding='utf-8'?&gt;<br />&lt;tomcat-users&gt;<br />  &lt;role rolename="tomcat"/&gt;<br />  &lt;role rolename="role1"/&gt;<br />  &lt;role rolename="manager"/&gt;<br />  &lt;role rolename="admin"/&gt;<br />  &lt;user username="tomcat" password="tomcat" roles="tomcat"/&gt;<br />  &lt;user username="role1" password="tomcat" roles="role1"/&gt;<br />  &lt;user username="both" password="tomcat" roles="tomcat,role1"/&gt;<br />  &lt;user username="lizongbo" password="lizongbopass" roles="admin,manager"/&gt;<br />&lt;/tomcat-users&gt;</div><div><br /><span><div>3.修改jakarta-tomcat-5.5.x\conf\server.xml来解决编码问题。<br />(给Connector 添加URIEncoding参数，参考<a href="http://blog.csdn.net/darkxie/archive/2004/10/25/TOMCATAPP.aspx"><u><font color="#0000ff"> http://blog.csdn.net/darkxie/archive/2004/10/25/TOMCATAPP.aspx </font></u></a>)</div><div>(可以设置成GB18030)<br />    &lt;Connector port="8080"<br />               maxThreads="150" minSpareThreads="25" maxSpareThreads="75"<br />               enableLookups="false" redirectPort="8443" acceptCount="200"<br />               connectionTimeout="20000" disableUploadTimeout="true" URIEncoding="GBK"<br />               compression="on" compressionMinSize="2048" <br />      noCompressionUserAgents="gozilla, traviata" <br />      compressableMimeType="text/html,text/xml"/&gt;</div><div> </div><div>    &lt;Connector port="8009" <br />               enableLookups="false" redirectPort="8443" protocol="AJP/1.3" URIEncoding="GBK"/&gt;</div><div> <span><div><br />4.启用支持gzip压缩.<br />(<a href="http://www.linuxaid.com.cn/forum/showdoc.jsp?l=1&amp;i=81169"><u><font color="#0000ff"> http://www.linuxaid.com.cn/forum/showdoc.jsp?l=1&amp;i=81169 </font></u></a>)<br />添加下列属性<br /> compression="on" <br />      compressionMinSize="2048" <br />      noCompressionUserAgents="gozilla, traviata" <br />      compressableMimeType="text/html,text/xml"</div><div> </div><div>5.设置虚拟主机。</div><div>在jakarta-tomcat-5.5.x\下建立文件夹vhost\www.mydomain.com。</div><div>然后修改jakarta-tomcat-5.5.x\conf\server.xml</div><div> </div><div>&lt;Engine defaultHost="localhost" name="Catalina"&gt;<br />      &lt;Host appBase="vhost/www.mydomain.com" name="<a href="http://www.mydomain.com/"><u><font color="#0000ff"> www.mydomain.com </font></u></a>"&gt;<br />      &lt;/Host&gt;<br />      &lt;Host appBase="webapps" name="localhost"&gt;<br />      &lt;/Host&gt;<br />      &lt;Realm className="org.apache.catalina.realm.UserDatabaseRealm"/&gt;<br />    &lt;/Engine&gt;</div><div> </div><div>6.添加数据库驱动,更新mail.jar和actiovation.jar</div><div>复制mysql-connector-java-3.0.16-ga-bin.jar,pg74.215.jdbc3.jar到 jakarta-tomcat-5.5.x\common\lib\</div><div>还有javamail 1.3.2的mail.jar，jaf-1_0_2的 activation.jar</div><div>msSQl 2000 JDBC sp3，msbase.jar,msutil,jar,mssqlserver.jar</div></span></div></span></div></span>
						</div>
				</div>
				<table cellspacing="0" border="0">
						<tbody>
						</tbody>
				</table>
				<div class="footerLinks">3:49 | <nobr><a title="この記事にコメントを投稿する場合にクリックします" href="http://jorycen.spaces.live.com/blog/cns!6FDD17E86EAABD69!111.entry#post" bvitemtype="post">コメントの投稿</a></nobr> | <nobr><a title="クリックすると、この記事のコメントが表示されます" href="http://jorycen.spaces.live.com/blog/cns!6FDD17E86EAABD69!111.entry#comment" bvitemtype="comment">コメントの表示 (1)</a></nobr> | <nobr><a title="クリックすると、この記事の固定リンクが表示されます" href="http://jorycen.spaces.live.com/blog/cns!6FDD17E86EAABD69!111.entry" bvitemtype="">固定リンク</a></nobr> | <nobr><a title="クリックすると、この記事のトラックバックが表示されます" href="http://jorycen.spaces.live.com/blog/cns!6FDD17E86EAABD69!111.entry#trackback" bvitemtype="trackback">トラックバック (0)</a></nobr> | <nobr><a title="この記事に関する記事を自分のスペースに投稿します" href="javascript:BlogIt('cns!6FDD17E86EAABD69!111');" bvitemtype="">この記事を引用</a></nobr></div>
				<div class="footer">
				</div>
		</div>
		<div class="fixedTable bvEntry" id="entrycns!6FDD17E86EAABD69!110" bv:cat="" bv:ca="true" bv:cns="cns!6FDD17E86EAABD69!110">
				<h4 class="TextColor1" id="subjcns!6FDD17E86EAABD69!110" style="MARGIN-BOTTOM: 0px">JSP+MYSQL配置全过程</h4>
				<div id="msgcns!6FDD17E86EAABD69!110">
						<div>JSP+MYSQL配置全过程<br />一、J2SDK的安装，jdk-1_5_0_06-windows-i586-p.exe<br />二、TOMCAT的安装，安装apache-tomcat-5.5.12.exe<br />只需要JAVA_HOME，CLASSPATH就可以了。<br />三、安装mysql-4.1.16-win32<br />解压缩mysql-4.1.13-win32.zip，运行setup.exe <br />首先出现的是安装向导欢迎界面,直接点击“Next”继续，选择安装类型,选择“自定义”custom安装，然后点“Next”下一步，出现自定义安装界面，选择安装路径：C:\MySQL Server 4.1(可自定义)点“OK”返回到自定义安装界面，路径已改为设置的路径，点“Next”，准备开始安装，点 “Install”开始安装，完成后出现创建MySQL.com帐号的界面。 <br />如果是首次使用MySQL，选 “Create anew free MySQL.com accout”，点“Next”，输入你的Email地址和自己设定的用于登录 MySQL.com的密码，填完后点“Next”进入第二步，填写姓名等相关信息，填完点“Next”，进入第三步，填完电话号码、公司名称等信息后，点 “Next”，然后出现预览你刚才填的信息的界面，点“Next”出现安装完成界面。 <br />注意，这里有个配置向导的选项（Configure the MySQL Server now），建议勾选立即配置你的MySQL。许多说安装完MySQL后无法启动，原因就在于没有配置MySQL。 <br />点击“Finish”完成安装，并开始配置MySQL，点“Next”，进入配置类型选择页面。选“Detailed configuration”(详细配置)，点“Next”，进入服务类型选择页面。选“Developer Machine”（开发者机器），这样占用系统的资源不会很多，点“Next” 后，进入数据库用法选择页面。 <br />选择“Multifunctional Database”，点“Next”，进入选择InnoDB数据存放位置页面，不用更改设置，直接放在Installation Path安装目录里即可，然后点“Next”，选择MySQL的同时联接数，选择 “Manual Setting”，设置为100(根据自己需要，酌情设置) <br />点“Next”，配置MySQL在TCP/IP通讯环境中的端口选择默认的3306端口即可。点“Next”，选择MySQL中的字符设置，注意，这里的选择将会影响你是否能在MySQL中使用中文。选择 gb2312字符集以便支持简体中文，点“Next”，设置Windows服务选项，注意，这里的选择很关键。<br />“Install As Windows Service” 一定要勾选，这是将MySQL作为Windows的服务运行。“Service Name”就用默认的“MySQL”下面的 “Launch the MySQL Server automatically”一定要勾选，这样Windows启动时，MySQL就会自动启动服务，要不然就要手工启动MySQL。 <br />许多人说安装MySQL后无法启动、无法连接、出现10061错误，原因就在这里。点“Next”，设置根帐号root的登录密码，“Modify Security Settings”是设置根帐号的密码，输入你设定的密码即可。<br />“Create An Anonymous Account”是创建一个匿名帐号，这样会导致未经授权的用户非法访问你的数据库，有安全隐患，建议不要勾选。 <br />点“Next”，MySQL配置向导将依据你上面的所有设定配置MySQL，以便MySQL的运行符合你的需要，点“Execute”开始配置，当出现“Service started successfully”时，说明你的配置完成，MySQL服务启动成功 <br />点“Finish”完成，整个MySQL的配置完成，剩下的就是用MySQL客户端连接MySQL服务器，然后使用了。<br />四、安装JDBC驱动：mysql-connector-java-3.1.8,这只是一个压缩包，并不需要安装，只要将其解压，我么使用的是文件夹mysql-connector-java-3.1.8里的文件：mysql-connector-java-3.1.8-bin.jar．<br />五、环境变量后还有很重要一步就是为JSP连接数据库配置驱动，这个其实很简单，就是把mysql-connector-java-3.1.8- bin.jar拷到某些文件夹里就行了，我在网上看了很多资料问了很多人，各种说法都有，我综合了一下，为了保险，我都全做了，呵呵，反正就是拷一个 400K的文件而已，现列出要把mysql-connector-java-3.1.8-bin.jar拷进去的文件夹，如下：　　<br />C:\Program Files\Apache Software Foundation\Tomcat 5.5\common\lib<br />C:\Program Files\Apache Software Foundation\Tomcat 5.5\share\lib<br />最后的环境变量是ClassPath=.;C:\Program Files\Apache Software Foundation\Tomcat 5.5\common\lib\servlet-api.jar;C:\Program Files\Apache Software Foundation\Tomcat 5.5\common\lib\jsp-api.jar;C:\jdk1.5.0_06\lib\mysql-connector-java-3.1.12\mysql-connector-java-3.1.12-bin.jar<br />现在我想在mysql里建一个数据库shujuku，以及在数据库里建一个表biao．具体的命令如下（假设mysql我是刚安装好的）<br />　　1. 进入dos状态（记住命令行的要运行在mysql的安装目录下的bin目录的）<br />　　2. 连接mysql　　输入：mysql –h localhost –u root –p　　输入在安装时已设好的密码，就近入了mysql的命令编辑界面了。<br />　　3. 使用mysql的基本命令(在mysql命令行编辑每输入完命令后最后一定要有分号，不然会报错)<br />　　显示数据库：show databases;　　使用数据库：use 数据库名；<br />　　4．建库　　命令：create database shujuku;<br />　　5.为数据库设置权限（用户和密码）<br />　　命令：grant all privileges on shujuku.* to test@localhost identified by “123456”;　　当你执行完这个命令以后，只要你再以用户名：test,密码：123456登录时你就只可以对shujuku这个数据库操作，这样避开使用root，对数据库的安全有很大帮助．<br />　　6.建表　　命令：create table biao(id int(8) primary key,name varchar(10));<br />　　剩下来的与标准sqsl命令基本上是一样的，具体操作略<br />　　值得一提的是，你在命令行上输入＂？＂，就会有mysql命令的简单帮助，如下：<br />　　呵呵，那样，我们还可以知道退出，就是＂exit＂，呵呵！<br />　六． JSP连接mysql<br />　　现在就是尝试用jsp连接mysql了　　我在eclipse里建了个test_mysql.jsp页面，代码如下：<br />&lt;%@ page contentType="text/html; charset=gb2312" %&gt;<br />&lt;%@ page language="java" %&gt;<br />&lt;%@ page import="com.mysql.jdbc.Driver" %&gt;<br />&lt;%@ page import="java.sql.*" %&gt;<br />&lt;%//驱动程序名<br />String driverName="com.mysql.jdbc.Driver" <br />String userName="cl41"; ;//数据库用户名<br />String userPasswd="123456";//密码<br />String dbName="db";//数据库名<br />String tableName="dbtest";//表名<br />String url="jdbc:mysql://localhost/"+dbName+"?user="+userName+"&amp;password="+userPasswd; //联结字符串<br />Class.forName("com.mysql.jdbc.Driver").newInstance();<br />Connection connection=DriverManager.getConnection(url);<br />Statement statement = connection.createStatement();<br />String sql="SELECT * FROM "+tableName;<br />ResultSet rs = statement.executeQuery(sql);<br />ResultSetMetaData rmeta = rs.getMetaData();//获得数据结果集合<br />int numColumns=rmeta.getColumnCount();//确定数据集的列数，亦字段数<br />out.print("id");// 输出每一个数据值<br />out.print("|");<br />out.print("num");<br />out.print("&lt;br&gt;");<br />while(rs.next()) {<br />out.print(rs.getString(1)+" ");<br />out.print("|");<br />out.print(rs.getString(2));<br />out.print("&lt;br&gt;");<br />}<br />out.print("&lt;br&gt;");<br />out.print("数据库操作成功，恭喜你");<br />rs.close();<br />statement.close();connection.close();%&gt;<br /></div>
				</div>
				<table cellspacing="0" border="0">
						<tbody>
						</tbody>
				</table>
				<div class="footerLinks">3:47 | <nobr><a title="この記事にコメントを投稿する場合にクリックします" href="http://jorycen.spaces.live.com/blog/cns!6FDD17E86EAABD69!110.entry#post" bvitemtype="post">コメントの投稿</a></nobr> | <nobr><a title="クリックすると、この記事の固定リンクが表示されます" href="http://jorycen.spaces.live.com/blog/cns!6FDD17E86EAABD69!110.entry" bvitemtype="">固定リンク</a></nobr> | <nobr><a title="クリックすると、この記事のトラックバックが表示されます" href="http://jorycen.spaces.live.com/blog/cns!6FDD17E86EAABD69!110.entry#trackback" bvitemtype="trackback">トラックバック (0)</a></nobr> | <nobr><a title="この記事に関する記事を自分のスペースに投稿します" href="javascript:BlogIt('cns!6FDD17E86EAABD69!110');" bvitemtype="">この記事を引用</a></nobr></div>
				<div class="footer">
				</div>
		</div>
		<div class="fixedTable bvEntry" id="entrycns!6FDD17E86EAABD69!109" bv:cat="" bv:ca="true" bv:cns="cns!6FDD17E86EAABD69!109">
				<h4 class="TextColor1" id="subjcns!6FDD17E86EAABD69!109" style="MARGIN-BOTTOM: 0px">tomcat下如何配置jsp、servlet和bean的问题</h4>
				<div id="msgcns!6FDD17E86EAABD69!109">
						<div>
								<div>
										<div>
												<font color="#15acbb">jdk-1_5_0</font>和<a href="http://apache.justdn.org/tomcat/tomcat-5/v5.5.17/bin/apache-tomcat-5.5.17.exe"><font color="#15acbb">tomcat</font></a></div>
										<div> </div>
										<div>      经常看到jsp的初学者问tomcat下如何配置jsp、servlet和bean的问题，于是总结了一下如何tomcat下配置jsp、servlet和ben，希望对那些初学者有所帮助。<br />　　<br />　　一、开发环境配置<br />　　<br />　　第一步：下载j2sdk和tomcat：到sun官方站（<a href="http://java.sun.com/j2se/1.5.0/download.jsp"><font color="#15acbb">http://java.sun.com/j2se/1.5.0/download.jsp</font></a>）下载j2sdk，注意下载版本为Windows Offline Installation的SDK，同时最好下载J2SE 1.5.0 Documentation，然后到tomcat官方站点（<a href="http://jakarta.apache.org/site/downloads/downloads_tomcat-5.cgi"><font color="#15acbb">http://jakarta.apache.org/site/downloads/downloads_tomcat-5.cgi</font></a>）下载tomcat（下载最新5.5.9版本的tomcat）；<br />　　<br />　　第二步：安装和配置你的j2sdk和tomcat：执行j2sdk和tomcat的安装程序，然后按默认设置进行安装即可。<br />　　<br />　　1.安装j2sdk以后，需要配置一下环境变量，在我的电脑-&gt;属性-&gt;高级-&gt;环境变量-&gt;系统变量中添加以下环境变量(假定你的j2sdk安装在c:\j2sdk1.5.0）：<br />　　<br />　　JAVA_HOME=c:\j2sdk1.5.0<br />　　classpath=.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;（.;一定不能少，因为它代表当前路径)<br />　　path=%JAVA_HOME%\bin<br />　　<br />　　接着可以写一个简单的java程序来测试J2SDK是否已安装成功：<br />　　<br />　　public class Test{<br />　　public static void main(String args[]){<br />　　System.out.println("This is a test program.");<br />　　}<br />　　}<br />　　<br />　　将上面的这段程序保存为文件名为Test.java的文件。<br />　　<br />　　然后打开命令提示符窗口，cd到你的Test.java所在目录，然后键入下面的命令<br />　　<br />　　javac Test.java<br />　　java Test<br />　　<br />　　此时如果看到打印出来This is a test program.的话说明安装成功了，如果没有打印出这句话，你需要仔细检查一下你的配置情况。<br />　　<br />　　2.安装Tomcat后，在我的电脑-&gt;属性-&gt;高级-&gt;环境变量-&gt;系统变量中添加以下环境变量(假定你的tomcat安装在c:\tomcat)：<br />　　<br />　　CATALINA_HOME=c:\tomcat<br />　　CATALINA_BASE=c:\tomcat<br />　　<br />　　然后修改环境变量中的classpath，把tomat安装目录下的common\lib下的(可以根据实际追加)servlet.jar追加到classpath中去，修改后的classpath如下：<br />　　<br />　　classpath=.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;%CATALINA_HOME%\common\lib\servlet.jar;<br />　　<br />　　接着可以启动tomcat，在IE中访问<a href="http://localhost:8080/"><font color="#15acbb">http://localhost:8080</font></a>，如果看到tomcat的欢迎页面的话说明安装成功了。<br />　　<br />　　第三步：建立自己的jsp app目录<br />　　<br />　　1.到Tomcat的安装目录的webapps目录，可以看到ROOT，examples, tomcat-docs之类Tomcat自带的的目录；<br />　　2.在webapps目录下新建一个目录，起名叫myapp；<br />　　3.myapp下新建一个目录WEB-INF，注意，目录名称是区分大小写的；<br />　　4.WEB-INF下新建一个文件web.xml，内容如下：<br />　　<br />　　&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />　　&lt;!DOCTYPE web-app<br />　　PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />　　"<a href="http://java.sun.com/dtd/web-app_2_3.dtd"><font color="#15acbb">http://java.sun.com/dtd/web-app_2_3.dtd</font></a>"&gt;<br />　　&lt;web-app&gt;<br />　　&lt;display-name&gt;My Web Application&lt;/display-name&gt;<br />　　&lt;description&gt;<br />　　A application for test.<br />　　&lt;/description&gt;<br />　　&lt;/web-app&gt;<br />　　<br />　　5.在myapp下新建一个测试的jsp页面，文件名为index.jsp，文件内容如下：<br />　　&lt;html&gt;&lt;body&gt;&lt;center&gt;<br />　　Now time is: &lt;%=new java.util.Date()%&gt;<br />　　&lt;/center&gt;&lt;/body&gt;&lt;/html&gt;<br />　　<br />　　6.重启Tomcat<br />　　<br />　　7.打开浏览器，输入<a href="http://localhost:8080/myapp/index.jsp"><font color="#15acbb">http://localhost:8080/myapp/index.jsp</font></a> 看到当前时间的话说明就成功了。<br />　　<br />　　第四步：建立自己的Servlet：<br />　　<br />　　1.用你最熟悉的编辑器（建议使用有语法检查的java ide）新建一个servlet程序，文件名为Test.java，文件内容如下：<br />　　<br />　　package test;<br />　　import java.io.IOException;<br />　　import java.io.PrintWriter;<br />　　import javax.servlet.ServletException;<br />　　import javax.servlet.http.HttpServlet;<br />　　import javax.servlet.http.HttpServletRequest;<br />　　import javax.servlet.http.HttpServletResponse;<br />　　public class Test extends HttpServlet {<br />　　protected void doGet(HttpServletRequest request, HttpServletResponse response)<br />　　throws ServletException, IOException {<br />　　PrintWriter out=response.getWriter();<br />　　out.println("&lt;html&gt;&lt;body&gt;&lt;h1&gt;This is a servlet test.&lt;/h1&gt;&lt;/body&gt;&lt;/html&gt;");<br />　　out.flush();<br />　　}<br />　　}<br />　　<br />　　2 .编译<br />　　将Test.java放在c:\test下，使用如下命令编译：<br />　　<br />　　C:\Test&gt;javac Test.java<br />　　<br />　　然后在c:\Test下会产生一个编译后的servlet文件：Test.class<br />　　<br />　　3 .将结构test\Test.class剪切到%CATALINA_HOME%\webapps\myapp\WEB-INF\classes下，也就是剪切那个test目录到classes目录下，如果classes目录不存在，就新建一个。 现在webapps\myapp\WEB-INF\classes下有test\Test.class的文件目录结构<br />　　<br />　　4 .修改webapps\myapp\WEB-INF\web.xml，添加servlet和servlet-mapping<br />　　<br />　　编辑后的web.xml如下所示，红色为添加的内容:<br />　　<br />　　&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />　　&lt;!DOCTYPE web-app<br />　　PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />　　"<a href="http://java.sun.com/dtd/web-app_2_3.dtd"><font color="#15acbb">http://java.sun.com/dtd/web-app_2_3.dtd</font></a>"&gt;<br />　　&lt;web-app&gt;<br />　　&lt;display-name&gt;My Web Application&lt;/display-name&gt;<br />　　&lt;description&gt;<br />　　A application for test.<br />　　&lt;/description&gt;<br />　　&lt;servlet&gt;<br />　　&lt;servlet-name&gt;Test&lt;/servlet-name&gt;<br />　　&lt;display-name&gt;Test&lt;/display-name&gt;<br />　　&lt;description&gt;A test Servlet&lt;/description&gt;<br />　　&lt;servlet-class&gt;test.Test&lt;/servlet-class&gt;<br />　　&lt;/servlet&gt;<br />　　&lt;servlet-mapping&gt;<br />　　&lt;servlet-name&gt;Test&lt;/servlet-name&gt;<br />　　&lt;url-pattern&gt;/Test&lt;/url-pattern&gt;<br />　　&lt;/servlet-mapping&gt;<br />　　&lt;/web-app&gt;<br />　　<br />　　这段话中的servlet这一段声明了你要调用的Servlet，而servlet-mapping则是将声明的servlet"映射"到地址/Test上<br />　　<br />　　5 .好了，重启动Tomcat，启动浏览器，输入<a href="http://localhost:8080/myapp/Test"><font color="#15acbb">http://localhost:8080/myapp/Test</font></a> 如果看到输出This is a servlet test.就说明编写的servlet成功了。<br />　　<br />　　注意：修改了web.xml以及新加了class，都要重启Tomcat<br />　　<br />　　第四步：建立自己的Bean：<br />　　<br />　　1.用你最熟悉的编辑器（建议使用有语法检查的java ide）新建一个java程序，文件名为TestBean.java，文件内容如下：<br />　　<br />　　package test;<br />　　public class TestBean{<br />　　private String name = null;<br />　　public TestBean(String strName_p){<br />　　this.name=strName_p;<br />　　}<br />　　public void setName(String strName_p){<br />　　this.name=strName_p;<br />　　}<br />　　public String getName(){<br />　　return this.name;<br />　　}<br />　　}<br />　　<br />　　2 .编译<br />　　<br />　　将TestBean.java放在c:\test下，使用如下命令编译：<br />　　<br />　　C:\Test&gt;javac TestBean.java<br />　　<br />　　然后在c:\Test下会产生一个编译后的bean文件：TestBean.class<br />　　<br />　　3 .将TestBean.class文件剪切到 %CATALINA_HOME%\webapps\myapp\WEB-INF\classes\test下，<br />　　<br />　　4 .新建一个TestBean.jsp文件，文件内容为：<br />　　<br />　　&lt;%@ page import="test.TestBean" %&gt;<br />　　&lt;html&gt;&lt;body&gt;&lt;center&gt;<br />　　&lt;%<br />　　TestBean testBean=new TestBean("This is a test java bean.");<br />　　%&gt;<br />　　Java bean name is: &lt;%=testBean.getName()%&gt;<br />　　&lt;/center&gt;&lt;/body&gt;&lt;/html&gt;<br />　　<br />　　5 .好了，重启Tomcat，启动浏览器，输入<a href="http://localhost:8080/myapp/TestBean.jsp"><font color="#15acbb">http://localhost:8080/myapp/TestBean.jsp</font></a> 如果看到输出Java bean name is: This is a test java bean.就说明编写的Bean成功了。<br />　　<br />　　这样就完成了整个Tomcat下的jsp、servlet和javabean的配置。接下来需要做的事情就是多看书、多读别人的好代码，自己多动手写代码以增强自己在这方面开发的能力了。<br />　　<br />　　jvm应填写到<br />　　c:\j2sdk\bin<br />　　<br />　　给你一个简单的配置：：：：<br />　　<br />　　JSP环境配置心得<br />　　<br />　　首先要说的是，使用jdk+tomcat完全可以配置我们的jsp服务器，不再需要其实任何东东，有很多文章介绍了Apache，其实根本用不着，一般的学习调试tomcat完全可以胜任了。<br />　　<br />　　安装jdk后，tomcat在安装之前会自动找到jdk的安装路径，一路点击"下一步"，经过一段时间的文件复制，最后"close"，完成comcat的安装。<br />　　<br />　　您最好去下载一个版本较高的tomcat，比如4.1以上的，因为它不需要设置太多的系统变量，右击"我的电脑"，选择"属性"-&gt;"高级"-&gt;"环境变量"-&gt;"系统变量"，新建一个TOMCAT_HOME，值设置成你的tomcat所在的路径，比如：D:\Program Files\Apache Group\Tomcat 5.5，配置完成。<br />　　<br />　　从开始菜单中找到tomcat选项，一般打开顺序是：开始-&gt;程序-&gt;Apache Tomcat 5.5，选择"Start Tomcat"，让jsp服务器开始运行，此时会打开一个类似Dos的窗口，会显示一些相关的信息。<br /></div>
								</div>
						</div>
				</div>
				<table cellspacing="0" border="0">
						<tbody>
						</tbody>
				</table>
				<div class="footerLinks">3:26 | <nobr><a title="この記事にコメントを投稿する場合にクリックします" href="http://jorycen.spaces.live.com/blog/cns!6FDD17E86EAABD69!109.entry#post" bvitemtype="post">コメントの投稿</a></nobr> | <nobr><a title="クリックすると、この記事の固定リンクが表示されます" href="http://jorycen.spaces.live.com/blog/cns!6FDD17E86EAABD69!109.entry" bvitemtype="">固定リンク</a></nobr> | <nobr><a title="クリックすると、この記事のトラックバックが表示されます" href="http://jorycen.spaces.live.com/blog/cns!6FDD17E86EAABD69!109.entry#trackback" bvitemtype="trackback">トラックバック (0)</a></nobr> | <nobr><a title="この記事に関する記事を自分のスペースに投稿します" href="javascript:BlogIt('cns!6FDD17E86EAABD69!109');" bvitemtype="">この記事を引用</a></nobr></div>
				<div class="footer">
				</div>
		</div>
		<div class="fixedTable bvEntry" id="entrycns!6FDD17E86EAABD69!108" bv:cat="" bv:ca="true" bv:cns="cns!6FDD17E86EAABD69!108">
				<h4 class="TextColor1" id="subjcns!6FDD17E86EAABD69!108" style="MARGIN-BOTTOM: 0px">Windows下JAVA环境变量的设置祥解</h4>
				<div id="msgcns!6FDD17E86EAABD69!108">
						<div>
								<div>
										<p>Windows下JAVA用到的环境变量主要有3个，JAVA_HOME、CLASSPATH、PATH。下面逐个分析。</p>
										<p>JAVA_HOME指向的是JDK的安装路径，如x:\JDK_1.4.2，在这路径下你应该能够找到bin、lib等目录。值得一提的是，JDK的安装路径可以选择任意磁盘目录，不过建议你放的目录层次浅一点，如果你放的目录很深，比如x:\XXXXXX\xxxxx\XXXX\xxxx\XXXX\xxxx\XXXX\xxx……<br />那么，下面的步骤和以后的应用你都要受累了，呵呵。设置方法：<br />JAVA_HOME=x:\JDK_1.4.2</p>
										<p>PATH环境变量原来Windows里面就有，你只需修改一下，使他指向JDK的bin目录，这样你在控制台下面编译、执行程序时就不需要再键入一大串路径了。设置方法是保留原来的PATH的内容，并在其中加上%JAVA_HOME%\bin (注，如果你对DOS批处理不了解，你可能不明白%%引起来的内容是什么意思；其实这里是引用上一步设定好的环境变量JAVA_HOME，你写成x:\JDK_1.4.2也是可以的；你可以打开一个控制台窗口，输入echo %JAVA_HOME%来看一下你的设置结果) ：<br />PATH=%JAVA_HOME%\bin;%PATH%<br />同样，%PATH%是引用以前你设置的PATH环境变量，你照抄以前的值就行了。</p>
										<p>CLASSPATH环境变量我放在最后面，是因为以后你出现的莫名其妙的怪问题80%以上都可能是由于CLASSPATH设置不对引起的，所以要加倍小心才行。<br />CLASSPATH=.;%JAVA_HOME%\lib\tools.jar<br />首先要注意的是最前面的".;"，如果你看不清，我给你念念——句点分号。这个是告诉JDK，搜索CLASS时先查找当前目录的CLASS文件——为什么这样搞，这是由于LINUX的安全机制引起的，LINUX用户很明白，WINDOWS用户就很难理解(因为WINDOWS默认的搜索顺序是先搜索当前目录的，再搜索系统目录的，再搜索PATH环境变量设定的) ，所以如果喜欢盘根究底的朋友不妨研究一下LINUX。<br />为什么CLASSPATH后面指定了tools.jar这个具体文件？不指定行不行？显然不行，行的话我还能这么罗索嘛！:) 这个是由java语言的import机制和jar机制决定的，你可以查资料解决。</p>
										<p>
												<br />呵呵，具体的设定方法: win2k\xp用户右键点击我的电脑-&gt;属性-&gt;高级-&gt;环境变量，修改下面系统变量那个框里的值就行了。<br />win9x用户修改autoexec.bat文件，在其末尾加入: <br />set JAVA_HOME=x:\JDK_1.4.2<br />set PATH=%JAVA_HOME%\bin;%PATH%<br />set CLASSPATH=.;%JAVA_HOME</p>
								</div>
						</div>
				</div>
		</div>
<img src ="http://www.blogjava.net/19851985lili/aggbug/93527.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/19851985lili/" target="_blank">☜♥☞MengChuChen</a> 2007-01-12 20:37 <a href="http://www.blogjava.net/19851985lili/articles/93527.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>web.xml参考大全  </title><link>http://www.blogjava.net/19851985lili/articles/93518.html</link><dc:creator>☜♥☞MengChuChen</dc:creator><author>☜♥☞MengChuChen</author><pubDate>Fri, 12 Jan 2007 11:49:00 GMT</pubDate><guid>http://www.blogjava.net/19851985lili/articles/93518.html</guid><wfw:comment>http://www.blogjava.net/19851985lili/comments/93518.html</wfw:comment><comments>http://www.blogjava.net/19851985lili/articles/93518.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/19851985lili/comments/commentRss/93518.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/19851985lili/services/trackbacks/93518.html</trackback:ping><description><![CDATA[
		<strong> 定义头和根元素<br /><br /></strong>部署描述符文件就像所有XML文件一样，必须以一个XML头开始。这个头声明可以使用的XML版本并给出文件的字符编码。<br />DOCYTPE声明必须立即出现在此头之后。这个声明告诉服务器适用的servlet规范的版本（如2.2或2.3）并指定管理此文件其余部分内容的语法的DTD(Document Type Definition，文档类型定义)。<br />所有部署描述符文件的顶层（根）元素为web-app。请注意，XML元素不像HTML，他们是大小写敏感的。因此，web-App和WEB-APP都是不合法的，web-app必须用小写。<br /><br /><b><font color="#000000">2 部署描述符文件内的元素次序</font></b><br /><br />XML元素不仅是大小写敏感的，而且它们还对出现在其他元素中的次序敏感。例如，XML头必须是文件中的第一项，DOCTYPE声明必须是第二项，而web-app元素必须是第三项。在web-app元素内，元素的次序也很重要。服务器不一定强制要求这种次序，但它们允许（实际上有些服务器就是这样做的）完全拒绝执行含有次序不正确的元素的Web应用。这表示使用非标准元素次序的web.xml文件是不可移植的。<br />下面的列表给出了所有可直接出现在web-app元素内的合法元素所必需的次序。例如，此列表说明servlet元素必须出现在所有servlet-mapping元素之前。请注意，所有这些元素都是可选的。因此，可以省略掉某一元素，但不能把它放于不正确的位置。<br />l icon icon元素指出IDE和GUI工具用来表示Web应用的一个和两个图像文件的位置。<br />l display-name display-name元素提供GUI工具可能会用来标记这个特定的Web应用的一个名称。<br />l description description元素给出与此有关的说明性文本。<br />l context-param context-param元素声明应用范围内的初始化参数。<br />l filter 过滤器元素将一个名字与一个实现javax.servlet.Filter接口的类相关联。<br />l filter-mapping 一旦命名了一个过滤器，就要利用filter-mapping元素把它与一个或多个servlet或JSP页面相关联。<br />l listener servlet API的版本2.3增加了对事件监听程序的支持，事件监听程序在建立、修改和删除会话或servlet环境时得到通知。Listener元素指出事件监听程序类。<br />l servlet 在向servlet或JSP页面制定初始化参数或定制URL时，必须首先命名servlet或JSP页面。Servlet元素就是用来完成此项任务的。<br />l servlet-mapping 服务器一般为servlet提供一个缺省的URL：http://host/webAppPrefix/servlet/ServletName。但是，常常会更改这个URL，以便servlet可以访问初始化参数或更容易地处理相对URL。在更改缺省URL时，使用servlet-mapping元素。<br />l session-config 如果某个会话在一定时间内未被访问，服务器可以抛弃它以节省内存。可通过使用HttpSession的setMaxInactiveInterval方法明确设置单个会话对象的超时值，或者可利用session-config元素制定缺省超时值。<br />l mime-mapping 如果Web应用具有想到特殊的文件，希望能保证给他们分配特定的MIME类型，则mime-mapping元素提供这种保证。<br />l welcom-file-list welcome-file-list元素指示服务器在收到引用一个目录名而不是文件名的URL时，使用哪个文件。<br />l error-page error-page元素使得在返回特定HTTP状态代码时，或者特定类型的异常被抛出时，能够制定将要显示的页面。<br />l taglib taglib元素对标记库描述符文件（Tag Libraryu Descriptor file）指定别名。此功能使你能够更改TLD文件的位置，而不用编辑使用这些文件的JSP页面。<br />l resource-env-ref resource-env-ref元素声明与资源相关的一个管理对象。<br />l resource-ref resource-ref元素声明一个资源工厂使用的外部资源。<br />l security-constraint security-constraint元素制定应该保护的URL。它与login-config元素联合使用<br />l login-config 用login-config元素来指定服务器应该怎样给试图访问受保护页面的用户授权。它与sercurity-constraint元素联合使用。<br />l security-role security-role元素给出安全角色的一个列表，这些角色将出现在servlet元素内的security-role-ref元素的role-name子元素中。分别地声明角色可使高级IDE处理安全信息更为容易。<br />l env-entry env-entry元素声明Web应用的环境项。<br />l ejb-ref ejb-ref元素声明一个EJB的主目录的引用。<br />l ejb-local-ref ejb-local-ref元素声明一个EJB的本地主目录的应用。<br /><br /><b>3 分配名称和定制的UL</b><br /><br />在web.xml中完成的一个最常见的任务是对servlet或JSP页面给出名称和定制的URL。用servlet元素分配名称，使用servlet-mapping元素将定制的URL与刚分配的名称相关联。<br />3.1 分配名称<br />为了提供初始化参数，对servlet或JSP页面定义一个定制URL或分配一个安全角色，必须首先给servlet或JSP页面一个名称。可通过servlet元素分配一个名称。最常见的格式包括servlet-name和servlet-class子元素（在web-app元素内），如下所示：<br />&lt;servlet&gt;<br />&lt;servlet-name&gt;Test&lt;/servlet-name&gt;<br />&lt;servlet-class&gt;moreservlets.TestServlet&lt;/servlet-class&gt;<br />&lt;/servlet&gt; 
<p>这表示位于WEB-INF/classes/moreservlets/TestServlet的servlet已经得到了注册名Test。给servlet一个名称具有两个主要的含义。首先，初始化参数、定制的URL模式以及其他定制通过此注册名而不是类名引用此servlet。其次,可在URL而不是类名中使用此名称。因此，利用刚才给出的定义，URL http://host/webAppPrefix/servlet/Test 可用于 http://host/webAppPrefix/servlet/moreservlets.TestServlet 的场所。<br />请记住：XML元素不仅是大小写敏感的，而且定义它们的次序也很重要。例如，web-app元素内所有servlet元素必须位于所有servlet-mapping元素（下一小节介绍）之前，而且还要位于5.6节和5.11节讨论的与过滤器或文档相关的元素（如果有的话）之前。类似地，servlet的servlet-name子元素也必须出现在servlet-class之前。5.2节"部署描述符文件内的元素次序"将详细介绍这种必需的次序。<br />例如，程序清单5-1给出了一个名为TestServlet的简单servlet，它驻留在moreservlets程序包中。因为此servlet是扎根在一个名为deployDemo的目录中的Web应用的组成部分，所以TestServlet.class放在deployDemo/WEB-INF/classes/moreservlets中。程序清单5-2给出将放置在deployDemo/WEB-INF/内的web.xml文件的一部分。此web.xml文件使用servlet-name和servlet-class元素将名称Test与TestServlet.class相关联。图5-1和图5-2分别显示利用缺省URL和注册名调用TestServlet时的结果。</p><p>程序清单5-1 TestServlet.java<br />package moreservlets;</p><p>import java.io.*;<br />import javax.servlet.*;<br />import javax.servlet.http.*;</p><p>/** Simple servlet used to illustrate servlet naming<br />* and custom URLs.<br />* &lt;P&gt;<br />* Taken from More Servlets and JavaServer Pages<br />* from Prentice Hall and Sun Microsystems Press,<br />* http://www.moreservlets.com/.<br />* &amp;copy; 2002 Marty Hall; may be freely used or adapted.<br />*/</p><p>public class TestServlet extends HttpServlet {<br />public void doGet(HttpServletRequest request,<br />HttpServletResponse response)<br />throws ServletException, IOException {<br />response.setContentType("text/html");<br />PrintWriter out = response.getWriter();<br />String uri = request.getRequestURI();<br />out.println(ServletUtilities.headWithTitle("Test Servlet") +<br />"&lt;BODY BGCOLOR=\"#FDF5E6\"&gt;\n" +<br />"&lt;H2&gt;URI: " + uri + "&lt;/H2&gt;\n" +<br />"&lt;/BODY&gt;&lt;/HTML&gt;");<br />}<br />}</p><p><br />程序清单5-2 web.xml（说明servlet名称的摘录）<br />&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />&lt;!DOCTYPE web-app<br />PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />"http://java.sun.com/dtd/web-app_2_3.dtd"&gt;</p><p>&lt;web-app&gt;<br />&lt;!-- … --&gt;<br />&lt;servlet&gt;<br />&lt;servlet-name&gt;Test&lt;/servlet-name&gt;<br />&lt;servlet-class&gt;moreservlets.TestServlet&lt;/servlet-class&gt;<br />&lt;/servlet&gt;<br />&lt;!-- … --&gt;<br />&lt;/web-app&gt;</p><p>3.2 定义定制的URL<br />大多数服务器具有一个缺省的serlvet URL：<br />http://host/webAppPrefix/servlet/packageName.ServletName。虽然在开发中使用这个URL很方便，但是我们常常会希望另一个URL用于部署。例如，可能会需要一个出现在Web应用顶层的URL（如，http://host/webAppPrefix/Anyname），并且在此URL中没有servlet项。位于顶层的URL简化了相对URL的使用。此外，对许多开发人员来说，顶层URL看上去比更长更麻烦的缺省URL更简短。<br />事实上，有时需要使用定制的URL。比如，你可能想关闭缺省URL映射，以便更好地强制实施安全限制或防止用户意外地访问无初始化参数的servlet。如果你禁止了缺省的URL，那么你怎样访问servlet呢？这时只有使用定制的URL了。<br />为了分配一个定制的URL，可使用servlet-mapping元素及其servlet-name和url-pattern子元素。Servlet-name元素提供了一个任意名称，可利用此名称引用相应的servlet；url-pattern描述了相对于Web应用的根目录的URL。url-pattern元素的值必须以斜杠（/）起始。<br />下面给出一个简单的web.xml摘录，它允许使用URL http://host/webAppPrefix/UrlTest而不是http://host/webAppPrefix/servlet/Test或<br />http://host/webAppPrefix/servlet/moreservlets.TestServlet。请注意，仍然需要XML头、DOCTYPE声明以及web-app封闭元素。此外，可回忆一下，XML元素出现地次序不是随意的。特别是，需要把所有servlet元素放在所有servlet-mapping元素之前。<br />&lt;servlet&gt;<br />&lt;servlet-name&gt;Test&lt;/servlet-name&gt;<br />&lt;servlet-class&gt;moreservlets.TestServlet&lt;/servlet-class&gt;<br />&lt;/servlet&gt;<br />&lt;!-- ... --&gt;<br />&lt;servlet-mapping&gt;<br />&lt;servlet-name&gt;Test&lt;/servlet-name&gt;<br />&lt;url-pattern&gt;/UrlTest&lt;/url-pattern&gt;<br />&lt;/servlet-mapping&gt;<br />URL模式还可以包含通配符。例如，下面的小程序指示服务器发送所有以Web应用的URL前缀开始，以..asp结束的请求到名为BashMS的servlet。<br />&lt;servlet&gt;<br />&lt;servlet-name&gt;BashMS&lt;/servlet-name&gt;<br />&lt;servlet-class&gt;msUtils.ASPTranslator&lt;/servlet-class&gt;<br />&lt;/servlet&gt;<br />&lt;!-- ... --&gt;<br />&lt;servlet-mapping&gt;<br />&lt;servlet-name&gt;BashMS&lt;/servlet-name&gt;<br />&lt;url-pattern&gt;/*.asp&lt;/url-pattern&gt;<br />&lt;/servlet-mapping&gt;<br />3.3 命名JSP页面<br />因为JSP页面要转换成sevlet，自然希望就像命名servlet一样命名JSP页面。毕竟，JSP页面可能会从初始化参数、安全设置或定制的URL中受益，正如普通的serlvet那样。虽然JSP页面的后台实际上是servlet这句话是正确的，但存在一个关键的猜疑：即，你不知道JSP页面的实际类名（因为系统自己挑选这个名字）。因此，为了命名JSP页面，可将jsp-file元素替换为servlet-calss元素，如下所示：<br />&lt;servlet&gt;<br />&lt;servlet-name&gt;Test&lt;/servlet-name&gt;<br />&lt;jsp-file&gt;/TestPage.jsp&lt;/jsp-file&gt;<br />&lt;/servlet&gt;<br />命名JSP页面的原因与命名servlet的原因完全相同：即为了提供一个与定制设置（如，初始化参数和安全设置）一起使用的名称，并且，以便能更改激活JSP页面的URL（比方说，以便多个URL通过相同页面得以处理，或者从URL中去掉.jsp扩展名）。但是，在设置初始化参数时，应该注意，JSP页面是利用jspInit方法，而不是init方法读取初始化参数的。<br />例如，程序清单5-3给出一个名为TestPage.jsp的简单JSP页面，它的工作只是打印出用来激活它的URL的本地部分。TestPage.jsp放置在deployDemo应用的顶层。程序清单5-4给出了用来分配一个注册名PageName，然后将此注册名与http://host/webAppPrefix/UrlTest2/anything 形式的URL相关联的web.xml文件（即，deployDemo/WEB-INF/web.xml）的一部分。</p><p>程序清单5-3 TestPage.jsp<br />&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"&gt;<br />&lt;HTML&gt;<br />&lt;HEAD&gt;<br />&lt;TITLE&gt;<br />JSP Test Page<br />&lt;/TITLE&gt;<br />&lt;/HEAD&gt;<br />&lt;BODY BGCOLOR="#FDF5E6"&gt;<br />&lt;H2&gt;URI: &lt;%= request.getRequestURI() %&gt;&lt;/H2&gt;<br />&lt;/BODY&gt;<br />&lt;/HTML&gt;</p><p><br />程序清单5-4 web.xml（说明JSP页命名的摘录）<br />&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />&lt;!DOCTYPE web-app<br />PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />"http://java.sun.com/dtd/web-app_2_3.dtd"&gt;</p><p>&lt;web-app&gt;<br />&lt;!-- ... --&gt;<br />&lt;servlet&gt;<br />&lt;servlet-name&gt;PageName&lt;/servlet-name&gt;<br />&lt;jsp-file&gt;/TestPage.jsp&lt;/jsp-file&gt;<br />&lt;/servlet&gt;<br />&lt;!-- ... --&gt;<br />&lt;servlet-mapping&gt;<br />&lt;servlet-name&gt; PageName &lt;/servlet-name&gt;<br />&lt;url-pattern&gt;/UrlTest2/*&lt;/url-pattern&gt;<br />&lt;/servlet-mapping&gt;<br />&lt;!-- ... --&gt;<br />&lt;/web-app&gt;</p><p><br /><b>4 禁止激活器servlet</b><br /><br />对servlet或JSP页面建立定制URL的一个原因是，这样做可以注册从init（servlet）或jspInit（JSP页面）方法中读取得初始化参数。但是，初始化参数只在是利用定制URL模式或注册名访问servlet或JSP页面时可以使用，用缺省URL http://host/webAppPrefix/servlet/ServletName 访问时不能使用。因此，你可能会希望关闭缺省URL，这样就不会有人意外地调用初始化servlet了。这个过程有时称为禁止激活器servlet，因为多数服务器具有一个用缺省的servlet URL注册的标准servlet，并激活缺省的URL应用的实际servlet。<br />有两种禁止此缺省URL的主要方法：<br />l 在每个Web应用中重新映射/servlet/模式。<br />l 全局关闭激活器servlet。<br />重要的是应该注意到，虽然重新映射每个Web应用中的/servlet/模式比彻底禁止激活servlet所做的工作更多，但重新映射可以用一种完全可移植的方式来完成。相反，全局禁止激活器servlet完全是针对具体机器的，事实上有的服务器（如ServletExec）没有这样的选择。下面的讨论对每个Web应用重新映射/servlet/ URL模式的策略。后面提供在Tomcat中全局禁止激活器servlet的详细内容。<br />4.1 重新映射/servlet/URL模式<br />在一个特定的Web应用中禁止以http://host/webAppPrefix/servlet/ 开始的URL的处理非常简单。所需做的事情就是建立一个错误消息servlet，并使用前一节讨论的url-pattern元素将所有匹配请求转向该servlet。只要简单地使用：<br />&lt;url-pattern&gt;/servlet/*&lt;/url-pattern&gt;<br />作为servlet-mapping元素中的模式即可。<br />例如，程序清单5-5给出了将SorryServlet servlet（程序清单5-6）与所有以http://host/webAppPrefix/servlet/ 开头的URL相关联的部署描述符文件的一部分。</p><p>程序清单5-5 web.xml（说明JSP页命名的摘录）<br />&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />&lt;!DOCTYPE web-app<br />PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />"http://java.sun.com/dtd/web-app_2_3.dtd"&gt;</p><p>&lt;web-app&gt;<br />&lt;!-- ... --&gt;<br />&lt;servlet&gt;<br />&lt;servlet-name&gt;Sorry&lt;/servlet-name&gt;<br />&lt;servlet-class&gt;moreservlets.SorryServlet&lt;/servlet-class&gt;<br />&lt;/servlet&gt;<br />&lt;!-- ... --&gt;<br />&lt;servlet-mapping&gt;<br />&lt;servlet-name&gt; Sorry &lt;/servlet-name&gt;<br />&lt;url-pattern&gt;/servlet/*&lt;/url-pattern&gt;<br />&lt;/servlet-mapping&gt;<br />&lt;!-- ... --&gt;<br />&lt;/web-app&gt;</p><p><br />程序清单5-6 SorryServlet.java<br />package moreservlets;</p><p>import java.io.*;<br />import javax.servlet.*;<br />import javax.servlet.http.*;</p><p>/** Simple servlet used to give error messages to<br />* users who try to access default servlet URLs<br />* (i.e., http://host/webAppPrefix/servlet/ServletName)<br />* in Web applications that have disabled this<br />* behavior.<br />* &lt;P&gt;<br />* Taken from More Servlets and JavaServer Pages<br />* from Prentice Hall and Sun Microsystems Press,<br />* http://www.moreservlets.com/.<br />* &amp;copy; 2002 Marty Hall; may be freely used or adapted.<br />*/</p><p>public class SorryServlet extends HttpServlet {<br />public void doGet(HttpServletRequest request,<br />HttpServletResponse response)<br />throws ServletException, IOException {<br />response.setContentType("text/html");<br />PrintWriter out = response.getWriter();<br />String title = "Invoker Servlet Disabled.";<br />out.println(ServletUtilities.headWithTitle(title) +<br />"&lt;BODY BGCOLOR=\"#FDF5E6\"&gt;\n" +<br />"&lt;H2&gt;" + title + "&lt;/H2&gt;\n" +<br />"Sorry, access to servlets by means of\n" +<br />"URLs that begin with\n" +<br />"http://host/webAppPrefix/servlet/\n" +<br />"has been disabled.\n" + <br />"&lt;/BODY&gt;&lt;/HTML&gt;");<br />}</p><p>public void doPost(HttpServletRequest request,<br />HttpServletResponse response)<br />throws ServletException, IOException {<br />doGet(request, response);<br />}<br />}</p><p><br />4.2 全局禁止激活器：Tomcat<br />Tomcat 4中用来关闭缺省URL的方法与Tomcat 3中所用的很不相同。下面介绍这两种方法：<br />1．禁止激活器： Tomcat 4<br />Tomcat 4用与前面相同的方法关闭激活器servlet，即利用web.xml中的url-mapping元素进行关闭。不同之处在于Tomcat使用了放在install_dir/conf中的一个服务器专用的全局web.xml文件，而前面使用的是存放在每个Web应用的WEB-INF目录中的标准web.xml文件。<br />因此，为了在Tomcat 4中关闭激活器servlet，只需在install_dir/conf/web.xml中简单地注释出/servlet/* URL映射项即可，如下所示：<br />&lt;!-- <br />&lt;servlet-mapping&gt;<br />&lt;servlet-name&gt;invoker&lt;/servlet-name&gt;<br />&lt;url-pattern&gt;/servlet/*&lt;/url-pattern&gt;<br />&lt;/servlet-mapping&gt;<br />--&gt;<br />再次提醒，应该注意这个项是位于存放在install_dir/conf的Tomcat专用的web.xml文件中的，此文件不是存放在每个Web应用的WEB-INF目录中的标准web.xml。<br />2．禁止激活器：Tomcat3<br />在Apache Tomcat的版本3中，通过在install_dir/conf/server.xml中注释出InvokerInterceptor项全局禁止缺省servlet URL。例如，下面是禁止使用缺省servlet URL的server.xml文件的一部分。<br />&lt;!-- <br />&lt;RequsetInterceptor <br />className="org.apache.tomcat.request.InvokerInterceptor"<br />debug="0" prefix="/servlet/" /&gt;<br />--&gt;</p><p><b>5 初始化和预装载servlet与JSP页面</b><br /><br />这里讨论控制servlet和JSP页面的启动行为的方法。特别是，说明了怎样分配初始化参数以及怎样更改服务器生存期中装载servlet和JSP页面的时刻。<br />5.1 分配servlet初始化参数<br />利用init-param元素向servlet提供初始化参数，init-param元素具有param-name和param-value子元素。例如，在下面的例子中，如果initServlet servlet是利用它的注册名（InitTest）访问的，它将能够从其方法中调用getServletConfig().getInitParameter("param1")获得"Value 1"，调用getServletConfig().getInitParameter("param2")获得"2"。<br />&lt;servlet&gt;<br />&lt;servlet-name&gt;InitTest&lt;/servlet-name&gt;<br />&lt;servlet-class&gt;moreservlets.InitServlet&lt;/servlet-class&gt;<br />&lt;init-param&gt;<br />&lt;param-name&gt;param1&lt;/param-name&gt;<br />&lt;param-value&gt;value1&lt;/param-value&gt;<br />&lt;/init-param&gt;<br />&lt;init-param&gt;<br />&lt;param-name&gt;param2&lt;/param-name&gt;<br />&lt;param-value&gt;2&lt;/param-value&gt;<br />&lt;/init-param&gt;<br />&lt;/servlet&gt;<br />在涉及初始化参数时，有几点需要注意：<br />l 返回值。GetInitParameter的返回值总是一个String。因此，在前一个例子中，可对param2使用Integer.parseInt获得一个int。<br />l JSP中的初始化。JSP页面使用jspInit而不是init。JSP页面还需要使用jsp-file元素代替servlet-class。<br />l 缺省URL。初始化参数只在通过它们的注册名或与它们注册名相关的定制URL模式访问Servlet时可以使用。因此，在这个例子中，param1和param2初始化参数将能够在使用URL http://host/webAppPrefix/servlet/InitTest 时可用，但在使用URL http://host/webAppPrefix/servlet/myPackage.InitServlet 时不能使用。<br />例如，程序清单5-7给出一个名为InitServlet的简单servlet，它使用init方法设置firstName和emailAddress字段。程序清单5-8给出分配名称InitTest给servlet的web.xml文件。<br />程序清单5-7 InitServlet.java<br />package moreservlets;</p><p>import java.io.*;<br />import javax.servlet.*;<br />import javax.servlet.http.*;</p><p>/** Simple servlet used to illustrate servlet<br />* initialization parameters.<br />* &lt;P&gt;<br />* Taken from More Servlets and JavaServer Pages<br />* from Prentice Hall and Sun Microsystems Press,<br />* http://www.moreservlets.com/.<br />* &amp;copy; 2002 Marty Hall; may be freely used or adapted.<br />*/</p><p>public class InitServlet extends HttpServlet {<br />private String firstName, emailAddress;</p><p>public void init() {<br />ServletConfig config = getServletConfig();<br />firstName = config.getInitParameter("firstName");<br />emailAddress = config.getInitParameter("emailAddress");<br />}<br /><br />public void doGet(HttpServletRequest request,<br />HttpServletResponse response)<br />throws ServletException, IOException {<br />response.setContentType("text/html");<br />PrintWriter out = response.getWriter();<br />String uri = request.getRequestURI();<br />out.println(ServletUtilities.headWithTitle("Init Servlet") +<br />"&lt;BODY BGCOLOR=\"#FDF5E6\"&gt;\n" +<br />"&lt;H2&gt;Init Parameters:&lt;/H2&gt;\n" +<br />"&lt;UL&gt;\n" +<br />"&lt;LI&gt;First name: " + firstName + "\n" +<br />"&lt;LI&gt;Email address: " + emailAddress + "\n" +<br />"&lt;/UL&gt;\n" + <br />"&lt;/BODY&gt;&lt;/HTML&gt;");<br />}<br />}</p><p><br />程序清单5-8 web.xml（说明初始化参数的摘录）<br />&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />&lt;!DOCTYPE web-app<br />PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />"http://java.sun.com/dtd/web-app_2_3.dtd"&gt;</p><p>&lt;web-app&gt;<br />&lt;!-- ... --&gt;<br />&lt;servlet&gt;<br />&lt;servlet-name&gt;InitTest&lt;/servlet-name&gt;<br />&lt;servlet-class&gt;moreservlets.InitServlet&lt;/servlet-class&gt;<br />&lt;init-param&gt;<br />&lt;param-name&gt;firstName&lt;/param-name&gt;<br />&lt;param-value&gt;Larry&lt;/param-value&gt;<br />&lt;/init-param&gt;<br />&lt;init-param&gt;<br />&lt;param-name&gt;emailAddress&lt;/param-name&gt;<br />&lt;param-value&gt;Ellison@Microsoft.com&lt;/param-value&gt;<br />&lt;/init-param&gt;<br />&lt;/servlet&gt;<br />&lt;!-- ... --&gt;<br />&lt;/web-app&gt;</p><p>5.2 分配JSP初始化参数<br />给JSP页面提供初始化参数在三个方面不同于给servlet提供初始化参数。<br />1）使用jsp-file而不是servlet-class。因此，WEB-INF/web.xml文件的servlet元素如下所示：<br />&lt;servlet&gt;<br />&lt;servlet-name&gt;PageName&lt;/servlet-name&gt;<br />&lt;jsp-file&gt;/RealPage.jsp&lt;/jsp-file&gt;<br />&lt;init-param&gt;<br />&lt;param-name&gt;...&lt;/param-name&gt;<br />&lt;param-value&gt;...&lt;/param-value&gt;<br />&lt;/init-param&gt;<br />...<br />&lt;/servlet&gt;<br />2)几乎总是分配一个明确的URL模式。对servlet，一般相应地使用以http://host/webAppPrefix/servlet/ 开始的缺省URL。只需记住，使用注册名而不是原名称即可。这对于JSP页面在技术上也是合法的。例如，在上面给出的例子中，可用URL http://host/webAppPrefix/servlet/PageName 访问RealPage.jsp的对初始化参数具有访问权的版本。但在用于JSP页面时，许多用户似乎不喜欢应用常规的servlet的URL。此外，如果JSP页面位于服务器为其提供了目录清单的目录中（如，一个既没有index.html也没有index.jsp文件的目录），则用户可能会连接到此JSP页面，单击它，从而意外地激活未初始化的页面。因此，好的办法是使用url-pattern（5.3节）将JSP页面的原URL与注册的servlet名相关联。这样，客户机可使用JSP页面的普通名称，但仍然激活定制的版本。例如，给定来自项目1的servlet定义，可使用下面的servlet-mapping定义：<br />&lt;servlet-mapping&gt;<br />&lt;servlet-name&gt;PageName&lt;/servlet-name&gt;<br />&lt;url-pattern&gt;/RealPage.jsp&lt;/url-pattern&gt;<br />&lt;/servlet-mapping&gt;<br />3）JSP页使用jspInit而不是init。自动从JSP页面建立的servlet或许已经使用了inti方法。因此，使用JSP声明提供一个init方法是不合法的，必须制定jspInit方法。<br />为了说明初始化JSP页面的过程，程序清单5-9给出了一个名为InitPage.jsp的JSP页面，它包含一个jspInit方法且放置于deployDemo Web应用层次结构的顶层。一般，http://host/deployDemo/InitPage.jsp 形式的URL将激活此页面的不具有初始化参数访问权的版本，从而将对firstName和emailAddress变量显示null。但是，web.xml文件（程序清单5-10）分配了一个注册名，然后将该注册名与URL模式/InitPage.jsp相关联。</p><p>程序清单5-9 InitPage.jsp<br />&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"&gt;<br />&lt;HTML&gt;<br />&lt;HEAD&gt;&lt;TITLE&gt;JSP Init Test&lt;/TITLE&gt;&lt;/HEAD&gt;<br />&lt;BODY BGCOLOR="#FDF5E6"&gt;<br />&lt;H2&gt;Init Parameters:&lt;/H2&gt;<br />&lt;UL&gt;<br />&lt;LI&gt;First name: &lt;%= firstName %&gt;<br />&lt;LI&gt;Email address: &lt;%= emailAddress %&gt;<br />&lt;/UL&gt;<br />&lt;/BODY&gt;&lt;/HTML&gt;<br />&lt;%!<br />private String firstName, emailAddress;</p><p>public void jspInit() {<br />ServletConfig config = getServletConfig();<br />firstName = config.getInitParameter("firstName");<br />emailAddress = config.getInitParameter("emailAddress");<br />}<br />%&gt;</p><p><br />程序清单5-10 web.xml（说明JSP页面的init参数的摘录）<br />&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />&lt;!DOCTYPE web-app<br />PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />"http://java.sun.com/dtd/web-app_2_3.dtd"&gt;</p><p>&lt;web-app&gt;<br />&lt;!-- ... --&gt;<br />&lt;servlet&gt;<br />&lt;servlet-name&gt;InitPage&lt;/servlet-name&gt;<br />&lt;jsp-file&gt;/InitPage.jsp&lt;/jsp-file&gt;<br />&lt;init-param&gt;<br />&lt;param-name&gt;firstName&lt;/param-name&gt;<br />&lt;param-value&gt;Bill&lt;/param-value&gt;<br />&lt;/init-param&gt;<br />&lt;init-param&gt;<br />&lt;param-name&gt;emailAddress&lt;/param-name&gt;<br />&lt;param-value&gt;gates@oracle.com&lt;/param-value&gt;<br />&lt;/init-param&gt;<br />&lt;/servlet&gt;<br />&lt;!-- ... --&gt; <br />&lt;servlet-mapping&gt;<br />&lt;servlet-name&gt; InitPage&lt;/servlet-name&gt;<br />&lt;url-pattern&gt;/InitPage.jsp&lt;/url-pattern&gt;<br />&lt;/servlet-mapping&gt;<br />&lt;!-- ... --&gt;<br />&lt;/web-app&gt;</p><p><br />5.3 提供应用范围内的初始化参数<br />一般，对单个地servlet或JSP页面分配初始化参数。指定的servlet或JSP页面利用ServletConfig的getInitParameter方法读取这些参数。但是，在某些情形下，希望提供可由任意servlet或JSP页面借助ServletContext的getInitParameter方法读取的系统范围内的初始化参数。<br />可利用context-param元素声明这些系统范围内的初始化值。context-param元素应该包含param-name、param-value以及可选的description子元素，如下所示：<br />&lt;context-param&gt;<br />&lt;param-name&gt;support-email&lt;/param-name&gt;<br />&lt;param-value&gt;blackhole@mycompany.com&lt;/param-value&gt;<br />&lt;/context-param&gt;<br />可回忆一下，为了保证可移植性，web.xml内的元素必须以正确的次序声明。但这里应该注意，context-param元素必须出现任意与文档有关的元素（icon、display-name或description）之后及filter、filter-mapping、listener或servlet元素之前。<br />5.4 在服务器启动时装载servlet<br />假如servlet或JSP页面有一个要花很长时间执行的init（servlet）或jspInit（JSP）方法。例如，假如init或jspInit方法从某个数据库或ResourceBundle查找产量。这种情况下，在第一个客户机请求时装载servlet的缺省行为将对第一个客户机产生较长时间的延迟。因此，可利用servlet的load-on-startup元素规定服务器在第一次启动时装载servlet。下面是一个例子。<br />&lt;servlet&gt;<br />&lt;servlet-name&gt; … &lt;/servlet-name&gt;<br />&lt;servlet-class&gt; … &lt;/servlet-class&gt; &lt;!-- Or jsp-file --&gt;<br />&lt;load-on-startup/&gt;<br />&lt;/servlet&gt;<br />可以为此元素体提供一个整数而不是使用一个空的load-on-startup。想法是服务器应该在装载较大数目的servlet或JSP页面之前装载较少数目的servlet或JSP页面。例如，下面的servlet项（放置在Web应用的WEB-INF目录下的web.xml文件中的web-app元素内）将指示服务器首先装载和初始化SearchServlet，然后装载和初始化由位于Web应用的result目录中的index.jsp文件产生的servlet。<br />&lt;servlet&gt;<br />&lt;servlet-name&gt;Search&lt;/servlet-name&gt;<br />&lt;servlet-class&gt;myPackage.SearchServlet&lt;/servlet-class&gt; &lt;!-- Or jsp-file --&gt;<br />&lt;load-on-startup&gt;1&lt;/load-on-startup&gt;<br />&lt;/servlet&gt;<br />&lt;servlet&gt;<br />&lt;servlet-name&gt;Results&lt;/servlet-name&gt;<br />&lt;servlet-class&gt;/results/index.jsp&lt;/servlet-class&gt; &lt;!-- Or jsp-file --&gt;<br />&lt;load-on-startup&gt;2&lt;/load-on-startup&gt;<br />&lt;/servlet&gt;<br /><br /><b>6 声明过滤器</b><br /><br />servlet版本2.3引入了过滤器的概念。虽然所有支持servlet API版本2.3的服务器都支持过滤器，但为了使用与过滤器有关的元素，必须在web.xml中使用版本2.3的DTD。<br />过滤器可截取和修改进入一个servlet或JSP页面的请求或从一个servlet或JSP页面发出的相应。在执行一个servlet或JSP页面之前，必须执行第一个相关的过滤器的doFilter方法。在该过滤器对其FilterChain对象调用doFilter时，执行链中的下一个过滤器。如果没有其他过滤器，servlet或JSP页面被执行。过滤器具有对到来的ServletRequest对象的全部访问权，因此，它们可以查看客户机名、查找到来的cookie等。为了访问servlet或JSP页面的输出，过滤器可将响应对象包裹在一个替身对象（stand-in object）中，比方说把输出累加到一个缓冲区。在调用FilterChain对象的doFilter方法之后，过滤器可检查缓冲区，如有必要，就对它进行修改，然后传送到客户机。<br />例如，程序清单5-11帝国难以了一个简单的过滤器，只要访问相关的servlet或JSP页面，它就截取请求并在标准输出上打印一个报告（开发过程中在桌面系统上运行时，大多数服务器都可以使用这个过滤器）。</p><p>程序清单5-11 ReportFilter.java<br />package moreservlets;</p><p>import java.io.*;<br />import javax.servlet.*;<br />import javax.servlet.http.*;<br />import java.util.*;</p><p>/** Simple filter that prints a report on the standard output <br />* whenever the associated servlet or JSP page is accessed.<br />* &lt;P&gt;<br />* Taken from More Servlets and JavaServer Pages<br />* from Prentice Hall and Sun Microsystems Press,<br />* http://www.moreservlets.com/.<br />* &amp;copy; 2002 Marty Hall; may be freely used or adapted.<br />*/</p><p>public class ReportFilter implements Filter {<br />public void doFilter(ServletRequest request,<br />ServletResponse response,<br />FilterChain chain)<br />throws ServletException, IOException {<br />HttpServletRequest req = (HttpServletRequest)request;<br />System.out.println(req.getRemoteHost() +<br />" tried to access " +<br />req.getRequestURL() +<br />" on " + new Date() + ".");<br />chain.doFilter(request,response);<br />}</p><p>public void init(FilterConfig config)<br />throws ServletException {<br />}<br /><br />public void destroy() {}<br />}</p><p>一旦建立了一个过滤器，可以在web.xml中利用filter元素以及filter-name（任意名称）、file-class（完全限定的类名）和（可选的）init-params子元素声明它。请注意，元素在web.xml的web-app元素中出现的次序不是任意的；允许服务器（但不是必需的）强制所需的次序，并且实际中有些服务器也是这样做的。但这里要注意，所有filter元素必须出现在任意filter-mapping元素之前，filter-mapping元素又必须出现在所有servlet或servlet-mapping元素之前。<br />例如，给定上述的ReportFilter类，可在web.xml中作出下面的filter声明。它把名称Reporter与实际的类ReportFilter（位于moreservlets程序包中）相关联。<br />&lt;filter&gt;<br />&lt;filter-name&gt;Reporter&lt;/filter-name&gt;<br />&lt;filter-class&gt;moresevlets.ReportFilter&lt;/filter-class&gt;<br />&lt;/filter&gt;<br />一旦命名了一个过滤器，可利用filter-mapping元素把它与一个或多个servlet或JSP页面相关联。关于此项工作有两种选择。<br />首先，可使用filter-name和servlet-name子元素把此过滤器与一个特定的servlet名（此servlet名必须稍后在相同的web.xml文件中使用servlet元素声明）关联。例如，下面的程序片断指示系统只要利用一个定制的URL访问名为SomeServletName的servlet或JSP页面，就运行名为Reporter的过滤器。<br />&lt;filter-mapping&gt;<br />&lt;filter-name&gt;Reporter&lt;/filter-name&gt;<br />&lt;servlet-name&gt;SomeServletName&lt;/servlet-name&gt;<br />&lt;/filter-mapping&gt;<br />其次，可利用filter-name和url-pattern子元素将过滤器与一组servlet、JSP页面或静态内容相关联。例如，相面的程序片段指示系统只要访问Web应用中的任意URL，就运行名为Reporter的过滤器。<br />&lt;filter-mapping&gt;<br />&lt;filter-name&gt;Reporter&lt;/filter-name&gt;<br />&lt;url-pattern&gt;/*&lt;/url-pattern&gt;<br />&lt;/filter-mapping&gt;<br />例如，程序清单5-12给出了将ReportFilter过滤器与名为PageName的servlet相关联的web.xml文件的一部分。名字PageName依次又与一个名为TestPage.jsp的JSP页面以及以模式http://host/webAppPrefix/UrlTest2/ 开头的URL相关联。TestPage.jsp的源代码已经JSP页面命名的谈论在前面的3节"分配名称和定制的URL"中给出。事实上，程序清单5-12中的servlet和servlet-name项从该节原封不动地拿过来的。给定这些web.xml项，可看到下面的标准输出形式的调试报告（换行是为了容易阅读）。<br />audit.irs.gov tried to access <br />http://mycompany.com/deployDemo/UrlTest2/business/tax-plan.html<br />on Tue Dec 25 13:12:29 EDT 2001.</p><p>程序清单5-12 Web.xml（说明filter用法的摘录）<br />&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />&lt;!DOCTYPE web-app<br />PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />"http://java.sun.com/dtd/web-app_2_3.dtd"&gt;</p><p>&lt;web-app&gt;<br />&lt;filter&gt;<br />&lt;filter-name&gt;Reporter&lt;/filter-name&gt;<br />&lt;filter-class&gt;moresevlets.ReportFilter&lt;/filter-class&gt;<br />&lt;/filter&gt;<br />&lt;!-- ... --&gt;<br />&lt;filter-mapping&gt;<br />&lt;filter-name&gt;Reporter&lt;/filter-name&gt;<br />&lt;servlet-name&gt;PageName&lt;/servlet-name&gt;<br />&lt;/filter-mapping&gt;<br />&lt;!-- ... --&gt;<br />&lt;servlet&gt;<br />&lt;servlet-name&gt;PageName&lt;/servlet-name&gt;<br />&lt;jsp-file&gt;/RealPage.jsp&lt;/jsp-file&gt;<br />&lt;/servlet&gt;<br />&lt;!-- ... --&gt;<br />&lt;servlet-mapping&gt;<br />&lt;servlet-name&gt; PageName &lt;/servlet-name&gt;<br />&lt;url-pattern&gt;/UrlTest2/*&lt;/url-pattern&gt;<br />&lt;/servlet-mapping&gt;<br />&lt;!-- ... --&gt;<br />&lt;/web-app&gt;</p><p><br /><b>7 指定欢迎页</b><br /><br />假如用户提供了一个像http://host/webAppPrefix/directoryName/ 这样的包含一个目录名但没有包含文件名的URL，会发生什么事情呢？用户能得到一个目录表？一个错误？还是标准文件的内容？如果得到标准文件内容，是index.html、index.jsp、default.html、default.htm或别的什么东西呢？<br />Welcome-file-list元素及其辅助的welcome-file元素解决了这个模糊的问题。例如，下面的web.xml项指出，如果一个URL给出一个目录名但未给出文件名，服务器应该首先试用index.jsp，然后再试用index.html。如果两者都没有找到，则结果有赖于所用的服务器（如一个目录列表）。<br />&lt;welcome-file-list&gt;<br />&lt;welcome-file&gt;index.jsp&lt;/welcome-file&gt;<br />&lt;welcome-file&gt;index.html&lt;/welcome-file&gt;<br />&lt;/welcome-file-list&gt;<br />虽然许多服务器缺省遵循这种行为，但不一定必须这样。因此，明确地使用welcom-file-list保证可移植性是一种良好的习惯。<br /><br /><b>8 指定处理错误的页面</b><br /><br />现在我了解到，你在开发servlet和JSP页面时从不会犯错误，而且你的所有页面是那样的清晰，一般的程序员都不会被它们的搞糊涂。但是，是人总会犯错误的，用户可能会提供不合规定的参数，使用不正确的URL或者不能提供必需的表单字段值。除此之外，其它开发人员可能不那么细心，他们应该有些工具来克服自己的不足。<br />error-page元素就是用来克服这些问题的。它有两个可能的子元素，分别是：error-code和exception-type。第一个子元素error-code指出在给定的HTTP错误代码出现时使用的URL。第二个子元素excpetion-type指出在出现某个给定的Java异常但未捕捉到时使用的URL。error-code和exception-type都利用location元素指出相应的URL。此URL必须以/开始。location所指出的位置处的页面可通过查找HttpServletRequest对象的两个专门的属性来访问关于错误的信息，这两个属性分别是：javax.servlet.error.status_code和javax.servlet.error.message。<br />可回忆一下，在web.xml内以正确的次序声明web-app的子元素很重要。这里只要记住，error-page出现在web.xml文件的末尾附近，servlet、servlet-name和welcome-file-list之后即可。<br /><br />8.1 error-code元素<br />为了更好地了解error-code元素的值，可考虑一下如果不正确地输入文件名，大多数站点会作出什么反映。这样做一般会出现一个404错误信息，它表示不能找到该文件，但几乎没提供更多有用的信息。另一方面，可以试一下在www.microsoft.com、www.ibm.com 处或者特别是在www.bea.com 处输出未知的文件名。这是会得出有用的消息，这些消息提供可选择的位置，以便查找感兴趣的页面。提供这样有用的错误页面对于Web应用来说是很有价值得。事实上，http://www.plinko.net/404/ 就是把整个站点专门用于404错误页面这个内容。这个站点包含来自全世界最好、最糟和最搞笑的404页面。<br />程序清单5-13给出一个JSP页面，此页面可返回给提供位置程序名的客户机。程序清单5-14给出指定程序清单5-13作为返回404错误代码时显示的页面的web.xml。请注意，浏览器中显示的URL仍然是客户机所提供的。错误页面是一种后台实现技术。<br />最后一点，请记住IE5的缺省配置显然不符合HTTP规范，它忽略了服务器生成的错误消息，而是显示自己的标准出错信息。可转到其Tools菜单，选择Internet Options，单击Advanced，取消Show Friendly HTTP Error Message来解决此问题。</p><p>程序清单5-13 NotFound.jsp<br />&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"&gt;<br />&lt;HTML&gt;<br />&lt;HEAD&gt;&lt;TITLE&gt;404: Not Found&lt;/TITLE&gt;&lt;/HEAD&gt;<br />&lt;BODY BGCOLOR="#FDF5E6"&gt;<br />&lt;H2&gt;Error!&lt;/H2&gt;<br />I'm sorry, but I cannot find a page that matches<br />&lt;%= request.getRequestURI() %&gt; on the system. Maybe you should<br />try one of the following:<br />&lt;UL&gt;<br />&lt;LI&gt;Go to the server's &lt;A HREF="/"&gt;home page&lt;/A&gt;.<br />&lt;LI&gt;Search for relevant pages.&lt;BR&gt;<br />&lt;FORM ACTION="http://www.google.com/search"&gt;<br />&lt;CENTER&gt;<br />Keywords: &lt;INPUT TYPE="TEXT" NAME="q"&gt;&lt;BR&gt;<br />&lt;INPUT TYPE="SUBMIT" VALUE="Search"&gt;<br />&lt;/CENTER&gt;<br />&lt;/FORM&gt;<br />&lt;LI&gt;Admire a random multiple of 404:<br />&lt;%= 404*((int)(1000*Math.random())) %&gt;.<br />&lt;LI&gt;Try a &lt;A HREF="http://www.plinko.net/404/rndindex.asp"<br />TARGET="_blank"&gt;<br />random 404 error message&lt;/A&gt;. From the amazing and<br />amusing plinko.net &lt;A HREF="http://www.plinko.net/404/"&gt;<br />404 archive&lt;/A&gt;.<br />&lt;/UL&gt;<br />&lt;/BODY&gt;&lt;/HTML&gt;</p><p><br />程序清单5-14 web.xml（指出HTTP错误代码的错误页面的摘录）<br />&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />&lt;!DOCTYPE web-app<br />PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />"http://java.sun.com/dtd/web-app_2_3.dtd"&gt;</p><p>&lt;web-app&gt;<br />&lt;error-page&gt;<br />&lt;error-code&gt;404&lt;/error-code&gt;<br />&lt;location&gt;/NotFound.jsp&lt;/location&gt;<br />&lt;/error-page&gt;<br />&lt;!-- ... --&gt;<br />&lt;/web-app&gt;</p><p><br />8.2 exception-type元素<br />error-code元素处理某个请求产生一个特定的HTTP状态代码时的情况。然而，对于servlet或JSP页面返回200但产生运行时异常这种同样是常见的情况怎么办呢？这正是exception-type元素要处理的情况。只需提供两样东西即可：即提供如下的一个完全限定的异常类和一个位置：<br />&lt;error-page&gt;<br />&lt;exception-type&gt;packageName.className&lt;/exception-type&gt;<br />&lt;location&gt;/SomeURL&lt;/location&gt;<br />&lt;/error-page&gt;<br />这样，如果Web应用中的任何servlet或JSP页面产生一个特定类型的未捕捉到的异常，则使用指定的URL。此异常类型可以是一个标准类型，如javax.ServletException或java.lang.OutOfMemoryError，或者是一个专门针对你的应用的异常。<br />例如，程序清单5-15给出了一个名为DumbDeveloperException的异常类，可用它来特别标记经验较少的程序员（不是说你的开发组中一定有这种人）所犯的错误。这个类还包含一个名为dangerousComputation的静态方法，它时不时地生成这种类型的异常。程序清单5-16给出对随机整数值调用dangerousCompution的一个JSP页面。在抛出此异常时，如程序清单5-18的web.xml版本中所给出的exception-type所指出的那样，对客户机显示DDE.jsp（程序清单5-17）。图5-16和图5-17分别给出幸运和不幸的结果。</p><p>程序清单5-15 DumbDeveloperException.java<br />package moreservlets;</p><p>/** Exception used to flag particularly onerous<br />programmer blunders. Used to illustrate the<br />exception-type web.xml element.<br />* &lt;P&gt;<br />* Taken from More Servlets and JavaServer Pages<br />* from Prentice Hall and Sun Microsystems Press,<br />* http://www.moreservlets.com/.<br />* &amp;copy; 2002 Marty Hall; may be freely used or adapted.<br />*/</p><p>public class DumbDeveloperException extends Exception {<br />public DumbDeveloperException() {<br />super("Duh. What was I *thinking*?");<br />}</p><p>public static int dangerousComputation(int n)<br />throws DumbDeveloperException {<br />if (n &lt; 5) {<br />return(n + 10);<br />} else {<br />throw(new DumbDeveloperException());<br />}<br />}<br />}</p><p><br />程序清单5-16 RiskyPage.jsp<br />&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"&gt;<br />&lt;HTML&gt;<br />&lt;HEAD&gt;&lt;TITLE&gt;Risky JSP Page&lt;/TITLE&gt;&lt;/HEAD&gt;<br />&lt;BODY BGCOLOR="#FDF5E6"&gt;<br />&lt;H2&gt;Risky Calculations&lt;/H2&gt;<br />&lt;%@ page import="moreservlets.*" %&gt;<br />&lt;% int n = ((int)(10 * Math.random())); %&gt;<br />&lt;UL&gt;<br />&lt;LI&gt;n: &lt;%= n %&gt;<br />&lt;LI&gt;dangerousComputation(n): <br />&lt;%= DumbDeveloperException.dangerousComputation(n) %&gt;<br />&lt;/UL&gt;<br />&lt;/BODY&gt;&lt;/HTML&gt;</p><p><br />程序清单5-17 DDE.jsp<br />&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"&gt;<br />&lt;HTML&gt;<br />&lt;HEAD&gt;&lt;TITLE&gt;Dumb&lt;/TITLE&gt;&lt;/HEAD&gt;<br />&lt;BODY BGCOLOR="#FDF5E6"&gt;<br />&lt;H2&gt;Dumb Developer&lt;/H2&gt;<br />We're brain dead. Consider using our competitors.<br />&lt;/BODY&gt;&lt;/HTML&gt;</p><p><br />程序清单5-18 web.xml（为异常指定错误页面的摘录）<br />&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />&lt;!DOCTYPE web-app<br />PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />"http://java.sun.com/dtd/web-app_2_3.dtd"&gt;</p><p>&lt;web-app&gt;<br />&lt;!-- ... --&gt;<br />&lt;servlet&gt; … &lt;/servlet&gt;<br />&lt;!-- ... --&gt;<br />&lt;error-page&gt;<br />&lt;exception-type&gt;<br />moreservlets.DumbDeveloperException<br />&lt;/exception-type&gt;<br />&lt;location&gt;/DDE.jsp&lt;/location&gt;<br />&lt;/error-page&gt;<br />&lt;!-- ... --&gt;<br />&lt;/web-app&gt;</p><p><b>9 提供安全性</b><br /><br />利用web.xml中的相关元素为服务器的内建功能提供安全性。<br />9.1 指定验证的方法<br />使用login-confgi元素规定服务器应该怎样验证试图访问受保护页面的用户。它包含三个可能的子元素，分别是：auth-method、realm-name和form-login-config。login-config元素应该出现在web.xml部署描述符文件的结尾附近，紧跟在security-constraint元素之后。<br />l auth-method<br />login-config的这个子元素列出服务器将要使用的特定验证机制。有效值为BASIC、DIGEST、FORM和CLIENT-CERT。服务器只需要支持BASIC和FORM。<br />BASIC指出应该使用标准的HTTP验证，在此验证中服务器检查Authorization头。如果缺少这个头则返回一个401状态代码和一个WWW-Authenticate头。这导致客户机弹出一个用来填写Authorization头的对话框。此机制很少或不提供对攻击者的防范，这些攻击者在Internet连接上进行窥探（如通过在客户机的子网上执行一个信息包探测装置），因为用户名和口令是用简单的可逆base64编码发送的，他们很容易得手。所有兼容的服务器都需要支持BASIC验证。<br />DIGEST指出客户机应该利用加密Digest Authentication形式传输用户名和口令。这提供了比BASIC验证更高的防范网络截取得的安全性，但这种加密比SSL（HTTPS）所用的方法更容易破解。不过，此结论有时没有意义，因为当前很少有浏览器支持Digest Authentication，所以servlet容器不需要支持它。<br />FORM指出服务器应该检查保留的会话cookie并且把不具有它的用户重定向到一个指定的登陆页。此登陆页应该包含一个收集用户名和口令的常规HTML表单。在登陆之后，利用保留会话级的cookie跟踪用户。虽然很复杂，但FORM验证防范网络窥探并不比BASIC验证更安全，如果有必要可以在顶层安排诸如SSL或网络层安全（如IPSEC或VPN）等额外的保护。所有兼容的服务器都需要支持FORM验证。<br />CLIENT-CERT规定服务器必须使用HTTPS（SSL之上的HTTP）并利用用户的公开密钥证书（Pulic Key Certificat）对用户进行验证。这提供了防范网络截取的很强的安全性，但只有兼容J2EE的服务器需要支持它。<br />l realm-name<br />此元素只在auth-method为BASIC时使用。它指出浏览器在相应对话框标题使用的、并作为Authorization头组成部分的安全域的名称。<br />l form-login-config<br />此元素只在auth-method为FORM时适用。它指定两个页面，分别是：包含收集用户名及口令的HTML表单的页面（利用form-login-page子元素），用来指示验证失败的页面（利用form-error-page子元素）。由form-login-page给出的HTML表单必须具有一个j_security_check的ACTION属性、一个名为j_username的用户名文本字段以及一个名为j_password的口令字段。<br />例如，程序清单5-19指示服务器使用基于表单的验证。Web应用的顶层目录中的一个名为login.jsp的页面将收集用户名和口令，并且失败的登陆将由相同目录中名为login-error.jsp的页面报告。</p><p>程序清单5-19 web.xml（说明login-config的摘录）<br />&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />&lt;!DOCTYPE web-app<br />PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />"http://java.sun.com/dtd/web-app_2_3.dtd"&gt;</p><p>&lt;web-app&gt;<br />&lt;!-- ... --&gt;<br />&lt;security-constraint&gt; ... &lt;/security-constraint&gt;<br />&lt;login-config&gt;<br />&lt;auth-method&gt; FORM &lt;/auth-method&gt;<br />&lt;form-login-config&gt;<br />&lt;form-login-page&gt;/login.jsp&lt;/form-login-page&gt;<br />&lt;form-error-page&gt;/login-error.jsp&lt;/form-error-page&gt;<br />&lt;/form-login-config&gt;<br />&lt;/login-config&gt;<br />&lt;!-- ... --&gt;<br />&lt;/web-app&gt;</p><p><br />9.2 限制对Web资源的访问<br />现在，可以指示服务器使用何种验证方法了。"了不起，"你说道，"除非我能指定一个来收到保护的URL，否则没有多大用处。"没错。指出这些URL并说明他们应该得到何种保护正是security-constriaint元素的用途。此元素在web.xml中应该出现在login-config的紧前面。它包含是个可能的子元素，分别是：web-resource-collection、auth-constraint、user-data-constraint和display-name。下面各小节对它们进行介绍。<br />l web-resource-collection<br />此元素确定应该保护的资源。所有security-constraint元素都必须包含至少一个web-resource-collection项。此元素由一个给出任意标识名称的web-resource-name元素、一个确定应该保护的URL的url-pattern元素、一个指出此保护所适用的HTTP命令（GET、POST等，缺省为所有方法）的http-method元素和一个提供资料的可选description元素组成。例如，下面的Web-resource-collection项（在security-constratint元素内）指出Web应用的proprietary目录中所有文档应该受到保护。<br />&lt;security-constraint&gt;<br />&lt;web-resource-coolection&gt;<br />&lt;web-resource-name&gt;Proprietary&lt;/web-resource-name&gt;<br />&lt;url-pattern&gt;/propritary/*&lt;/url-pattern&gt;<br />&lt;/web-resource-coolection&gt;<br />&lt;!-- ... --&gt;<br />&lt;/security-constraint&gt;<br />重要的是应该注意到，url-pattern仅适用于直接访问这些资源的客户机。特别是，它不适合于通过MVC体系结构利用RequestDispatcher来访问的页面，或者不适合于利用类似jsp:forward的手段来访问的页面。这种不匀称如果利用得当的话很有好处。例如，servlet可利用MVC体系结构查找数据，把它放到bean中，发送请求到从bean中提取数据的JSP页面并显示它。我们希望保证决不直接访问受保护的JSP页面，而只是通过建立该页面将使用的bean的servlet来访问它。url-pattern和auth-contraint元素可通过声明不允许任何用户直接访问JSP页面来提供这种保证。但是，这种不匀称的行为可能让开发人员放松警惕，使他们偶然对应受保护的资源提供不受限制的访问。 <br />l auth-constraint<br />尽管web-resource-collention元素质出了哪些URL应该受到保护，但是auth-constraint元素却指出哪些用户应该具有受保护资源的访问权。此元素应该包含一个或多个标识具有访问权限的用户类别role-name元素，以及包含（可选）一个描述角色的description元素。例如，下面web.xml中的security-constraint元素部门规定只有指定为Administrator或Big Kahuna（或两者）的用户具有指定资源的访问权。<br />&lt;security-constraint&gt;<br />&lt;web-resource-coolection&gt; ... &lt;/web-resource-coolection&gt;<br />&lt;auth-constraint&gt;<br />&lt;role-name&gt;administrator&lt;/role-name&gt;<br />&lt;role-name&gt;kahuna&lt;/role-name&gt;<br />&lt;/auth-constraint&gt;<br />&lt;/security-constraint&gt;<br />重要的是认识到，到此为止，这个过程的可移植部分结束了。服务器怎样确定哪些用户处于任何角色以及它怎样存放用户的口令，完全有赖于具体的系统。<br />例如，Tomcat使用install_dir/conf/tomcat-users.xml将用户名与角色名和口令相关联，正如下面例子中所示，它指出用户joe（口令bigshot）和jane（口令enaj）属于administrator和kahuna角色。<br />&lt;tomcat-users&gt;<br />&lt;user name="joe" password="bigshot" roles="administrator,kahuna" /&gt;<br />&lt;user name="jane" password="enaj" roles="kahuna" /&gt;<br />&lt;/tomcat-users&gt;<br />l user-data-constraint<br />这个可选的元素指出在访问相关资源时使用任何传输层保护。它必须包含一个transport-guarantee子元素（合法值为NONE、INTEGRAL或CONFIDENTIAL），并且可选地包含一个description元素。transport-guarantee为NONE值将对所用的通讯协议不加限制。INTEGRAL值表示数据必须以一种防止截取它的人阅读它的方式传送。虽然原理上（并且在未来的HTTP版本中），在INTEGRAL和CONFIDENTIAL之间可能会有差别，但在当前实践中，他们都只是简单地要求用SSL。例如，下面指示服务器只允许对相关资源做HTTPS连接：<br />&lt;security-constraint&gt;<br />&lt;!-- ... --&gt;<br />&lt;user-data-constraint&gt;<br />&lt;transport-guarantee&gt;CONFIDENTIAL&lt;/transport-guarantee&gt;<br />&lt;/user-data-constraint&gt;<br />&lt;/security-constraint&gt;<br />l display-name<br />security-constraint的这个很少使用的子元素给予可能由GUI工具使用的安全约束项一个名称。<br />9.3 分配角色名<br />迄今为止，讨论已经集中到完全由容器（服务器）处理的安全问题之上了。但servlet以及JSP页面也能够处理它们自己的安全问题。<br />例如，容器可能允许用户从bigwig或bigcheese角色访问一个显示主管人员额外紧贴的页面，但只允许bigwig用户修改此页面的参数。完成这种更细致的控制的一种常见方法是调用HttpServletRequset的isUserInRole方法，并据此修改访问。<br />Servlet的security-role-ref子元素提供出现在服务器专用口令文件中的安全角色名的一个别名。例如，假如编写了一个调用request.isUserInRole（"boss"）的servlet，但后来该servlet被用在了一个其口令文件调用角色manager而不是boss的服务器中。下面的程序段使该servlet能够使用这两个名称中的任何一个。<br />&lt;servlet&gt;<br />&lt;!-- ... --&gt;<br />&lt;security-role-ref&gt;<br />&lt;role-name&gt;boss&lt;/role-name&gt; &lt;!-- New alias --&gt;<br />&lt;role-link&gt;manager&lt;/role-link&gt; &lt;!-- Real name --&gt;<br />&lt;/security-role-ref&gt;<br />&lt;/servlet&gt;<br />也可以在web-app内利用security-role元素提供将出现在role-name元素中的所有安全角色的一个全局列表。分别地生命角色使高级IDE容易处理安全信息。<br /><br /><b>10 控制会话超时</b><br /><br />如果某个会话在一定的时间内未被访问，服务器可把它扔掉以节约内存。可利用HttpSession的setMaxInactiveInterval方法直接设置个别会话对象的超时值。如果不采用这种方法，则缺省的超时值由具体的服务器决定。但可利用session-config和session-timeout元素来给出一个适用于所有服务器的明确的超时值。超时值的单位为分钟，因此，下面的例子设置缺省会话超时值为三个小时（180分钟）。<br />&lt;session-config&gt;<br />&lt;session-timeout&gt;180&lt;/session-timeout&gt;<br />&lt;/session-config&gt;<br /><br /><b>11 Web应用的文档化</b><br /><br />越来越多的开发环境开始提供servlet和JSP的直接支持。例子有Borland Jbuilder Enterprise Edition、Macromedia UltraDev、Allaire JRun Studio（写此文时，已被Macromedia收购）以及IBM VisuaAge for Java等。<br />大量的web.xml元素不仅是为服务器设计的，而且还是为可视开发环境设计的。它们包括icon、display-name和discription等。<br />可回忆一下，在web.xml内以适当地次序声明web-app子元素很重要。不过，这里只要记住icon、display-name和description是web.xml的web-app元素内的前三个合法元素即可。<br />l icon<br />icon元素指出GUI工具可用来代表Web应用的一个和两个图像文件。可利用small-icon元素指定一幅16 x 16的GIF或JPEG图像，用large-icon元素指定一幅32 x 32的图像。下面举一个例子： <br />&lt;icon&gt;<br />&lt;small-icon&gt;/images/small-book.gif&lt;/small-icon&gt;<br />&lt;large-icon&gt;/images/tome.jpg&lt;/large-icon&gt;<br />&lt;/icon&gt;<br />l display-name<br />display-name元素提供GUI工具可能会用来标记此Web应用的一个名称。下面是个例子。<br />&lt;display-name&gt;Rare Books&lt;/display-name&gt;<br />l description<br />description元素提供解释性文本，如下所示：<br />&lt;description&gt;<br />This Web application represents the store developed for<br />rare-books.com, an online bookstore specializing in rare<br />and limited-edition books.<br />&lt;/description&gt;<br /><br /><b>12 关联文件与MIME类型</b><br /><br />服务器一般都具有一种让Web站点管理员将文件扩展名与媒体相关联的方法。例如，将会自动给予名为mom.jpg的文件一个image/jpeg的MIME类型。但是，假如你的Web应用具有几个不寻常的文件，你希望保证它们在发送到客户机时分配为某种MIME类型。mime-mapping元素（具有extension和mime-type子元素）可提供这种保证。例如，下面的代码指示服务器将application/x-fubar的MIME类型分配给所有以.foo结尾的文件。<br />&lt;mime-mapping&gt;<br />&lt;extension&gt;foo&lt;/extension&gt;<br />&lt;mime-type&gt;application/x-fubar&lt;/mime-type&gt;<br />&lt;/mime-mapping&gt;<br />或许，你的Web应用希望重载（override）标准的映射。例如，下面的代码将告诉服务器在发送到客户机时指定.ps文件作为纯文本（text/plain）而不是作为PostScript（application/postscript）。<br />&lt;mime-mapping&gt;<br />&lt;extension&gt;ps&lt;/extension&gt;<br />&lt;mime-type&gt;application/postscript&lt;/mime-type&gt;<br />&lt;/mime-mapping&gt;<br /><br /><br /><b>13 定位TLD</b><br /><br />JSP taglib元素具有一个必要的uri属性，它给出一个TLD（Tag Library Descriptor）文件相对于Web应用的根的位置。TLD文件的实际名称在发布新的标签库版本时可能会改变，但我们希望避免更改所有现有JSP页面。此外，可能还希望使用保持taglib元素的简练性的一个简短的uri。这就是部署描述符文件的taglib元素派用场的所在了。Taglib包含两个子元素：taglib-uri和taglib-location。taglib-uri元素应该与用于JSP taglib元素的uri属性的东西相匹配。Taglib-location元素给出TLD文件的实际位置。例如，假如你将文件chart-tags-1.3beta.tld放在WebApp/WEB-INF/tlds中。现在，假如web.xml在web-app元素内包含下列内容。<br />&lt;taglib&gt;<br />&lt;taglib-uri&gt;/charts.tld&lt;/taglib-uri&gt;<br />&lt;taglib-location&gt;<br />/WEB-INF/tlds/chart-tags-1.3beta.tld<br />&lt;/taglib-location&gt;<br />&lt;/taglib&gt;<br />给出这个说明后，JSP页面可通过下面的简化形式使用标签库。<br />&lt;%@ taglib uri="/charts.tld" prefix="somePrefix" %&gt;<br /><b><br />14 指定应用事件监听程序<br /></b><br />应用事件监听器程序是建立或修改servlet环境或会话对象时通知的类。它们是servlet规范的版本2.3中的新内容。这里只简单地说明用来向Web应用注册一个监听程序的web.xml的用法。<br />注册一个监听程序涉及在web.xml的web-app元素内放置一个listener元素。在listener元素内，listener-class元素列出监听程序的完整的限定类名，如下所示：<br />&lt;listener&gt;<br />&lt;listener-class&gt;package.ListenerClass&lt;/listener-class&gt;<br />&lt;/listener&gt;<br />虽然listener元素的结构很简单，但请不要忘记，必须正确地给出web-app元素内的子元素的次序。listener元素位于所有的servlet元素之前以及所有filter-mapping元素之后。此外，因为应用生存期监听程序是serlvet规范的2.3版本中的新内容，所以必须使用web.xml DTD的2.3版本，而不是2.2版本。<br />例如，程序清单5-20给出一个名为ContextReporter的简单的监听程序，只要Web应用的Servlet-Context建立（如装载Web应用）或消除（如服务器关闭）时，它就在标准输出上显示一条消息。程序清单5-21给出此监听程序注册所需要的web.xml文件的一部分。</p><p>程序清单5-20 ContextReporterjava<br />package moreservlets;</p><p>import javax.servlet.*;<br />import java.util.*;</p><p>/** Simple listener that prints a report on the standard output <br />* when the ServletContext is created or destroyed.<br />* &lt;P&gt;<br />* Taken from More Servlets and JavaServer Pages<br />* from Prentice Hall and Sun Microsystems Press,<br />* http://www.moreservlets.com/.<br />* &amp;copy; 2002 Marty Hall; may be freely used or adapted.<br />*/</p><p>public class ContextReporter implements ServletContextListener {<br />public void contextInitialized(ServletContextEvent event) {<br />System.out.println("Context created on " +<br />new Date() + ".");<br />}</p><p>public void contextDestroyed(ServletContextEvent event) {<br />System.out.println("Context destroyed on " +<br />new Date() + ".");<br />}<br />}</p><p><br />程序清单5-21 web.xml（声明一个监听程序的摘录）<br />&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />&lt;!DOCTYPE web-app<br />PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />"http://java.sun.com/dtd/web-app_2_3.dtd"&gt;</p><p>&lt;web-app&gt;<br />&lt;!-- ... --&gt;<br />&lt;filter-mapping&gt; … &lt;/filter-mapping&gt;<br />&lt;listener&gt;<br />&lt;listener-class&gt;package.ListenerClass&lt;/listener-class&gt;<br />&lt;/listener&gt;<br />&lt;servlet&gt; ... &lt;/servlet&gt;<br />&lt;!-- ... --&gt;<br />&lt;/web-app&gt;</p><p><br /><b>15 J2EE元素</b><br /><br />本节描述用作J2EE环境组成部分的Web应用的web.xml元素。这里将提供一个简明的介绍，详细内容可以参阅http://java.sun.com/j2ee/j2ee-1_3-fr-spec.pdf的Java 2 Plantform Enterprise Edition版本1.3规范的第5章。<br />l distributable<br />distributable元素指出，Web应用是以这样的方式编程的：即，支持集群的服务器可安全地在多个服务器上分布Web应用。例如，一个可分布的应用必须只使用Serializable对象作为其HttpSession对象的属性，而且必须避免用实例变量（字段）来实现持续性。distributable元素直接出现在discription元素之后，并且不包含子元素或数据，它只是一个如下的标志。<br />&lt;distributable /&gt;<br />l resource-env-ref<br />resource-env-ref元素声明一个与某个资源有关的管理对象。此元素由一个可选的description元素、一个resource-env-ref-name元素（一个相对于java:comp/env环境的JNDI名）以及一个resource-env-type元素（指定资源类型的完全限定的类），如下所示：<br />&lt;resource-env-ref&gt;<br />&lt;resource-env-ref-name&gt;<br />jms/StockQueue<br />&lt;/resource-env-ref-name&gt;<br />&lt;resource-env-ref-type&gt;<br />javax.jms.Queue<br />&lt;/resource-env-ref-type&gt;<br />&lt;/resource-env-ref&gt;<br />l env-entry<br />env-entry元素声明Web应用的环境项。它由一个可选的description元素、一个env-entry-name元素（一个相对于java:comp/env环境JNDI名）、一个env-entry-value元素（项值）以及一个env-entry-type元素（java.lang程序包中一个类型的完全限定类名，java.lang.Boolean、java.lang.String等）组成。下面是一个例子：<br />&lt;env-entry&gt;<br />&lt;env-entry-name&gt;minAmout&lt;/env-entry-name&gt;<br />&lt;env-entry-value&gt;100.00&lt;/env-entry-value&gt;<br />&lt;env-entry-type&gt;minAmout&lt;/env-entry-type&gt;<br />&lt;/env-entry&gt;<br />l ejb-ref<br />ejb-ref元素声明对一个EJB的主目录的应用。它由一个可选的description元素、一个ejb-ref-name元素（相对于java:comp/env的EJB应用）、一个ejb-ref-type元素（bean的类型，Entity或Session）、一个home元素（bean的主目录接口的完全限定名）、一个remote元素（bean的远程接口的完全限定名）以及一个可选的ejb-link元素（当前bean链接的另一个bean的名称）组成。<br />l ejb-local-ref<br />ejb-local-ref元素声明一个EJB的本地主目录的引用。除了用local-home代替home外，此元素具有与ejb-ref元素相同的属性并以相同的方式使用。</p><img src ="http://www.blogjava.net/19851985lili/aggbug/93518.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/19851985lili/" target="_blank">☜♥☞MengChuChen</a> 2007-01-12 19:49 <a href="http://www.blogjava.net/19851985lili/articles/93518.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JSCODE</title><link>http://www.blogjava.net/19851985lili/articles/93478.html</link><dc:creator>☜♥☞MengChuChen</dc:creator><author>☜♥☞MengChuChen</author><pubDate>Fri, 12 Jan 2007 08:32:00 GMT</pubDate><guid>http://www.blogjava.net/19851985lili/articles/93478.html</guid><wfw:comment>http://www.blogjava.net/19851985lili/comments/93478.html</wfw:comment><comments>http://www.blogjava.net/19851985lili/articles/93478.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/19851985lili/comments/commentRss/93478.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/19851985lili/services/trackbacks/93478.html</trackback:ping><description><![CDATA[
		<p>function trim(str)<br />{<br />    if(typeof(str)!="string") return "";<br />    var rexp=/\s*$/;<br />    var lexp=/^\s*/;<br />    return str.replace(rexp,"").replace(lexp,"");<br />}<br />function bs(obj)<br />{<br /> obj.disabled=true;<br /> obj.style.width=100;<br /> obj.value='提交中，请等待';<br />}</p>
		<p>function bodydisabled()<br />{<br /> var b = document.getElementsByTagName('body'); <br /> b[0].setAttribute('disabled','true');<br />}<br />function isInt(s)  //整数输入判断<br />{<br />   if (s.value == "") return true;<br />   var chk=parseInt(s.value,10);<br />   if(chk!=s.value || chk&lt;0)<br />     {<br />       alert("该字段应是正整数！");<br />       s.focus();<br />       return false;<br />      }<br />   return true;<br />}</p>
		<p>function isFloat(s)  //浮点数输入判断<br />{<br />  if (s.value == "") return true;<br />   var chk=parseFloat(s.value);<br />   if(chk!=s.value)<br />     {<br />   alert("该字段应是整数或小数！");<br />      s.focus();<br />      return false;<br />      }<br />   return true;<br />}</p>
		<p>function isDate(obj) //时间输入判断<br />{<br /> var m,str,exp,d;<br /> str=trim(obj.value);<br /> if(str=="") return true;<br /> str=str.replace(/-0/g,"-");<br /> exp=/\d{4}-\d{1,2}-\d{1,2}/;<br /> if(str.match(exp)!=null)<br />    {<br />        m=str.split("-");<br />  d=new Date(Date.parse(m[1]+'-'+m[2]+'-'+m[0]));<br />  if(d&gt;=new Date(1800,1,1) &amp;&amp; d&lt;=new Date(2070,6,6) &amp;&amp; d.getFullYear()==parseInt(m[0]) &amp;&amp; (d.getMonth()+1)==parseInt(m[1]) &amp;&amp; d.getDate()==parseInt(m[2]))<br />  {<br />            return true;<br />  }<br />    }<br /> alert("该字段应是正确的日期值：YYYY-MM-DD！\n 例如 2005年1月5日 输入为: 2005-01-05");<br /> obj.focus();<br />    return false;<br />}</p>
		<p>
				<br />// 下面代码屏蔽右键</p>
		<p>if (window.Event) <br />  document.captureEvents(Event.MOUSEUP); <br /> <br />function nocontextmenu() <br />{<br /> event.cancelBubble = true<br /> event.returnValue = false;<br /> <br /> return false;<br />}<br /> <br />function norightclick(e) <br />{<br /> if (window.Event) <br /> {<br />  if (e.which == 2 || e.which == 3)<br />   return false;<br /> }<br /> else<br />  if (event.button == 2 || event.button == 3)<br />  {<br />   event.cancelBubble = true<br />   event.returnValue = false;<br />   return false;<br />  }<br /> <br />}<br />document.oncontextmenu = nocontextmenu;  // for IE5+<br />document.onmousedown = norightclick;  // for all others</p>
		<p>//屏蔽其它键<br />function documentonkeydown()<br />{</p>
		<p>  if (event.ctrlKey &amp;&amp; event.keyCode==78)  //屏蔽 Ctrl+n<br />  {   <br />     event.returnValue=false;   <br />   }<br />  if (event.keyCode==116)                  //屏蔽 F5 刷新键<br />  {<br />     event.keyCode=0;<br />     event.returnValue=false;<br />  }<br />  if (event.keyCode==122)                  //屏蔽 F11 <br />  {<br />     event.keyCode=0;<br />     event.returnValue=false;<br />  }<br />  <br />  if ((event.keyCode == 8) &amp;&amp; <br />      (event.srcElement.type != "text" &amp;&amp; <br />      event.srcElement.type != "textarea" &amp;&amp; <br />      event.srcElement.type != "password") ||           //屏蔽退格删除键   <br />      (event.keyCode==116)||                            //屏蔽 F5 刷新键<br />      (event.ctrlKey &amp;&amp; event.keyCode==82)){            //Ctrl + R<br />     event.keyCode=0;<br />     event.returnvalue=false;<br />  }</p>
		<p>  if ((event.altKey) &amp;&amp; ((event.keyCode==37)||  //屏蔽 Alt+ 方向键 ←<br />       (event.keyCode==39)))   //屏蔽 Alt+ 方向键 →<br />  {  <br />     event.keyCode=0;<br />     <br />     alert("禁止使用ALT+方向键前进或后退网页");<br />     event.returnValue=false;<br />     event.cancelBubble = false;<br />  }<br />  if ((event.shiftKey) &amp;&amp; (event.keyCode==121))   //屏蔽 shift+F10<br />  {<br />     event.keyCode=0;<br />     event.returnValue=false;<br />  }</p>
		<p>  if (window.event.srcElement.tagName == "A" &amp;&amp; window.event.shiftKey) <br />      event.keyCode=0;<br />      window.event.returnvalue = false;  //屏蔽 shift 加鼠标左键新开一网页  <br />}</p>
		<p>
				<br />document.onkeydown = documentonkeydown;</p>
		<p>
				<br />//打印页面</p>
		<p>function printpage() { print(document); }</p>
		<p>//检查浏览器版本<br />function VersionCheck()<br />{<br />   this.version = navigator.appVersion.substring(22,25);<br />   if (navigator.appVersion.substring(17,21) != "MSIE")<br />     alert ("当前不是IE浏览器 ,请使用IE浏览器.");<br />   if ( this.version &lt;5.5)<br />     alert ("当前IE版本小于5.5,请使用IE5.5 以上版本");<br />}</p>
		<p>VersionCheck() </p>
		<p>1.将彻底屏蔽鼠标右键,无右键菜单 <br />&lt;body oncontextmenu="window.event.returnvalue=false"&gt; <br />也可以用于网页中Table框架中 <br />&lt;table border oncontextmenu=return(false)&gt;&lt;td&gt;no&lt;/table&gt; <br />  <br />2.取消选取、防止复制 <br />&lt;body onselectstart="return false"&gt; <br />  <br />3.不准粘贴 <br />&lt;body onpaste="return false"&gt; <br />  <br />4.防止复制 <br />&lt;body oncopy="return false;" oncut="return false;"&gt; <br />  <br />5.IE地址栏前换成自己的图标 <br />&lt;link rel="Shortcut Icon" href="favicon.ico"&gt; <br />说明：关于favicon.ico文件的制作。你可以先在FW中做一个图片，属于你自己站点一个 <br />小图标。然后在ACD see将文件属性改为*.ico，然后将你做的*.ICO文件传到你的服务器 <br /><br />目录中，然后就可以使用以上代码来实现，当别人登陆你的站点时，地址栏里使用的就 <br />是你自定义的图标了。很PP哦。 <br />  <br />6.可以在收藏夹中显示出你的图标 <br />&lt;link rel="Bookmark" href="favicon.ico"&gt; <br />说明：制作方法和上面的一样。只是显示的方式不同，这个是在别人收藏你的网页地址 <br />时显示的个性图标。也很PP. <br />  <br />7.关闭输入法 <br />&lt;input style="ime-mode:disabled"&gt; <br />说明：这段代码是在表格提交时用到的。也就是在输入数据时不可以使用其他输入法模 <br />式。 <br /><br />8.永远都会带着框架 <br />&lt;script language="javascript"&gt;&lt;!-- <br />　if (window == top)top.location.href = "frames.htm";// --&gt;&lt;/script&gt; <br />说明：frames.htm为你的网页，这也是保护页面的一种方法 <br />  <br />9.防止被人frame <br />&lt;SCRIPT LANGUAGE=javascript&gt;&lt;!-- <br />　if (top.location != self.location)top.location=self.location; <br />// --&gt;&lt;/SCRIPT&gt; <br />  <br />10.网页将不能被另存为 <br />&lt;noscript&gt;&lt;iframe src=*.html&gt;&lt;/iframe&gt;&lt;/noscript&gt; <br />说明：&lt;noscirpt&gt;的用法很广，其中一条就是可以使JS广告失效。 <br />  <br />11.查源文件 <br />&lt;input type=button value=查看网页源代码 <br />onclick="window.location = 'view-source:'+ '<a href="http://www.e3i5.com/test.htm&amp;#39;;&quot;&gt;" target="_blank"><u><font color="#000080">http://www.e3i5.com/test.htm&amp;#39;;"&gt;</font></u></a>    <br />  <br />12.COOKIE脚本记录，有很大的用处哦 <br />function get_cookie(Name) { <br />var search = Name + "=" <br />var returnvalue = ""; <br />if (documents.cookie.length &gt; 0) { <br />offset = documents.cookie.indexOf(search) <br />if (offset != -1) { // if cookie exists <br />offset += search.length <br />// set index of beginning of value <br />end = documents.cookie.indexOf(";", offset); <br />// set index of end of cookie value <br />if (end == -1) <br />end = documents.cookie.length; <br />returnvalue=unescape(documents.cookie.substring(offset, end)) <br />} <br />} <br />return returnvalue; <br />} <br />function loadpopup(){ <br />if (get_cookie('popped')==''){ <br />openpopup() <br />documents.cookie="popped=yes" <br /><br />} <br />} <br />说明：以上是JS代码，请自己加起始符和结束符 <br /><br />13.内框架&lt;IFRAME&gt;使用 <br />Iframe标记的使用格式是: 　　 <br />&lt;iframe src="URL" width="x" height="x" scrolling="[OPTION]" frameborder="x" <br />name="main"&gt;&lt;/iframe&gt; <br />src：文件的路径，既可是HTML文件，也可以是文本、ASP等； 　　 <br />width、height："内部框架"区域的宽与高； 　　 <br />scrolling:当SRC的指定的HTML文件在指定的区域不显不完时， <br />滚动选项，如果设置为NO，则不出现滚动条；如为Auto：则自动出现滚动条； <br />如为Yes，则显示; 　FrameBorder：区域边框的宽度，为了让“内部框架“与邻近的内 <br />容相融合，常设置为0。 <br />name:框架的名字，用来进行识别。 <br />比如: 　当你想用父框架控制内部框架时，可以使用： target="框架的名字"来控制。 <br />  <br />例子：&lt;iframe name="mm" src="<a href="http://www.e3i5.com&quot;;;/" target="_blank"><u><font color="#000080">http://www.e3i5.com";;</font></u></a>    width="100%" height="100% <br />" marginwidth="0" marginheight="0" hspace="0" vspace="0" frameborder="0" scr <br />olling="no"&gt;&lt;/iframe&gt; <br />  <br />14.自动跳转 <br />在源代码中的&lt;head&gt;…&lt;/head&gt;加入如下代码： <br />&lt;meta http-equiv="refresh"content="3;URL=<a href="http://www.e3i5.com;/" target="_blank"><u><font color="#000080">http://www.e3i5.com;</font></u></a>    charset=gb2312 <br />"&gt; <br />说明：content="3 表示3秒刷新到URL <br />  <br />15.如何改变链接的鼠标形状 <br />只需在链接上加上这一代码就行的了 <br />或者跟上面的用CSS写也行 <br />style="cursor:hand"　　　　　 　style="cursor:crosshair" <br />style="cursor:text" 　　　　　　style="cursor:wait" <br />style="cursor:move" 　　　　　　style="cursor:help" <br />style="cursor:e-resize" 　　　　style="cursor:n-resize" <br />style="cursor:nw-resize" 　 　　style="cursor:w-resize" <br />style="cursor:s-resize" 　　　　style="cursor:se-resize" <br />style="cursor:sw-resize" <br />以上代码你只需要加到连接或是页面的STYLE区里就可以实现鼠标多样化。 <br />16.全屏显示 <br />&lt;form&gt; <br />&lt;div align="center"&gt; <br />&lt;input type="BUTTON" name="FullScreen" value="全屏显示" onClick="window.open <br />(document.location, 'big', 'fullscreen=yes')"&gt; <br />&lt;/div&gt; <br /><br />&lt;/form&gt; <br />把它放到&lt;body&gt;区中。 <br />22.网页不会被缓存 <br />HTMl网页 <br />&lt;META HTTP-EQUIV="pragma" CONTENT="no-cache"&gt; <br />&lt;META HTTP-EQUIV="Cache-Control" CONTENT="no-cache, must-revalidate"&gt; <br />&lt;META HTTP-EQUIV="expires" CONTENT="Wed, 26 Feb 1997 08:21:57 GMT"&gt; <br />或者&lt;META HTTP-EQUIV="expires" CONTENT="0"&gt; <br />ASP网页 <br />　Response.Expires = -1 <br />　Response.ExpiresAbsolute = Now() - 1 <br />　Response.cachecontrol = "no-cache" <br />PHP网页 <br />header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); <br />header("Cache-Control: no-cache, must-revalidate"); <br />header("Pragma: no-cache"); <br />  <br />  <br />23. 定义数据库连接的一些常量 <br />&lt;% <br />'定义数据库连接的一些常量 <br />Const adOpenForwardOnly　　 = 0 '游标只向前浏览记录，不支持分页、Recordset、 <br />BookMark <br />Const adOpenKeyset　　　　 = 1 '键集游标，其他用户对记录说做的修改将反映到记 <br />录集中，但其他用户增加或删除记录不会反映到记录集中。支持分页、Recordset、Boo <br />kMark <br />Const adOpenDynamic　　　　 = 2 '动态游标功能最强，但耗资源也最多。用户对记录 <br />说做的修改，增加或删除记录都将反映到记录集中。支持全功能浏览(ACCESS不支持)。 <br />  <br />Const adOpenStatic　　　　 = 3 '静态游标，只是数据的一个快照，用户对记录说做 <br />的修改，增加或删除记录都不会反映到记录集中。支持向前或向后移动 <br />Const adLockReadOnly　　　　= 1 '锁定类型，默认的，只读，不能作任何修改 <br />Const adLockPessimistic　　 = 2 '当编辑时立即锁定记录，最安全的方式 <br />Const adLockOptimistic　　　= 3 '只有在调用Update方法时才锁定记录集，而在此前 <br />的其他操作仍可对当前记录进行更改、插入和删除等 <br />Const adLockBatchOptimistic = 4 '当编辑时记录不会被锁定，而更改、插入和删除是 <br />在批处理方式下完成的 <br />Const adCmdText　= &amp;H0001 <br />Const adCmdTable = &amp;H0002 <br />%&gt; <br />  <br />24.最小化、最大化、关闭窗口 <br />&lt;object id=hh1 classid="clsid:ADB880A6-D8FF-11CF-9377-00AA003B7A11"&gt; <br />&lt;param name="Command" value="Minimize"&gt;&lt;/object&gt; <br />&lt;object id=hh2 classid="clsid:ADB880A6-D8FF-11CF-9377-00AA003B7A11"&gt; <br />&lt;param name="Command" value="Maximize"&gt;&lt;/object&gt; <br />&lt;OBJECT id=hh3 classid="clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11"&gt; <br />&lt;PARAM NAME="Command" value="Close"&gt;&lt;/OBJECT&gt; <br />&lt;input type=button value=最小化 onclick=hh1.Click()&gt; <br />&lt;input type=button value=最大化 onclick=hh2.Click()&gt; <br />&lt;input type=button value=关闭 onclick=hh3.Click()&gt; <br />说明：本例适用于IE <br />  <br />25.判断上一页的来源 <br />asp页: <br />request.servervariables("HTTP_REFERER") <br />javascript: <br />document.referrer <br />26.光标是停在文本框文字的最后 <br />&lt;script language="javascript"&gt; <br />function cc() <br />{ <br />　var e = event.srcElement; <br />　var r =e.createTextRange(); <br />　r.moveStart('character',e.value.length); <br />　r.collapse(true); <br />　r.select(); <br />} <br />&lt;/script&gt; <br />&lt;input type=text name=text1 value="123" onfocus="cc()"&gt; <br />说明：适用于表格数据提交 <br />如果转萜，请注明转自-=e代时光=- <a href="http://www.e3i5.com/" target="_blank"><u><font color="#000080">http://www.e3i5.com</font></u></a>    <br />  <br />27.怎样通过asp的手段来检查来访者是否用了代理 <br />&lt;% if Request.ServerVariables("HTTP_X_FORWARDED_FOR")&lt;&gt;"" then <br />response.write "&lt;font color=#FF0000&gt;您通过了代理服务器，"&amp; _ <br />"真实的IP为"&amp;Request.ServerVariables("HTTP_X_FORWARDED_FOR") <br />end if <br />%&gt; <br />  <br />28.取得控件的绝对位置 <br />&lt;script language="javascript"&gt; <br />function getIE(e){ <br />　var t=e.offsetTop; <br />　var l=e.offsetLeft; <br />　while(e=e.offsetParent){ <br />　　t+=e.offsetTop; <br />　　l+=e.offsetLeft; <br />　　} <br />　alert("top="+t+"\nleft="+l); <br />　} <br />&lt;/script&gt; <br />file://VBScript <br />&lt;script language="VBScript"&gt;&lt;!-- <br />function getIE() <br />　dim t,l,a,b <br />　set a=document.all.img1 <br />　t=document.all.img1.offsetTop <br />　l=document.all.img1.offsetLeft <br />　while a.tagName&lt;&gt;"BODY" <br />　　set a = a.offsetParent <br />　　t=t+a.offsetTop <br />　　l=l+a.offsetLeft <br />　wend <br />　msgbox "top="&amp;t&amp;chr(13)&amp;"left="&amp;l,64,"得到控件的位置" <br />end function <br />--&gt;&lt;/script&gt; <br />说明：本例适用于JS <br /><br />网页经典代码（二） <br />  <br />  <br />29.滚动特效 <br />&lt;marquee onMouseOver="this.stop()" onMouseOut="this.start()" scrollamount="2 <br />" scrolldelay="0" direction="up" width="330" height="120" border="0" align=" <br />center" id="MARQUEE1"&gt; <br />&lt;p&gt;欢迎光临阳春学生网 <br />我们地址是<a href="http://www.ycuu.net/" target="_blank"><u><font color="#000080">http://www.ycuu.net</font></u></a>    <br />感谢 <br />&lt;/marquee&gt; <br />30.自动更新提示 <br />&lt;body&gt; <br />&lt;TABLE border=2 cellspacing=0 cellpadding=3&gt; <br />&lt;TR&gt;&lt;TD bgcolor="#000044"&gt; <br />&lt;FONT color="#4400ff" face=georgia,arial size=+1&gt; <br />&lt;CENTER&gt; <br />&lt;SCRIPT LANGUAGE="javascript"&gt; <br />&lt;!-- <br />document.write(document.title); <br />//--&gt; <br />&lt;/SCRIPT&gt; <br />&lt;/TD&gt;&lt;/TR&gt; <br />&lt;TR&gt;&lt;TD bgcolor="#440000"&gt; <br />&lt;FONT size=-1 color="#ff0000" face="trebuchet MS","arial"&gt; <br />&lt;SCRIPT LANGUAGE="javascript"&gt; <br />&lt;!-- Begin <br />function getCookieVal (offset) { <br />var endstr = documents.cookie.indexOf (";", offset); <br />if (endstr == -1) <br />endstr = documents.cookie.length; <br />return unescape(documents.cookie.substring(offset, endstr)); <br />} <br />function GetCookie (name) { <br />var arg = name + "="; <br />var alen = arg.length; <br />var clen = documents.cookie.length; <br />var i = 0; <br />while (i &lt; clen) { <br />var j = i + alen; <br />if (documents.cookie.substring(i, j) == arg) <br />return getCookieVal (j); <br />i = documents.cookie.indexOf(" ", i) + 1; <br />if (i == 0) break; <br />} <br />return null; <br />} <br />function SetCookie (name, value) { <br />var argv = SetCookie.arguments; <br />var argc = SetCookie.arguments.length; <br />var expires = (argc &gt; 2) ? argv[2] : null; <br />var path = (argc &gt; 3) ? argv[3] : null; <br />var domain = (argc &gt; 4) ? argv[4] : null; <br />var secure = (argc &gt; 5) ? argv[5] : false; <br />documents.cookie = name + "=" + escape (value) + <br />((expires == null) ? "" : ("; expires=" + expires.toGMTString())) + <br />((path == null) ? "" : ("; path=" + path)) + <br />((domain == null) ? "" : ("; domain=" + domain)) + <br />((secure == true) ? "; secure" : ""); <br />} <br />function DeleteCookie(name) { <br />var exp = new Date(); <br />FixCookieDate (exp); <br />exp.setTime (exp.getTime() - 1); <br />var cval = GetCookie (name); <br />if (cval != null) <br />documents.cookie = name + "=" + cval + "; expires=" + exp.toGMTString(); <br />} <br />var cookie_date=new Date(document.lastModified); <br />var expdate = new Date(); <br />expdate.setTime(expdate.getTime()+(5*24*60*60*1000)); <br />document.write("&lt;Font color=ff8800&gt;" + "上次更新时间: "+ "&lt;/font&gt;" +document <br />.lastModified); <br />document.write(""); <br />if (!(cookie_date == GetCookie("cookie_date"))){ <br />SetCookie("cookie_date",cookie_date,expdate); <br />document.write("&lt;font color='yellow'&gt; <br />站点上次更新!&lt;/font&gt; <br />"); <br />} <br />// End --&gt; <br />&lt;/SCRIPT&gt; <br />&lt;/FONT&gt; <br />&lt;/TD&gt;&lt;/TR&gt; <br />&lt;/TABLE&gt; <br />&lt;/CENTER&gt; <br />&lt;/body&gt; <br />  <br />  <br />31.关于表格提交的几种格式 <br />&lt;input type=text name=txtPostalCode onKeypress="if (event.keyCode &lt; 45 || ev <br />ent.keyCode &gt; 57) event.returnvalue = false;"&gt; <br />限制输入字符，你可以改变KEYCODE的值来限制输入。你将KEYCODE的值设为极大和极小 <br />就什么也不能输入了。这个可以屏蔽你想屏蔽的字符有一定的选择性.. <br />&lt;INPUT type="text" name="username" value="james" disabled&gt; <br /><br />使用disabled属性后的区域的值，不能被传递给其他的程序（ASP/CGI）去处理，如果你 <br />非要传递请通过隐藏属性去做。这个比较单一，功能不强。一般用于未完成的站点。 <br />&lt;INPUT type="text" name="partNumber" value="1500" readonly&gt; <br />readonly属性顾名思义是“只读”。它将TEXT转化为一个对象，禁止对它进行编辑。你 <br />虽然可以通过TAB键在多个TEXT区域间切换，但是不能修改已经指定的TEXT区的值。但是 <br />它不象Disabled属性那样，可以进行正常的数值传递。 <br /><br />加入收藏夹：&lt;a href="javascript:window.external.AddFavorite('...::ycuu阳春学生网ycuu::....')"&gt;加入收藏夹&lt;/a&gt;<br /><br />设为首页：&lt;a onclick="this.style.behavior='url(#default#homepage)';this.setHomePage('<a href="http://www.ycuu.net/" target="_blank"><u><font color="#000080">http://www.ycuu.net</font></u></a>   &amp;#39;);" href="<a href="http://www.ycuu.net/" target="_blank"><u><font color="#000080">http://www.ycuu.net</font></u></a>   ";&gt;设为首页&lt;/a&gt; <br /><br />各种播放器代码<br /><br />1.avi格式<br /><br />&lt;object id="video" width="400" height="200" border="0" classid="clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA"&gt;<br />&lt;param name="ShowDisplay" value="0"&gt;<br />&lt;param name="ShowControls" value="1"&gt;<br />&lt;param name="AutoStart" value="1"&gt;<br />&lt;param name="AutoRewind" value="0"&gt;<br />&lt;param name="PlayCount" value="0"&gt;<br />&lt;param name="Appearance value="0 value="""&gt;<br />&lt;param name="BorderStyle value="0 value="""&gt;<br />&lt;param name="MovieWindowHeight" value="240"&gt;<br />&lt;param name="MovieWindowWidth" value="320"&gt;<br />&lt;param name="FileName" value="file:///D|/work/vod/Mbar.avi"&gt;<br />&lt;embed width="400" height="200" border="0" showdisplay="0" showcontrols="1" autostart="1" autorewind="0" playcount="0" moviewindowheight="240" moviewindowwidth="320" filename="file:///D|/work/vod/Mbar.avi" src="Mbar.avi"&gt;<br />&lt;/embed&gt; <br />&lt;/object&gt;<br /><br />2.mpg格式 <br /><br />&lt;object classid="clsid:05589FA1-C356-11CE-BF01-00AA0055595A" id="ActiveMovie1" width="239" height="250"&gt;<br />&lt;param name="Appearance" value="0"&gt;<br />&lt;param name="AutoStart" value="-1"&gt;<br />&lt;param name="AllowChangeDisplayMode" value="-1"&gt;<br />&lt;param name="AllowHideDisplay" value="0"&gt;<br />&lt;param name="AllowHideControls" value="-1"&gt;<br />&lt;param name="AutoRewind" value="-1"&gt;<br />&lt;param name="Balance" value="0"&gt;<br />&lt;param name="CurrentPosition" value="0"&gt;<br />&lt;param name="DisplayBackColor" value="0"&gt;<br />&lt;param name="DisplayForeColor" value="16777215"&gt;<br />&lt;param name="DisplayMode" value="0"&gt;<br />&lt;param name="Enabled" value="-1"&gt;<br />&lt;param name="EnableContextMenu" value="-1"&gt;<br />&lt;param name="EnablePositionControls" value="-1"&gt;<br />&lt;param name="EnableSelectionControls" value="0"&gt;<br />&lt;param name="EnableTracker" value="-1"&gt;<br />&lt;param name="Filename" value="../../../mpeg/halali.mpg" valuetype="ref"&gt;<br />&lt;param name="FullScreenMode" value="0"&gt;<br />&lt;param name="MovieWindowSize" value="0"&gt;<br />&lt;param name="PlayCount" value="1"&gt;<br />&lt;param name="Rate" value="1"&gt;<br />&lt;param name="SelectionStart" value="-1"&gt;<br />&lt;param name="SelectionEnd" value="-1"&gt;<br />&lt;param name="ShowControls" value="-1"&gt;<br />&lt;param name="ShowDisplay" value="-1"&gt;<br />&lt;param name="ShowPositionControls" value="0"&gt;<br />&lt;param name="ShowTracker" value="-1"&gt;<br />&lt;param name="Volume" value="-480"&gt;<br />&lt;/object&gt;<br /><br /><br />3.smi格式 <br /><br />&lt;OBJECT id=RVOCX classid=clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA width=240 <br />height=180&gt;<br />&lt;param name="_ExtentX" value="6350"&gt;<br />&lt;param name="_ExtentY" value="4763"&gt;<br />&lt;param name="AUTOSTART" value="-1"&gt;<br />&lt;param name="SHUFFLE" value="0"&gt;<br />&lt;param name="PREFETCH" value="0"&gt;<br />&lt;param name="NOLABELS" value="-1"&gt;<br />&lt;param name="SRC" value="rm.rm"&gt;<br />&lt;param name="CONTROLS" value="ImageWindow"&gt;<br />&lt;param name="CONSOLE" value="console1"&gt;<br />&lt;param name="LOOP" value="0"&gt;<br />&lt;param name="NUMLOOP" value="0"&gt;<br />&lt;param name="CENTER" value="0"&gt;<br />&lt;param name="MAINTAINASPECT" value="0"&gt;<br />&lt;param name="BACKGROUNDCOLOR" value="#000000"&gt;&lt;embed src="real.smi" type="audio/x-pn-realaudio-plugin" console="Console1" controls="ImageWindow" height="180" width="240" autostart="true"&gt;&lt;/OBJECT&gt;<br /><br />4.rm格式 <br /><br />&lt;OBJECT ID=video1 CLASSID="clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA" HEIGHT=288 WIDTH=352&gt;<br /><br />&lt;param name="_ExtentX" value="9313"&gt;<br />&lt;param name="_ExtentY" value="7620"&gt;<br />&lt;param name="AUTOSTART" value="0"&gt;<br />&lt;param name="SHUFFLE" value="0"&gt;<br />&lt;param name="PREFETCH" value="0"&gt;<br />&lt;param name="NOLABELS" value="0"&gt;<br />&lt;param name="SRC" value="<a href="rtsp://203.207.131.35/vod/dawan-a.rm&quot;;;&gt;" target="_blank"><u><font color="#000080">rtsp://203.207.131.35/vod/dawan-a.rm";;&gt;</font></u></a>   <br />&lt;param name="CONTROLS" value="ImageWindow"&gt;<br />&lt;param name="CONSOLE" value="Clip1"&gt;<br />&lt;param name="LOOP" value="0"&gt;<br />&lt;param name="NUMLOOP" value="0"&gt;<br />&lt;param name="CENTER" value="0"&gt;<br />&lt;param name="MAINTAINASPECT" value="0"&gt;<br />&lt;param name="BACKGROUNDCOLOR" value="#000000"&gt;&lt;embed SRC type="audio/x-pn-realaudio-plugin" CONSOLE="Clip1" CONTROLS="ImageWindow" HEIGHT="288" WIDTH="352" AUTOSTART="false"&gt;<br /><br />&lt;/OBJECT&gt;<br /><br />5.wmv格式<br /><br />&lt;object id="NSPlay" width=200 height=180 classid="CLSID:22d6f312-b0f6-11d0-94ab-0080c74c7e95" codebase="<a href="http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=6,4,5,715&quot;" target="_blank"><u><font color="#000080">http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=6,4,5,715"</font></u></a>    standby="Loading Microsoft Windows Media Player components..." type="application/x-oleobject" align="right" hspace="5"&gt;<br />&lt;!-- ASX File Name --&gt;<br />&lt;param name="AutoRewind" value=1&gt;<br />&lt;param name="FileName" value="xxxxxx.wmv"&gt;<br />&lt;!-- Display Controls --&gt;<br /><br />&lt;param name="ShowControls" value="1"&gt;<br />&lt;!-- Display Position Controls --&gt;<br /><br />&lt;param name="ShowPositionControls" value="0"&gt;<br />&lt;!-- Display Audio Controls --&gt;<br /><br />&lt;param name="ShowAudioControls" value="1"&gt;<br />&lt;!-- Display Tracker Controls --&gt;<br /><br />&lt;param name="ShowTracker" value="0"&gt;<br />&lt;!-- Show Display --&gt;<br /><br />&lt;param name="ShowDisplay" value="0"&gt;<br />&lt;!-- Display Status Bar --&gt;<br /><br />&lt;param name="ShowStatusBar" value="0"&gt;<br />&lt;!-- Diplay Go To Bar --&gt;<br /><br />&lt;param name="ShowGotoBar" value="0"&gt;<br />&lt;!-- Display Controls --&gt;<br /><br />&lt;param name="ShowCaptioning" value="0"&gt;<br />&lt;!-- Player Autostart --&gt;<br /><br />&lt;param name="AutoStart" value=1&gt;<br />&lt;!-- Animation at Start --&gt;<br /><br />&lt;param name="Volume" value="-2500"&gt;<br />&lt;param name="AnimationAtStart" value="0"&gt;<br />&lt;!-- Transparent at Start --&gt;<br /><br />&lt;param name="TransparentAtStart" value="0"&gt;<br />&lt;!-- Do not allow a change in display size --&gt;<br /><br />&lt;param name="AllowChangeDisplaySize" value="0"&gt;<br />&lt;!-- Do not allow scanning --&gt;<br /><br />&lt;param name="AllowScan" value="0"&gt;<br />&lt;!-- Do not show contect menu on right mouse click --&gt;<br /><br />&lt;param name="EnableContextMenu" value="0"&gt;<br />&lt;!-- Do not allow playback toggling on mouse click --&gt;<br />&lt;param name="ClickToPlay" value="0"&gt;<br />&lt;/object&gt;<br /><br /><strong>给滚动条换色</strong></p>
		<p>    几乎所有网页的滚动条都是默认的灰色，如果把它的颜色换换，来点另类的，相信一定会使网页更加靓丽。我们只要在网页代码&lt; head&gt; &lt; /head&gt;之间插入下面的代码，即可随心所欲地更改颜色了。 </p>
		<p>    &lt; style&gt;<br />　　body {SCROLLBAR-FACE-COLOR:#3333FF;(立体滚动条凸出部分的颜色)<br />　　SCROLLBAR-HIGHLIGHT-COLOR:#505050;(滚动条空白部分的颜色)<br />　　SCROLLBAR-SHADOW-COLOR:#fc2400;(立体滚动条阴影的颜色)<br />　　SCROLLBAR-ARROW-COLOR:#666666;(上下按钮上三角箭头的颜色)<br />　　SCROLLBAR-BASE-COLOR:#333333; (滚动条的基本颜色)<br />　　SCROLLBAR-DARK-SHADOW-COLOR:#b4fc48} (立体滚动条强阴影的颜色)<br />　　&lt; /style&gt; </p>
		<p>    后面的16位颜色值你可以随意更改，括号内是解释说明，在输入时请不要插入。 </p>
		<p>    <b>隐藏滚动条</b></p>
		<p>    在任何情况下，如果网页超出显示范围，就会出现滚动条。但有时我们并不想让它显示，如何隐藏它呢？只需在&lt; body&gt; &lt; /body&gt;之间插入代码：&lt; body style="overflow-x:hidden;overflow-y:hidden"&gt;即可。其中x表示水平滚动条，将其改为y的话就可以隐藏垂直滚动条。 </p>
		<p>    <b>滚屏显示</b></p>
		<p>    当网页中有长篇文章时，浏览起来就比较吃劲了，想想一边忙着拖动滚动条，一边忙着浏览，确实挺累人的。为了客人能够轻松的浏览，我们可以使用script代码实现网页的自动滚屏，当双击网页的时候，网页将会自动向下滚动，再次单击时滚动停止。将下面的代码插入到&lt; body&gt; &lt; /body&gt;之间。 </p>
		<p>    &lt; script language"javascript"&gt;<br />　　var currentpos,timer;<br />　　function initialize()<br />　　{<br />　　timer=setInterval("scrollwindow()",10);<br />　　}<br />　　function sc(){<br />　　clearInterval(timer);<br />　　}<br />　　function scrollwindow()<br />　　{<br />　　currentpos=document.body.scrollTop;<br />　　window.scroll(0,++currentpos);<br />　　if (currentpos != document.body.scrollTop)<br />　　sc();<br />　　}<br />　　document.onmousedown=sc<br />　　document.ondblclick=initialize<br />　　&lt; /script&gt;</p>
<img src ="http://www.blogjava.net/19851985lili/aggbug/93478.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/19851985lili/" target="_blank">☜♥☞MengChuChen</a> 2007-01-12 16:32 <a href="http://www.blogjava.net/19851985lili/articles/93478.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JSP中的Java文件操作</title><link>http://www.blogjava.net/19851985lili/articles/93176.html</link><dc:creator>☜♥☞MengChuChen</dc:creator><author>☜♥☞MengChuChen</author><pubDate>Thu, 11 Jan 2007 07:07:00 GMT</pubDate><guid>http://www.blogjava.net/19851985lili/articles/93176.html</guid><wfw:comment>http://www.blogjava.net/19851985lili/comments/93176.html</wfw:comment><comments>http://www.blogjava.net/19851985lili/articles/93176.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/19851985lili/comments/commentRss/93176.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/19851985lili/services/trackbacks/93176.html</trackback:ping><description><![CDATA[
		<table cellspacing="0" cellpadding="0" width="95%" border="0">
				<!-- BEGIN alcyc -->
				<tbody>
						<tr>
								<td align="middle" width="100%">
										<h2>
												<b>JSP中的Java文件操作</b>
										</h2>
								</td>
						</tr>
						<tr>
								<td width="100%">
										<p>最近收集了一些JSP中关于操作JAVA文件的一些做法</p>
										<p>文件的建立/检查与删除 <br /><br />&lt;%@ page contentType="text/html;charset=gb2312"%&gt; <br />&lt;%@ page import="java.io.*"%&gt; <br />&lt;html&gt; <br />&lt;head&gt; <br />&lt;title&gt;文件的建立、检查与删除&lt;/title&gt; <br />&lt;/head&gt; <br />&lt;body&gt; <br />&lt;% <br />String path=request.getRealPath(""); <br />//out.println(path); <br />File f=new File(path,"File.txt"); <br />//out.println(f); <br />//out.println(f.exists()); <br /><br />if(f.exists()){//检查File.txt是否存在 <br />f.delete();//删除File.txt文件 <br />out.println(path + "\File.txt 存在，已删除。"); <br />}else{ <br />f.createNewFile();//在当前目录下建立一个名为File.txt的文件 <br />out.println(path + "\File.txt 不存在，已建立。");//输出目前所在的目录路径 <br />} <br />%&gt; <br /><br /><br /><br />目录的建立/检查与删除 <br /><br />&lt;%@ page contentType="text/html;charset=gb2312"%&gt; <br />&lt;%@ page import="java.io.*"%&gt; <br />&lt;html&gt; <br />&lt;head&gt; <br />&lt;title&gt;目录的建立/检查与删除&lt;/title&gt; <br />&lt;/head&gt; <br />&lt;body&gt; <br />&lt;% <br />String path=request.getRealPath(""); <br />path=path + "\Sub";//将要建立的目录路径 <br />File d=new File(path);//建立代表Sub目录的File对象，并得到它的一个引用 <br />if(d.exists()){//检查Sub目录是否存在 <br />d.delete(); <br />out.println("Sub目录存在，已删除"); <br />}else{ <br />d.mkdir();//建立Sub目录 <br />out.println("Sub目录不存在，已建立"); <br />} <br />%&gt; <br />&lt;/body&gt; <br />&lt;/html&gt; <br /><br /><br /><br />如何在JSP中处理虚拟目录 <br /><br />&lt;%@ page contentType="text/html;charset=gb2312"%&gt; <br />&lt;%@ page import="java.io.*"%&gt; <br />&lt;html&gt; <br />&lt;head&gt; <br />&lt;title&gt;JSP中如何处理虚拟目录&lt;/title&gt; <br />&lt;/head&gt; <br />&lt;body&gt; <br />取得虚拟目录对应的磁盘路径&lt;br&gt; <br />Web站点主目录的位置为&lt;font color=#ff0000&gt;&lt;%=request.getRealPath("/")%&gt;&lt;/font&gt;&lt;br&gt; <br />JSP网页所在的目录位置&lt;font color=#ff0000&gt;&lt;%=request.getRealPath("./")%&gt;&lt;/font&gt;&lt;br&gt; <br />JSP网页所在目录上一层目录的位置&lt;font color=#ff0000&gt;&lt;%=request.getRealPath("../")%&gt;&lt;/font&gt;&lt;br&gt; <br />&lt;/body&gt; <br />&lt;/html&gt; <br /><br /><br /><br />文件属性的取得 <br /><br />&lt;%@ page contentType="text/html;charset=gb2312"%&gt; <br />&lt;%@ page import="java.util.Date,java.io.*"%&gt; <br />&lt;html&gt; <br />&lt;head&gt; <br />&lt;title&gt;文件属性的取得&lt;/title&gt; <br />&lt;/head&gt; <br />&lt;body&gt; <br />&lt;% <br />String path=request.getRealPath("/"); <br />File f=new File(path,"ReadData.txt"); <br />if(f.exists()){ <br />%&gt; <br />&lt;%=f.getName()%&gt;的属性如下：&lt;br&gt;&lt;br&gt; <br />文件长度为：&lt;%=f.length()%&gt; <br />&lt;%=f.isFile()?"是文件":"不是文件"%&gt;&lt;br&gt; <br />&lt;%=f.isDirectory()?"是目录":"不是目录"%&gt;&lt;br&gt; <br />&lt;%=f.canRead()?"可读取":"不可读取"%&gt;&lt;br&gt; <br />&lt;%=f.canWrite()?"可写入":"不可写入"%&gt;&lt;br&gt; <br />&lt;%=f.isHidden()?"是隐藏文件":"不是隐藏文件"%&gt;&lt;br&gt; <br />文件的最后修改日期为：&lt;%=new Date(f.lastModified())%&gt;&lt;br&gt; <br />&lt;% <br />}else{ <br />f.createNewFile();//在当前目录下建立一个名为ReaData.txt的文件 <br />%&gt; <br />&lt;%=f.getName()%&gt;的属性如下：&lt;br&gt;&lt;br&gt; <br />文件长度为：&lt;%=f.length()%&gt; <br />&lt;%=f.isFile()?"是文件":"不是文件"%&gt;&lt;br&gt; <br />&lt;%=f.isDirectory()?"是目录":"不是目录"%&gt;&lt;br&gt; <br />&lt;%=f.canRead()?"可读取":"不可读取"%&gt;&lt;br&gt; <br />&lt;%=f.canWrite()?"可写入":"不可写入"%&gt;&lt;br&gt; <br />&lt;%=f.isHidden()?"是隐藏文件":"不是隐藏文件"%&gt;&lt;br&gt; <br />文件的最后修改日期为：&lt;%=new Date(f.lastModified())%&gt;&lt;br&gt; <br />&lt;% <br />} <br />%&gt; <br />&lt;/body&gt; <br />&lt;/html&gt; <br /><br />取出目录中文件的方法 <br /><br />&lt;%@ page contentType="text/html;charset=gb2312"%&gt; <br />&lt;%@ page import="java.io.*"%&gt; <br />&lt;html&gt; <br />&lt;head&gt; <br />&lt;title&gt;取出目录中文件的方法--列出目录中的文件&lt;/title&gt; <br />&lt;/head&gt; <br />&lt;body&gt; <br />&lt;% <br />String path=request.getRealPath("/"); <br />File d=new File(path);//建立当前目录中文件的File对象 <br />File list[]=d.listFiles();//取得代表目录中所有文件的File对象数组 <br />out.println("&lt;font color=#ff0000&gt;" + path + "目录下的文件：&lt;/font&gt;&lt;br&gt;"); <br />for(int i=0;i&lt;list.length;i++){ <br />if(list&lt;I&gt;.isFile()){ <br />out.println(list&lt;I&gt;.getName() + "&lt;br&gt;"); <br />} <br />} <br />out.println("&lt;br&gt;&lt;font color=#ff0000&gt;" + path + "目录下的目录：&lt;/font&gt;&lt;br&gt;"); <br />for(int i=0;i&lt;list.length;i++){ <br />if(list&lt;I&gt;.isDirectory()){ <br />out.println(list&lt;I&gt;.getName() + "&lt;br&gt;"); <br />} <br />} <br />%&gt; <br />&lt;/body&gt; <br />&lt;/html&gt; <br /><br /><br /><br />判断是否为空白文件 <br /><br />&lt;%@ page contentType="text/html;charset=gb2312"%&gt; <br />&lt;%@ page import="java.io.*"%&gt; <br />&lt;html&gt; <br />&lt;head&gt; <br />&lt;title&gt;判断是否为空白文件&lt;/title&gt; <br />&lt;/head&gt; <br />&lt;body&gt; <br />&lt;% <br />String path=request.getRealPath("/"); <br />out.println(path); <br />FileReader fr=new FileReader(path + "\AtEnd.txt");//建立FileReader对象，并实例化为fr <br />//对FileReader类生成的对象使用read()方法，可以从字符流中读取下一个字符。 <br />if(fr.read()==-1)//判断是否已读到文件的结尾 <br />{ <br />out.print("AtEnd.txt文件中没有数据&lt;br&gt;"); <br />}else{ <br />out.println("AtEnd.txt文件中有数据"); <br />} <br />fr.close(); <br />%&gt; <br />&lt;/body&gt; <br />&lt;/html&gt; <br />    &lt;B&gt;读取所有的文件数据&lt;/B&gt; <br />&lt;ccid_nobr&gt; <br />&lt;table width="400" border="1" cellspacing="0" cellpadding="2" <br />bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"&gt; <br />&lt;tr&gt; <br />&lt;td bgcolor="e6e6e6" class="code" style="font-size:9pt"&gt; <br />&lt;pre&gt;&lt;ccid_code&gt; &lt;%@ page contentType="text/html;charset=gb2312"%&gt; <br />&lt;%@ page import="java.io.*,java.lang.*"%&gt; <br />&lt;html&gt; <br />&lt;head&gt; <br />&lt;title&gt;读取所有的文件数据&lt;/title&gt; <br />&lt;/head&gt; <br />&lt;body&gt; <br />&lt;% <br />String path=request.getRealPath("."); <br />FileReader fr=new FileReader(path + "\ReadData.txt"); <br />//关键在于读取过程中，要判断所读取的字符是否已经到了文件的末尾， <br />并且这个字符是不是文件中的断行符，即判断该字符值是否为13。 <br />int c=fr.read();//从文件中读取一个字符 <br />//判断是否已读到文件结尾 <br />while(c!=-1){ <br />out.print((char)c);//输出读到的数据 <br />c=fr.read();//从文件中继续读取数据 <br />if(c==13){//判断是否为断行字符 <br />out.print("&lt;br&gt;");//输出分行标签 <br />fr.skip(1);//略过一个字符 <br />//c=fr.read();//读取一个字符 <br />} <br />} <br />fr.close(); <br />%&gt; <br />&lt;/body&gt; <br />&lt;/html&gt; <br /><br />一行一行读取数据 <br /><br />&lt;%@ page contentType="text/html;charset=gb2312"%&gt; <br />&lt;%@ page import="java.io.*"%&gt; <br />&lt;html&gt; <br />&lt;head&gt; <br />&lt;title&gt;文件读取&lt;/title&gt; <br />&lt;/head&gt; <br />&lt;body&gt; <br />&lt;% <br />String path=request.getRealPath("");//取得当前目录的路径 <br />FileReader fr=new FileReader(path + "\file\inc\t.txt");//建立FileReader对象，并实例化为fr <br />BufferedReader br=new BufferedReader(fr);//建立BufferedReader对象，并实例化为br <br />String Line=br.readLine();//从文件读取一行字符串 <br />//判断读取到的字符串是否不为空 <br />while(Line!=null){ <br />out.println(Line + "&lt;br&gt;");//输出从文件中读取的数据 <br />Line=br.readLine();//从文件中继续读取一行数据 <br />} <br />br.close();//关闭BufferedReader对象 <br />fr.close();//关闭文件 <br />%&gt; <br />&lt;/body&gt; <br />&lt;/html&gt; <br /><br /><br /><br />略过文件中的字符不读取 <br /><br />&lt;%@ page contentType="text/html;charset=gb2312"%&gt; <br />&lt;%@ page import="java.io.*"%&gt; <br />&lt;html&gt; <br />&lt;head&gt; <br />&lt;title&gt;略过字节不读取&lt;/title&gt; <br />&lt;/head&gt; <br />&lt;body&gt; <br />&lt;% <br />String path=request.getRealPath("."); <br />FileReader fr=new FileReader(path + "\ReadData.txt"); <br />fr.skip(2);//跳过2个字节 <br />int c=fr.read();//读取一个字节 <br />while(c!=-1){ <br />out.print((char)c); <br />c=fr.read(); <br />} <br />fr.close(); <br />%&gt; <br />&lt;/body&gt; <br />&lt;/html&gt; <br /><br /><br /><br />将数据写入文件 <br /><br />&lt;%@ page contentType="text/html;charset=gb2312"%&gt; <br />&lt;%@ page import="java.io.*"%&gt; <br />&lt;html&gt; <br />&lt;head&gt; <br />&lt;title&gt;将数据写入文件&lt;/title&gt; <br />&lt;/head&gt; <br />&lt;body&gt; <br />&lt;% <br />String path=request.getRealPath("."); <br />FileWriter fw=new FileWriter(path + "\WriteData.txt");//建立FileWriter对象，并实例化fw <br />//将字符串写入文件 <br />fw.write("大家好！"); <br />fw.write("本书是《JSP编程技巧》"); <br />fw.write("请多多指教！"); <br />fw.write("email:stride@sina.com"); <br />fw.close(); <br /><br />FileReader fr=new FileReader(path + "\WriteData.txt"); <br />BufferedReader br=new BufferedReader(fr);//建立BufferedReader对象，并实例化为br <br />String Line=br.readLine(); <br />//读取一行数据 <br />out.println(Line + "&lt;br&gt;"); <br />br.close();//关闭BufferedReader对象 <br />fr.close(); <br />%&gt; <br />&lt;/body&gt; <br />&lt;/html&gt; <br /><br /><br /><br />将写入文件的数据分行 <br /><br />&lt;%@ page contentType="text/html;charset=gb2312"%&gt; <br />&lt;%@ page import="java.io.*"%&gt; <br />&lt;html&gt; <br />&lt;head&gt; <br />&lt;title&gt;将写入文件的数据分行&lt;/title&gt; <br />&lt;/head&gt; <br />&lt;body&gt; <br />&lt;% <br />String path=request.getRealPath("."); <br />FileWriter fw=new FileWriter(path + "\WriteData.txt"); <br />BufferedWriter bw=new BufferedWriter(fw); <br />bw.write("大家好！"); <br />bw.write("本书是《JSP编程技巧》。"); <br />bw.newLine();//断行 <br />bw.write("请多多指教！"); <br />bw.newLine();//断行 <br />bw.write("email: stride@sina.com"); <br />bw.flush();//将数据更新至文件 <br />fw.close();//关闭文件流 <br />out.println("写入文件内容为：&lt;br&gt;"); <br />FileReader fr=new FileReader(path + "\WriteData.txt"); <br />BufferedReader br=new BufferedReader(fr); <br />String Line=br.readLine();//读取一行数据 <br />while(Line!=null){ <br />out.println(Line + "&lt;br&gt;"); <br />Line=br.readLine(); <br />} <br />fr.close(); <br />%&gt; <br />&lt;/body&gt; <br />&lt;/html&gt; <br /><br /><br /><br />如何将数据追加写入到文件 <br /><br />&lt;%@ page contentType="text/html;charset=gb2312"%&gt; <br />&lt;%@ page import="java.io.*"%&gt; <br />&lt;html&gt; <br />&lt;head&gt; <br />&lt;title&gt;将写入文件的数据分行&lt;/title&gt; <br />&lt;/head&gt; <br />&lt;body&gt; <br />&lt;% <br />String path=request.getRealPath("."); <br />RandomAccessFile rf=new RandomAccessFile(path + "\WriteData.txt","rw"); <br />//定义一个类RandomAccessFile的对象，并实例化 <br />rf.seek(rf.length());//将指针移动到文件末尾 <br />rf.writeBytes("\nAppend a line to the file!"); <br />rf.close();//关闭文件流 <br />out.println("写入文件内容为：&lt;br&gt;"); <br />FileReader fr=new FileReader(path + "\WriteData.txt"); <br />BufferedReader br=new BufferedReader(fr);//读取文件的BufferedRead对象 <br />String Line=br.readLine(); <br />while(Line!=null){ <br />out.println(Line + "&lt;br&gt;"); <br />Line=br.readLine(); <br />} <br />fr.close();//关闭文件 <br />%&gt; <br />&lt;/body&gt; <br />&lt;/html&gt;&lt;/I&gt;&lt;/I&gt;&lt;/I&gt;&lt;/I&gt; </p>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.blogjava.net/19851985lili/aggbug/93176.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/19851985lili/" target="_blank">☜♥☞MengChuChen</a> 2007-01-11 15:07 <a href="http://www.blogjava.net/19851985lili/articles/93176.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>