﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-Java Tools-随笔分类-案例</title><link>http://www.blogjava.net/simie/category/23758.html</link><description /><language>zh-cn</language><lastBuildDate>Sun, 08 Jul 2007 06:14:01 GMT</lastBuildDate><pubDate>Sun, 08 Jul 2007 06:14:01 GMT</pubDate><ttl>60</ttl><item><title>利用JAVA操作EXCEL文件</title><link>http://www.blogjava.net/simie/archive/2007/07/08/128853.html</link><dc:creator>和田雨</dc:creator><author>和田雨</author><pubDate>Sun, 08 Jul 2007 02:18:00 GMT</pubDate><guid>http://www.blogjava.net/simie/archive/2007/07/08/128853.html</guid><wfw:comment>http://www.blogjava.net/simie/comments/128853.html</wfw:comment><comments>http://www.blogjava.net/simie/archive/2007/07/08/128853.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/simie/comments/commentRss/128853.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/simie/services/trackbacks/128853.html</trackback:ping><description><![CDATA[<blockquote>使用Windows操作系统的朋友对Excel（电子表格）一定不会陌生，但是要使用Java语言来操纵Excel文件并不是一件容易的事。在Web应用日益盛行的今天，通过Web来操作Excel文件的需求越来越强烈，目前较为流行的操作是在JSP或Servlet 中创建一个CSV （comma separated values）文件，并将这个文件以MIME，text/csv类型返回给浏览器，接着浏览器调用Excel并且显示CSV文件。这样只是说可以访问到Excel文件，但是还不能真正的操纵Excel文件，本文将给大家一个惊喜，向大家介绍一个开放源码项目，Java Excel API，使用它大家就可以方便地操纵Excel文件了。</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>JAVA EXCEL API简介</span></a></p>
<p>
<p>Java Excel是一开放源码项目，通过它Java开发人员可以读取Excel文件的内容、创建新的Excel文件、更新已经存在的Excel文件。使用该API非Windows操作系统也可以通过纯Java应用来处理Excel数据表。因为是使用Java编写的，所以我们在Web应用中可以通过JSP、Servlet来调用API实现对Excel数据表的访问。</p>
<p>现在发布的稳定版本是V2.0，提供以下功能：</p>
<ul>
    <li>从Excel 95、97、2000等格式的文件中读取数据；
    <li>读取Excel公式（可以读取Excel 97以后的公式）；
    <li>生成Excel数据表（格式为Excel 97）；
    <li>支持字体、数字、日期的格式化；
    <li>支持单元格的阴影操作，以及颜色操作；
    <li>修改已经存在的数据表； </li>
</ul>
<p>现在还不支持以下功能，但不久就会提供了：</p>
<ol>
    <li>不能够读取图表信息；
    <li>可以读，但是不能生成公式，任何类型公式最后的计算值都可以读出； </li>
</ol>
<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-javaExcel/?ca=j-t10#main"><strong><font color=#996699>回页首</font></strong></a></td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<br><br>
<p><a name=2><span class=atitle>应用示例</span></a></p>
<p>
<p><a name=N10070><span class=smalltitle><strong><font face=Arial>1 从Excel文件读取数据表</font></strong></span></a></p>
<p><strong><font face=Arial></font></strong>
<p>Java Excel API既可以从本地文件系统的一个文件(.xls)，也可以从输入流中读取Excel数据表。读取Excel数据表的第一步是创建Workbook(术语：工作薄)，下面的代码片段举例说明了应该如何操作：(完整代码见ExcelReading.java)</p>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>import java.io.*;
            import jxl.*;
            &#8230; &#8230; &#8230; &#8230;
            try
            {
            //构建Workbook对象, 只读Workbook对象
            //直接从本地文件创建Workbook
            //从输入流创建Workbook
            InputStream is = new FileInputStream(sourcefile);
            jxl.Workbook rwb = Workbook.getWorkbook(is);
            }
            catch (Exception e)
            {
            e.printStackTrace();
            }
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>一旦创建了Workbook，我们就可以通过它来访问Excel Sheet(术语：工作表)。参考下面的代码片段：</p>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>//获取第一张Sheet表
            Sheet rs = rwb.getSheet(0);
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>我们既可能通过Sheet的名称来访问它，也可以通过下标来访问它。如果通过下标来访问的话，要注意的一点是下标从0开始，就像数组一样。</p>
<p>一旦得到了Sheet，我们就可以通过它来访问Excel Cell(术语：单元格)。参考下面的代码片段：</p>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>//获取第一行，第一列的值
            Cell c00 = rs.getCell(0, 0);
            String strc00 = c00.getContents();
            //获取第一行，第二列的值
            Cell c10 = rs.getCell(1, 0);
            String strc10 = c10.getContents();
            //获取第二行，第二列的值
            Cell c11 = rs.getCell(1, 1);
            String strc11 = c11.getContents();
            System.out.println("Cell(0, 0)" + " value : " + strc00 + "; type : " + c00.getType());
            System.out.println("Cell(1, 0)" + " value : " + strc10 + "; type : " + c10.getType());
            System.out.println("Cell(1, 1)" + " value : " + strc11 + "; type : " + c11.getType());
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>如果仅仅是取得Cell的值，我们可以方便地通过getContents()方法，它可以将任何类型的Cell值都作为一个字符串返回。示例代码中Cell(0, 0)是文本型，Cell(1, 0)是数字型，Cell(1,1)是日期型，通过getContents()，三种类型的返回值都是字符型。</p>
<p>如果有需要知道Cell内容的确切类型，API也提供了一系列的方法。参考下面的代码片段：</p>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>String strc00 = null;
            double strc10 = 0.00;
            Date strc11 = null;
            Cell c00 = rs.getCell(0, 0);
            Cell c10 = rs.getCell(1, 0);
            Cell c11 = rs.getCell(1, 1);
            if(c00.getType() == CellType.LABEL)
            {
            LabelCell labelc00 = (LabelCell)c00;
            strc00 = labelc00.getString();
            }
            if(c10.getType() == CellType.NUMBER)
            {
            NmberCell numc10 = (NumberCell)c10;
            strc10 = numc10.getValue();
            }
            if(c11.getType() == CellType.DATE)
            {
            DateCell datec11 = (DateCell)c11;
            strc11 = datec11.getDate();
            }
            System.out.println("Cell(0, 0)" + " value : " + strc00 + "; type : " + c00.getType());
            System.out.println("Cell(1, 0)" + " value : " + strc10 + "; type : " + c10.getType());
            System.out.println("Cell(1, 1)" + " value : " + strc11 + "; type : " + c11.getType());
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>在得到Cell对象后，通过getType()方法可以获得该单元格的类型，然后与API提供的基本类型相匹配，强制转换成相应的类型，最后调用相应的取值方法getXXX()，就可以得到确定类型的值。API提供了以下基本类型，与Excel的数据格式相对应，如下图所示：</p>
<br><br><img height=218 alt="" src="http://www.ibm.com/developerworks/cn/java/l-javaExcel/image001.jpg" width=365> <br>
<p>每种类型的具体意义，请参见Java Excel API Document。</p>
<p>当你完成对Excel电子表格数据的处理后，一定要使用close()方法来关闭先前创建的对象，以释放读取数据表的过程中所占用的内存空间，在读取大量数据时显得尤为重要。参考如下代码片段：</p>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>//操作完成时，关闭对象，释放占用的内存空间
            rwb.close();
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>Java Excel API提供了许多访问Excel数据表的方法，在这里我只简要地介绍几个常用的方法，其它的方法请参考附录中的Java Excel API Document。</p>
<p><strong>Workbook类提供的方法</strong> </p>
<p>1. int getNumberOfSheets() <br>获得工作薄（Workbook）中工作表（Sheet）的个数，示例： </p>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>jxl.Workbook rwb = jxl.Workbook.getWorkbook(new File(sourcefile));
            int sheets = rwb.getNumberOfSheets();
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>2. Sheet[] getSheets() <br>返回工作薄（Workbook）中工作表（Sheet）对象数组，示例： </p>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>jxl.Workbook rwb = jxl.Workbook.getWorkbook(new File(sourcefile));
            Sheet[] sheets = rwb.getSheets();
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>3. String getVersion() <br>返回正在使用的API的版本号，好像是没什么太大的作用。 </p>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>jxl.Workbook rwb = jxl.Workbook.getWorkbook(new File(sourcefile));
            String apiVersion = rwb.getVersion();
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p><strong>Sheet接口提供的方法</strong> </p>
<p>1) String getName() <br>获取Sheet的名称，示例： </p>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>jxl.Workbook rwb = jxl.Workbook.getWorkbook(new File(sourcefile));
            jxl.Sheet rs = rwb.getSheet(0);
            String sheetName = rs.getName();
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>2) int getColumns() <br>获取Sheet表中所包含的总列数，示例： </p>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>jxl.Workbook rwb = jxl.Workbook.getWorkbook(new File(sourcefile));
            jxl.Sheet rs = rwb.getSheet(0);
            int rsColumns = rs.getColumns();
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>3) Cell[] getColumn(int column) <br>获取某一列的所有单元格，返回的是单元格对象数组，示例： </p>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>jxl.Workbook rwb = jxl.Workbook.getWorkbook(new File(sourcefile));
            jxl.Sheet rs = rwb.getSheet(0);
            Cell[] cell = rs.getColumn(0);
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>4) int getRows() <br>获取Sheet表中所包含的总行数，示例： </p>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>jxl.Workbook rwb = jxl.Workbook.getWorkbook(new File(sourcefile));
            jxl.Sheet rs = rwb.getSheet(0);
            int rsRows = rs.getRows();
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>5) Cell[] getRow(int row) <br>获取某一行的所有单元格，返回的是单元格对象数组，示例子： </p>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>jxl.Workbook rwb = jxl.Workbook.getWorkbook(new File(sourcefile));
            jxl.Sheet rs = rwb.getSheet(0);
            Cell[] cell = rs.getRow(0);
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>6) Cell getCell(int column, int row) <br>获取指定单元格的对象引用，需要注意的是它的两个参数，第一个是列数，第二个是行数，这与通常的行、列组合有些不同。 </p>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>jxl.Workbook rwb = jxl.Workbook.getWorkbook(new File(sourcefile));
            jxl.Sheet rs = rwb.getSheet(0);
            Cell cell = rs.getCell(0, 0);
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p><a name=N10115><span class=smalltitle><strong><font face=Arial>2 生成新的Excel工作薄</font></strong></span></a></p>
<p><strong><font face=Arial></font></strong>
<p>下面的代码主要是向大家介绍如何生成简单的Excel工作表，在这里单元格的内容是不带任何修饰的(如：字体，颜色等等)，所有的内容都作为字符串写入。(完整代码见ExcelWriting.java)</p>
<p>与读取Excel工作表相似，首先要使用Workbook类的工厂方法创建一个可写入的工作薄(Workbook)对象，这里要注意的是，只能通过API提供的工厂方法来创建Workbook，而不能使用WritableWorkbook的构造函数，因为类WritableWorkbook的构造函数为protected类型。示例代码片段如下：</p>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>import java.io.*;
            import jxl.*;
            import jxl.write.*;
            &#8230; &#8230; &#8230; &#8230;
            try
            {
            //构建Workbook对象, 只读Workbook对象
            //Method 1：创建可写入的Excel工作薄
            jxl.write.WritableWorkbook wwb = Workbook.createWorkbook(new File(targetfile));
            //Method 2：将WritableWorkbook直接写入到输出流
            /*
            OutputStream os = new FileOutputStream(targetfile);
            jxl.write.WritableWorkbook wwb = Workbook.createWorkbook(os);
            */
            }
            catch (Exception e)
            {
            e.printStackTrace();
            }
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>API提供了两种方式来处理可写入的输出流，一种是直接生成本地文件，如果文件名不带全路径的话，缺省的文件会定位在当前目录，如果文件名带有全路径的话，则生成的Excel文件则会定位在相应的目录；另外一种是将Excel对象直接写入到输出流，例如：用户通过浏览器来访问Web服务器，如果HTTP头设置正确的话，浏览器自动调用客户端的Excel应用程序，来显示动态生成的Excel电子表格。</p>
<p>接下来就是要创建工作表，创建工作表的方法与创建工作薄的方法几乎一样，同样是通过工厂模式方法获得相应的对象，该方法需要两个参数，一个是工作表的名称，另一个是工作表在工作薄中的位置，参考下面的代码片段：</p>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>//创建Excel工作表
            jxl.write.WritableSheet ws = wwb.createSheet("Test Sheet 1", 0);
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>"这锅也支好了，材料也准备齐全了，可以开始下锅了！"，现在要做的只是实例化API所提供的Excel基本数据类型，并将它们添加到工作表中就可以了，参考下面的代码片段：</p>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>//1.添加Label对象
            jxl.write.Label labelC = new jxl.write.Label(0, 0, "This is a Label cell");
            ws.addCell(labelC);
            //添加带有字型Formatting的对象
            jxl.write.WritableFont wf = new jxl.write.WritableFont(WritableFont.TIMES, 18, WritableFont.BOLD, true);
            jxl.write.WritableCellFormat wcfF = new jxl.write.WritableCellFormat(wf);
            jxl.write.Label labelCF = new jxl.write.Label(1, 0, "This is a Label Cell", wcfF);
            ws.addCell(labelCF);
            //添加带有字体颜色Formatting的对象
            jxl.write.WritableFont wfc = new jxl.write.WritableFont(WritableFont.ARIAL, 10, WritableFont.NO_BOLD, false,
            UnderlineStyle.NO_UNDERLINE, jxl.format.Colour.RED);
            jxl.write.WritableCellFormat wcfFC = new jxl.write.WritableCellFormat(wfc);
            jxl.write.Label labelCFC = new jxl.write.Label(1, 0, "This is a Label Cell", wcfFC);
            ws.addCell(labelCF);
            //2.添加Number对象
            jxl.write.Number labelN = new jxl.write.Number(0, 1, 3.1415926);
            ws.addCell(labelN);
            //添加带有formatting的Number对象
            jxl.write.NumberFormat nf = new jxl.write.NumberFormat("#.##");
            jxl.write.WritableCellFormat wcfN = new jxl.write.WritableCellFormat(nf);
            jxl.write.Number labelNF = new jxl.write.Number(1, 1, 3.1415926, wcfN);
            ws.addCell(labelNF);
            //3.添加Boolean对象
            jxl.write.Boolean labelB = new jxl.write.Boolean(0, 2, false);
            ws.addCell(labelB);
            //4.添加DateTime对象
            jxl.write.DateTime labelDT = new jxl.write.DateTime(0, 3, new java.util.Date());
            ws.addCell(labelDT);
            //添加带有formatting的DateFormat对象
            jxl.write.DateFormat df = new jxl.write.DateFormat("dd MM yyyy hh:mm:ss");
            jxl.write.WritableCellFormat wcfDF = new jxl.write.WritableCellFormat(df);
            jxl.write.DateTime labelDTF = new jxl.write.DateTime(1, 3, new java.util.Date(), wcfDF);
            ws.addCell(labelDTF);
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>这里有两点大家要引起大家的注意。第一点，在构造单元格时，单元格在工作表中的位置就已经确定了。一旦创建后，单元格的位置是不能够变更的，尽管单元格的内容是可以改变的。第二点，单元格的定位是按照下面这样的规律(column, row)，而且下标都是从0开始，例如，A1被存储在(0, 0)，B1被存储在(1, 0)。</p>
<p>最后，不要忘记关闭打开的Excel工作薄对象，以释放占用的内存，参见下面的代码片段：</p>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>//写入Exel工作表
            wwb.write();
            //关闭Excel工作薄对象
            wwb.close();
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>这可能与读取Excel文件的操作有少少不同，在关闭Excel对象之前，你必须要先调用write()方法，因为先前的操作都是存储在缓存中的，所以要通过该方法将操作的内容保存在文件中。如果你先关闭了Excel对象，那么只能得到一张空的工作薄了。</p>
<p><a name=N10145><span class=smalltitle><strong><font face=Arial>3 拷贝、更新Excel工作薄</font></strong></span></a></p>
<p>接下来简要介绍一下如何更新一个已经存在的工作薄，主要是下面二步操作，第一步是构造只读的Excel工作薄，第二步是利用已经创建的Excel工作薄创建新的可写入的Excel工作薄，参考下面的代码片段：(完整代码见ExcelModifying.java)</p>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>//创建只读的Excel工作薄的对象
            jxl.Workbook rw = jxl.Workbook.getWorkbook(new File(sourcefile));
            //创建可写入的Excel工作薄对象
            jxl.write.WritableWorkbook  wwb = Workbook.createWorkbook(new File(targetfile), rw);
            //读取第一张工作表
            jxl.write.WritableSheet ws = wwb.getSheet(0);
            //获得第一个单元格对象
            jxl.write.WritableCell wc = ws.getWritableCell(0, 0);
            //判断单元格的类型, 做出相应的转化
            if(wc.getType() == CellType.LABEL)
            {
            Label l = (Label)wc;
            l.setString("The value has been modified.");
            }
            //写入Excel对象
            wwb.write();
            //关闭可写入的Excel对象
            wwb.close();
            //关闭只读的Excel对象
            rw.close();
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>之所以使用这种方式构建Excel对象，完全是因为效率的原因，因为上面的示例才是API的主要应用。为了提高性能，在读取工作表时，与数据相关的一些输出信息，所有的格式信息，如：字体、颜色等等，是不被处理的，因为我们的目的是获得行数据的值，既使没有了修饰，也不会对行数据的值产生什么影响。唯一的不利之处就是，在内存中会同时保存两个同样的工作表，这样当工作表体积比较大时，会占用相当大的内存，但现在好像内存的大小并不是什么关键因素了。</p>
<p>一旦获得了可写入的工作表对象，我们就可以对单元格对象进行更新的操作了，在这里我们不必调用API提供的add()方法，因为单元格已经于工作表当中，所以我们只需要调用相应的setXXX()方法，就可以完成更新的操作了。</p>
<p>尽单元格原有的格式化修饰是不能去掉的，我们还是可以将新的单元格修饰加上去，以使单元格的内容以不同的形式表现。</p>
<p>新生成的工作表对象是可写入的，我们除了更新原有的单元格外，还可以添加新的单元格到工作表中，这与示例2的操作是完全一样的。</p>
<p>最后，不要忘记调用write()方法，将更新的内容写入到文件中，然后关闭工作薄对象，这里有两个工作薄对象要关闭，一个是只读的，另外一个是可写入的。</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-javaExcel/?ca=j-t10#main"><strong><font color=#996699>回页首</font></strong></a></td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<br><br>
<p><a name=3><span class=atitle>小结</span></a></p>
<p>
<p>本文只是对Java Excel API中常用的方法作了介绍，要想更详尽地了解API，请大家参考API文档，或源代码。Java Excel API是一个开放源码项目，请大家关注它的最新进展，有兴趣的朋友也可以申请加入这个项目，或者是提出宝贵的意见。</p>
<br><br>
<p><a name=resources><span class=atitle>参考资料 </span></a></p>
<ol>
    <li>Java Excel API 文档
    <li><a href="http://www.andykhan.com/jexcelapi/"><font color=#996699>http://www.andykhan.com/jexcelapi/</font></a> </li>
</ol>
<br><br>
<p><a name=author><span class=atitle>关于作者</span></a></p>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td colSpan=3><img height=5 alt="" src="http://www.ibm.com/i/c.gif" width="100%"></td>
        </tr>
        <tr vAlign=top align=left>
            <td>
            <p>&#160;</p>
            </td>
            <td><img height=5 alt="" src="http://www.ibm.com/i/c.gif" width=4></td>
            <td width="100%">
            <p>就叫我Rubber吧，我是一个Java迷，希望我们能成为朋友，我的Eamil： <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#116;&#105;&#109;&#64;&#116;&#114;&#101;&#110;&#100;&#46;&#99;&#111;&#109;&#46;&#99;&#110;&#63;&#99;&#99;&#61;&#117;&#115;&#101;&#114;&#105;&#100;&#64;&#117;&#115;&#46;&#105;&#98;&#109;&#46;&#99;&#111;&#109;"><font color=#5c81a7>tim@trend.com.cn</font></a>，我的联系电话0755-83501377 </p>
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.blogjava.net/simie/aggbug/128853.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/simie/" target="_blank">和田雨</a> 2007-07-08 10:18 <a href="http://www.blogjava.net/simie/archive/2007/07/08/128853.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>对一个简单的 JDBC 包装器的扩展及应用 </title><link>http://www.blogjava.net/simie/archive/2007/07/03/127905.html</link><dc:creator>和田雨</dc:creator><author>和田雨</author><pubDate>Tue, 03 Jul 2007 09:22:00 GMT</pubDate><guid>http://www.blogjava.net/simie/archive/2007/07/03/127905.html</guid><wfw:comment>http://www.blogjava.net/simie/comments/127905.html</wfw:comment><comments>http://www.blogjava.net/simie/archive/2007/07/03/127905.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/simie/comments/commentRss/127905.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/simie/services/trackbacks/127905.html</trackback:ping><description><![CDATA[<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr vAlign=top>
            <td width="100%">
            <h1>对一个简单的 JDBC 包装器的扩展及应用</h1>
            <img class=display-img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=1></td>
            <td class=no-print width=192><img height=18 alt=developerWorks src="http://www.ibm.com/developerworks/cn/i/dw.gif" width=192></td>
        </tr>
    </tbody>
</table>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr vAlign=top>
            <td width=10><img height=1 alt="" src="http://www.ibm.com/i/c.gif" width=10></td>
            <td width="100%">
            <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="本文将对《一个简单的 JDBC 包装器》中的JDBC包装器进行一些扩展，然后介绍一下其在jsp+javabean开发模式中的应用。" name=body><input type=hidden value="对一个简单的 JDBC 包装器的扩展及应用" 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=#996699 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><a href="http://www.ibm.com/developerworks/cn/java/l-jdbcwrap/index.html#author"><font color=#996699>宗锋</font></a> (<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#122;&#111;&#110;&#103;&#95;&#102;&#101;&#110;&#103;&#64;&#50;&#54;&#51;&#46;&#110;&#101;&#116;&#63;&#115;&#117;&#98;&#106;&#101;&#99;&#116;&#61;&#23545;&#19968;&#20010;&#31616;&#21333;&#30340;&#32;&#74;&#68;&#66;&#67;&#32;&#21253;&#35013;&#22120;&#30340;&#25193;&#23637;&#21450;&#24212;&#29992;&#38;&#97;&#109;&#112;&#59;&#99;&#99;&#61;&#122;&#111;&#110;&#103;&#95;&#102;&#101;&#110;&#103;&#64;&#50;&#54;&#51;&#46;&#110;&#101;&#116;"><font color=#5c81a7>zong_feng@263.net</font></a>)西北大学计算机系硕士<br></p>
            <p>2001 年 12 月 16 日</p>
            <blockquote>本文将对 <a href="http://www.ibm.com/developerworks/cn/java/j-jdbcwrap/index.html"><font color=#996699>《一个简单的 JDBC 包装器》</font></a>中的JDBC包装器进行一些扩展，然后介绍一下其在jsp+javabean开发模式中的应用。 </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 href="http://www.ibm.com/developerworks/cn/java/j-jdbcwrap/index.html"><font color=#996699>《一个简单的 JDBC 包装器》</font></a>，觉得这篇文章很有应用价值，我便在自己的开发中使用了它，不过这个包装器也存在一些不足，于是我对它进行了一些扩展。首先原文中的Table类缺少删除功能，我便增加了删除功能。代码如下：
            <table cellSpacing=0 cellPadding=0 width=550 border=0>
                <tbody>
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>public void delRow(Row row) throws SQLException {
                        String ss="";
                        ss = "delete from "+name+" where ";
                        for (int i=0; i&lt;row.length(); ++i) {
                        String k = row.getKey( i );
                        String v = row.get( i );
                        ss += k+"='"+v+"'";
                        if (i != row.length()-1)
                        ss += " and ";
                        }
                        Connection con = database.getConnection();
                        Statement st = con.createStatement();
                        st.executeUpdate( ss );
                        }
                        public void delRow(String conditions)throws SQLException {
                        String ss="";
                        ss = "delete from "+name+" where ";
                        ss +=conditions;
                        Connection con = database.getConnection();
                        Statement st = con.createStatement();
                        st.executeUpdate( ss );
                        }</pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br></p>
            <p>这两个函数分别用于删除一个Row和满足一定条件的记录。对于具有主关键字的表，我们可以用下面代码中的方法二来进行删除，如果没有主关键字，我们可以用方法一删除。</p>
            <p>示例如下：
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>//方法一
                        Row e = table.getRow( "id=2001" );
                        table.delRow(e);
                        //方法二
                        table.delRow("id=2001");
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br></p>
            <p>另外这个包装器没有对查询结果为NULL的情况作处理，我通过修改Table类的execute函数和RowSet类的get函数对这种情况作了处理。具体代码见附件。</p>
            <p>下面谈谈利用这个JDBC包装器实现对数据库的封装，假定我们有一个表:student，创建表的Sql语句如下：
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>create table student(
                        id varchar(10) not null primary key,
                        name varchar(16) not null,
                        sex char(2) not null,
                        password varchar(16) not null,
                        department varchar(32) not null
                        )</pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br></p>
            <p>我们对这个表进行封装，下面是Student类的主要代码：
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>public class Student{
                        private Row r;
                        public Student() {
                        r=new Row();
                        }
                        public Student(Row row) {
                        this.r=row;
                        }
                        private Table getTable() {
                        Database db =
                        new Database( "jdbc:mysql://localhost:3306/manger",
                        "zf", "zf" );
                        return db.getTable("student");
                        }
                        public void setName(String name){
                        r.put("name",name);
                        }
                        public void setPassword(String pass){
                        r.put("password",pass);
                        }
                        public void setId(String number){
                        r.put("id",number);
                        }
                        public void setDepart(String depart){
                        r.put("department",depart);
                        }
                        public void setSex(String sex){
                        r.put("sex",sex);
                        }
                        public String getName(){
                        return r.get("name");
                        }
                        public String getPassword(){
                        return r.get("password");
                        }
                        public String getId(){
                        return r.get("id");
                        }
                        public String getDepart(){
                        return r.get("department");
                        }
                        public String getSex(){
                        return r.get("sex");
                        }
                        /**
                        *condition表示限制条件，如果为空，则插入新记录，否则更新记录
                        */
                        public void save(String conditions) throws SQLException{
                        if(conditions==null)
                        {getTable().putRow(r);}
                        else
                        getTable().putRow(r,conditions);
                        }
                        /**
                        *由于id作为主关键字，所以我们使用字符串为参数的delRow()函数
                        */
                        public void delete()throws SQLException{
                        //getTable().delRow(this.r);
                        String conditions="";
                        conditions = "id=" + "'"+getId()+"'";
                        getTable().delRow(conditions);
                        }
                        }</pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br></p>
            <p>下面这个类是相应的一个查询类的主要代码：
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>public class StudentFactory{
                        public static Student findStudentById(String id)
                        throws SQLException{
                        Row r=getTable().getRow("id="+id);
                        if(r==null)
                        return null；
                        else
                        return new Student(r);
                        }
                        public static Student[] findAllStudents()
                        throws SQLException{
                        RowSet rs=getTable().getRows("1&gt;0");
                        if (rs==null)
                        return null;
                        else
                        Student[] stu=null;
                        stu=new Student[rs.length()];
                        for(int i=0;i&lt;rs.length(); i++){
                        stu[i]=new Student(rs.get(i));
                        }
                        return stu;
                        }
                        }</pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br></p>
            <p>我使用javabean来实现很多功能，这样可以减少在jsp中的java代码量，方便我们对界面的改进。我们要实现的功能为对学生的编辑，添加，删除和列表。这些功能定义在两个javabean中：下面是两个jsp文件的主要代码：
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>&lt;%-- student.jsp --%&gt;
                        &lt;%@ page contentType="text/html;charset=GB2312" %&gt;
                        &lt;%@ page import="org.gjt.mm.mysql.*,manger.bean.*,manger.tools.*,manger.business.*" %&gt;
                        &lt;html&gt;
                        &lt;head&gt;
                        &lt;SCRIPT TYPE="text/javascript" LANGUAGE="JavaScript" &gt;
                        &lt;!--
                        function doDelete()
                        {
                        if(confirm('你确定删除吗?')) {
                        document.EditForm.event.value='delete';
                        document.EditForm.submit();
                        }
                        }
                        function doEdit()
                        {
                        if(confirm('你确定编辑吗?')) {
                        document.EditForm.event.value='showEdit';
                        document.EditForm.submit();
                        }
                        }
                        function showAddPage()
                        {
                        document.location='editstudent.jsp?event=showAdd';
                        }
                        &lt;/SCRIPT&gt;
                        &lt;/head&gt;
                        &lt;body bgcolor="#FFFFFF" text="#000000"&gt;
                        &lt;%
                        try {
                        Class.forName("org.gjt.mm.mysql.Driver").newInstance();
                        }
                        catch (Exception E) {
                        out.println("Unable to load driver.");
                        } %&gt;
                        &lt;jsp:useBean id="table" scope="page" class="manger.bean.ListStudentBean" /&gt;
                        &lt;%
                        Student[] student=table.getStudent(pageContext);
                        int total=0;
                        int currPage=table.getCurPage();
                        int pageCount=table.getPageCount();
                        if(student!=null)
                        {total=student.length;}%&gt;
                        &lt;FORM NAME="EditForm" ACTION="editstudent.jsp"&gt;
                        &lt;INPUT TYPE="HIDDEN" NAME="event" VALUE=""&gt;
                        &lt;table width="75%" border="1"&gt;
                        &lt;tr&gt;
                        &lt;td colspan="5"&gt;学生列表&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                        &lt;td&gt;学号&lt;/td&gt;
                        &lt;td&gt;姓名&lt;/td&gt;
                        &lt;td&gt;班级&lt;/td&gt;
                        &lt;td&gt;备注一&lt;/td&gt;
                        &lt;td&gt;选择&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;%for (int i=0;i&lt;total;i++){
                        Student current=student[i];%&gt;
                        &lt;tr&gt;
                        &lt;td&gt;&lt;%=current.getId()%&gt;&lt;/td&gt;
                        &lt;td&gt;&lt;%=current.getName()%&gt;&lt;/td&gt;
                        &lt;td&gt;&lt;%=current.getDepart()%&gt;&lt;/td&gt;
                        &lt;td&gt;&lt;%=current.getSex() %&gt;&lt;/td&gt;
                        &lt;td&gt;
                        &lt;input type="checkbox" name="id" value=&lt;%=current.getId()%&gt;&gt;
                        &lt;/td&gt;
                        &lt;% } %&gt;
                        &lt;/tr&gt;&lt;tr&gt;
                        &lt;td colspan="5"&gt;
                        &lt;INPUT TYPE="BUTTON" onclick="doEdit();" VALUE="编辑"&gt;
                        &lt;INPUT TYPE="BUTTON" onclick="showAddPage()" VALUE="增加"&gt;
                        &lt;INPUT TYPE="BUTTON" onclick="doDelete();" VALUE="删除"&gt;
                        &lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;/table&gt;
                        &lt;/form&gt;
                        &lt;/html&gt;</pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br></p>
            <p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>&lt;%-- studentedit.jsp --%&gt;
                        &lt;jsp:useBean id="table" scope="page" class="manger.bean.EditStudentBean" /&gt;
                        &lt;%table.processRequest(pageContext);%&gt;
                        &lt;p&gt;_lt;/p&gt;
                        &lt;form name="EditForm" action="editstudent.jsp"&gt;
                        &lt;INPUT TYPE="hidden" NAME="event" VALUE="&lt;%=table.getEvent()%&gt;" &gt;
                        &lt;table width="75%" border="1"&gt;
                        &lt;tr&gt;
                        &lt;td colspan="2"&gt;
                        &lt;div align="center"&gt;&lt;b&gt;编辑学生信息&lt;/b&gt;&lt;/div&gt;
                        &lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                        &lt;td width="40%"&gt;学号：&lt;/td&gt;
                        &lt;td width="60%"&gt;
                        &lt;input type="text" name="id" value="&lt;%=table.getStudent().getId()%&gt;"&gt;
                        &lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;%--下面的一些学生信息我们省略了--%&gt;
                        &lt;tr&gt;
                        &lt;td colspan="2"&gt;
                        &lt;input type="submit" name="Submit" value="确定"&gt;
                        &lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;/table&gt;
                        &lt;/form&gt;
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br></p>
            <p>我的想法是在student.jsp中显示学生列表，从这个页面可以转到增加和编辑页面，也可以在这个页面中删除学生，这三个功能都是由editstudent.jsp完成的。在editstudent.jsp中非常关键的一行代码就是&lt;%table.processRequest(pageContext);%&gt;，这会调用EditStudentBean类的processRequest方法：下面是EditStudentBean类processRequest方法和addStudent方法的代码:
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>public void processRequest (PageContext pageContext)
                        throws SQLException,ServletException,IOException{
                        this.student.setId("");
                        this.student.setName("");
                        this.student.setPassword("");
                        this.student.setDepart("");
                        this.student.setSex("");
                        HttpServletRequest request=(HttpServletRequest)pageContext.getRequest();
                        String event=request.getParameter("event");
                        //this.event=event;
                        if(event==null || event.equals("")||event.equals("showAdd"))
                        {this.event="add";
                        }
                        else if(event.equals("showEdit"))
                        {this.event="edit";
                        String id=request.getParameter("id");
                        Student stu=StudentFactory.findStudentById(id);
                        this.student=stu;
                        }
                        else if(event.equals("add"))
                        {this.addStudent(pageContext);
                        }
                        else if(event.equals("delete"))
                        {this.deleteStudent(pageContext);
                        }
                        else if(event.equals("edit"))
                        {this.editStudent(pageContext);
                        }
                        }
                        public void addStudent(PageContext page)
                        throws SQLException,ServletException,IOException{
                        HttpServletRequest request=(HttpServletRequest)page.getRequest();
                        HttpServletResponse response=(HttpServletResponse)page.getResponse();
                        JspWriter out=page.getOut();
                        String id=request.getParameter("id");
                        String name=request.getParameter("name");
                        String sex=request.getParameter("sex");
                        String pass=request.getParameter("password");
                        String depart=request.getParameter("depart");
                        if (id!=null&amp;&amp;name!=null&amp;&amp;sex!=null&amp;&amp;pass!=null&amp;&amp;depart!=null
                        &amp;&amp;!id.equals("")&amp;&amp;!name.equals("")&amp;&amp;!sex.equals("")&amp;&amp;!pass.equals("")&amp;&amp;!depart.equals(""))
                        {Student s=new Student();
                        s.setId(id);
                        s.setName(name);
                        s.setSex(sex);
                        s.setPassword(pass);
                        s.setDepart(depart);
                        s.save(null);
                        response.sendRedirect("student.jsp");
                        }
                        else
                        {out.print("请添完所有信息");
                        }
                        }</pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br></p>
            <p>processRequest方法的功能主要为获取提交给editstudent.jsp的event的值，根据不同的event调用不同的函数。例如event=add，则调用addStudent函数。</p>
            <p>注意：在设置Student对象的各个属性值时，一定要按照表(见上面的SQL语句)中顺序来设置，例如在表中,id字段在name字段的前面，所以setId方法在setName方法前面，这主要是由于Table类中的putRow函数中执行插入操作的SQL语句有缺陷。在那个SQL语句中，它是按各属性在Row中的顺序来执行插入操作的。如过你不愿意按表中字段的顺序来设置Student的属性，可以对putRow函数更改如下：
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>String ss = "";
                        if (conditions==null) {
                        ss = "INSERT INTO "+name+'(";
                        for (int i=0;i&lt;row.length();++i) {
                        String k = row.getKey( i );
                        ss += k;
                        if (i != row.length()-1)
                        ss += ", ";
                        }
                        ss +=") VALUES (";
                        for (int j=0; j&lt;row.length(); ++j) {
                        String v = row.get( j );
                        ss += "'"+v+"'";
                        if (j != row.length()-1)
                        ss += ", ";
                        }
                        ss += ")";
                        }</pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br></p>
            <p>限于篇幅，我省略了student.jsp文件中的一些内容，对这个jsp文件进行处理的bean为ListStudentBean，这个类主要实现一个函数getStudent，这个函数主要通过StudentFactory查寻到所有的学生，由于我在此函数中进行了分页处理，因此此函数只返回当前页需要的Student数组。具体的代码参看 <a href="http://www.ibm.com/developerworks/cn/java/l-jdbcwrap/jdbc.zip"><font color=#5c81a7>附件</font></a>。 </p>
            <p>总之，我改进之后的这个JDBC封装器还是比较有效的，它能满足一般地需要，当然你也可以根据你的情况对其进行扩充，以更好地适应你的开发。</p>
            <p>代码在Tomcat4.01+mysql3.23.43下测试通过。</p>
            <br><br>
            <p><a name=author><span class=atitle>关于作者</span></a></p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td colSpan=3><img height=5 alt="" src="http://www.ibm.com/i/c.gif" width="100%"></td>
                    </tr>
                    <tr vAlign=top align=left>
                        <td>
                        <p>&#160;</p>
                        </td>
                        <td><img height=5 alt="" src="http://www.ibm.com/i/c.gif" width=4></td>
                        <td width="100%">
                        <p>宗锋，男，西北大学计算机系硕士。兴趣主要集中在：java，linux，enhydra，barracuda。希望能与有共同爱好的朋友进行交流。E-mail: <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#122;&#111;&#110;&#103;&#95;&#102;&#101;&#110;&#103;&#64;&#50;&#54;&#51;&#46;&#110;&#101;&#116;&#63;&#99;&#99;&#61;&#122;&#111;&#110;&#103;&#95;&#102;&#101;&#110;&#103;&#64;&#50;&#54;&#51;&#46;&#110;&#101;&#116;"><font color=#5c81a7>zong_feng@263.net</font></a>. </p>
                        </td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.blogjava.net/simie/aggbug/127905.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/simie/" target="_blank">和田雨</a> 2007-07-03 17:22 <a href="http://www.blogjava.net/simie/archive/2007/07/03/127905.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一个简单的 JDBC 包装器 </title><link>http://www.blogjava.net/simie/archive/2007/07/03/127902.html</link><dc:creator>和田雨</dc:creator><author>和田雨</author><pubDate>Tue, 03 Jul 2007 09:16:00 GMT</pubDate><guid>http://www.blogjava.net/simie/archive/2007/07/03/127902.html</guid><wfw:comment>http://www.blogjava.net/simie/comments/127902.html</wfw:comment><comments>http://www.blogjava.net/simie/archive/2007/07/03/127902.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/simie/comments/commentRss/127902.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/simie/services/trackbacks/127902.html</trackback:ping><description><![CDATA[<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr vAlign=top>
            <td width="100%">
            <h1>一个简单的 JDBC 包装器</h1>
            <p id=subtitle>一种简单程序的快速数据访问解决方案</p>
            <img class=display-img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=1></td>
            <td class=no-print width=192><img height=18 alt=developerWorks src="http://www.ibm.com/developerworks/cn/i/dw.gif" width=192></td>
        </tr>
    </tbody>
</table>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr vAlign=top>
            <td width=10><img height=1 alt="" src="http://www.ibm.com/i/c.gif" width=10></td>
            <td width="100%">
            <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="JDBC 提供了一种强大、全面的接口用来从 Java 程序访问数据库。对于较小的项目来说，使用 JDBC 似乎是理所当然的，它使一些程序员避免了一起使用数据库。本文描述了一种简单的包装器库，它让使用简单的数据库易如反掌。您会发现您已经开始想在编写的每一个程序中都使用 JDBC。" name=body><input type=hidden value="一个简单的 JDBC 包装器" 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=#996699 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><a href="http://www.ibm.com/developerworks/cn/java/j-jdbcwrap/index.html#author"><u><font color=#996699>Greg Travis</font></u></a> (<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#109;&#105;&#116;&#111;&#64;&#112;&#97;&#110;&#105;&#120;&#46;&#99;&#111;&#109;&#63;&#115;&#117;&#98;&#106;&#101;&#99;&#116;&#61;&#19968;&#20010;&#31616;&#21333;&#30340;&#32;&#74;&#68;&#66;&#67;&#32;&#21253;&#35013;&#22120;&#38;&#97;&#109;&#112;&#59;&#99;&#99;&#61;&#109;&#105;&#116;&#111;&#64;&#112;&#97;&#110;&#105;&#120;&#46;&#99;&#111;&#109;"><u><font color=#5c81a7>mito@panix.com</font></u></a>), 自由程序员<br></p>
            <p>2001 年 8 月 04 日</p>
            <blockquote>JDBC 提供了一种强大、全面的接口用来从 Java 程序访问数据库。对于较小的项目来说，使用 JDBC 似乎是理所当然的，它使一些程序员避免了一起使用数据库。本文描述了一种简单的包装器库，它让使用简单的数据库易如反掌。您会发现您已经开始想在编写的每一个程序中都使用 JDBC。</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>事情发生得很突然。您正在修改一个程序，您原以为它是个小程序，不料竟发现它已经迅速增长成为一个庞大的东西 ― 一个 <em>项目</em>― 而现在您已到了需要保存一些数据的时候了。 </p>
            <p>问题是，您并不是有意让程序发展到这种程度的。 您只是不由自主地做了一小部分修改。您并没有真正准备要存储或装入。而且，您的程序是个 applet，而 applet 是无法存储或装入的。</p>
            <p>可以存储或装入它们吗？</p>
            <p>实际上，JDBC API 允许任何 Java 程序 ― 甚至是 applet ― 连接到关系型数据库（RDBMS）上。 不幸的是，JDBC 对您的小程序来说可能有一点头重脚轻了。毕竟，如果您希望做的只是存储一点点数据的话，RDBMS 是一个强大、复杂的系统。</p>
            <p>在本文中，我们将分析一个简单的使用 JDBC 的抽象层。对于简单的应用程序来说，它可以让您只用几行代码就实现存储和装入结构化数据。它不会处理复杂的 RDBMS 使用，但那正是我们要避免的，不是吗？</p>
            <a name=complex>
            <p><a name=h4069><span class=atitle>JDBC 的复杂性</span></a></p>
            <p>JDBC 使用起来可能是一个复杂的 API。它不仅必须支持整个强大的 SQL 标准，还必须很好地隐藏不同数据库引擎之间的区别。</p>
            <p>JDBC 的复杂还在于关系型数据库是基于 SQL 构建的，而 SQL 是要给人用的，而不是给程序用的。直接使用 JDBC 有点象同时用两种语言编程。</p>
            <p>虽然 JDBC 的这些方面并不是什么坏事，但它们确实与我们的目标 ― 快速地存储少量数据相冲突。</p>
            <a name=simplify><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/j-jdbcwrap/index.html#main"><strong><font color=#996699>回页首</font></strong></a></td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br><br>
            <p><a name=h4750><span class=atitle>简化的抽象</span></a></p>
            <p>我们将创建一个简单的抽象层，让您不必顾虑所有繁琐的细节问题来直接使用 JDBC。如果您早已熟悉 JDBC 或关系型数据库了，那您一眼看到我们的类列表应该是很熟悉的：</p>
            <ul>
                <li><code>Database</code>
                <li><code>Table</code>
                <li><code>RowSet</code>
                <li><code>Row</code> </li>
            </ul>
            <p>我们这里不是在作任何实质性的事情；我们的数据模型本质上和关系型模型是一样的，但去掉了烦人的细节（同时去掉了强大的功能）。每一个类映射到一个基本的 RDBMS 概念上，同时也映射到一个 JDBC 类上。就是这种映射让我们的 API 可以在保持易用性的同时保留它的相关特性。</p>
            <p>这种 API 的设计是基于对我们的数据存储需要的设想。如果您发现自己的程序需要一点不同的地方，您可以随意地改变这种抽象以适应您的情况。 这些类可以被认为是一种简化您工作的模式，而不是一成不变的规则。</p>
            <p>如果您不熟悉 SQL 或者 RDBMS 技术，不必害怕。 下面的四节中，每一节都会帮助您熟悉我们的一个类，还有这些类映射到的 RDBMS 功能。</p>
            <p><a name=N10094><span class=smalltitle><strong><font face=Arial>Database 类</font></strong></span></a></p>
            <p>当使用 JDBC 与数据库建立连接时，您必须告诉 JDBC 在何处可以找到实际的数据。 因为不同的数据库引擎有不同的访问方法和描述这些方法的不同语法，所以有不止一种方法来指定数据源。 在 JDBC 中，统一资源标识符（Uniform Resource Identifier，URI）字符串是用来指定数据源的，而这个字符串的结构是依赖于数据库的。</p>
            <p><code>Database</code> 类的主要目的就是封装这个字符串，还有建立连接操作时可能需要的任何用户名／密码信息。 </p>
            <p>下面是如何创建一个 <code>Database</code> 对象的方法： </p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>  Database db =
                        new Database( "jdbc:postgresql://localhost/mito",
                        "mito", "" );
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>构造函数的第一个参数是数据源的 URI。 在这个示例中，我使用了 <em>PostgreSQL</em>数据库引擎，而且在本机上访问了一个名为 mito 的数据库。 另外，我指定我的用户名 mito 和一个空的密码分别作为第二个和第三个参数。 </p>
            <p>一旦您创建了 <code>Database</code> 对象，您就可以使用它来访问数据，如我们在下一章可以看到的一样。 </p>
            <p><a name=N100BC><span class=smalltitle><strong><font face=Arial>Table 类</font></strong></span></a></p>
            <p>我们在 API 中对简化的一个设想就是，当您从表的一行读取数据时，您会得到整行的数据。换句话说，表的一行是作为读写单独一块数据的最小单位。这并不十分有效，但效率不是我们方法中所首要考虑的。</p>
            <p><code>Talbe</code> 类让您可以读写这些行对象。您必须做的第一步是创建一个表对象，它简单得只要知道它的名称即可： </p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>  Table table = db.getTable( "employee" );
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>创建 <code>Table</code> 对象的操作实际上并没有做任何事，只是让对象记住自己的名称。要做一些实际的事，我们就需要实际地使用这个 Table 对象了。在这里，我们从表中读取一行。 </p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>  Row row = table.getRow( "id=101");
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>注意，我们已经指定了我们只需要那些&#8216;id&#8217;值设定为&#8216;101&#8217;的行。通过使用 <code>getRow()</code> 方法，我们假定只有一行符合这个条件。在另外的情况下，我们可能需要多个行，那样我们就需要这样使用 <code>getRows()</code> 方法： </p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>  RowSet rows = table.getRows( "id&lt;103" );
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>在这种情况下,返回的值是一个 <code>RowSet</code> ，而不是一个 Row。 <code>RowSet</code> 就是 Row 的一个集合。 </p>
            <p>在接下来的两节里，我们将讨论 <code>Row</code> 和 <code>RowSet</code> 类。 </p>
            <p><a name=N10100><span class=smalltitle><strong><font face=Arial>Row 类</font></strong></span></a></p>
            <p>在我们的抽象中， <code>Row</code> 是在 RDBMS 中表示表中一行的名称／值对的集合。不同于 RDBMS 值可以是不同的类型， <code>Row</code> 仅包含一种类型，即字符串类型。 这还是为了让事情简单一点 ― 我们假定您不需要字符串类型提供的任何更强大的功能。 </p>
            <p>一旦您有了一个 <code>Row</code> ，就很容易从其中取出一个值，正如我们在清单 1 中看见的一样。 </p>
            <br><br><a name=listing1><strong>L清单 1. 从 Row 中获取值 </strong></a><br>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>  Row e = table.getRow( "id=100" );
                        String name = e.get( "name" );
                        System.out.println( "Employee name: "+name );
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>还要注意的是 <code>Row</code> 是排序的，这样您就可以通过索引来取出名称／值的对。清单 2 中给出了这样的一个示例。 </p>
            <br><br><a name=listing2><strong>清单 2. 迭代整个 Row </strong></a><br>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>  Row e = table.getRow( "id=100" );
                        for (int i=0; i&lt;e.length(); ++i) {
                        String key = e.getKey( i );
                        String value = e.get( i );
                        System.out.println( key+" = "+value );
                        }
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>当然，您还可以改变 <code>Row</code> 中的值。这是在数据库中更改数据所必需的 — 稍后我们会看到这一点。 </p>
            <p><a name=N10142><span class=smalltitle><strong><font face=Arial>RowSet 类</font></strong></span></a></p>
            <p>记住有一些查询可以返回多个 <code>Row</code> ，这样的话您就会得到一个 <code>RowSet</code> 。 <code>RowSet</code> 有一点不同于基于 Vector 的包装器。你可以轻易地迭代 <code>RowSet</code> 中所有的 <code>Row</code> ，在清单 3 中可以看到这一点。 </p>
            <br><br><a name=listing3><strong>清单 3. 迭代整个 RowSet </strong></a><br>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>  RowSet rs = table.get( "id&lt;104" );
                        for (int i=0; i&lt;rs.length(); ++i) {
                        Row row = rs.get( i );
                        // do something with the row....
                        }
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p><a name=N1016D><span class=smalltitle><strong><font face=Arial>一个完整的示例</font></strong></span></a></p>
            <p>现在我们已经看过了所有的类，让我们来看一个完整的示例吧。在清单 4 中，我们将抽取出符合特定条件的一套记录，然后打印出它们的值。</p>
            <br><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>    // First, get all rows meeting the criterion
                        RowSet rs = table.getRows( "id&lt;103" );
                        // Iterate through the set
                        for (int i=0; i&lt;rs.length(); ++i) {
                        // Grab each row in turn
                        Row row = rs.get( i );
                        // Get and print the value of the "name" field
                        String name = row.get( "name" );
                        System.out.println( "Name: "+name );
                        }
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>如此容易！在下一节中，我们将看看怎样向数据库写入数据。</p>
            <a name=modifying><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/j-jdbcwrap/index.html#main"><strong><font color=#996699>回页首</font></strong></a></td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br><br>
            <p><a name=h12852><span class=atitle>修改数据</span></a></p>
            <p>正如前面所提到的，使用我们的 API 读写数据是以整个 <em>行</em>为单位的。为了向数据库写入数据，您必须创建（或修改） <code>Row</code> 对象，然后向数据库写入那个 <code>Row</code> 对象。 </p>
            <p>向数据库写入数据是通过使用 <code>Table</code> 中的 <code>putRow</code> 方法。这种方法有两种变体： </p>
            <ul>
                <li><code>public void putRow( Row row )</code>
                <li><code>public void putRow( Row row, String conditions )</code> </li>
            </ul>
            <p>这两种变体分别对应于 SQL 中的 <code>INSERT</code> 和 <code>UPDATE</code> 命令。 </p>
            <p>在第一个变体中，写一行意味着将一个全新的行插入表中。</p>
            <p>在第二个变体中，写一行意味着修改一个现有的行。 <code>conditions</code> 参数使您能够指定您想要修改的是哪一行（哪些行）。 </p>
            <p>让我们来看看每种方法的一个示例。</p>
            <p><a name=N101CE><span class=smalltitle><strong><font face=Arial>插入一个新行</font></strong></span></a></p>
            <p>插入一个新行很简单，因为您不必指定要修改的行（一行或多行）。您只是简单地把行插入：</p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>  table.putRow( row );
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>您可以重新创建一个 <code>Row</code> ，如清单 5 所示。 </p>
            <br><br><a name=listing5><strong>清单 5. 重新创建一个 Row </strong></a><br>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>  // Create an empty row object
                        Row row = new Row();
                        // Fill it up with data
                        row.put( "id", "200" );
                        row.put( "name", "Joey Capellino" );
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>或者，您可以修改一个以前曾经从数据库中读取的一个现有的行，如清单 6 所示。</p>
            <br><br><a name=listing6><strong>清单 6. 修改现有的 Row </strong></a><br>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>  // Grab a row from the database
                        Row row = table.getRow( someConditions );
                        // Change some or all of the fields
                        row.put( "name", "Joey Capellino" );
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>虽然通常是在插入时重新创建 <code>Row</code> ，更新时使用现有的 <code>Row</code> ，实际上您可以用任何方式来进行。 </p>
            <p><a name=N1020C><span class=smalltitle><strong><font face=Arial>更新现有的行</font></strong></span></a></p>
            <p>正如前面的部分提到的，对于您如何 <em>创建</em>用来更新的 <code>Row</code> 是没有限制的。 但是，通常您是使用一个刚从数据库中读出的 <code>Row</code> 。 </p>
            <p>为了详细描述这一点，我们将使用一个示例（在该例子中我们读出一个员工的姓名），改变这个名字，然后将更改后的结果写回数据库，如清单 7 所示。</p>
            <br><br><a name=listing7><strong>清单 7. 通过修改 Row 进行更新 </strong></a><br>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>    Row row = table.getRow( "id=104" );
                        row.put( "name", newName );
                        table.putRow( row, "id=104" );
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>注意我们必须在调用 <code>putRow()</code> 中指定条件。这样才会使调用成为 <em>更新</em>，而不是 <em>插入</em>。 </p>
            <p>注意，这个调用将更新 <em>所有</em>符合条件的行，而不是其中的一行。 </p>
            <a name=conclusion><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/j-jdbcwrap/index.html#main"><strong><font color=#996699>回页首</font></strong></a></td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br><br>
            <p><a name=h16647><span class=atitle>结论</span></a></p>
            <p>在本文中，我们初步认识了一种通过 JDBC 包提供一种简化的通往关系型数据库接口的 API。这种抽象保留了 JDBC 接口的很多基本关系型功能，但对其进行了简化，从而让使用非常地方便。这种简化是以效率为代价的，但当目标是简单性时，这并不是一个令人惊奇的结果。</p>
            <br><br>
            <p><a name=resources><span class=atitle>参考资料 </span></a></p>
            <ul>
                <li>您可以参阅本文在 developerWorks 全球站点上的 <a href="http://www.ibm.com/developerworks/library/j-jdbcwrap/index.html?S_TACT=105AGX52&amp;S_CMP=cn-a-j"><u><font color=#5c81a7>英文原文</font></u></a>. <br><br>
                <li>参加本文的 <a href="javascript:void forumWindow()"><u><font color=#5c81a7>讨论论坛</font></u></a>。 <br><br>
                <li>下载本文中讨论的类的全部资料：
                <ul>
                    <li><a href="http://www.ibm.com/developerworks/cn/java/j-jdbcwrap/sidedatabasejava.html"><u><font color=#996699>Database.java</font></u></a>
                    <li><a href="http://www.ibm.com/developerworks/cn/java/j-jdbcwrap/sidetablejava.html"><u><font color=#5c81a7>Table.java</font></u></a>
                    <li><a href="http://www.ibm.com/developerworks/cn/java/j-jdbcwrap/siderowsetjava.html"><u><font color=#5c81a7>RowSet.java</font></u></a>
                    <li><a href="http://www.ibm.com/developerworks/cn/java/j-jdbcwrap/siderowjava.html"><u><font color=#5c81a7>Row.java</font></u></a> </li>
                </ul>
                <br>
                <li><a href="http://java.sun.com/products/jdbc/learning.html"><u><font color=#5c81a7>JDBC 学习中心</font></u></a>包含许多教程的链接。 <br><br>
                <li>阅读 <a href="http://java.sun.com/j2se/1.3/docs/guide/jdbc/index.html"><u><font color=#5c81a7>JDBC 文档页</font></u></a>可以获得很多有用的文档的链接。 <br><br>
                <li>您可以在 Amazon 购买 <a href="http://www.amazon.com/exec/obidos/ASIN/0201433281/javasoftsunmicroA"><u><font color=#5c81a7>《JDBC API 教程和参考大全》，第 2 版</font></u></a>，或者只是 <a href="http://java.sun.com/docs/books/jdbc/index.html"><u><font color=#5c81a7>阅读它</font></u></a>。 <br><br>
                <li><a href="http://www.iam.unibe.ch/~scg/Archive/Software/FreeDB/FreeDB.list.html"><u><font color=#5c81a7>免费数据库清单</font></u></a>包含许多免费 RDBMS 软件包的链接，您可以在启用 JDBC 的程序的服务器端使用。 <br><br>
                <li>本文中的代码已经在 <a href="http://www.postgresql.org/"><u><font color=#5c81a7>PostgreSQL</font></u></a>数据库引擎上通过了测试。 <br><br>
                <li>在 <a href="http://www.ibm.com/developerworks/cn/java/j-jdbcnew/index.html"><u><font color=#5c81a7>&#8220;JDBC 3.0 中有什么新内容&#8221;</font></u></a>（developerWorks，2001 年 7 月）中，Josh Heidebrecht 向我们介绍了 JDBC 最新的修正情况。 <br><br>
                <li>在 <a href="http://www.ibm.com/developerworks/java/library/j-spejb/index.html?S_TACT=105AGX52&amp;S_CMP=cn-a-j"><u><font color=#5c81a7>&#8220;将 RDBMS 存储过程作为 session EJB 组件的方法来封装&#8221;</font></u></a>（developerWorks，2000 年 10 月）中学习如何通过 Enterprise JavaBeans 来调用旧的存储过程。 <br><br>
                <li>阅读 <a href="http://www.ibm.com/developerworks/java/library/co-tipdiv.html?S_TACT=105AGX52&amp;S_CMP=cn-a-j"><u><font color=#5c81a7>&#8220;对象－数据分离和 EJB&#8221;</font></u></a>（developerWorks，2001 年 4 月），就能知道面向对象和面向数据的开发人员的分离是怎样产生的了。然后阅读接下来的文章 <a href="http://www.ibm.com/developerworks/java/library/co-tipdiv2.html?S_TACT=105AGX52&amp;S_CMP=cn-a-j"><u><font color=#5c81a7>&#8220;在您的 EBJ 项目上克服对象－数据分离&#8221;</font></u></a>（developerWorks，2001 年 4 月），看看您能对它做什么。 <br><br>
                <li>开发人员在选择数据库时应该注重什么功能？这个问题可以参阅 <a href="http://www.ibm.com/developerworks/java/library/z-dbpick.html?S_TACT=105AGX52&amp;S_CMP=cn-a-j"><u><font color=#5c81a7>&#8220;选择数据库管理系统&#8221;</font></u></a>（developerWorks，2001 年 7 月）。 <br><br>
                <li>在 <a href="http://www.ibm.com/developerworks/cn/java/index.html"><u><font color=#5c81a7>developerWorks Java 技术专区</font></u></a>寻找更多 Java 参考资料。 <br></li>
            </ul>
            <br><br>
            <p><a name=author><span class=atitle>关于作者</span></a></p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td colSpan=3><img height=5 alt="" src="http://www.ibm.com/i/c.gif" width="100%"></td>
                    </tr>
                    <tr vAlign=top align=left>
                        <td>
                        <p>&#160;</p>
                        </td>
                        <td><img height=5 alt="" src="http://www.ibm.com/i/c.gif" width=4></td>
                        <td width="100%">
                        <p>Greg Travis 是居住在纽约的一个自由程序员。他对计算机的兴趣可能是源于&#8220; Bionic Woman&#8221;中的一段情节 － Jamie 四处奔跑，试图逃离一所灯光和门都被邪恶的人工智能所控制的房子，人工智能还通过扬声器嘲笑她。他是一个传统观念的虔诚信徒 － 如果一个计算机程序能够工作，那完全是个巧合。可以通过 <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#109;&#105;&#116;&#111;&#64;&#112;&#97;&#110;&#105;&#120;&#46;&#99;&#111;&#109;&#63;&#99;&#99;&#61;&#109;&#105;&#116;&#111;&#64;&#112;&#97;&#110;&#105;&#120;&#46;&#99;&#111;&#109;"><u><font color=#5c81a7>mito@panix.com</font></u></a>与他联系。 </p>
                        </td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.blogjava.net/simie/aggbug/127902.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/simie/" target="_blank">和田雨</a> 2007-07-03 17:16 <a href="http://www.blogjava.net/simie/archive/2007/07/03/127902.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一个读取xml文件内容的类</title><link>http://www.blogjava.net/simie/archive/2007/07/03/127844.html</link><dc:creator>和田雨</dc:creator><author>和田雨</author><pubDate>Tue, 03 Jul 2007 06:55:00 GMT</pubDate><guid>http://www.blogjava.net/simie/archive/2007/07/03/127844.html</guid><wfw:comment>http://www.blogjava.net/simie/comments/127844.html</wfw:comment><comments>http://www.blogjava.net/simie/archive/2007/07/03/127844.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/simie/comments/commentRss/127844.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/simie/services/trackbacks/127844.html</trackback:ping><description><![CDATA[一个读取xml文件内容的类&nbsp;<br>package&nbsp;project.util.xml;<br><br>import&nbsp;java.io.*;<br>import&nbsp;java.util.*;<br>import&nbsp;javax.servlet.http.*;<br>import&nbsp;org.apache.log4j.*;<br>import&nbsp;org.jdom.*;<br>import&nbsp;org.jdom.input.*;<br><br>/**<br>*&nbsp;&lt;p&gt;Title:&nbsp;&lt;font&nbsp;color="steelblue"&nbsp;size="10"&gt;读取xml文件信息&lt;/font&gt;&lt;/p&gt;<br>*&nbsp;&lt;p&gt;Description:&nbsp;&lt;font&nbsp;color="steelblue"&gt;从XML配置文件中获得配置信息。excerpt&nbsp;form&nbsp;jdom。&lt;/font&gt;&lt;/p&gt;<br>*&nbsp;&lt;p&gt;Copyright:&nbsp;&lt;font&nbsp;color="steelblue"&gt;Copyright&nbsp;(c)&nbsp;2004&lt;/font&gt;&lt;/p&gt;<br>*&nbsp;&lt;p&gt;Company:&nbsp;&lt;font&nbsp;color="steelblue"&gt;Harmonious&lt;/font&gt;&lt;/p&gt;<br>*&nbsp;@author&nbsp;&lt;font&nbsp;color="steelblue"&gt;TZL&lt;/font&gt;<br>*&nbsp;@version&nbsp;&lt;font&nbsp;color="steelblue"&gt;1.0&lt;/font&gt;<br>*/<br><br>public&nbsp;class&nbsp;XMLReader&nbsp;{<br>/*<br>#设置根的输出配置，格式为&nbsp;"info&nbsp;[2004-05-01&nbsp;22:35:30]&nbsp;[name]logname(b.c)&nbsp;[line]&nbsp;86&nbsp;msg--&gt;log信息"<br>log4j.rootLogger=DEBUG,&nbsp;rootAppender<br>log4j.appender.rootAppender=org.apache.log4j.RollingFileAppender<br>log4j.appender.rootAppender.File=e:/MapXtremeSmpl.log<br>log4j.appender.rootAppender.MaxFileSize=1000KB<br>log4j.appender.rootAppender.layout=org.apache.log4j.PatternLayout<br>log4j.appender.rootAppender.layout.ConversionPattern=%-5p&nbsp;[%d{yyyy-mm-dd&nbsp;HH:mm:ss}]&nbsp;[name]&nbsp;%c{2}&nbsp;[line]&nbsp;%L&nbsp;msg--&gt;&nbsp;%m%n<br>*/<br>static&nbsp;public&nbsp;Logger&nbsp;log&nbsp;=&nbsp;Logger.getLogger(XMLReader.class);<br>protected&nbsp;Element&nbsp;m_RootElement&nbsp;=&nbsp;null;<br>protected&nbsp;String&nbsp;m_webAppPath&nbsp;=&nbsp;null;<br><br>/**<br>*&nbsp;&lt;font&nbsp;color="orange"&gt;构造函数。&lt;/font&gt;<br>*&nbsp;@param&nbsp;xmlFile&nbsp;&lt;font&nbsp;color="steelblue"&gt;要读取的配置文件的绝对路径。&lt;/font&gt;<br>*/<br>public&nbsp;XMLReader(String&nbsp;xmlFile)&nbsp;{<br>m_webAppPath&nbsp;=&nbsp;null;<br>try&nbsp;{<br>PatternLayout&nbsp;layout&nbsp;=&nbsp;new&nbsp;PatternLayout("%-5p&nbsp;%d{yyyy-MM-dd&nbsp;HH:mm:ss}&nbsp;[name]&nbsp;%c{2}&nbsp;[line]&nbsp;%L&nbsp;[msg]&nbsp;%m%n");<br>ConsoleAppender&nbsp;appender&nbsp;=&nbsp;new&nbsp;ConsoleAppender(/*new&nbsp;SimpleLayout(),*/layout,&nbsp;"System.err");<br>log.addAppender(appender);<br><br>SAXBuilder&nbsp;builder&nbsp;=&nbsp;new&nbsp;SAXBuilder();<br>document．nbspdoc&nbsp;=&nbsp;null;<br>doc&nbsp;=&nbsp;builder.build(new&nbsp;FileInputStream(xmlFile));<br>m_RootElement&nbsp;=&nbsp;doc.getRootElement();<br>}<br>catch&nbsp;(IOException&nbsp;ex)&nbsp;{<br>log.error("XMLReader构造时出现IO错误:"&nbsp;+&nbsp;ex.toString());<br>}<br>catch&nbsp;(JDOMException&nbsp;ex1)&nbsp;{<br>log.error("XMLReader构造时分析XML文件出错:"&nbsp;+&nbsp;ex1.toString());<br>}<br>catch&nbsp;(Exception&nbsp;ex)&nbsp;{<br>log.error("XMLReader&nbsp;构造出错:"&nbsp;+&nbsp;ex.toString());<br>}<br>}<br><br>/**<br>*&nbsp;&lt;font&nbsp;color="orange"&gt;构造函数。配置文件必须指定为发布的应用的根目录下的/XmlConfig/Config.xml。&lt;/font&gt;<br>*&nbsp;@param&nbsp;servletObj&nbsp;&lt;font&nbsp;color="steelblue"&gt;随便一个HttpServlet对象。&lt;/font&gt;<br>*/<br>public&nbsp;XMLReader(HttpServlet&nbsp;servletObj)&nbsp;{<br>m_webAppPath&nbsp;=&nbsp;servletObj.getServletContext().getRealPath("/");<br>String&nbsp;configFileName&nbsp;=&nbsp;m_webAppPath&nbsp;+&nbsp;"XmlConfig/Config.xml";<br><br>try&nbsp;{<br>PatternLayout&nbsp;layout&nbsp;=&nbsp;new&nbsp;PatternLayout("%-5p&nbsp;%d{yyyy-MM-dd&nbsp;HH:mm:ss}&nbsp;[name]&nbsp;%c{2}&nbsp;[line]&nbsp;%L&nbsp;[msg]&nbsp;%m%n");<br>ConsoleAppender&nbsp;appender&nbsp;=&nbsp;new&nbsp;ConsoleAppender(&nbsp;/*new&nbsp;SimpleLayout(),*/layout,&nbsp;"System.err");<br>log.addAppender(appender);<br><br>SAXBuilder&nbsp;builder&nbsp;=&nbsp;new&nbsp;SAXBuilder();<br>document．nbspdoc&nbsp;=&nbsp;null;<br>doc&nbsp;=&nbsp;builder.build(new&nbsp;FileInputStream(configFileName));<br>m_RootElement&nbsp;=&nbsp;doc.getRootElement();<br>}<br>catch&nbsp;(IOException&nbsp;ex)&nbsp;{<br>log.error("XMLReader构造时出现IO错误（/XmlConfig/Config.xml）:"&nbsp;+&nbsp;ex.toString());<br>}<br>catch&nbsp;(JDOMException&nbsp;ex1)&nbsp;{<br>log.error("XMLReader构造时分析XML文件出错（/XmlConfig/Config.xml）:"&nbsp;+&nbsp;ex1.toString());<br>}<br>catch&nbsp;(Exception&nbsp;ex)&nbsp;{<br>log.error("XMLReader构造出错（/XmlConfig/Config.xml）:"&nbsp;+&nbsp;ex.toString());<br>}<br>}<br><br>/**<br>*&nbsp;&lt;font&nbsp;color="orange"&gt;web应用发布在web服务器的绝对路径根目录，最后已经有目录分割符。&lt;/font&gt;<br>*&nbsp;@return&nbsp;&lt;font&nbsp;color="tomato"&gt;返回web应用发布在web服务器的绝对路径的根目录。&lt;/font&gt;<br>*/<br>public&nbsp;String&nbsp;getWebAppPath()&nbsp;{<br>return&nbsp;m_webAppPath;<br>}<br><br>/**<br>*&nbsp;&lt;font&nbsp;color="orange"&gt;从配置文件中获得配置信息。&lt;/font&gt;<br>*&nbsp;@param&nbsp;key&nbsp;&lt;font&nbsp;color="steelblue"&gt;要获取的配置名称。&lt;/font&gt;<br>*&nbsp;@param&nbsp;curRootName&nbsp;&lt;font&nbsp;color="steelblue"&gt;查找的起始节点名称，如果为null从根开始查找。&lt;/font&gt;<br>*&nbsp;@return&nbsp;&lt;font&nbsp;color="tomato"&gt;配置的字符串。&lt;/font&gt;<br>*/<br>public&nbsp;String&nbsp;getElementvalue(String&nbsp;curRootName,&nbsp;String&nbsp;key)&nbsp;{<br>String&nbsp;value&nbsp;=&nbsp;null;<br>Element&nbsp;curRoot&nbsp;=&nbsp;getElement(null,&nbsp;curRootName);<br>if&nbsp;(null&nbsp;==&nbsp;curRoot)&nbsp;{<br>curRoot&nbsp;=&nbsp;m_RootElement;<br>}<br>Element&nbsp;keyNode&nbsp;=&nbsp;getElement(curRoot,&nbsp;key);<br>if&nbsp;(null&nbsp;!=&nbsp;keyNode)&nbsp;{<br>value&nbsp;=&nbsp;keyNode.getTextTrim();<br><br>}<br>return&nbsp;value;<br>}<br><br>/**<br>*&nbsp;&lt;font&nbsp;color="orange"&gt;根据名字获得节点。广度遍历，递归调用。&lt;/font&gt;<br>*&nbsp;@param&nbsp;nodeName&nbsp;&lt;font&nbsp;color="steelblue"&gt;节点的名字。&lt;/font&gt;<br>*&nbsp;@param&nbsp;curRoot&nbsp;&lt;font&nbsp;color="steelblue"&gt;&nbsp;从开始查找的起始节点，如果为null从根开始查找。&lt;/font&gt;<br>*&nbsp;@return&nbsp;&lt;font&nbsp;color="tomato"&gt;返回从指定节点下找到的第一个节点。如果没有返回null。&lt;/font&gt;<br>*/<br>private&nbsp;Element&nbsp;getElement(Element&nbsp;curRoot,&nbsp;String&nbsp;nodeName)&nbsp;{<br>Element&nbsp;retElement&nbsp;=&nbsp;null;<br><br>if&nbsp;(null&nbsp;==&nbsp;nodeName)<br>return&nbsp;m_RootElement;<br><br>if&nbsp;(null&nbsp;==&nbsp;curRoot)&nbsp;{<br>curRoot&nbsp;=&nbsp;m_RootElement;<br>}<br><br>if&nbsp;(null&nbsp;!=&nbsp;curRoot)&nbsp;{<br>retElement&nbsp;=&nbsp;curRoot.getChild(nodeName);<br>if&nbsp;(null&nbsp;==&nbsp;retElement)&nbsp;{<br>List&nbsp;nestElements&nbsp;=&nbsp;curRoot.getChildren();<br>Iterator&nbsp;iterator&nbsp;=&nbsp;nestElements.iterator();<br>while&nbsp;(iterator.hasNext()&nbsp;&amp;&amp;&nbsp;null&nbsp;==&nbsp;retElement)&nbsp;{<br>retElement&nbsp;=&nbsp;getElement(&nbsp;(Element)&nbsp;iterator.next(),&nbsp;nodeName);<br>}<br>}<br>}<br><br>return&nbsp;retElement;<br>}<br><br>/**<br>*&nbsp;&lt;font&nbsp;color="orange"&gt;获得指定节点的属性。&lt;/font&gt;<br>*&nbsp;@param&nbsp;elementName&nbsp;&lt;font&nbsp;color="steelblue"&gt;节点的名称。&lt;/font&gt;<br>*&nbsp;@param&nbsp;attName&nbsp;&lt;font&nbsp;color="steelblue"&gt;要获得的属性的名称。&lt;/font&gt;<br>*&nbsp;@return&nbsp;&lt;font&nbsp;color="tomato"&gt;要查找的属性的值。&lt;/font&gt;<br>*/<br>public&nbsp;String&nbsp;getElementAtrribute(String&nbsp;elementName,&nbsp;String&nbsp;attName)<br>{<br>Element&nbsp;el&nbsp;=&nbsp;getElement(null,&nbsp;elementName);<br>if&nbsp;(null&nbsp;==&nbsp;el)<br>return&nbsp;null;<br><br>return&nbsp;el.getAttributevalue(attName);<br>}<br><br>}
<img src ="http://www.blogjava.net/simie/aggbug/127844.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/simie/" target="_blank">和田雨</a> 2007-07-03 14:55 <a href="http://www.blogjava.net/simie/archive/2007/07/03/127844.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>从网上抓取指定URL源码的方案</title><link>http://www.blogjava.net/simie/archive/2007/07/03/127841.html</link><dc:creator>和田雨</dc:creator><author>和田雨</author><pubDate>Tue, 03 Jul 2007 06:52:00 GMT</pubDate><guid>http://www.blogjava.net/simie/archive/2007/07/03/127841.html</guid><wfw:comment>http://www.blogjava.net/simie/comments/127841.html</wfw:comment><comments>http://www.blogjava.net/simie/archive/2007/07/03/127841.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/simie/comments/commentRss/127841.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/simie/services/trackbacks/127841.html</trackback:ping><description><![CDATA[<strong>引言<br></strong>　　在做无线项目的时候，与通讯公司的数据通讯有一部分是通过ＸＭＬ交互的，所以必须要动态抓取通讯公司提供的固定的Internet上的数据，便研究了一下如何抓取固定url上的数据，现与大家分享一下。<br><br>　　类名GetPageCode，有一个方法GetSource，通过属性传递参数，入参控制的是要取得URL的地址，代理服务器的设置及输出方式的控制，这里大家可以再扩展自己的需要，我这里只提供了两种方式，一种是直接写到本地的某个文件中，另外一种就是返回字符串的。类里已经作了比较详细的注释，我想大家很容易就看明白了，如果实在不明白，&nbsp;那就ｍｓｎ上问吧，ＭＳＮ：yubo@x263.net。<br><br>&nbsp;&nbsp;调用方式：<br>&nbsp;&nbsp;#region&nbsp;测试获取远程网页<br><br><br>
<table borderColor=#666666 cellSpacing=4 borderColorDark=#cccccc cellPadding=0 width="100%" bgColor=#cccccc borderColorLight=#666666 border=1>
    <tbody>
        <tr>
            <td style="WORD-BREAK: break-all" align=left><br>GetPageCode&nbsp;gpc&nbsp;=&nbsp;new&nbsp;GetPageCode();<br>&nbsp;&nbsp;gpc.Url="http://ppcode.com";<br>&nbsp;&nbsp;gpc.ProxyState=1;//使用代理服务器，0为不使用，设置为1后下面的代理设置才起作用<br>&nbsp;&nbsp;gpc.ProxyAddress="http://proxyName.com";//代理服务器地址<br>&nbsp;&nbsp;gpc.ProxyPort="80";//代理服务器的端口<br>&nbsp;&nbsp;gpc.ProxyAccount="proxy";//代理服务器账号<br>&nbsp;&nbsp;gpc.ProxyPassword="password";//代理服务器密码<br>&nbsp;&nbsp;gpc.ProxyDomain="bqc";//代理服务器域<br>&nbsp;&nbsp;gpc.OutFilePath=filePath;//设置输出文件路径的地方，如果不设置，则返回字符串<br>&nbsp;&nbsp;gpc.GetSource();//处理<br>&nbsp;&nbsp;string&nbsp;tempErr=gpc.NoteMessage;//如果出错，这里会提示<br>&nbsp;&nbsp;string&nbsp;tempCode=gpc.OutString;//返回的字符串<br>&nbsp;&nbsp;#endregion<br>&nbsp;&nbsp;类代码：<br>&nbsp;&nbsp;using&nbsp;System;<br>&nbsp;&nbsp;using&nbsp;System.Collections;<br>&nbsp;&nbsp;using&nbsp;System.ComponentModel;<br>&nbsp;&nbsp;using&nbsp;System.Data;<br>&nbsp;&nbsp;using&nbsp;System.Drawing;<br>&nbsp;&nbsp;using&nbsp;System.IO;<br>&nbsp;&nbsp;using&nbsp;System.Net;<br>&nbsp;&nbsp;using&nbsp;System.Text;<br>&nbsp;&nbsp;using&nbsp;System.Web;<br>&nbsp;&nbsp;namespace&nbsp;Test.Com<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;///&nbsp;&lt;summary&gt;<br>&nbsp;&nbsp;&nbsp;///&nbsp;功能：取得Internet上的URL页的源码<br>&nbsp;&nbsp;&nbsp;///&nbsp;创建：2004-03-22<br>&nbsp;&nbsp;&nbsp;///&nbsp;作者：Rexsp&nbsp;MSN:yubo@x263.net<br>&nbsp;&nbsp;///&nbsp;&lt;/summary&gt;<br>&nbsp;&nbsp;&nbsp;public&nbsp;class&nbsp;GetPageCode<br>&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;#region&nbsp;私有变量<br>&nbsp;&nbsp;///&nbsp;&lt;summary&gt;<br>&nbsp;&nbsp;///&nbsp;网页URL地址<br>&nbsp;&nbsp;///&nbsp;&lt;/summary&gt;<br>&nbsp;&nbsp;private&nbsp;string&nbsp;url=null;<br>&nbsp;&nbsp;///&nbsp;&lt;summary&gt;<br>&nbsp;&nbsp;///&nbsp;是否使用代码服务器：0&nbsp;不使用&nbsp;&nbsp;1&nbsp;使用代理服务器<br>&nbsp;&nbsp;///&nbsp;&lt;/summary&gt;<br>&nbsp;&nbsp;private&nbsp;int&nbsp;proxyState=0;<br>&nbsp;&nbsp;///&nbsp;&lt;summary&gt;<br>&nbsp;&nbsp;///&nbsp;代理服务器地址<br>&nbsp;&nbsp;///&nbsp;&lt;/summary&gt;<br>&nbsp;&nbsp;private&nbsp;string&nbsp;proxyAddress=null;<br>&nbsp;&nbsp;///&nbsp;&lt;summary&gt;<br>&nbsp;&nbsp;///&nbsp;代理服务器端口<br>&nbsp;&nbsp;///&nbsp;&lt;/summary&gt;<br>&nbsp;&nbsp;private&nbsp;string&nbsp;proxyPort=null;<br>&nbsp;&nbsp;///&nbsp;&lt;summary&gt;<br>&nbsp;&nbsp;///&nbsp;代理服务器用户名<br>&nbsp;&nbsp;///&nbsp;&lt;/summary&gt;<br>&nbsp;&nbsp;private&nbsp;string&nbsp;proxyAccount=null;<br>&nbsp;&nbsp;///&nbsp;&lt;summary&gt;<br>&nbsp;&nbsp;///&nbsp;代理服务器密码<br>&nbsp;&nbsp;///&nbsp;&lt;/summary&gt;<br>&nbsp;&nbsp;private&nbsp;string&nbsp;proxyPassword=null;<br>&nbsp;&nbsp;///&nbsp;&lt;summary&gt;<br>&nbsp;&nbsp;///&nbsp;代理服务器域<br>&nbsp;&nbsp;///&nbsp;&lt;/summary&gt;<br>&nbsp;&nbsp;private&nbsp;string&nbsp;proxyDomain=null;<br>&nbsp;///&nbsp;&lt;summary&gt;<br>&nbsp;&nbsp;///&nbsp;输出文件路径<br>&nbsp;&nbsp;///&nbsp;&lt;/summary&gt;<br>&nbsp;&nbsp;private&nbsp;string&nbsp;outFilePath=null;<br>&nbsp;&nbsp;///&nbsp;&lt;summary&gt;<br>&nbsp;&nbsp;///&nbsp;输出的字符串<br>&nbsp;&nbsp;///&nbsp;&lt;/summary&gt;<br>&nbsp;&nbsp;private&nbsp;string&nbsp;outString=null;<br>&nbsp;&nbsp;///&nbsp;&lt;summary&gt;<br>&nbsp;&nbsp;///&nbsp;提示信息<br>&nbsp;&nbsp;///&nbsp;&lt;/summary&gt;<br>&nbsp;&nbsp;private&nbsp;string&nbsp;noteMessage;<br><br>&nbsp;&nbsp;#endregion<br><br>&nbsp;&nbsp;#region&nbsp;公共属性<br>&nbsp;&nbsp;///&nbsp;&lt;summary&gt;<br>&nbsp;&nbsp;///&nbsp;欲读取的URL地址<br>&nbsp;&nbsp;///&nbsp;&lt;/summary&gt;<br>&nbsp;&nbsp;public&nbsp;string&nbsp;Url<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;get{return&nbsp;url;}<br>&nbsp;&nbsp;&nbsp;set{url=value;}<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;///&nbsp;&lt;summary&gt;<br>&nbsp;&nbsp;///&nbsp;是否使用代理服务器标志<br>&nbsp;&nbsp;///&nbsp;&lt;/summary&gt;<br>&nbsp;&nbsp;public&nbsp;int&nbsp;ProxyState<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;get{return&nbsp;proxyState;}<br>&nbsp;&nbsp;&nbsp;set{proxyState=value;}<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;///&nbsp;&lt;summary&gt;<br>&nbsp;&nbsp;///&nbsp;代理服务器地址<br>&nbsp;&nbsp;///&nbsp;&lt;/summary&gt;<br>&nbsp;&nbsp;public&nbsp;string&nbsp;ProxyAddress<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;get{return&nbsp;proxyAddress;}<br>&nbsp;&nbsp;&nbsp;set{proxyAddress=value;}<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;///&nbsp;&lt;summary&gt;<br><br>&nbsp;&nbsp;///&nbsp;代理服务器端口<br>&nbsp;&nbsp;///&nbsp;&lt;/summary&gt;<br>&nbsp;&nbsp;public&nbsp;string&nbsp;ProxyPort<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;get{return&nbsp;proxyPort;}<br>&nbsp;&nbsp;&nbsp;set{proxyPort=value;}<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;///&nbsp;&lt;summary&gt;<br>&nbsp;&nbsp;///&nbsp;代理服务器账号<br>&nbsp;&nbsp;///&nbsp;&lt;/summary&gt;<br>&nbsp;&nbsp;public&nbsp;string&nbsp;ProxyAccount<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;get{return&nbsp;proxyAccount;}<br>&nbsp;&nbsp;&nbsp;set{proxyAccount=value;}<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;///&nbsp;&lt;summary&gt;<br>&nbsp;&nbsp;///&nbsp;代理服务器密码<br>&nbsp;&nbsp;///&nbsp;&lt;/summary&gt;<br>&nbsp;&nbsp;public&nbsp;string&nbsp;ProxyPassword<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;get{return&nbsp;proxyPassword;}<br>&nbsp;&nbsp;&nbsp;set{proxyPassword=value;}<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;///&nbsp;&lt;summary&gt;<br>&nbsp;&nbsp;///&nbsp;代理服务器域<br>&nbsp;&nbsp;///&nbsp;&lt;/summary&gt;<br>&nbsp;&nbsp;public&nbsp;string&nbsp;ProxyDomain<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;get{return&nbsp;proxyDomain;}<br>&nbsp;&nbsp;&nbsp;set{proxyDomain=value;}<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;///&nbsp;&lt;summary&gt;<br>&nbsp;&nbsp;///&nbsp;输出文件路径<br>&nbsp;&nbsp;///&nbsp;&lt;/summary&gt;<br>&nbsp;&nbsp;public&nbsp;string&nbsp;OutFilePath<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;get{return&nbsp;outFilePath;}<br><br>&nbsp;&nbsp;set{outFilePath=value;}<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;///&nbsp;&lt;summary&gt;<br>&nbsp;&nbsp;///&nbsp;返回的字符串<br>&nbsp;&nbsp;///&nbsp;&lt;/summary&gt;<br>&nbsp;&nbsp;public&nbsp;string&nbsp;OutString<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;get{return&nbsp;outString;}<br>&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;///&nbsp;&lt;summary&gt;<br>&nbsp;&nbsp;///&nbsp;返回提示信息<br>&nbsp;&nbsp;///&nbsp;&lt;/summary&gt;<br>&nbsp;&nbsp;public&nbsp;string&nbsp;NoteMessage<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;get{return&nbsp;noteMessage;}<br>&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;#endregion<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;#region&nbsp;构造函数<br>&nbsp;&nbsp;public&nbsp;GetPageCode()<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;#endregion<br><br>&nbsp;&nbsp;#region&nbsp;公共方法<br>&nbsp;&nbsp;///&nbsp;&lt;summary&gt;<br>&nbsp;&nbsp;///&nbsp;读取指定URL地址，存到指定文件中<br>&nbsp;&nbsp;///&nbsp;&lt;/summary&gt;<br>&nbsp;&nbsp;public&nbsp;void&nbsp;GetSource()&nbsp;<br>&nbsp;&nbsp;{&nbsp;<br>&nbsp;&nbsp;&nbsp;WebRequest&nbsp;request&nbsp;=&nbsp;WebRequest.Create(this.url);<br>&nbsp;&nbsp;&nbsp;//使用代理服务器的处理<br>&nbsp;&nbsp;&nbsp;if(this.proxyState==1)<br>&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;//默认读取80端口的数据<br><br>&nbsp;&nbsp;&nbsp;&nbsp;if(this.proxyPort==null)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.ProxyPort="80";<br><br>&nbsp;&nbsp;&nbsp;&nbsp;WebProxy&nbsp;myProxy=new&nbsp;WebProxy();&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;myProxy&nbsp;=&nbsp;(WebProxy)request.Proxy;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;myProxy.Address&nbsp;=&nbsp;new&nbsp;Uri(this.ProxyAddress+":"+this.ProxyPort);&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;myProxy.Credentials&nbsp;=&nbsp;new&nbsp;NetworkCredential(this.proxyAccount,&nbsp;this.proxyPassword,&nbsp;this.ProxyDomain);<br>&nbsp;&nbsp;&nbsp;&nbsp;request.Proxy&nbsp;=&nbsp;myProxy;&nbsp;<br>&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;try<br>&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;//请求服务<br>&nbsp;&nbsp;&nbsp;&nbsp;WebResponse&nbsp;response&nbsp;=&nbsp;request.GetResponse();<br>&nbsp;&nbsp;&nbsp;&nbsp;//返回信息<br>&nbsp;&nbsp;&nbsp;&nbsp;Stream&nbsp;resStream&nbsp;=&nbsp;response.GetResponseStream();&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;StreamReader&nbsp;sr&nbsp;=&nbsp;new&nbsp;StreamReader(resStream,&nbsp;System.Text.Encoding.Default);<br>&nbsp;&nbsp;&nbsp;&nbsp;string&nbsp;tempCode=&nbsp;sr.ReadToEnd();<br>&nbsp;&nbsp;&nbsp;&nbsp;resStream.Close();&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;sr.Close();<br><br>&nbsp;&nbsp;&nbsp;&nbsp;//如果输出文件路径为空，便将得到的内容赋给OutString属性<br>&nbsp;&nbsp;&nbsp;&nbsp;if(this.outFilePath==null)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.outString=tempCode;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;else<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FileInfo&nbsp;fi&nbsp;=&nbsp;new&nbsp;FileInfo(this.outFilePath);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//如果存在文件则先干掉<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(fi.Exists)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fi.Delete();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;StreamWriter&nbsp;sw&nbsp;=&nbsp;new&nbsp;StreamWriter(this.outFilePath,true,Encoding.Default);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sw.Write(tempCode);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sw.Flush();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sw.Close();<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;catch<br>&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;this.noteMessage="出错了，请检查网络是否连通;";<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;#endregion<br><br>&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;}<br></td>
        </tr>
    </tbody>
</table>
<img src ="http://www.blogjava.net/simie/aggbug/127841.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/simie/" target="_blank">和田雨</a> 2007-07-03 14:52 <a href="http://www.blogjava.net/simie/archive/2007/07/03/127841.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JSP生成验证码源程序</title><link>http://www.blogjava.net/simie/archive/2007/07/03/127839.html</link><dc:creator>和田雨</dc:creator><author>和田雨</author><pubDate>Tue, 03 Jul 2007 06:51:00 GMT</pubDate><guid>http://www.blogjava.net/simie/archive/2007/07/03/127839.html</guid><wfw:comment>http://www.blogjava.net/simie/comments/127839.html</wfw:comment><comments>http://www.blogjava.net/simie/archive/2007/07/03/127839.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/simie/comments/commentRss/127839.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/simie/services/trackbacks/127839.html</trackback:ping><description><![CDATA[<table borderColor=#666666 cellSpacing=4 borderColorDark=#cccccc cellPadding=0 width="100%" bgColor=#cccccc borderColorLight=#666666 border=1>
    <tbody>
        <tr>
            <td style="WORD-BREAK: break-all" align=left>&lt;%@&nbsp;page&nbsp;contentType="image/jpeg"&nbsp;import="java.awt.*,&nbsp;<br>java.awt.image.*,java.util.*,javax.imageio.*"&nbsp;%&gt;&nbsp;<br>&lt;%&nbsp;<br>//&nbsp;在内存中创建图象&nbsp;<br>int&nbsp;width=60,&nbsp;height=20;&nbsp;<br>BufferedImage&nbsp;image&nbsp;=&nbsp;new&nbsp;BufferedImage(width,&nbsp;height,&nbsp;<br>BufferedImage.TYPE_INT_RGB);&nbsp;<br><br>//&nbsp;获取图形上下文&nbsp;<br>Graphics&nbsp;g&nbsp;=&nbsp;image.getGraphics();&nbsp;<br><br>//&nbsp;设定背景色&nbsp;<br>g.setColor(new&nbsp;Color(0xDCDCDC));&nbsp;<br>g.fillRect(0,&nbsp;0,&nbsp;width,&nbsp;height);&nbsp;<br><br>//画边框&nbsp;<br>g.setColor(Color.black);&nbsp;<br>g.drawRect(0,0,width-1,height-1);&nbsp;<br><br>//&nbsp;取随机产生的认证码(4位数字)&nbsp;<br>String&nbsp;rand&nbsp;=&nbsp;request.getParameter("rand");&nbsp;<br>rand&nbsp;=&nbsp;rand.substring(0,rand.indexOf("."));&nbsp;<br>switch(rand.length())&nbsp;<br>{&nbsp;<br>case&nbsp;1:&nbsp;rand&nbsp;=&nbsp;"000"+rand;&nbsp;break;&nbsp;<br>case&nbsp;2:&nbsp;rand&nbsp;=&nbsp;"00"+rand;&nbsp;break;&nbsp;<br>case&nbsp;3:&nbsp;rand&nbsp;=&nbsp;"0"+rand;&nbsp;break;&nbsp;<br>default:&nbsp;rand&nbsp;=&nbsp;rand.substring(0,4);&nbsp;break;&nbsp;<br>}&nbsp;<br><br>//&nbsp;将认证码存入SESSION&nbsp;<br>session.setAttribute("rand",rand);&nbsp;<br><br>//&nbsp;将认证码显示到图象中&nbsp;<br>g.setColor(Color.black);&nbsp;<br>Integer&nbsp;tempNumber&nbsp;=&nbsp;new&nbsp;Integer(rand);&nbsp;<br>String&nbsp;numberStr&nbsp;=&nbsp;tempNumber.toString();&nbsp;<br><br>g.setFont(new&nbsp;Font("Atlantic&nbsp;Inline",Font.PLAIN,18));&nbsp;<br>String&nbsp;Str&nbsp;=&nbsp;numberStr.substring(0,1);&nbsp;<br>g.drawString(Str,8,17);&nbsp;<br><br>Str&nbsp;=&nbsp;numberStr.substring(1,2);&nbsp;<br>g.drawString(Str,20,15);&nbsp;<br>Str&nbsp;=&nbsp;numberStr.substring(2,3);&nbsp;<br>g.drawString(Str,35,18);&nbsp;<br><br>Str&nbsp;=&nbsp;numberStr.substring(3,4);&nbsp;<br>g.drawString(Str,45,15);&nbsp;<br><br>//&nbsp;随机产生88个干扰点，使图象中的认证码不易被其它程序探测到&nbsp;<br>Random&nbsp;random&nbsp;=&nbsp;new&nbsp;Random();&nbsp;<br>for&nbsp;(int&nbsp;i=0;i&lt;20;i++)&nbsp;<br>{&nbsp;<br>int&nbsp;x&nbsp;=&nbsp;random.nextInt(width);&nbsp;<br>int&nbsp;y&nbsp;=&nbsp;random.nextInt(height);&nbsp;<br>g.drawOval(x,y,0,0);&nbsp;<br>}&nbsp;<br><br>//&nbsp;图象生效&nbsp;<br>g.dispose();&nbsp;<br><br>//&nbsp;输出图象到页面&nbsp;<br>ImageIO.write(image,&nbsp;"JPEG",&nbsp;response.getOutputStream());&nbsp;<br>%&gt;</td>
        </tr>
    </tbody>
</table>
<img src ="http://www.blogjava.net/simie/aggbug/127839.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/simie/" target="_blank">和田雨</a> 2007-07-03 14:51 <a href="http://www.blogjava.net/simie/archive/2007/07/03/127839.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>编写你自己的单点登录（SSO）服务（转载</title><link>http://www.blogjava.net/simie/archive/2007/07/02/127526.html</link><dc:creator>和田雨</dc:creator><author>和田雨</author><pubDate>Mon, 02 Jul 2007 05:10:00 GMT</pubDate><guid>http://www.blogjava.net/simie/archive/2007/07/02/127526.html</guid><wfw:comment>http://www.blogjava.net/simie/comments/127526.html</wfw:comment><comments>http://www.blogjava.net/simie/archive/2007/07/02/127526.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/simie/comments/commentRss/127526.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/simie/services/trackbacks/127526.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 摘要：单点登录（SSO）的技术被越来越广泛地运用到各个领域的软件系统当中。本文从业务的角度分析了单点登录的需求和应用领域；从技术本身的角度分析了单点登录技术的内部机制和实现手段，并且给出Web-SSO和桌面SSO的实现、源代码和详细讲解；还从安全和性能的角度对现有的实现技术进行进一步分析，指出相应的风险和需要改进的方面。本文除了从多个方面和角度给出了对单点登录（SSO）的全面分析，还并且讨论了如何...&nbsp;&nbsp;<a href='http://www.blogjava.net/simie/archive/2007/07/02/127526.html'>阅读全文</a><img src ="http://www.blogjava.net/simie/aggbug/127526.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/simie/" target="_blank">和田雨</a> 2007-07-02 13:10 <a href="http://www.blogjava.net/simie/archive/2007/07/02/127526.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>jsp生成汉字验证码 (彩色)</title><link>http://www.blogjava.net/simie/archive/2007/07/02/127515.html</link><dc:creator>和田雨</dc:creator><author>和田雨</author><pubDate>Mon, 02 Jul 2007 04:57:00 GMT</pubDate><guid>http://www.blogjava.net/simie/archive/2007/07/02/127515.html</guid><wfw:comment>http://www.blogjava.net/simie/comments/127515.html</wfw:comment><comments>http://www.blogjava.net/simie/archive/2007/07/02/127515.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/simie/comments/commentRss/127515.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/simie/services/trackbacks/127515.html</trackback:ping><description><![CDATA[<span class=tpc_content><font size=2>一些网站采用了字母和数字的验证码，数字和字母加起来一共30多个，如果有心，还是能够通过方法识别出来。</font><span style="FONT-SIZE: 0pt; COLOR: #ffffff"> O8&lt;@d3 </span><font size=2>&nbsp;<br>我在网上看到一篇文章"jsp彩色验证码"，我进行了加强，生成的验证码内容为汉字，可以方便应用在面向汉语网民的网站认证上。</font><span style="FONT-SIZE: 0pt; COLOR: #ffffff"> oxcd:, Vc </span><font size=2>&nbsp;<br></font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">iXV6:&amp;\9"r </span><font size=2>&nbsp;<br>当然，我还看到别人考虑的几种方法：</font><span style="FONT-SIZE: 0pt; COLOR: #ffffff"> {i867@H_e </span><font size=2>&nbsp;<br>1.生成计算题，比如20+34*(23-12)=?，用户必须输入正确的答案才能通过验证，这个想法挺好，但是用户必须打开计算器进行计算，增加了用户的难度</font><span style="FONT-SIZE: 0pt; COLOR: #ffffff"> dza^8ynu </span><font size=2>&nbsp;<br>2.问一些常见的问题，比如&#8220;人&#8221;这个字由几笔组成。这也是不错的想法，关键是必须有上万条的题库，而且题库的答案必须是明确的，简单易比较的，这个难度也较大。</font><span style="FONT-SIZE: 0pt; COLOR: #ffffff"> |||o&lt; </span><font size=2>&nbsp;<br></font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">ejas+ </span><font size=2>&nbsp;<br>下面是彩色汉字验证码的代码。</font><span style="FONT-SIZE: 0pt; COLOR: #ffffff"> ,"-07[X </span><font size=2>&nbsp;<br></font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">]j&amp;J&amp;.:&amp;, </span><font size=2>&nbsp;<br></font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">dVTACb` </span><font size=2>&nbsp;<br>&lt;%@ page contentType="image/jpeg" import="java.awt.*,java.awt.image.*,java.util.*,javax.imageio.*" %&gt; </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">YwpC}G;  </span><font size=2>&nbsp;<br>&lt;%! </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">(.&amp;vEwK </span><font size=2>&nbsp;<br>//create by smallnest </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">z(S Lcx </span><font size=2>&nbsp;<br>//email: </font><a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#115;&#109;&#97;&#108;&#108;&#110;&#101;&#115;&#116;&#64;&#103;&#109;&#97;&#105;&#108;&#46;&#99;&#111;&#109;"><font color=#0000ff size=2><u>smallnest@gmail.com</u></font></a><font size=2> </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">&lt;p-Y a_&amp;u </span><font size=2>&nbsp;<br>//website:</font><a href="http://www.kuaff.com/" target=_blank><font color=#0000ff size=2><u>www.kuaff.com</u></font></a><font size=2> </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">hpC%no /s </span><font size=2>&nbsp;<br></font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">Du:x%[~] </span><font size=2>&nbsp;<br></font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">99Ztr4E </span><font size=2>&nbsp;<br></font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">Jk)|S2 </span><font size=2>&nbsp;<br></font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">: pZ&lt;K"Z-&amp; </span><font size=2>&nbsp;<br>//生成随机颜色 </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">s*# ]mm.MD </span><font size=2>&nbsp;<br>Color getRandColor(Random random,int fc,int bc) </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">M-C|5ahf8B </span><font size=2>&nbsp;<br>{ </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">!DF}` d </span><font size=2>&nbsp;<br>if(fc&gt;255) fc=255; </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">{+9C59]sA </span><font size=2>&nbsp;<br>if(bc&gt;255) bc=255; </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">^k41]4 RD </span><font size=2>&nbsp;<br>int r=fc+random.nextInt(bc-fc); </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">')/u5Y{fp </span><font size=2>&nbsp;<br>int g=fc+random.nextInt(bc-fc); </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">F\(TcR( </span><font size=2>&nbsp;<br>int b=fc+random.nextInt(bc-fc); </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">qQ5&gt; k=3 </span><font size=2>&nbsp;<br>return new Color(r,g,b); </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">2Es&amp;*Kr+" </span><font size=2>&nbsp;<br>} </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff"> '0 )!e!= </span><font size=2>&nbsp;<br>%&gt; </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">=H NQZD`e </span><font size=2>&nbsp;<br>&lt;% </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">q=X0lJ&lt;V </span><font size=2>&nbsp;<br>//设置页面不缓存 </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">Qsd{m_y# </span><font size=2>&nbsp;<br>response.setHeader("Pragma","No-cache"); </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">p[brf&gt;x </span><font size=2>&nbsp;<br>response.setHeader("Cache-Control","no-cache"); </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">h-r&lt;TW </span><font size=2>&nbsp;<br>response.setDateHeader("Expires", 0); </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">hB~(UCtd </span><font size=2>&nbsp;<br></font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">{m@moH 3N </span><font size=2>&nbsp;<br></font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">"&gt;^0|,(e </span><font size=2>&nbsp;<br>// 设置图片的长宽 </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">G"KO </span><font size=2>&nbsp;<br>int width=176, height=30; </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">rl&gt; 1bV?8 </span><font size=2>&nbsp;<br>//设置备选汉字，剔除一些不雅的汉字 </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">&gt;22XQgGh </span><font size=2>&nbsp;<br>String base = "\u7684\u4e00\u4e86\u662f\u6211\u4e0d\u5728\u4eba\u4eec\u6709\u6765\u4ed6\u8fd9\u4e0a\u7740\u4e2a\u5730\u5230\u5927\u91cc\u8bf4\u5c31\u53bb\u5b50\u5f97\u4e5f\u548c\u90a3\u8981\u4e0b\u770b\u5929\u65f6\u8fc7\u51fa\u5c0f\u4e48\u8d77\u4f60\u90fd\u628a\u597d\u8fd8\u591a\u6ca1\u4e3a\u53c8\u53ef\u5bb6\u5b66\u53ea\u4ee5\u4e3b\u4f1a\u6837\u5e74\u60f3\u751f\u540c\u8001\u4e2d\u5341\u4ece\u81ea\u9762\u524d\u5934\u9053\u5b83\u540e\u7136\u8d70\u5f88\u50cf\u89c1\u4e24\u7528\u5979\u56fd\u52a8\u8fdb\u6210\u56de\u4ec0\u8fb9\u4f5c\u5bf9\u5f00\u800c\u5df1\u4e9b\u73b0\u5c71\u6c11\u5019\u7ecf\u53d1\u5de5\u5411\u4e8b\u547d\u7ed9\u957f\u6c34\u51e0\u4e49\u4e09\u58f0\u4e8e\u9ad8\u624b\u77e5\u7406\u773c\u5fd7\u70b9\u5fc3\u6218\u4e8c\u95ee\u4f46\u8eab\u65b9\u5b9e\u5403\u505a\u53eb\u5f53\u4f4f\u542c\u9769\u6253\u5462\u771f\u5168\u624d\u56db\u5df2\u6240\u654c\u4e4b\u6700\u5149\u4ea7\u60c5\u8def\u5206\u603b\u6761\u767d\u8bdd\u4e1c\u5e2d\u6b21\u4eb2\u5982\u88ab\u82b1\u53e3\u653e\u513f\u5e38\u6c14\u4e94\u7b2c\u4f7f\u5199\u519b\u5427\u6587\u8fd0\u518d\u679c\u600e\u5b9a\u8bb8\u5feb\u660e\u884c\u56e0\u522b\u98de\u5916\u6811\u7269\u6d3b\u90e8\u95e8\u65e0\u5f80\u8239\u671b\u65b0\u5e26\u961f\u5148\u529b\u5b8c\u5374\u7ad9\u4ee3\u5458\u673a\u66f4\u4e5d\u60a8\u6bcf\u98ce\u7ea7\u8ddf\u7b11\u554a\u5b69\u4e07\u5c11\u76f4\u610f\u591c\u6bd4\u9636\u8fde\u8f66\u91cd\u4fbf\u6597\u9a6c\u54ea\u5316\u592a\u6307\u53d8\u793e\u4f3c\u58eb\u8005\u5e72\u77f3\u6ee1\u65e5\u51b3\u767e\u539f\u62ff\u7fa4\u7a76\u5404\u516d\u672c\u601d\u89e3\u7acb\u6cb3\u6751\u516b\u96be\u65e9\u8bba\u5417\u6839\u5171\u8ba9\u76f8\u7814\u4eca\u5176\u4e66\u5750\u63a5\u5e94\u5173\u4fe1\u89c9\u6b65\u53cd\u5904\u8bb0\u5c06\u5343\u627e\u4e89\u9886\u6216\u5e08\u7ed3\u5757\u8dd1\u8c01\u8349\u8d8a\u5b57\u52a0\u811a\u7d27\u7231\u7b49\u4e60\u9635\u6015\u6708\u9752\u534a\u706b\u6cd5\u9898\u5efa\u8d76\u4f4d\u5531\u6d77\u4e03\u5973\u4efb\u4ef6\u611f\u51c6\u5f20\u56e2\u5c4b\u79bb\u8272\u8138\u7247\u79d1\u5012\u775b\u5229\u4e16\u521a\u4e14\u7531\u9001\u5207\u661f\u5bfc\u665a\u8868\u591f\u6574\u8ba4\u54cd\u96ea\u6d41\u672a\u573a\u8be5\u5e76\u5e95\u6df1\u523b\u5e73\u4f1f\u5fd9\u63d0\u786e\u8fd1\u4eae\u8f7b\u8bb2\u519c\u53e4\u9ed1\u544a\u754c\u62c9\u540d\u5440\u571f\u6e05\u9633\u7167\u529e\u53f2\u6539\u5386\u8f6c\u753b\u9020\u5634\u6b64\u6cbb\u5317\u5fc5\u670d\u96e8\u7a7f\u5185\u8bc6\u9a8c\u4f20\u4e1a\u83dc\u722c\u7761\u5174\u5f62\u91cf\u54b1\u89c2\u82e6\u4f53\u4f17\u901a\u51b2\u5408\u7834\u53cb\u5ea6\u672f\u996d\u516c\u65c1\u623f\u6781\u5357\u67aa\u8bfb\u6c99\u5c81\u7ebf\u91ce\u575a\u7a7a\u6536\u7b97\u81f3\u653f\u57ce\u52b3\u843d\u94b1\u7279\u56f4\u5f1f\u80dc\u6559\u70ed\u5c55\u5305\u6b4c\u7c7b\u6e10\u5f3a\u6570\u4e61\u547c\u6027\u97f3\u7b54\u54e5\u9645\u65e7\u795e\u5ea7\u7ae0\u5e2e\u5566\u53d7\u7cfb\u4ee4\u8df3\u975e\u4f55\u725b\u53d6\u5165\u5cb8\u6562\u6389\u5ffd\u79cd\u88c5\u9876\u6025\u6797\u505c\u606f\u53e5\u533a\u8863\u822c\u62a5\u53f6\u538b\u6162\u53d4\u80cc\u7ec6"; </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">=-/!18 </span><font size=2>&nbsp;<br>//备选汉字的长度 </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">k63GRbd? </span><font size=2>&nbsp;<br>int length = base.length(); </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">n\+47N*ze </span><font size=2>&nbsp;<br></font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">,"jx! </span><font size=2>&nbsp;<br></font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">2b8~3d[L </span><font size=2>&nbsp;<br>//创建内存图像 </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">e/6VUo@&gt;% </span><font size=2>&nbsp;<br>BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">X/$V%6) </span><font size=2>&nbsp;<br>// 获取图形上下文 </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">"g&amp;Xk0 </span><font size=2>&nbsp;<br>Graphics g = image.getGraphics(); </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">NEE4{?Q? </span><font size=2>&nbsp;<br></font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">k &gt;@l </span><font size=2>&nbsp;<br></font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">Q{AR6CRAt </span><font size=2>&nbsp;<br>//创建随机类的实例 </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">ch6) "2 </span><font size=2>&nbsp;<br>Random random = new Random(); </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">&gt;&gt;#&gt;"&lt;CMT </span><font size=2>&nbsp;<br></font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">K#]~p^Z} </span><font size=2>&nbsp;<br></font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">aF@:;!cVu </span><font size=2>&nbsp;<br>// 设定图像背景色(因为是做背景，所以偏淡) </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">NAL2w3 </span><font size=2>&nbsp;<br>g.setColor(getRandColor(random,200,250)); </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">{&lt;=!bYh </span><font size=2>&nbsp;<br>g.fillRect(0, 0, width, height); </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">7@mFmb] -# </span><font size=2>&nbsp;<br></font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">+.S``"' </span><font size=2>&nbsp;<br></font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">Eg^${%,d </span><font size=2>&nbsp;<br>//备选字体 </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">RE]p3t|O </span><font size=2>&nbsp;<br>String[] fontTypes = {"\u5b8b\u4f53","\u65b0\u5b8b\u4f53","\u9ed1\u4f53","\u6977\u4f53","\u96b6\u4e66"}; </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">b&lt;psU?/% _ </span><font size=2>&nbsp;<br>int fontTypesLength = fontTypes.length; </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">YZ?KfO=r </span><font size=2>&nbsp;<br></font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">6&lt; 1B; </span><font size=2>&nbsp;<br></font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">&lt;;G d~( </span><font size=2>&nbsp;<br>//在图片背景上增加噪点 </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">Q`6 A{@5Y </span><font size=2>&nbsp;<br>g.setColor(getRandColor(random,160,200)); </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">8M`w </span><font size=2>&nbsp;<br>g.setFont(new Font("Times New Roman",Font.PLAIN,14)); </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">S h (%oy&lt;+ </span><font size=2>&nbsp;<br>for (int i=0;i&lt;6;i++) </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">[NFmqEEanb </span><font size=2>&nbsp;<br>{ </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">_R6 Lr9q </span><font size=2>&nbsp;<br>g.drawString("*********************************************",0,5*(i+2)); </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">goQ2Va+ </span><font size=2>&nbsp;<br>} </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">}):f;M* </span><font size=2>&nbsp;<br></font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">9L+)0)( </span><font size=2>&nbsp;<br></font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">+4vsFa6* </span><font size=2>&nbsp;<br></font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">Fj%N4$?(m </span><font size=2>&nbsp;<br></font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">+Sv2qb </span><font size=2>&nbsp;<br>//取随机产生的认证码(6个汉字) </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">%[B|3.e </span><font size=2>&nbsp;<br></font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">=e?R(E^Y" </span><font size=2>&nbsp;<br></font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">XSp~5|I </span><font size=2>&nbsp;<br>//保存生成的汉字字符串 </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">p^ &gt;Q(g </span><font size=2>&nbsp;<br>String sRand=""; </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">/0A5(P&amp;q/ </span><font size=2>&nbsp;<br>for (int i=0;i&lt;6;i++) </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">ypeul27H8 </span><font size=2>&nbsp;<br>{ </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">h570L^ </span><font size=2>&nbsp;<br>int start = random.nextInt(length); </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">L[4Aolk:M </span><font size=2>&nbsp;<br>String rand=base.substring(start,start+1); </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">&amp;hA0:^ </span><font size=2>&nbsp;<br>sRand+=rand; </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">D/ ^Kl </span><font size=2>&nbsp;<br></font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">$N^odf(2  </span><font size=2>&nbsp;<br>//设置字体的颜色 </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">2A&lt;BW~3FPt </span><font size=2>&nbsp;<br>g.setColor(getRandColor(random,10,150)); </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">C hhWE@! </span><font size=2>&nbsp;<br>//设置字体 </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">6&lt;\w'- </span><font size=2>&nbsp;<br>g.setFont(new Font(fontTypes[random.nextInt(fontTypesLength)],Font.BOLD,18 + random.nextInt(6))); </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">ftVk!3e </span><font size=2>&nbsp;<br>//将此汉字画到图片上 </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">dMjL#H} </span><font size=2>&nbsp;<br>g.drawString(rand,24*i+ 10 + random.nextInt(8),24); </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">I_i 7 % </span><font size=2>&nbsp;<br>} </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">! [ $qI1 </span><font size=2>&nbsp;<br></font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">X8H6Fki </span><font size=2>&nbsp;<br></font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">eP{42 C0= </span><font size=2>&nbsp;<br>//将认证码存入session </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">kCl -?N{og </span><font size=2>&nbsp;<br>session.setAttribute("rand",sRand); </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">&lt;uT}CUy </span><font size=2>&nbsp;<br></font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">lfKXsvP </span><font size=2>&nbsp;<br></font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">+M'E6E%w </span><font size=2>&nbsp;<br>g.dispose(); </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">*$4SR? </span><font size=2>&nbsp;<br></font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">OIFYpaBXb </span><font size=2>&nbsp;<br></font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">&lt;~[q5tC+ </span><font size=2>&nbsp;<br>//输出图象到页面 </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">/z &lt;4A^+ </span><font size=2>&nbsp;<br>ImageIO.write(image, "JPEG", response.getOutputStream()); </font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">L$ "5TP&lt; </span><font size=2>&nbsp;<br>%&gt;</font><span style="FONT-SIZE: 0pt; COLOR: #ffffff"> &amp;+ Q :0Y </span><font size=2>&nbsp;<br></font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">~ oNku2, </span><font size=2>&nbsp;<br></font><span style="FONT-SIZE: 0pt; COLOR: #ffffff"> |D6AG!J </span><font size=2>&nbsp;<br></font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">4f$X#: </span><font size=2>&nbsp;<br>===========================</font><span style="FONT-SIZE: 0pt; COLOR: #ffffff"> qozOA`,l </span><font size=2>&nbsp;<br></font><span style="FONT-SIZE: 0pt; COLOR: #ffffff">/j|Au)P </span><font size=2>&nbsp;<br>注:此方法没有在本站JSP虚拟主机测试过,不知道性能如何,如果要用验证请看:</font><span style="FONT-SIZE: 0pt; COLOR: #ffffff"> ~J|X4&gt;.Vm&nbsp;</span><font size=2>&nbsp;<br></font></span>
<img src ="http://www.blogjava.net/simie/aggbug/127515.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/simie/" target="_blank">和田雨</a> 2007-07-02 12:57 <a href="http://www.blogjava.net/simie/archive/2007/07/02/127515.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>