﻿<?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-文章分类-struts</title><link>http://www.blogjava.net/HappyJava/category/29132.html</link><description>幸福人生(J2EE)</description><language>zh-cn</language><lastBuildDate>Thu, 24 Jan 2008 10:59:25 GMT</lastBuildDate><pubDate>Thu, 24 Jan 2008 10:59:25 GMT</pubDate><ttl>60</ttl><item><title>struts+hibernate结构的分页组件(一) </title><link>http://www.blogjava.net/HappyJava/articles/177483.html</link><dc:creator>李建軍</dc:creator><author>李建軍</author><pubDate>Thu, 24 Jan 2008 05:58:00 GMT</pubDate><guid>http://www.blogjava.net/HappyJava/articles/177483.html</guid><wfw:comment>http://www.blogjava.net/HappyJava/comments/177483.html</wfw:comment><comments>http://www.blogjava.net/HappyJava/articles/177483.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/HappyJava/comments/commentRss/177483.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/HappyJava/services/trackbacks/177483.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: web.xml&lt;?xml version="1.0" encoding="UTF-8"?&gt;&lt;web-app version="2.4" &nbsp;xmlns="http://java.sun.com/xml/ns/j2ee" &nbsp;xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" &nbsp;x...&nbsp;&nbsp;<a href='http://www.blogjava.net/HappyJava/articles/177483.html'>阅读全文</a><img src ="http://www.blogjava.net/HappyJava/aggbug/177483.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/HappyJava/" target="_blank">李建軍</a> 2008-01-24 13:58 <a href="http://www.blogjava.net/HappyJava/articles/177483.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts Spring Hibernate实现上传下载</title><link>http://www.blogjava.net/HappyJava/articles/177480.html</link><dc:creator>李建軍</dc:creator><author>李建軍</author><pubDate>Thu, 24 Jan 2008 05:48:00 GMT</pubDate><guid>http://www.blogjava.net/HappyJava/articles/177480.html</guid><wfw:comment>http://www.blogjava.net/HappyJava/comments/177480.html</wfw:comment><comments>http://www.blogjava.net/HappyJava/articles/177480.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/HappyJava/comments/commentRss/177480.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/HappyJava/services/trackbacks/177480.html</trackback:ping><description><![CDATA[<div class="tit">Struts Spring Hibernate实现上传下载</div>
<div class="date">2007-09-06 13:31</div>
<table style="table-layout: fixed">
    <tbody>
        <tr>
            <td>
            <div class="cnt"><a href="http://www.mydown.com/code/249/249992.html" target="_blank"><font color="#dd4822"><u>下载本文源代码</u></font></a><br />
            <br />
            　　<strong>引言</strong><br />
            <br />
            　　文件的上传和下载在<a class="bluekey" href="http://www.yesky.com/key/3547/3547.html" target="_blank"><u><font color="#0000ff">J2EE</font></u></a>编程已经是一个非常古老的话题了，也许您马上就能掰着指头数出好几个著名的大件：如SmartUpload、<a class="bluekey" href="http://www.yesky.com/key/927/5927.html" target="_blank"><u><font color="#0000ff">Apache</font></u></a>的FileUpload。但如果您的项目是构建在Struts Spring <a class="bluekey" href="http://www.yesky.com/key/845/5845.html" target="_blank"><u><font color="#0000ff">Hibernate</font></u></a>（以下称SSH）框架上的，这些大件就显得笨重而沧桑了，SSH提供了一个简捷方便的文件上传下载的方案，我们只需要通过一些配置并辅以少量的代码就可以完好解决这个问题了。<br />
            <br />
            　　本文将围绕SSH文件上传下载的主题，向您详细讲述如何开发基于SSH的Web程序。SSH各框架的均为当前最新版本：<br />
            <br />
            　　?Struts 1.2<br />
            <br />
            　　?Spring 1.2.5<br />
            <br />
            　　?Hibernate 3.0<br />
            <br />
            　　本文选用的数据库为<a class="bluekey" href="http://www.yesky.com/key/777/5777.html" target="_blank"><u><font color="#0000ff">Oracle</font></u></a> 9i，当然你可以在不改动代码的情况下，通过配置文件的调整将其移植到任何具有Blob字段类型的数据库上，如<a class="bluekey" href="http://www.yesky.com/key/1784/6784.html" target="_blank"><u><font color="#0000ff">MySQL</font></u></a>，SQLServer等。<br />
            <br />
            　　<strong>总体实现</strong><br />
            <br />
            　　上传文件保存到T_FILE表中，T_FILE表结构如下：<br />
            <br />
            <table width="90%" align="center" border="0">
                <tbody>
                    <tr>
                        <td>
                        <div align="center"><img src="http://www.j2medev.com/Article/UploadFiles/200512/20051223124236286.gif" border="0"  alt="" /><br />
                        图 1 T_FILE表结构</div>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            　　其中：<br />
            <br />
            　　?FILE_ID：文件ID，32个字符，用Hibernate的uuid.hex算法生成。<br />
            <br />
            　　?FILE_NAME：文件名。<br />
            <br />
            　　?FILE_CONTENT：文件内容，对应Oracle的Blob类型。<br />
            <br />
            　　?REMARK：文件备注。<br />
            <br />
            　　文件数据存储在Blob类型的FILE_CONTENT表字段上，在Spring中采用OracleLobHandler来处理Lob字段（包括Clob和Blob），由于在程序中不需要引用到oracle数据驱动程序的具体类且屏蔽了不同数据库处理Lob字段方法上的差别，从而撤除程序在多数据库移植上的樊篱。 <br />
            <br />
            　　1．首先数据表中的Blob字段在Java领域对象中声明为byte[]类型，而非java.sql.Blob类型。<br />
            <br />
            　　2．数据表Blob字段在Hibernate持久化映射文件中的type为org.springframework.orm.hibernate3.support.BlobByteArrayType，即Spring所提供的用户自定义的类型，而非java.sql.Blob。 <br />
            <br />
            　　3．在Spring中使用org.springframework.jdbc.support.lob.OracleLobHandler处理Oracle数据库的Blob类型字段。<br />
            <br />
            　　通过这样的设置和配置，我们就可以象持久化表的一般字段类型一样处理Blob字段了。<br />
            <br />
            　　以上是Spring＋Hibernate将文件二进制数据持久化到数据库的解决方案，而Struts通过将表单中file类型的组件映射为ActionForm中类型为org.apache.struts.upload. FormFile的属性来获取表单提交的文件数据。<br />
            <br />
            　　综上所述，我们可以通过图 2，描绘出SSH处理文件上传的方案：<br />
            <br />
            <table width="90%" align="center" border="0">
                <tbody>
                    <tr>
                        <td>
                        <div align="center"><img src="http://www.j2medev.com/Article/UploadFiles/200512/20051223124239387.jpg" border="0"  alt="" /><br />
                        图 2 SSH处理文件上传技术方案</div>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            　　文件上传的页面如图 3所示：<br />
            <br />
            <table width="90%" align="center" border="0">
                <tbody>
                    <tr>
                        <td>
                        <div align="center"><img src="http://www.j2medev.com/Article/UploadFiles/200512/20051223124241524.jpg" border="0"  alt="" /><br />
                        图 3 文件上传页面</div>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            　　文件下载的页面如图 4所示：<br />
            <br />
            <table width="90%" align="center" border="0">
                <tbody>
                    <tr>
                        <td>
                        <div align="center"><img src="http://www.j2medev.com/Article/UploadFiles/200512/20051223124243421.jpg" border="0"  alt="" /><br />
                        图 4 文件下载页面</div>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            　　该工程的资源结构如图 5所示：<br />
            <br />
            <table width="90%" align="center" border="0">
                <tbody>
                    <tr>
                        <td>
                        <div align="center"><img src="http://www.j2medev.com/Article/UploadFiles/200512/20051223124245158.gif" border="0"  alt="" /><br />
                        图 5 工程资源结构</div>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            　　工程的类按SSH的层次结构划分为数据持久层、业务层和Web层；WEB-INF下的applicationContext.xml为Spring的配置文件，struts-config.xml为Struts的配置文件，file-upload.jsp为文件上传页面，file-list.jsp为文件列表页面。<br />
            <br />
            　　本文后面的章节将从数据持久层-＞业务层-＞Web层的开发顺序，逐层讲解文件上传下载的开发过程。<br />
            <strong>数据持久层<br />
            <br />
            </strong>　　1、领域对象及映射文件<br />
            <br />
            　　您可以使用Hibernate Middlegen、HIbernate Tools、Hibernate Syhchronizer等工具或手工的方式，编写Hibernate的领域对象和映射文件。其中对应T_FILE表的领域对象Tfile.java为：<br />
            <br />
            　　代码 1 领域对象Tfile<br />
            <br />
            <table bordercolor="#cccccc" width="90%" align="center" bgcolor="#e3e3e3" border="1">
                <tbody>
                    <tr>
                        <td>1. package sshfile.model;<br />
                        2. public class Tfile<br />
                        3.{<br />
                        4. private String fileId;<br />
                        5. private String fileName;<br />
                        6. private byte[] fileContent;<br />
                        7. private String remark;<br />
                        8. &#8230;//getter and setter<br />
                        9. }</td>
                    </tr>
                </tbody>
            </table>
            <br />
            　　特别需要注意的是：数据库表为Blob类型的字段在Tfile中的fileContent类型为byte[]。Tfile的Hibernate映射文件Tfile.hbm.xml放在Tfile .java类文件的相同目录下：<br />
            <br />
            　　代码 2 领域对象映射文件<br />
            <br />
            <table bordercolor="#cccccc" width="90%" align="center" bgcolor="#e3e3e3" border="1">
                <tbody>
                    <tr>
                        <td>1. ＜?xml version="1.0"?＞<br />
                        2. ＜!DOCTYPE hibernate-mapping PUBLIC<br />
                        3. "-//Hibernate/Hibernate Mapping DTD 3.0//EN"<br />
                        4. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" ＞<br />
                        5. ＜hibernate-mapping＞<br />
                        6. ＜class name="sshfile.model.Tfile" table="T_FILE"＞<br />
                        7. ＜id name="fileId" type="java.lang.String" column="FILE_ID"＞<br />
                        8. ＜generator class="uuid.hex"/＞<br />
                        9. ＜/id＞<br />
                        10. ＜property name="fileContent"<br />
                        11. type="org.springframework.orm.hibernate3.support.BlobByteArrayType"<br />
                        12. column="FILE_CONTENT" lazy="true"/＞<br />
                        13. &#8230;//其它一般字段的映射<br />
                        14. ＜/class＞<br />
                        15. ＜/hibernate-mapping＞</td>
                    </tr>
                </tbody>
            </table>
            <br />
            　　fileContent字段映射为Spring所提供的BlobByteArrayType类型，BlobByteArrayType是用户自定义的数据类型，它实现了Hibernate 的org.hibernate.usertype.UserType接口。BlobByteArrayType使用从sessionFactory获取的Lob操作句柄lobHandler将byte[]的数据保存到Blob数据库字段中。这样，我们就再没有必要通过硬编码的方式，先insert然后再update来完成Blob类型数据的持久化，这个原来难伺候的老爷终于被平民化了。关于lobHandler的配置请见本文后面的内容。<br />
            <br />
            　　此外lazy="true"说明地返回整个Tfile对象时，并不返回fileContent这个字段的数据，只有在显式调用tfile.getFileContent()方法时才真正从数据库中获取fileContent的数据。这是Hibernate3引入的新特性，对于包含重量级大数据的表字段，这种抽取方式提高了对大字段操作的灵活性，否则加载Tfile对象的结果集时如果总是返回fileContent，这种批量的数据抽取将可以引起数据库的"洪泛效应"。<br />
            <br />
            　　2、DAO编写和配置<br />
            <br />
            　　Spring强调面向接口编程，所以我们将所有对Tfile的数据操作的方法定义在TfileDAO接口中，这些接口方法分别是：<br />
            <br />
            　　?findByFildId(String fileId)<br />
            <br />
            　　?save(Tfile tfile)<br />
            <br />
            　　?List findAll()<br />
            <br />
            　　TfileDAOHibernate提供了对TfileDAO接口基于Hibernate的实现，如代码 3所示：<br />
            <br />
            　　代码 3 基于Hibernate 的fileDAO实现类<br />
            <br />
            <table bordercolor="#cccccc" width="90%" align="center" bgcolor="#e3e3e3" border="1">
                <tbody>
                    <tr>
                        <td>1. package sshfile.dao;<br />
                        2.<br />
                        3. import sshfile.model.*;<br />
                        4. import org.springframework.orm.hibernate3.support.HibernateDaoSupport;<br />
                        5. import java.util.List;<br />
                        6.<br />
                        7. public class TfileDAOHibernate<br />
                        8. extends HibernateDaoSupport implements TfileDAO<br />
                        9. {<br />
                        10. public Tfile findByFildId(String fileId)<br />
                        11. {<br />
                        12. return (Tfile) getHibernateTemplate().get(Tfile.class, fileId);<br />
                        13. }<br />
                        14. public void save(Tfile tfile)<br />
                        15. {<br />
                        16. getHibernateTemplate().save(tfile);<br />
                        17. getHibernateTemplate().flush();<br />
                        18. }<br />
                        19. public List findAll()<br />
                        20. {<br />
                        21. return getHibernateTemplate().loadAll(Tfile.class);<br />
                        22. }<br />
                        23. }</td>
                    </tr>
                </tbody>
            </table>
            <br />
            　　TfileDAOHibernate通过扩展Spring提供的Hibernate支持类HibernateDaoSupport而建立，HibernateDaoSupport封装了HibernateTemplate，而HibernateTemplate封装了Hibernate所提供几乎所有的的数据操作方法，如execute(HibernateCallback action)，load(Class entityClass, Serializable id)，save(final Object entity)等等。<br />
            <br />
            　　所以我们的DAO只需要简单地调用父类的HibernateTemplate就可以完成几乎所有的数据库操作了。<br />
            <br />
            　　由于Spring通过代理Hibernate完成数据层的操作，所以原Hibernate的配置文件hibernate.cfg.xml的信息也转移到Spring的配置文件中：<br />
            <br />
            　　代码 4 Spring中有关Hibernate的配置信息<br />
            <br />
            <table bordercolor="#cccccc" width="90%" align="center" bgcolor="#e3e3e3" border="1">
                <tbody>
                    <tr>
                        <td>1. ＜beans＞<br />
                        2. ＜!-- 数据源的配置 //--＞<br />
                        3. ＜bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"<br />
                        4. destroy-method="close"＞<br />
                        5. ＜property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/＞<br />
                        6. ＜property name="url" value="jdbc:oracle:thin:@localhost:1521:ora9i"/＞<br />
                        7. ＜property name="username" value="test"/＞<br />
                        8. ＜property name="password" value="test"/＞<br />
                        9. ＜/bean＞<br />
                        10. ＜!-- Hibernate会话工厂配置 //--＞<br />
                        11. ＜bean id="sessionFactory"<br />
                        12. class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"＞<br />
                        13. ＜property name="dataSource" ref="dataSource"/＞<br />
                        14. ＜property name="mappingDirectoryLocations"＞<br />
                        15. ＜list＞<br />
                        16. ＜value＞classpath:/sshfile/model＜/value＞<br />
                        17. ＜/list＞<br />
                        18. ＜/property＞<br />
                        19. ＜property name="hibernateProperties"＞<br />
                        20. ＜props＞<br />
                        21. ＜prop key="hibernate.dialect"＞org.hibernate.dialect.OracleDialect＜/prop＞<br />
                        22. ＜prop key="hibernate.cglib.use_reflection_optimizer"＞true＜/prop＞<br />
                        23. ＜/props＞<br />
                        24. ＜/property＞<br />
                        25. ＜/bean＞<br />
                        26. ＜!-- Hibernate 模板//--＞<br />
                        27. ＜bean id="hibernateTemplate"<br />
                        28. class="org.springframework.orm.hibernate3.HibernateTemplate"＞<br />
                        29. ＜property name="sessionFactory" ref="sessionFactory"/＞<br />
                        30. ＜/bean＞<br />
                        31. ＜!--DAO配置 //--＞<br />
                        32. ＜bean id="tfileDAO" class="sshfile.dao.TfileDAOHibernate"＞<br />
                        33. ＜property name="hibernateTemplate" ref="hibernateTemplate" /＞<br />
                        34. ＜/bean＞<br />
                        35. &#8230;<br />
                        36. ＜/beans＞</td>
                    </tr>
                </tbody>
            </table>
            <br />
            　　第3~9行定义了一个数据源，其实现类是apache的BasicDataSource，第11~25行定义了Hibernate的会话工厂，会话工厂类用Spring提供的LocalSessionFactoryBean维护，它注入了数据源和资源映射文件，此外还通过一些键值对设置了Hibernate所需的属性。<br />
            <br />
            　　其中第16行通过类路径的映射方式，将sshfile.model类包目录下的所有领域对象的映射文件装载进来，在本文的例子里，它将装载进Tfile.hbm.xml映射文件。如果有多个映射文件需要声明，使用类路径映射方式显然比直接单独指定映射文件名的方式要简便。 <br />
            <br />
            　　第27~30行定义了Spring代理Hibernate数据操作的HibernateTemplate模板，而第32~34行将该模板注入到tfileDAO中。<br />
            <br />
            　　需要指定的是Spring 1.2.5提供了两套Hibernate的支持包，其中Hibernate 2相关的封装类位于org.springframework.orm.hibernate2.*包中，而Hibernate 3.0的封装类位于org.springframework.orm.hibernate3.*包中，需要根据您所选用Hibernate版本进行正确选择。<br />
            <br />
            　　3、Lob字段处理的配置<br />
            <br />
            　　我们前面已经指出Oracle的Lob字段和一般类型的字段在操作上有一个明显的区别--那就是你必须首先通过Oracle的empty_blob()/empty_clob()初始化Lob字段，然后获取该字段的引用，通过这个引用更改其值。所以要完成对Lob字段的操作，Hibernate必须执行两步数据库访问操作，先Insert再Update。<br />
            <br />
            　　使用BlobByteArrayType字段类型后，为什么我们就可以象一般的字段类型一样操作Blob字段呢？可以确定的一点是：BlobByteArrayType不可能逾越Blob天生的操作方式，原来是BlobByteArrayType数据类型本身具体数据访问的功能，它通过LobHandler将两次数据访问的动作隐藏起来，使Blob字段的操作在表现上和其他一般字段业类型无异，所以LobHandler即是那个"苦了我一个，幸福十亿人"的那位幕后英雄。<br />
            <br />
            　　LobHandler必须注入到Hibernate会话工厂sessionFactory中，因为sessionFactory负责产生与数据库交互的Session。LobHandler的配置如代码 5所示：<br />
            <br />
            　　代码 5 Lob字段的处理句柄配置<br />
            <br />
            <table bordercolor="#cccccc" width="90%" align="center" bgcolor="#e3e3e3" border="1">
                <tbody>
                    <tr>
                        <td>1. ＜beans＞<br />
                        2. &#8230;<br />
                        3. ＜bean id="nativeJdbcExtractor"<br />
                        4. class="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor"<br />
                        5. lazy-init="true"/＞<br />
                        6. ＜bean id="lobHandler"<br />
                        7. class="org.springframework.jdbc.support.lob.OracleLobHandler" lazy-init="true"＞<br />
                        8. ＜property name="nativeJdbcExtractor"＞<br />
                        9. ＜ref local="nativeJdbcExtractor"/＞<br />
                        10. ＜/property＞<br />
                        11. ＜/bean＞<br />
                        12. &#8230;<br />
                        13. ＜/beans＞</td>
                    </tr>
                </tbody>
            </table>
            <br />
            　　首先，必须定义一个能够从连接池中抽取出本地数据库JDBC对象（如OracleConnection，OracleResultSet等）的抽取器：nativeJdbcExtractor，这样才可以执行一些特定数据库的操作。对于那些仅封装了Connection而未包括Statement的简单数据连接池，SimpleNativeJdbcExtractor是效率最高的抽取器实现类，但具体到apache的BasicDataSource连接池，它封装了所有JDBC的对象，这时就需要使用CommonsDbcpNativeJdbcExtractor了。Spring针对几个著名的Web服务器的数据源提供了相应的JDBC抽取器：<br />
            <br />
            　　?WebLogic：WebLogicNativeJdbcExtractor<br />
            <br />
            　　?WebSphere：WebSphereNativeJdbcExtractor<br />
            <br />
            　　?JBoss：JBossNativeJdbcExtractor<br />
            <br />
            　　在定义了JDBC抽取器后，再定义lobHandler。Spring 1.2.5提供了两个lobHandler：<br />
            <br />
            　　?DefaultLobHandler：适用于大部分的数据库，如SqlServer，MySQL，对Oracle 10g也适用，但不适用于Oracle 9i（看来Oracle 9i确实是个怪胎，谁叫Oracle 公司自己都说Oracle 9i是一个过渡性的产品呢）。<br />
            <br />
            　　?OracleLobHandler：适用于Oracle 9i和Oracle 10g。<br />
            <br />
            　　由于我们的数据库是Oracle9i，所以使用OracleLobHandler。<br />
            <br />
            　　在配置完LobHandler后， 还需要将其注入到sessionFactory的Bean中，下面是调用后的sessionFactory Bean的配置：<br />
            <br />
            　　代码 6 将lobHandler注入到sessionFactory中的配置<br />
            <br />
            <table bordercolor="#cccccc" width="90%" align="center" bgcolor="#e3e3e3" border="1">
                <tbody>
                    <tr>
                        <td>1. ＜beans＞<br />
                        2. &#8230;<br />
                        3. ＜bean id="sessionFactory"<br />
                        4. class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"＞<br />
                        5. ＜property name="dataSource" ref="dataSource"/＞<br />
                        6. ＜!-- 为处理Blob类型字段的句柄声明 //--＞<br />
                        7. ＜property name="lobHandler" ref="lobHandler"/＞<br />
                        8. &#8230;<br />
                        9. ＜/bean＞<br />
                        10. &#8230;<br />
                        11. ＜/beans＞</td>
                    </tr>
                </tbody>
            </table>
            <p><br />
            　　如第7所示，通过sessionFactory的lobHandler属性进行注入。</p>
            <p><strong>业务层<br />
            <br />
            </strong>　　1、业务层接口<br />
            <br />
            　　"面向接口而非面向类编程"是Spring不遗余力所推荐的编程原则，这条原则也已经为大部开发者所接受；此外，JDK的动态代理只对接口有效，否则必须使用CGLIB生成目标类的子类。我们依从于Spring的倡导为业务类定义一个接口：<br />
            <br />
            　　代码 7 业务层操作接口<br />
            <br />
            <table bordercolor="#cccccc" width="90%" align="center" bgcolor="#e3e3e3" border="1">
                <tbody>
                    <tr>
                        <td>1. public interface FileService<br />
                        2. {<br />
                        3. void save(FileActionForm fileForm);//将提交的上传文件保存到数据表中<br />
                        4. List getAllFile();//得到T_FILE所示记录<br />
                        5. void write(OutputStream os,String fileId);//将某个文件的文件数据写出到输出流中<br />
                        6. String getFileName(String fileId);//获取文件名<br />
                        7. }</td>
                    </tr>
                </tbody>
            </table>
            <br />
            　　其中save(FileActionForm fileForm)方法，将封装在fileForm中的上传文件保存到数据库中，这里我们使用FileActionForm作为方法入参，FileActionForm是Web层的表单数据对象，它封装了提交表单的数据。将FileActionForm直接作为业务层的接口入参，相当于将Web层传播到业务层中去，即将业务层绑定在特定的Web层实现技术中，按照分层模型学院派的观点，这是一种反模块化的设计，但在"一般"的业务系统并无需提供多种UI界面，系统Web层将来切换到另一种实现技术的可能性也微乎其微，所以笔者觉得没有必要为了这个业务层完全独立于调用层的过高目标而去搞一个额外的隔离层，浪费了原材料不说，还将系统搞得过于复杂，相比于其它原则，"简单"始终是最大的一条原则。<br />
            <br />
            　　getAllFile()负责获取T_FILE表所有记录，以便在网页上显示出来。<br />
            <br />
            　　而getFileName(String fileId)和write(OutputStream os,String fileId)则用于下载某个特定的文件。具体的调用是将Web层将response.getOutputStream()传给write(OutputStream os,String fileId)接口，业务层直接将文件数据输出到这个响应流中。具体实现请参见错误！未找到引用源。节下载文件部分。<br />
            <br />
            　　2、业务层接口实现类<br />
            <br />
            　　FileService的实现类为FileServiceImpl，其中save(FileActionForm fileForm)的实现如下所示：<br />
            <br />
            　　代码 8 业务接口实现类之save()<br />
            <br />
            <table bordercolor="#cccccc" width="90%" align="center" bgcolor="#e3e3e3" border="1">
                <tbody>
                    <tr>
                        <td>1. &#8230;<br />
                        2. public class FileServiceImpl<br />
                        3. implements FileService<br />
                        4. {<br />
                        5. private TfileDAO tfileDAO;<br />
                        6. public void save(FileActionForm fileForm)<br />
                        7. {<br />
                        8. Tfile tfile = new Tfile();<br />
                        9. try<br />
                        10. {<br />
                        11. tfile.setFileContent(fileForm.getFileContent().getFileData());<br />
                        12. }<br />
                        13. catch (FileNotFoundException ex)<br />
                        14. {<br />
                        15. throw new RuntimeException(ex);<br />
                        16. }<br />
                        17. catch (IOException ex)<br />
                        18. {<br />
                        19. throw new RuntimeException(ex);<br />
                        20. }<br />
                        21. tfile.setFileName(fileForm.getFileContent().getFileName());<br />
                        22. tfile.setRemark(fileForm.getRemark());<br />
                        23. tfileDAO.save(tfile);<br />
                        24. }<br />
                        25. &#8230;<br />
                        26. }</td>
                    </tr>
                </tbody>
            </table>
            <br />
            　　在save(FileActionForm fileForm)方法里，完成两个步骤：<br />
            <br />
            　　其一，象在水桶间倒水一样，将FileActionForm对象中的数据倒入到Tfile对象中；<br />
            <br />
            　　其二，调用TfileDAO保存数据。<br />
            <br />
            　　需要特别注意的是代码的第11行，FileActionForm的fileContent属性为org.apache.struts.upload.FormFile类型，FormFile提供了一个方便的方法getFileData()，即可获取文件的二进制数据。通过解读FormFile接口实现类DiskFile的原码，我们可能知道FormFile本身并不缓存文件的数据，只有实际调用getFileData()时，才从磁盘文件输入流中获取数据。由于FormFile使用流读取方式获取数据，本身没有缓存文件的所有数据，所以对于上传超大体积的文件，也是没有问题的；但是，由于数据持久层的Tfile使用byte[]来缓存文件的数据，所以并不适合处理超大体积的文件（如100M），对于超大体积的文件，依然需要使用java.sql.Blob类型以常规流操作的方式来处理。<br />
            <br />
            　　此外，通过FileForm的getFileName()方法就可以获得上传文件的文件名，如第21行代码所示。<br />
            <br />
            　　write(OutputStream os,String fileId)方法的实现，如代码 9所示：<br />
            <br />
            　　代码 9 业务接口实现类之write()<br />
            <br />
            <table bordercolor="#cccccc" width="90%" align="center" bgcolor="#e3e3e3" border="1">
                <tbody>
                    <tr>
                        <td>1. &#8230;<br />
                        2. public class FileServiceImpl<br />
                        3. implements FileService<br />
                        4. {<br />
                        5.<br />
                        6. public void write(OutputStream os, String fileId)<br />
                        7. {<br />
                        8. Tfile tfile = tfileDAO.findByFildId(fileId);<br />
                        9. try<br />
                        10. {<br />
                        11. os.write(tfile.getFileContent());<br />
                        12. os.flush();<br />
                        13. }<br />
                        14. catch (IOException ex)<br />
                        15. {<br />
                        16. throw new RuntimeException(ex);<br />
                        17. }<br />
                        18. }<br />
                        19. &#8230;<br />
                        20. }</td>
                    </tr>
                </tbody>
            </table>
            <br />
            　　write(OutputStream os,String fileId)也简单地分为两个操作步骤，首先，根据fileId加载表记录，然后将fileContent写入到输出流中。<br />
            <br />
            　　3、Spring事务配置<br />
            <br />
            　　下面，我们来看如何在Spring配置文件中为FileService配置声明性的事务<br />
            <br />
            <table bordercolor="#cccccc" width="90%" align="center" bgcolor="#e3e3e3" border="1">
                <tbody>
                    <tr>
                        <td>1. ＜beans＞<br />
                        2. &#8230; <br />
                        3. ＜bean id="transactionManager"<br />
                        4. class="org.springframework.orm.hibernate3.HibernateTransactionManager"＞<br />
                        5. ＜property name="sessionFactory" ref="sessionFactory"/＞<br />
                        6. ＜/bean＞<br />
                        7. ＜!-- 事务处理的AOP配置 //--＞<br />
                        8. ＜bean id="txProxyTemplate" abstract="true"<br />
                        9. class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"＞<br />
                        10. ＜property name="transactionManager" ref="transactionManager"/＞<br />
                        11. ＜property name="transactionAttributes"＞<br />
                        12. ＜props＞<br />
                        13. ＜prop key="get*"＞PROPAGATION_REQUIRED,readOnly＜/prop＞<br />
                        14. ＜prop key="find*"＞PROPAGATION_REQUIRED,readOnly＜/prop＞<br />
                        15. ＜prop key="save"＞PROPAGATION_REQUIRED＜/prop＞<br />
                        16. ＜prop key="write"＞PROPAGATION_REQUIRED,readOnly＜/prop＞<br />
                        17. ＜/props＞<br />
                        18. ＜/property＞<br />
                        19. ＜/bean＞<br />
                        20. ＜bean id="fileService" parent="txProxyTemplate"＞<br />
                        21. ＜property name="target"＞<br />
                        22. ＜bean class="sshfile.service.FileServiceImpl"＞<br />
                        23. ＜property name="tfileDAO" ref="tfileDAO"/＞<br />
                        24. ＜/bean＞<br />
                        25. ＜/property＞<br />
                        26. ＜/bean＞<br />
                        27. ＜/beans＞</td>
                    </tr>
                </tbody>
            </table>
            <br />
            　　Spring的事务配置包括两个部分：<br />
            <br />
            　　其一，定义事务管理器transactionManager，使用HibernateTransactionManager实现事务管理；<br />
            <br />
            　　其二，对各个业务接口进行定义，其实txProxyTemplate和fileService是父子节点的关系，本来可以将txProxyTemplate定义的内容合并到fileService中一起定义，由于我们的系统仅有一个业务接口需要定义，所以将其定义的一部分抽象到父节点txProxyTemplate中意义确实不大，但是对于真实的系统，往往拥有为数众多的业务接口需要定义，将这些业务接口定义内容的共同部分抽取到一个父节点中，然后在子节点中通过parent进行关联，就可以大大简化业务接口的配置了。<br />
            <br />
            　　父节点txProxyTemplate注入了事务管理器，此外还定义了业务接口事务管理的方法（允许通过通配符的方式进行匹配声明，如前两个接口方法），有些接口方法仅对数据进行读操作，而另一些接口方法需要涉及到数据的更改。对于前者，可以通过readOnly标识出来，这样有利于操作性能的提高，需要注意的是由于父类节点定义的Bean仅是子节点配置信息的抽象，并不能具体实现化一个Bean对象，所以需要特别标注为abstract="true"，如第8行所示。<br />
            <br />
            　　fileService作为一个目标类被注入到事务代理器中，而fileService实现类所需要的tfileDAO实例，通过引用3.2节中定义的tfileDAO Bean注入。<br />
            <strong>Web层实现<br />
            <br />
            </strong>　　1、Web层的构件和交互流程<br />
            <br />
            　　Web层包括主要3个功能：<br />
            <br />
            　　?上传文件。<br />
            <br />
            　　?列出所有已经上传的文件列表，以供点击下载。<br />
            <br />
            　　?下载文件。<br />
            <br />
            　　Web层实现构件包括与2个JSP页面，1个ActionForm及一个Action：<br />
            <br />
            　　?file-upload.jsp：上传文件的页面。<br />
            <br />
            　　?file-list.jsp：已经上传文件的列表页面。<br />
            <br />
            　　?FileActionForm：file-upload.jsp页面表单对应的ActionForm。<br />
            <br />
            　　?FileAction：继承org.apache.struts.actions.DispatchAction的Action，这样这个Action就可以通过一个URL参数区分中响应不同的请求。<br />
            <br />
            　　Web层的这些构件的交互流程如图 6所示：<br />
            <br />
            <table width="90%" align="center" border="0">
                <tbody>
                    <tr>
                        <td>
                        <div align="center"><img src="http://www.j2medev.com/Article/UploadFiles/200512/20051223124246845.jpg" border="0"  alt="" /><br />
                        图 6 Web层Struts流程图</div>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            　　其中，在执行文件上传的请求时，FileAction在执行文件上传后，forward到loadAllFile出口中，loadAllFile加载数据库中所有已经上传的记录，然后forward到名为fileListPage的出口中，调用file-list.jsp页面显示已经上传的记录。<br />
            <br />
            　　2、FileAction功能<br />
            <br />
            　　Struts 1.0的Action有一个弱项：一个Action只能处理一种请求，Struts 1.1中引入了一个DispatchAction，允许通过URL参数指定调用Action中的某个方法，如http://yourwebsite/fileAction.do?method=upload即调用FileAction中的upload方法。通过这种方式，我们就可以将一些相关的请求集中到一个Action当中编写，而没有必要为某个请求操作编写一个Action类。但是参数名是要在struts-config.xml中配置的：<br />
            <br />
            <table bordercolor="#cccccc" width="90%" align="center" bgcolor="#e3e3e3" border="1">
                <tbody>
                    <tr>
                        <td>1. ＜struts-config＞<br />
                        2. ＜form-beans＞<br />
                        3. ＜form-bean name="fileActionForm" type="sshfile.web.FileActionForm" /＞<br />
                        4. ＜/form-beans＞<br />
                        5. ＜action-mappings＞<br />
                        6. ＜action name="fileActionForm" parameter="method" path="/fileAction"<br />
                        7. type="sshfile.web.FileAction"＞<br />
                        8. ＜forward name="fileListPage" path="/file-list.jsp" /＞<br />
                        9. ＜forward name="loadAllFile" path="/fileAction.do?method=listAllFile" /＞<br />
                        10. ＜/action＞<br />
                        11. ＜/action-mappings＞<br />
                        12. ＜/struts-config＞</td>
                    </tr>
                </tbody>
            </table>
            <br />
            　　第6行的parameter="method"指定了承载方法名的参数，第9行中，我们还配置了一个调用FileAction不同方法的Action出口。<br />
            <br />
            　　FileAction共有3个请求响应的方法，它们分别是：<br />
            <br />
            　　?upload(&#8230;)：处理上传文件的请求。<br />
            <br />
            　　?listAllFile(&#8230;)：处理加载数据库表中所有记录的请求。<br />
            <br />
            　　?download（&#8230;）：处理下载文件的请求。<br />
            <br />
            　　下面我们分别对这3个请求处理方法进行讲解。<br />
            <br />
            　　2.1 上传文件<br />
            <br />
            　　上传文件的请求处理方法非常简单，简之言之，就是从Spring容器中获取业务层处理类FileService，调用其save(FileActionForm form)方法上传文件，如下所示：<br />
            <br />
            <table bordercolor="#cccccc" width="90%" align="center" bgcolor="#e3e3e3" border="1">
                <tbody>
                    <tr>
                        <td>1. public class FileAction<br />
                        2. extends DispatchAction<br />
                        3. {<br />
                        4. //将上传文件保存到数据库中<br />
                        5. public ActionForward upload(ActionMapping mapping, ActionForm form,<br />
                        6. HttpServletRequest request,<br />
                        7. HttpServletResponse response)<br />
                        8. {<br />
                        9. FileActionForm fileForm = (FileActionForm) form;<br />
                        10. FileService fileService = getFileService();<br />
                        11. fileService.save(fileForm);<br />
                        12. return mapping.findForward("loadAllFile");<br />
                        13. }<br />
                        14. //从Spring容器中获取FileService对象<br />
                        15. private FileService getFileService()<br />
                        16. {<br />
                        17. ApplicationContext appContext = WebApplicationContextUtils.<br />
                        18. getWebApplicationContext(this.getServlet().getServletContext());<br />
                        19. return (FileService) appContext.getBean("fileService");<br />
                        20. }<br />
                        21. &#8230;<br />
                        22. }</td>
                    </tr>
                </tbody>
            </table>
            <br />
            　　由于FileAction其它两个请求处理方法也需要从Spring容器中获取FileService实例，所以我们特别提供了一个getFileService()方法（第15~21行）。重构的一条原则就是："发现代码中有重复的表达式，将其提取为一个变量；发现类中有重复的代码段，将其提取为一个方法；发现不同类中有相同的方法，将其提取为一个类"。在真实的系统中，往往拥有多个Action和多个Service类，这时一个比较好的设置思路是，提供一个获取所有Service实现对象的工具类，这样就可以将Spring 的Service配置信息屏蔽在一个类中，否则Service的配置名字散落在程序各处，维护性是很差的。<br />
            <br />
            　　2.2 列出所有已经上传的文件<br />
            <br />
            　　listAllFile方法调用Servie层方法加载T_FILE表中所有记录，并将其保存在Request域中，然后forward到列表页面中：<br />
            <br />
            <table bordercolor="#cccccc" width="90%" align="center" bgcolor="#e3e3e3" border="1">
                <tbody>
                    <tr>
                        <td>1. public class FileAction<br />
                        2. extends DispatchAction<br />
                        3. {<br />
                        4. &#8230;<br />
                        5. public ActionForward listAllFile(ActionMapping mapping, ActionForm form,<br />
                        6. HttpServletRequest request,<br />
                        7. HttpServletResponse response)<br />
                        8. throws ModuleException<br />
                        9. {<br />
                        10. FileService fileService = getFileService();<br />
                        11. List fileList = fileService.getAllFile();<br />
                        12. request.setAttribute("fileList",fileList);<br />
                        13. return mapping.findForward("fileListPage");<br />
                        14. }<br />
                        15. }</td>
                    </tr>
                </tbody>
            </table>
            <br />
            　　file-list.jsp页面使用Struts标签展示出保存在Request域中的记录：<br />
            <br />
            <table bordercolor="#cccccc" width="90%" align="center" bgcolor="#e3e3e3" border="1">
                <tbody>
                    <tr>
                        <td>1. ＜%@page contentType="text/html; charset=GBK"%＞<br />
                        2. ＜%@taglib uri="/WEB-INF/struts-logic.tld" prefix="logic"%＞<br />
                        3. ＜%@taglib uri="/WEB-INF/struts-bean.tld" prefix="bean"%＞<br />
                        4. ＜html＞<br />
                        5. ＜head＞<br />
                        6. ＜title＞file-download＜/title＞<br />
                        7. ＜/head＞<br />
                        8. ＜body bgcolor="#ffffff"＞<br />
                        9. ＜ol＞<br />
                        10. ＜logic:iterate id="item" name="fileList" scope="request"＞<br />
                        11. ＜li＞<br />
                        12. ＜a href='fileAction.do?method=download&amp;fileId=<br />
                        13. ＜bean:write name="item"property="fileId"/＞'＞<br />
                        14. ＜bean:write name="item" property="fileName"/＞<br />
                        15. ＜/a＞<br />
                        16. ＜/li＞<br />
                        17. ＜/logic:iterate＞<br />
                        18. ＜/ol＞<br />
                        19. ＜/body＞<br />
                        20. ＜/html＞</td>
                    </tr>
                </tbody>
            </table>
            <br />
            　　展现页面的每条记录挂接着一个链接地址，形如：fileAction.do?method=download&amp;fileId=xxx，method参数指定了这个请求由FileAction的download方法来响应，fileId指定了记录的主键。<br />
            <br />
            　　由于在FileActionForm中，我们定义了fileId的属性，所以在download响应方法中，我们将可以从FileActionForm中取得fileId的值。这里涉及到一个处理多个请求Action所对应的ActionForm的设计问题，由于原来的Action只能对应一个请求，那么原来的ActionForm非常简单，它仅需要将这个请求的参数项作为其属性就可以了，但现在一个Action对应多个请求，每个请求所对应的参数项是不一样的，此时的ActionForm的属性就必须是多请求参数项的并集了。所以，除了文件上传请求所对应的fileContent和remark属性外还包括文件下载的fileId属性：<br />
            <br />
            <table width="90%" align="center" border="0">
                <tbody>
                    <tr>
                        <td>
                        <div align="center"><img src="http://www.j2medev.com/Article/UploadFiles/200512/20051223124247394.jpg" border="0"  alt="" /><br />
                        图 7 FileActionForm</div>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            　　当然这样会造成属性的冗余，比如在文件上传的请求中，只会用到fileContent和remark属性，而在文件下载的请求时，只会使用到fileId属性。但这种冗余是会带来好处的--它使得一个Action可以处理多个请求。<br />
            <br />
            　　2.3 下载文件<br />
            <br />
            　　在列表页面中点击一个文件下载，其请求由FileAction的download方法来响应，download方法调用业务层的FileService方法，获取文件数据并写出到response的响应流中。通过合理设置HTTP响应头参数，将响应流在客户端表现为一个下载文件对话框，其代码如下所示：<br />
            <br />
            　　代码 10 业务接口实现类之download<br />
            <br />
            <table bordercolor="#cccccc" width="90%" align="center" bgcolor="#e3e3e3" border="1">
                <tbody>
                    <tr>
                        <td>1. public class FileAction<br />
                        2. extends DispatchAction<br />
                        3. {<br />
                        4. &#8230;<br />
                        5. public ActionForward download(ActionMapping mapping, ActionForm form,<br />
                        6. HttpServletRequest request,<br />
                        7. HttpServletResponse response)<br />
                        8. throws ModuleException<br />
                        9. {<br />
                        10. FileActionForm fileForm = (FileActionForm) form;<br />
                        11. FileService fileService = getFileService();<br />
                        12. String fileName = fileService.getFileName(fileForm.getFileId());<br />
                        13. try<br />
                        14. {<br />
                        15. response.setContentType("application/x-msdownload");<br />
                        16. response.setHeader("Content-Disposition",<br />
                        17. "attachment;" " filename=" <br />
                        18. new String(fileName.getBytes(), "ISO-8859-1"));<br />
                        19. fileService.write(response.getOutputStream(), fileForm.getFileId());<br />
                        20. }<br />
                        21. catch (Exception e)<br />
                        22. {<br />
                        23. throw new ModuleException(e.getMessage());<br />
                        24. }<br />
                        25. return null;<br />
                        26. }<br />
                        27. }</td>
                    </tr>
                </tbody>
            </table>
            <br />
            　　第15~18行，设置HTTP响应头，将响应类型设置为application/x-msdownload MIME类型，则响应流在IE中将弹出一个文件下载的对话框，如图 4所示。IE所支持的MIME类型多达26种，您可以通过这个网址查看其他的MIME类型：<br />
            <br />
            http://msdn.microsoft.com/workshop/networking/moniker/overview/appendix_a.asp。<br />
            <br />
            　　如果下载文件的文件名含有中文字符，如果不对其进行硬编码，如第18行所示，客户文件下载对话框中出现的文件名将会发生乱码。<br />
            第19行代码获得response的输出流，作为FileServie write(OutputStream os,String fileId)的入参，这样文件的内容将写到response的输出流中。<br />
            <br />
            　　3、web.xml文件的配置<br />
            <br />
            　　Spring容器在何时启动呢？我可以在Web容器初始化来执行启动Spring容器的操作，Spring提供了两种方式启动的方法：<br />
            <br />
            　　?通过org.springframework.web.context .ContextLoaderListener容器监听器，在Web容器初始化时触发初始化Spring容器，在web.xml中通过＜listener＞＜/listener＞对其进行配置。<br />
            <br />
            　　?通过Servlet org.springframework.web.context.ContextLoaderServlet，将其配置为自动启动的Servlet，在Web容器初始化时，通过这个Servlet启动Spring容器。<br />
            <br />
            　　在初始化Spring容器之前，必须先初始化log4J的引擎，Spring也提供了容器监听器和自动启动Servlet两种方式对log4J引擎进行初始化：<br />
            <br />
            　　?org.springframework.web.util .Log4jConfigListener<br />
            <br />
            　　?org.springframework.web.util.Log4jConfigServlet<br />
            <br />
            　　下面我们来说明如何配置web.xml启动Spring容器：<br />
            <br />
            　　代码 11 web.xml中对应Spring的配置内容<br />
            <br />
            <table bordercolor="#cccccc" width="90%" align="center" bgcolor="#e3e3e3" border="1">
                <tbody>
                    <tr>
                        <td>1. ＜web-app＞<br />
                        2. ＜context-param＞<br />
                        3. ＜param-name＞contextConfigLocation＜/param-name＞<br />
                        4. ＜param-value＞/WEB-INF/applicationContext.xml＜/param-value＞<br />
                        5. ＜/context-param＞<br />
                        6. ＜context-param＞<br />
                        7. ＜param-name＞log4jConfigLocation＜/param-name＞<br />
                        8. ＜param-value＞/WEB-INF/log4j.properties＜/param-value＞<br />
                        9. ＜/context-param＞<br />
                        10. ＜servlet＞<br />
                        11. ＜servlet-name＞log4jInitServlet＜/servlet-name＞<br />
                        12. ＜servlet-class＞org.springframework.web.util.Log4jConfigServlet＜/servlet-class＞<br />
                        13. ＜load-on-startup＞1＜/load-on-startup＞<br />
                        14. ＜/servlet＞<br />
                        15. ＜servlet＞<br />
                        16. ＜servlet-name＞springInitServlet＜/servlet-name＞<br />
                        17. ＜servlet-class＞org.springframework.web.context.ContextLoaderServlet＜/servlet-class＞<br />
                        18. ＜load-on-startup＞2＜/load-on-startup＞<br />
                        19. ＜/servlet＞<br />
                        20. &#8230;<br />
                        21. ＜/web-app＞</td>
                    </tr>
                </tbody>
            </table>
            <br />
            　　启动Spring容器时，需要得到两个信息：Spring配置文件的地址和Log4J属性文件，这两上信息分别通过contextConfigLocationWeb和log4jConfigLocation容器参数指定，如果有多个Spring配置文件，则用逗号隔开，如：<br />
            <br />
            /WEB-INF/applicationContext_1.xml, /WEB-INF/applicationContext_1.xm2<br />
            <br />
            　　由于在启动ContextLoaderServlet之前，必须事先初始化Log4J的引擎，所以Log4jConfigServlet必须在ContextLoaderServlet之前启动，这通过＜load-on-startup＞来指定它们启动的先后顺序。<br />
            <br />
            　　乱码是开发Web应用程序一个比较老套又常见问题，由于不同Web应用服务器的默认编码是不一样的，为了方便Web应用在不同的Web应用服务器上移植，最好的做法是Web程序自身来处理编码转换的工作。经典的作法是在web.xml中配置一个编码转换过滤器，Spring就提供了一个编码过滤器类CharacterEncodingFilter，下面，我们为应用配置上这个过滤器：<br />
            <br />
            <table bordercolor="#cccccc" width="90%" align="center" bgcolor="#e3e3e3" border="1">
                <tbody>
                    <tr>
                        <td>1. ＜web-app＞<br />
                        2. &#8230;<br />
                        3. ＜filter＞<br />
                        4. ＜filter-name＞encodingFilter＜/filter-name＞<br />
                        5. ＜filter-class＞org.springframework.web.filter.CharacterEncodingFilter＜/filter-class＞<br />
                        6. ＜init-param＞<br />
                        7. ＜param-name＞encoding＜/param-name＞<br />
                        8. ＜param-value＞GBK＜/param-value＞<br />
                        9. ＜/init-param＞<br />
                        10. ＜/filter＞<br />
                        11. ＜filter-mapping＞<br />
                        12. ＜filter-name＞encodingFilter＜/filter-name＞<br />
                        13. ＜url-pattern＞/*＜/url-pattern＞<br />
                        14. ＜/filter-mapping＞<br />
                        15. &#8230;<br />
                        16. ＜/web-app＞</td>
                    </tr>
                </tbody>
            </table>
            <br />
            　　Spring的过滤器类是org.springframework.web.filter.CharacterEncodingFilter，通过encoding参数指定编码转换类型为GBK，＜filter-mapping＞的配置使该过滤器截获所有的请示。<br />
            <br />
            　　Struts的框架也需要在web.xml中配置，想必读者朋友对Struts的配置都很熟悉，故在此不再提及，请参见本文所提供的源码。<br />
            <br />
            　　<strong>总结</strong><br />
            <br />
            　　本文通过一个文件上传下载的Web应用，讲解了如何构建基于SSH的Web应用，通过Struts和FormFile，Spring的LobHandler以及Spring为HibernateBlob处理所提供的用户类BlobByteArrayType ，实现上传和下载文件的功能仅需要廖廖数行的代码即告完成。读者只需对程序作稍许的调整，即可处理Clob字段：<br />
            <br />
            　　?领域对象对应Clob字段的属性声明为String类型；<br />
            <br />
            　　?映射文件对应Clob字段的属性声明为org.springframework.orm.hibernate3.support.ClobStringType类型。<br />
            <br />
            　　本文通过SSH对文件上传下载简捷完美的实现得以管中窥豹了解SSH强强联合构建Web应用的强大优势。在行文中，还穿插了一些分层的设计经验，配置技巧和Spring所提供的方便类，相信这些知识对您的开发都有所裨益。</p>
            </div>
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.blogjava.net/HappyJava/aggbug/177480.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/HappyJava/" target="_blank">李建軍</a> 2008-01-24 13:48 <a href="http://www.blogjava.net/HappyJava/articles/177480.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts实现上传下载</title><link>http://www.blogjava.net/HappyJava/articles/177478.html</link><dc:creator>李建軍</dc:creator><author>李建軍</author><pubDate>Thu, 24 Jan 2008 05:46:00 GMT</pubDate><guid>http://www.blogjava.net/HappyJava/articles/177478.html</guid><wfw:comment>http://www.blogjava.net/HappyJava/comments/177478.html</wfw:comment><comments>http://www.blogjava.net/HappyJava/articles/177478.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/HappyJava/comments/commentRss/177478.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/HappyJava/services/trackbacks/177478.html</trackback:ping><description><![CDATA[<div class="tit">&nbsp;</div>
<div class="date">2006年11月08日 星期三 下午 08:36</div>
<table style="table-layout: fixed">
    <tbody>
        <tr>
            <td>
            <div class="cnt">
            <p><font style="background-color: #ff0000">上传代码：</font></p>
            <p><font style="background-color: #ff0000">UploadActionForm.java中内容</font></p>
            <p>package com.seavision.OurSecond.action.knowledge;</p>
            <p>import javax.servlet.http.HttpServletRequest;</p>
            <p>import org.apache.struts.action.ActionErrors;<br />
            import org.apache.struts.action.ActionForm;<br />
            import org.apache.struts.action.ActionMapping;<br />
            import org.apache.struts.upload.FormFile;</p>
            <p>/**<br />
            &nbsp;* MyEclipse Struts Creation date: 11-08-2006<br />
            &nbsp;* <br />
            &nbsp;* XDoclet definition:<br />
            &nbsp;* <br />
            &nbsp;* @struts.form name="UploadActionForm"<br />
            &nbsp;*/<br />
            public class UploadActionForm extends ActionForm {</p>
            <p>&nbsp;private FormFile file;</p>
            <p>&nbsp;private String cataID;</p>
            <p>&nbsp;private String cataName;</p>
            <p>&nbsp;private String parentID;</p>
            <p>&nbsp;private String parentName;</p>
            <p>&nbsp;private String fileName;</p>
            <p>&nbsp;private String digist;</p>
            <p>&nbsp;public String getCataID() {<br />
            &nbsp;&nbsp;return cataID;<br />
            &nbsp;}</p>
            <p>&nbsp;public void setCataID(String cataID) {<br />
            &nbsp;&nbsp;this.cataID = cataID;<br />
            &nbsp;}</p>
            <p>&nbsp;public String getCataName() {<br />
            &nbsp;&nbsp;return cataName;<br />
            &nbsp;}</p>
            <p>&nbsp;public void setCataName(String cataName) {<br />
            &nbsp;&nbsp;this.cataName = cataName;<br />
            &nbsp;}</p>
            <p>&nbsp;public String getDigist() {<br />
            &nbsp;&nbsp;return digist;<br />
            &nbsp;}</p>
            <p>&nbsp;public void setDigist(String digist) {<br />
            &nbsp;&nbsp;this.digist = digist;<br />
            &nbsp;}</p>
            <p>&nbsp;public String getFileName() {<br />
            &nbsp;&nbsp;return fileName;<br />
            &nbsp;}</p>
            <p>&nbsp;public void setFileName(String fileName) {<br />
            &nbsp;&nbsp;this.fileName = fileName;<br />
            &nbsp;}</p>
            <p>&nbsp;public String getParentID() {<br />
            &nbsp;&nbsp;return parentID;<br />
            &nbsp;}</p>
            <p>&nbsp;public void setParentID(String parentID) {<br />
            &nbsp;&nbsp;this.parentID = parentID;<br />
            &nbsp;}</p>
            <p>&nbsp;public String getParentName() {<br />
            &nbsp;&nbsp;return parentName;<br />
            &nbsp;}</p>
            <p>&nbsp;public void setParentName(String parentName) {<br />
            &nbsp;&nbsp;this.parentName = parentName;<br />
            &nbsp;}</p>
            <p>&nbsp;public FormFile getFile() {<br />
            &nbsp;&nbsp;return file;<br />
            &nbsp;}</p>
            <p>&nbsp;public void setFile(FormFile file) {<br />
            &nbsp;&nbsp;this.file = file;<br />
            &nbsp;}</p>
            <p>}</p>
            <p><font style="background-color: #ff0000">UploadAction.java中内容</font></p>
            <p><font style="background-color: #ffffff">package com.seavision.OurSecond.action.knowledge;</font></p>
            <p><font style="background-color: #ffffff">import java.io.File;<br />
            import java.io.FileNotFoundException;<br />
            import java.io.FileOutputStream;<br />
            import java.io.IOException;<br />
            import java.sql.Timestamp;<br />
            import java.text.DateFormat;<br />
            import java.text.SimpleDateFormat;<br />
            import java.util.Date;</font></p>
            <p><font style="background-color: #ffffff">import javax.servlet.http.HttpServletRequest;<br />
            import javax.servlet.http.HttpServletResponse;</font></p>
            <p><font style="background-color: #ffffff">import org.apache.struts.action.Action;<br />
            import org.apache.struts.action.ActionForm;<br />
            import org.apache.struts.action.ActionForward;<br />
            import org.apache.struts.action.ActionMapping;<br />
            import org.apache.struts.upload.FormFile;</font></p>
            <p><font style="background-color: #ffffff">import com.seavision.OurSecond.beans.KnowDocInfoVO;<br />
            import com.seavision.OurSecond.beans.UserVO;<br />
            import com.seavision.OurSecond.common.BaseAction;<br />
            import com.seavision.OurSecond.components.knowledge.KnowLedgeManageFactory;<br />
            import com.seavision.OurSecond.components.knowledge.UploadAndDownManage;</font></p>
            <p><font style="background-color: #ffffff">/**<br />
            &nbsp;* MyEclipse Struts Creation date: 11-08-2006<br />
            &nbsp;* <br />
            &nbsp;* XDoclet definition:<br />
            &nbsp;* <br />
            &nbsp;* @struts.action path="/page/knowledge/UploadAction" name="UploadActionForm"<br />
            &nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; input="/page/knowledge/ReferKnowledgePage.jsp" scope="request"<br />
            &nbsp;*/<br />
            public class UploadAction extends BaseAction {</font></p>
            <p><font style="background-color: #ffffff">&nbsp;// --------------------------------------------------------- Instance<br />
            &nbsp;// Variables</font></p>
            <p><font style="background-color: #ffffff">&nbsp;// --------------------------------------------------------- Methods</font></p>
            <p><font style="background-color: #ffffff">&nbsp;/**<br />
            &nbsp; * Method execute<br />
            &nbsp; * <br />
            &nbsp; * @param mapping<br />
            &nbsp; * @param form<br />
            &nbsp; * @param request<br />
            &nbsp; * @param response<br />
            &nbsp; * @return ActionForward<br />
            &nbsp; */<br />
            &nbsp;</font></p>
            <p><font style="background-color: #ffffff">&nbsp;public ActionForward execute(ActionMapping mapping, ActionForm form,<br />
            &nbsp;&nbsp;&nbsp;HttpServletRequest request, HttpServletResponse response) {<br />
            &nbsp;&nbsp;UploadActionForm UploadActionForm = (UploadActionForm) form;<br />
            &nbsp;&nbsp;<br />
            &nbsp;&nbsp;this.initializeAction(request, "PeopleManagePage2Action");<br />
            &nbsp;&nbsp;String message=null;<br />
            &nbsp;&nbsp;UserVO uservo = (UserVO) this.getAttribute("loginUserBean");<br />
            &nbsp;&nbsp;if (this.check(uservo)) {<br />
            &nbsp;&nbsp;&nbsp;message = "您还没有登录或您离开系统时间太久，请重新登录";<br />
            &nbsp;&nbsp;&nbsp;return this.moveToFailure(message, "logon", mapping);<br />
            &nbsp;&nbsp;}<br />
            &nbsp;&nbsp;FormFile file=UploadActionForm.getFile();<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("1.......................");<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //获得上传文件的后缀名<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String Suffix = file.getFileName().substring(<br />
            &nbsp;&nbsp;&nbsp;&nbsp;file.getFileName().lastIndexOf("."));<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("2.......................");<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //获取数据<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String cataID=UploadActionForm.getCataID();<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String cataName=UploadActionForm.getCataName();<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String parentID=UploadActionForm.getParentID();<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String parentName=UploadActionForm.getParentName();<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String fileName=UploadActionForm.getFileName();<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String digist=UploadActionForm.getDigist();</font></p>
            <p><font style="background-color: #ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 由于乱码原因，测试固定值<br />
            //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (parentName==null||parentName.equals("")){<br />
            //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;parentName="阳平";<br />
            //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
            //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (parentID==null||parentID.equals("")){<br />
            //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;parentID="111";<br />
            //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
            //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; parentName="parent";<br />
            //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cataName="cata";<br />
            //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
            //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("1!!!!!!!!!!!!!!!!!!!1"+ parentName +"!!!!!"+cataName);<br />
            //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(cataID+" ; "+cataName+" ; "+fileName);<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //检查文件是否是合法文件<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!Suffix.equals(".txt")&amp;&amp;!Suffix.equals(".pdf")&amp;&amp;!Suffix.equals(".doc")){<br />
            &nbsp;&nbsp;&nbsp;System.out.println("不是合法文件.............");<br />
            &nbsp;&nbsp;&nbsp;return mapping.getInputForward();<br />
            &nbsp;&nbsp;}<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("Suffix&nbsp;&nbsp; :&nbsp;&nbsp; "+Suffix);<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //设置文件大小<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int fileSize=file.getFileSize();<br />
            &nbsp;&nbsp;int fileMaxSize=Integer.parseInt("1024100000");<br />
            &nbsp;&nbsp;if(fileSize&gt;fileMaxSize){<br />
            &nbsp;&nbsp;&nbsp;System.out.println("文件太大........");<br />
            &nbsp;&nbsp;&nbsp;return mapping.getInputForward();<br />
            &nbsp;&nbsp;}&nbsp;<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
            &nbsp;&nbsp;//创建上传文件所在根目录和子目录<br />
            &nbsp;&nbsp;String dir="d:/"+parentName+"/";<br />
            &nbsp;&nbsp;String filepath&nbsp;&nbsp; =new&nbsp;&nbsp; String(dir);&nbsp;&nbsp; <br />
            &nbsp;&nbsp;&nbsp;&nbsp; File&nbsp;&nbsp; pathName=new&nbsp;&nbsp; File(filepath);&nbsp;&nbsp; <br />
            &nbsp;&nbsp;&nbsp;&nbsp; boolean b=pathName.mkdir();<br />
            &nbsp;&nbsp;&nbsp;&nbsp; String dir1="d:/"+parentName+"/"+cataName+"/";<br />
            &nbsp;&nbsp;String filepath1&nbsp;&nbsp; =new&nbsp;&nbsp; String(dir1);&nbsp;&nbsp; <br />
            &nbsp;&nbsp;&nbsp;&nbsp; File&nbsp;&nbsp; pathName1=new&nbsp;&nbsp; File(filepath1);&nbsp;&nbsp; <br />
            &nbsp;&nbsp;&nbsp;&nbsp; boolean b1=pathName1.mkdir();<br />
            &nbsp;&nbsp;&nbsp;&nbsp; //上传文件<br />
            &nbsp;&nbsp;&nbsp;&nbsp; Date date=new Date();<br />
            &nbsp;&nbsp;&nbsp;&nbsp; final String random=String.valueOf(date.getTime());<br />
            &nbsp;&nbsp;&nbsp;&nbsp; System.out.println(";;;;;;;;;;;;;;;;;"+date.getTime()+date.getTime());<br />
            &nbsp;&nbsp;&nbsp;&nbsp; File uploadfile=new File(dir1+random+fileName+Suffix);<br />
            &nbsp;&nbsp;&nbsp;&nbsp; try {<br />
            &nbsp;&nbsp;&nbsp;FileOutputStream fout = new FileOutputStream(uploadfile);<br />
            &nbsp;&nbsp;&nbsp;fout.write(file.getFileData());<br />
            &nbsp;&nbsp;&nbsp;fout.close();<br />
            &nbsp;&nbsp;&nbsp;System.out.println("上传文件成功..............");<br />
            &nbsp;&nbsp;&nbsp;//调用方法...............cataID,fileName,fileSize,<br />
            &nbsp;&nbsp;&nbsp;//digist,uploadDate,authorID,author,dotNum<br />
            &nbsp;&nbsp;&nbsp;KnowLedgeManageFactory factory=KnowLedgeManageFactory.getKnowLedgeManageFactory();<br />
            &nbsp;&nbsp;&nbsp;UploadAndDownManage uploadAndDownManage=factory.getUploadAndDownManage();<br />
            &nbsp;&nbsp;&nbsp;KnowDocInfoVO knowDocInfo=new KnowDocInfoVO();<br />
            &nbsp;&nbsp;&nbsp;knowDocInfo.setCataID(Integer.parseInt(cataID));<br />
            &nbsp;&nbsp;&nbsp;knowDocInfo.setFileName(random+fileName+Suffix);<br />
            &nbsp;&nbsp;&nbsp;knowDocInfo.setFileSize(file.getFileSize());<br />
            &nbsp;&nbsp;&nbsp;knowDocInfo.setDigist(digist);<br />
            &nbsp;&nbsp;&nbsp;//得到当前日期<br />
            &nbsp;&nbsp;&nbsp;Date dates = new Date(System.currentTimeMillis());<br />
            &nbsp;&nbsp;&nbsp;DateFormat sdf=SimpleDateFormat.getDateTimeInstance(DateFormat.MEDIUM,DateFormat.MEDIUM);<br />
            &nbsp;&nbsp;&nbsp;String datetime=sdf.format(date);<br />
            &nbsp;&nbsp;&nbsp;Timestamp time=Timestamp.valueOf(datetime);<br />
            &nbsp;&nbsp;&nbsp;System.out.println("..............time : "+time);<br />
            &nbsp;&nbsp;&nbsp;knowDocInfo.setUploadDate(time);<br />
            &nbsp;&nbsp;&nbsp;//得到上传的用户ID和姓名<br />
            &nbsp;&nbsp;&nbsp;<br />
            &nbsp;&nbsp;&nbsp;knowDocInfo.setAuthorID(uservo.getUserID());<br />
            &nbsp;&nbsp;&nbsp;knowDocInfo.setAuthor(uservo.getName());<br />
            &nbsp;&nbsp;&nbsp;String st=uploadAndDownManage.addKnowDocInfo(knowDocInfo);<br />
            &nbsp;&nbsp;&nbsp;if (st.equals("success")) {</font></p>
            <p><font style="background-color: #ffffff">&nbsp;&nbsp;&nbsp;&nbsp;return this.moveToSuccess("success", mapping);<br />
            &nbsp;&nbsp;&nbsp;} else {<br />
            &nbsp;&nbsp;&nbsp;&nbsp;message = " 上传失败！";<br />
            &nbsp;&nbsp;&nbsp;&nbsp;return this.moveToFailure(message, "false", mapping);<br />
            &nbsp;&nbsp;&nbsp;}<br />
            &nbsp;&nbsp;<br />
            &nbsp;&nbsp;} catch (FileNotFoundException e) {<br />
            &nbsp;&nbsp;&nbsp;e.getMessage();<br />
            &nbsp;&nbsp;} catch (IOException e) {<br />
            &nbsp;&nbsp;&nbsp;e.getMessage();<br />
            &nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp; <br />
            &nbsp;&nbsp;return null;<br />
            &nbsp;}</font></p>
            <p><font style="background-color: #ffffff">}</font></p>
            <p>&nbsp;</p>
            <p><font style="background-color: #ff0000">下载部分：&nbsp; DownloadAction.java中</font></p>
            <p>package com.seavision.OurSecond.action.knowledge;</p>
            <p>import java.io.BufferedInputStream;<br />
            import java.io.File;<br />
            import java.io.FileInputStream;<br />
            import java.io.OutputStream;</p>
            <p>import javax.servlet.http.HttpServletRequest;<br />
            import javax.servlet.http.HttpServletResponse;</p>
            <p>import org.apache.struts.action.ActionForm;<br />
            import org.apache.struts.action.ActionForward;<br />
            import org.apache.struts.action.ActionMapping;</p>
            <p>import com.seavision.OurSecond.beans.KnowDocInfoVO;<br />
            import com.seavision.OurSecond.beans.UserVO;<br />
            import com.seavision.OurSecond.common.BaseAction;<br />
            import com.seavision.OurSecond.components.knowledge.CatalogManage;<br />
            import com.seavision.OurSecond.components.knowledge.KnowDocManage;<br />
            import com.seavision.OurSecond.components.knowledge.KnowLedgeManageFactory;</p>
            <p>public class DownloadAction extends BaseAction {</p>
            <p>&nbsp;public ActionForward execute(ActionMapping mapping, ActionForm form,<br />
            &nbsp;&nbsp;&nbsp;HttpServletRequest request, HttpServletResponse response)<br />
            &nbsp;&nbsp;&nbsp;throws Exception {</p>
            <p>&nbsp;&nbsp;try {</p>
            <p>&nbsp;&nbsp;&nbsp;this.initializeAction(request, "DownloadAction");<br />
            &nbsp;&nbsp;&nbsp;// 从session获得loginUserBean<br />
            &nbsp;&nbsp;&nbsp;String message = "";<br />
            &nbsp;&nbsp;&nbsp;UserVO uservo = (UserVO) this.getAttribute("loginUserBean");<br />
            &nbsp;&nbsp;&nbsp;if (this.check(uservo)) {<br />
            &nbsp;&nbsp;&nbsp;&nbsp;message = "您还没有登录或您离开系统时间太久，请重新登录";<br />
            &nbsp;&nbsp;&nbsp;&nbsp;return this.moveToFailure(message, "logon", mapping);<br />
            &nbsp;&nbsp;&nbsp;}<br />
            &nbsp;&nbsp;&nbsp;System.out.println("进入DownloadAction....................................");<br />
            &nbsp;&nbsp;&nbsp;//获得所有需要数据开始<br />
            &nbsp;&nbsp;&nbsp;String docID=this.getParameter("docID");<br />
            &nbsp;&nbsp;&nbsp;KnowLedgeManageFactory factory=KnowLedgeManageFactory.getKnowLedgeManageFactory();<br />
            &nbsp;&nbsp;&nbsp;KnowDocManage knowDocManage = factory.getKnowDocManage();<br />
            &nbsp;&nbsp;&nbsp;CatalogManage catalogManage=factory.getCatalogManage();<br />
            &nbsp;&nbsp;&nbsp;KnowDocInfoVO knowDocInfo=knowDocManage.getKnowDoc(docID);<br />
            &nbsp;&nbsp;&nbsp;String[] s=catalogManage.getCataAndParent(String.valueOf(knowDocInfo.getCataID()));<br />
            &nbsp;&nbsp;&nbsp;String cataName=s[0];<br />
            &nbsp;&nbsp;&nbsp;String parentName=s[1];<br />
            &nbsp;&nbsp;&nbsp;<br />
            &nbsp;&nbsp;&nbsp;<br />
            &nbsp;&nbsp;&nbsp;String dir="d:/"+parentName+"/"+cataName+"/"+knowDocInfo.getFileName();<br />
            &nbsp;&nbsp;&nbsp;System.out.println("dir&nbsp;&nbsp; :&nbsp;&nbsp; "+ dir);<br />
            &nbsp;&nbsp;&nbsp;<br />
            &nbsp;&nbsp;&nbsp;File file=new File(dir);<br />
            &nbsp;&nbsp;&nbsp;FileInputStream fis=new FileInputStream(file);<br />
            &nbsp;&nbsp;&nbsp;BufferedInputStream bis = new BufferedInputStream(fis);<br />
            &nbsp;&nbsp;&nbsp;byte[] buffer=new byte[1024*1024];<br />
            &nbsp;&nbsp;&nbsp;response.setContentType("application/x-msdownload");<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; response.setHeader("Content-Disposition", "attachment; filename=" + knowDocInfo.getFileName());<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OutputStream os=response.getOutputStream();<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int len = bis.read(buffer); len != -1; len = bis.read(buffer)){<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;os.write(buffer, 0, len);<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bis.close();<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fis.close();<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; os.close();<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //下载成功。进行点击数统计<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; KnowDocManage knowDocManages=factory.getKnowDocManage();<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String ret =knowDocManages.updKnowDocDotNum(docID);<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (ret.equals("success")){<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; return this.moveToSuccess("success", mapping); <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return this.moveToFailure(message, "false", mapping);<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //获得所有需要数据结束<br />
            //&nbsp;&nbsp;&nbsp;if (st.equals("success")) {<br />
            //<br />
            //&nbsp;&nbsp;&nbsp;&nbsp;return this.moveToSuccess("success", mapping);<br />
            //&nbsp;&nbsp;&nbsp;} else {<br />
            //&nbsp;&nbsp;&nbsp;&nbsp;message = " 编辑失敗！";<br />
            //&nbsp;&nbsp;&nbsp;&nbsp;return this.moveToFailure(message, "false", mapping);<br />
            //&nbsp;&nbsp;&nbsp;}<br />
            &nbsp;&nbsp;} catch (Exception e) {</p>
            <p>&nbsp;&nbsp;&nbsp;return this.moveToError(e.getMessage(), "eroor", mapping);<br />
            &nbsp;&nbsp;}</p>
            <p>&nbsp;}</p>
            <p>}<br />
            </p>
            </div>
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.blogjava.net/HappyJava/aggbug/177478.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/HappyJava/" target="_blank">李建軍</a> 2008-01-24 13:46 <a href="http://www.blogjava.net/HappyJava/articles/177478.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>spring与hibernate,struts的冲突问题</title><link>http://www.blogjava.net/HappyJava/articles/177476.html</link><dc:creator>李建軍</dc:creator><author>李建軍</author><pubDate>Thu, 24 Jan 2008 05:45:00 GMT</pubDate><guid>http://www.blogjava.net/HappyJava/articles/177476.html</guid><wfw:comment>http://www.blogjava.net/HappyJava/comments/177476.html</wfw:comment><comments>http://www.blogjava.net/HappyJava/articles/177476.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/HappyJava/comments/commentRss/177476.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/HappyJava/services/trackbacks/177476.html</trackback:ping><description><![CDATA[<div class="tit">spring与hibernate,struts的冲突问题</div>
<div class="date">2007年11月26日 星期一 03:00</div>
<table style="table-layout: fixed">
    <tbody>
        <tr>
            <td>
            <div class="cnt">spring的版本是2.0.hibernate的版本是3.2.struts的版本是1.4<br />
            spring所依赖的包,有时候会与其它框架所依赖的包造成冲突,引起系统一些摸不清楚的问题<br />
            最近就遇到了两个这方面的问题,费了好大的劲才解决.<br />
            1,spring与hibernate的冲突.两个框架都依赖asm.jar包spring的版本是asm-2.23.jar.hibernate依赖的是asm.jar<br />
            需要将asm-2.2.3.jar删除.没有删除的话会引起这样的异常<br />
            <font color="#ff6600">"org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in ServletContext resource [/WEB-INF/classes/applicationContext.xml]: Invocation of init method failed; nested exception is java.lang.ExceptionInInitializerError <br />
            &nbsp;&nbsp;&nbsp;&nbsp; Caused by: <br />
            &nbsp;&nbsp;&nbsp;&nbsp; java.lang.ExceptionInInitializerError <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.hibernate.proxy.pojo.cglib.CGLIBLazyInitializer.getProxyFactory(CGLIBLazyInitializer.java:117) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.hibernate.proxy.pojo.cglib.CGLIBProxyFactory.postInstantiate(CGLIBProxyFactory.java:43) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.hibernate.tuple.entity.PojoEntityTuplizer.buildProxyFactory(PojoEntityTuplizer.java:162) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.hibernate.tuple.entity.AbstractEntityTuplizer.&lt;init&gt;(AbstractEntityTuplizer.java:135) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.hibernate.tuple.entity.PojoEntityTuplizer.&lt;init&gt;(PojoEntityTuplizer.java:55) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.hibernate.tuple.entity.EntityEntityModeToTuplizerMapping.&lt;init&gt;(EntityEntityModeToTuplizerMapping.java:56) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.hibernate.tuple.entity.EntityMetamodel.&lt;init&gt;(EntityMetamodel.java:295) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.hibernate.persister.entity.AbstractEntityPersister.&lt;init&gt;(AbstractEntityPersister.java:434) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.hibernate.persister.entity.SingleTableEntityPersister.&lt;init&gt;(SingleTableEntityPersister.java:109) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.hibernate.persister.PersisterFactory.createClassPersister(PersisterFactory.java:55) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.hibernate.impl.SessionFactoryImpl.&lt;init&gt;(SessionFactoryImpl.java:226) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1294) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.springframework.orm.hibernate3.LocalSessionFactoryBean.newSessionFactory(LocalSessionFactoryBean.java:805) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.springframework.orm.hibernate3.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:745) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.springframework.orm.hibernate3.AbstractSessionFactoryBean.afterPropertiesSet(AbstractSessionFactoryBean.java:134) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1202) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1172) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:428) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:251) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:156) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:248) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:160) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:284) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:352) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:244) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:187) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:49) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at com.wukol.listener.StartupListener.contextInitialized(StartupListener.java:27) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3830) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.core.StandardContext.start(StandardContext.java:4337) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:791) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:771) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:525) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:626) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.startup.HostConfig.deployDescriptors(HostConfig.java:553) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:488) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1138) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:311) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1053) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.core.StandardHost.start(StandardHost.java:719) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.core.StandardService.start(StandardService.java:516) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.core.StandardServer.start(StandardServer.java:710) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.startup.Catalina.start(Catalina.java:566) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at java.lang.reflect.Method.invoke(Method.java:597) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:288) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; Caused by: java.lang.SecurityException: class "org.objectweb.asm.CodeVisitor"'s signer information does not match signer information of other classes in the same package <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at java.lang.ClassLoader.checkCerts(ClassLoader.java:775) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at java.lang.ClassLoader.preDefineClass(ClassLoader.java:487) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at java.lang.ClassLoader.defineClass(ClassLoader.java:614) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLoader.java:1817) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:872) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1325) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1204) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at net.sf.cglib.core.KeyFactory$Generator.generateClass(KeyFactory.java:165) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at net.sf.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at net.sf.cglib.core.KeyFactory$Generator.create(KeyFactory.java:145) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at net.sf.cglib.core.KeyFactory.create(KeyFactory.java:117) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at net.sf.cglib.core.KeyFactory.create(KeyFactory.java:108) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at net.sf.cglib.core.KeyFactory.create(KeyFactory.java:104) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at net.sf.cglib.proxy.Enhancer.&lt;clinit&gt;(Enhancer.java:69) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; ... 52 more</font> <font color="#ff6600">"</font><br />
            2,hibernate与struts的冲突,两个框架都依赖common-collections.jar.hibernate的是common-collections-2.1.1.jar,struts的是common-collections.jar.需要将hibernate所依赖的common-collections-2.1.1.jar删除.没有删除的话会引起这个异常<br />
            <font color="#ff6600">java.lang.SecurityException: class "org.apache.commons.collections.ArrayStack"'s signer information does not match signer information of other classes in the same package <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at java.lang.ClassLoader.checkCerts(ClassLoader.java:775) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at java.lang.ClassLoader.preDefineClass(ClassLoader.java:487) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at java.lang.ClassLoader.defineClass(ClassLoader.java:614) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLoader.java:1817) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:872) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1325) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1204) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.commons.digester.Digester.&lt;init&gt;(Digester.java:142) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.struts.action.ActionServlet.initServlet(ActionServlet.java:1751) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.struts.action.ActionServlet.init(ActionServlet.java:349) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at javax.servlet.GenericServlet.init(GenericServlet.java:212) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1161) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:981) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4045) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.core.StandardContext.start(StandardContext.java:4351) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:791) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:771) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:525) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:626) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.startup.HostConfig.deployDescriptors(HostConfig.java:553) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:488) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1138) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:311) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1053) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.core.StandardHost.start(StandardHost.java:719) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.core.StandardService.start(StandardService.java:516) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.core.StandardServer.start(StandardServer.java:710) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.startup.Catalina.start(Catalina.java:566) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at java.lang.reflect.Method.invoke(Method.java:597) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:288) <br />
            &nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413) "<br />
            "</font></div>
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.blogjava.net/HappyJava/aggbug/177476.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/HappyJava/" target="_blank">李建軍</a> 2008-01-24 13:45 <a href="http://www.blogjava.net/HappyJava/articles/177476.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts+Hibernate开发实践 分页的实现</title><link>http://www.blogjava.net/HappyJava/articles/177475.html</link><dc:creator>李建軍</dc:creator><author>李建軍</author><pubDate>Thu, 24 Jan 2008 05:44:00 GMT</pubDate><guid>http://www.blogjava.net/HappyJava/articles/177475.html</guid><wfw:comment>http://www.blogjava.net/HappyJava/comments/177475.html</wfw:comment><comments>http://www.blogjava.net/HappyJava/articles/177475.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/HappyJava/comments/commentRss/177475.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/HappyJava/services/trackbacks/177475.html</trackback:ping><description><![CDATA[<table height="600" width="100%" background="/i/bg2.gif" border="0">
    <tbody>
        <tr>
            <td bgcolor="#eeeeee" height="72">
            <p align="center"><font size="4"><br />
            </font>&nbsp;</p>
            </td>
        </tr>
        <tr valign="top">
            <td><font size="4">在进行web应用开发的时候经常要进行分页处理，经常看到一些人在问分页处理的问题，现在我把自己的处理方法写在这儿，希望能对需要进行分页处理的朋友有所帮助。<br />
            <br />
            一、在struts中分页有两种结构：<br />
            1. 在Action中通过DAO查询出所有的记录，然后加到session或request对象中，传到客户端，由JSP进行分页。<br />
            这种方法对于在数据量少的时候很方便，也不影响速度。<br />
            2.在Action中每次通过DAO只查询出一页的记录，再传给JSP页面。<br />
            这种结构对于数据量大的程序很好，但对于数据量小的情况，会增加对服务器的请求，加大服务器的负载。<br />
            二、Hibernate查询<br />
            由于在Hibernate中直接提供了对数据库定点定量的查询方法，所以我采用的是第2种方法。<br />
            <br />
            如：<br />
            从第1万条开始取出100条记录<br />
            Query q = session.createQuery("from Cat as c");<br />
            <br />
            q.setFirstResult(10000);<br />
            q.setMaxResults(100);<br />
            List l = q.list();<br />
            <br />
            三、具体实现<br />
            <br />
            1.Pager类<br />
            <br />
            package com.jpcf.db.helper;<br />
            import java.math.*;<br />
            public class Pager {<br />
            private int totalRows; //总行数<br />
            private int pageSize = 10; //每页显示的行数<br />
            private int currentPage; //当前页号<br />
            private int totalPages; //总页数<br />
            private int startRow; //当前页在数据库中的起始行<br />
            public Pager() {<br />
            }<br />
            public Pager(int _totalRows) {<br />
            totalRows = _totalRows;<br />
            totalPages=totalRows/pageSize;<br />
            int mod=totalRows%pageSize;<br />
            if(mod&gt;0){<br />
            totalPages++;<br />
            }<br />
            currentPage = 1;<br />
            startRow = 0;<br />
            }<br />
            public int getStartRow() {<br />
            return startRow;<br />
            }<br />
            public int getTotalPages() {<br />
            return totalPages;<br />
            }<br />
            public int getCurrentPage() {<br />
            return currentPage;<br />
            }<br />
            public int getPageSize() {<br />
            return pageSize;<br />
            }<br />
            public void setTotalRows(int totalRows) {<br />
            this.totalRows = totalRows;<br />
            }<br />
            public void setStartRow(int startRow) {<br />
            this.startRow = startRow;<br />
            }<br />
            public void setTotalPages(int totalPages) {<br />
            this.totalPages = totalPages;<br />
            }<br />
            public void setCurrentPage(int currentPage) {<br />
            this.currentPage = currentPage;<br />
            }<br />
            public void setPageSize(int pageSize) {<br />
            this.pageSize = pageSize;<br />
            }<br />
            public int getTotalRows() {<br />
            return totalRows;<br />
            }<br />
            public void first() {<br />
            currentPage = 1;<br />
            startRow = 0;<br />
            }<br />
            public void previous() {<br />
            if (currentPage == 1) {<br />
            return;<br />
            }<br />
            currentPage--;<br />
            startRow = (currentPage - 1) * pageSize;<br />
            }<br />
            public void next() {<br />
            if (currentPage &lt; totalPages) {<br />
            currentPage++;<br />
            }<br />
            startRow = (currentPage - 1) * pageSize;<br />
            }<br />
            public void last() {<br />
            currentPage = totalPages;<br />
            startRow = (currentPage - 1) * pageSize;<br />
            }<br />
            public void refresh(int _currentPage) {<br />
            currentPage = _currentPage;<br />
            if (currentPage &gt; totalPages) {<br />
            last();<br />
            }<br />
            }<br />
            }<br />
            <br />
            Pager类用于计算首页、前一页、下一页、尾页的在数据库中的起始行，当前的页码。<br />
            <br />
            2.PagerHelp类<br />
            <br />
            package com.jpcf.db.helper;<br />
            import javax.servlet.http.*;<br />
            public class PagerHelper {<br />
            public static Pager getPager(HttpServletRequest httpServletRequest,<br />
            int totalRows) {<br />
            //定义pager对象，用于传到页面<br />
            Pager pager = new Pager(totalRows);<br />
            //从Request对象中获取当前页号<br />
            String currentPage = httpServletRequest.getParameter("currentPage");<br />
            //如果当前页号为空，表示为首次查询该页<br />
            //如果不为空，则刷新pager对象，输入当前页号等信息<br />
            if (currentPage != null) {<br />
            pager.refresh(Integer.parseInt(currentPage));<br />
            }<br />
            //获取当前执行的方法，首页，前一页，后一页，尾页。<br />
            String pagerMethod = httpServletRequest.getParameter("pageMethod");<br />
            if (pagerMethod != null) {<br />
            if (pagerMethod.equals("first")) {<br />
            pager.first();<br />
            } else if (pagerMethod.equals("previous")) {<br />
            pager.previous();<br />
            } else if (pagerMethod.equals("next")) {<br />
            pager.next();<br />
            } else if (pagerMethod.equals("last")) {<br />
            pager.last();<br />
            }<br />
            }<br />
            return pager;<br />
            }<br />
            }<br />
            <br />
            PageHelper这个类，我不用说应该也知道用来干嘛了<br />
            <br />
            3.DAO类<br />
            <br />
            package com.jpcf.db.dao;<br />
            import com.jpcf.db.model.*;<br />
            import com.jpcf.db.helper.HibernateUtil;<br />
            import net.sf.hibernate.*;<br />
            import java.util.*;<br />
            import com.jpcf.db.controller.*;<br />
            public class VehiclePropertyDAO {<br />
            public Collection findWithPage(int pageSize, int startRow) throws<br />
            HibernateException {<br />
            Collection vehicleList = null;<br />
            Transaction tx = null;<br />
            try {<br />
            Session session = HibernateUtil.currentSession();<br />
            tx = session.beginTransaction();<br />
            Query q = session.createQuery("from VehicleProperty vp");<br />
            q.setFirstResult(startRow);<br />
            q.setMaxResults(pageSize);<br />
            vehicleList = q.list();<br />
            tx.commit();<br />
            } catch (HibernateException he) {<br />
            if (tx != null) {<br />
            tx.rollback();<br />
            }<br />
            throw he;<br />
            } finally {<br />
            HibernateUtil.closeSession();<br />
            }<br />
            return vehicleList;<br />
            }<br />
            public int getRows(String query) throws<br />
            HibernateException {<br />
            int totalRows = 0;<br />
            Transaction tx = null;<br />
            try {<br />
            Session session = HibernateUtil.currentSession();<br />
            tx = session.beginTransaction();<br />
            totalRows = ((Integer) session.iterate(query).next()).<br />
            intValue();<br />
            tx.commit();<br />
            } catch (HibernateException he) {<br />
            if (tx != null) {<br />
            tx.rollback();<br />
            }<br />
            throw he;<br />
            } finally {<br />
            HibernateUtil.closeSession();<br />
            }<br />
            return totalRows;<br />
            }<br />
            }<br />
            DAO类我就贴这些分页需要的代码了。<br />
            &#8220;from VehicleProperty vp&#8221;也可以用一个参数传进来，有兴趣的自己改一下吧<br />
            <br />
            4.Action<br />
            <br />
            下面是在Action中用到的代码：/<br />
            public ActionForward queryWithPage(ActionMapping actionMapping,<br />
            ActionForm actionForm,<br />
            HttpServletRequest httpServletRequest,<br />
            HttpServletResponse httpServletresponse) {<br />
            Collection clInfos = null;//用于输出到页面的记录集合<br />
            int totalRows;//记录总行数<br />
            VehiclePropertyDAO vehicleDAO = new VehiclePropertyDAO();<br />
            //取得当前表中的总行数<br />
            try {<br />
            totalRows = vehicleDAO.getRows("select count(*) from VehicleProperty");<br />
            } catch (Exception ex) {<br />
            servlet.log(ex.toString());<br />
            return actionMapping.findForward(Constants.FAILURE);<br />
            }<br />
            //通过PagerHelper类来获取用于输出到页面的pager对象<br />
            Pager pager=PagerHelper.getPager(httpServletRequest,totalRows);<br />
            //取出从startRow开始的pageSize行记录<br />
            try {<br />
            clInfos = vehicleDAO.findWithPage(pager.getPageSize(), pager.getStartRow());<br />
            } catch (Exception ex) {<br />
            servlet.log(ex.toString());<br />
            return actionMapping.findForward(Constants.FAILURE);<br />
            }<br />
            //把输出的记录集和pager对象保存到request对象中<br />
            httpServletRequest.setAttribute("CLINFOS", clInfos);<br />
            httpServletRequest.setAttribute("PAGER", pager);<br />
            return actionMapping.findForward(Constants.SUCCESS);<br />
            }<br />
            <br />
            查询语句select count(*) from VehicleProperty 也可以换成你需要的任意的条件（select count(*) from VehicleProperty where ..)<br />
            <br />
            <br />
            5.JSP页面使用<br />
            <br />
            下面就是在JSP中的应用了：<br />
            <br />
            &lt;td colspan="8" align="right" class="head"&gt;<br />
            第&lt;bean:write name="PAGER" property="currentPage"/&gt;页&amp;nbsp;<br />
            共&lt;bean:write name="PAGER" property="totalPages"/&gt;页&amp;nbsp;<br />
            &lt;html:link action="/bussiness/clInfo/queryWithPage.do?method=queryWithPage&amp;amp;pageMethod=first" paramName="PAGER" paramProperty="currentPage" paramId="currentPage"&gt;首页&lt;/html:link&gt;<br />
            &lt;html:link action="/bussiness/clInfo/queryWithPage.do?method=queryWithPage&amp;amp;pageMethod=previous" paramName="PAGER" paramProperty="currentPage" paramId="currentPage"&gt;上一页&lt;/html:link&gt;<br />
            &lt;html:link action="/bussiness/clInfo/queryWithPage.do?method=queryWithPage&amp;amp;pageMethod=next" paramName="PAGER" paramProperty="currentPage" paramId="currentPage"&gt;下一页&lt;/html:link&gt;<br />
            &lt;html:link action="/bussiness/clInfo/queryWithPage.do?method=queryWithPage&amp;amp;pageMethod=last" paramName="PAGER" paramProperty="currentPage" paramId="currentPage"&gt;尾页&lt;/html:link&gt;<br />
            &lt;/td&gt;<br />
            <br />
            解释一下这一行:"/bussiness/clInfo/queryWithPage.do?method=queryWithPage&amp;amp;pageMethod=first<br />
            method=queryWithPage 是由于我的Action继承的是DispatchAction,需要一个method参数<br />
            pageMethod=first 是用来在PageHelper类中判断执行哪个操作<br />
            <br />
            四、总结<br />
            <br />
            我做的这个也只是一个借鉴，还有很多没有实现的，比如还可以加一下 go 直接到第n页的功能。<br />
            <br />
            其实最关键的是把当前页号和要执行的是功能(上一页，下一页)的参数从页面传进来，在Action中就可以根据这两个参数去取下一个页面上要显示的记录集了</font></td>
        </tr>
    </tbody>
</table>
<img src ="http://www.blogjava.net/HappyJava/aggbug/177475.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/HappyJava/" target="_blank">李建軍</a> 2008-01-24 13:44 <a href="http://www.blogjava.net/HappyJava/articles/177475.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一个struts的分页－－sql server存储过程版（等数据库）分页（更新）</title><link>http://www.blogjava.net/HappyJava/articles/177429.html</link><dc:creator>李建軍</dc:creator><author>李建軍</author><pubDate>Thu, 24 Jan 2008 02:26:00 GMT</pubDate><guid>http://www.blogjava.net/HappyJava/articles/177429.html</guid><wfw:comment>http://www.blogjava.net/HappyJava/comments/177429.html</wfw:comment><comments>http://www.blogjava.net/HappyJava/articles/177429.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/HappyJava/comments/commentRss/177429.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/HappyJava/services/trackbacks/177429.html</trackback:ping><description><![CDATA[<div class="postText">
<p>说是struts分页,实际上这个分页类不局限在某个框架下用的<br />
<br />
实现方法是通过list和 map 来封装数据结果集省了建立formbean和手动对formbean赋值的麻烦，<br />
用list和 map 来封装后使用起来和rs基本上一样，有些地方比RS方便些。<br />
本分页类中对查询参数已经作了处理，所以不需要在自己在去拼URL参数了。<br />
<br />
<br />
sql server分页使用存储过程要更高效些<br />
下面这个存储过程是从SQL区找到的</p>
<p>-----------------------------------------------------------------------------------------------------------------------------------<br />
CREATE Proc p_show<br />
@QueryStr varchar(8000), --表名、视图名、查询语句<br />
@PageSize int=10,&nbsp;&nbsp; --每页的大小(行数)<br />
@PageCurrent int=1,&nbsp;&nbsp; --要显示的页<br />
@FdShow varchar (8000)='', --要显示的字段列表,如果查询结果有标识字段,需要指定此值,且不包含标识字段<br />
@FdOrder nvarchar (3000)='' --排序字段列表<br />
as<br />
declare @FdName nvarchar(550) --表中的主键或表、临时表中的标识列名<br />
&nbsp;,@Id1 varchar(80),@Id2 varchar(80) --开始和结束的记录号<br />
&nbsp;,@Obj_ID int&nbsp;&nbsp;&nbsp; --对象ID<br />
--表中有复合主键的处理<br />
declare @strfd nvarchar(4000) --复合主键列表<br />
&nbsp;,@strjoin varchar(8000) --连接字段<br />
&nbsp;,@strwhere nvarchar(4000) --查询条件</p>
<p><br />
select @Obj_ID=object_id(@QueryStr)<br />
&nbsp;,@FdShow=case isnull(@FdShow,'') when '' then ' *' else ' <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#39;&#43;&#64;&#70;&#100;&#83;&#104;&#111;&#119;">'+@FdShow</a> end<br />
&nbsp;,@FdOrder=case isnull(@FdOrder,'') when '' then '' else ' order by <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#39;&#43;&#64;&#70;&#100;&#79;&#114;&#100;&#101;&#114;">'+@FdOrder</a> end<br />
&nbsp;,@QueryStr=case when @Obj_ID is not null then ' <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#39;&#43;&#64;&#81;&#117;&#101;&#114;&#121;&#83;&#116;&#114;">'+@QueryStr</a> else ' (<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#39;&#43;&#64;&#81;&#117;&#101;&#114;&#121;&#83;&#116;&#114;&#43;&#39;">'+@QueryStr+'</a>) a' end</p>
<p>--如果显示第一页，可以直接用top来完成<br />
if @PageCurrent=1 <br />
begin<br />
&nbsp;select @Id1=cast(@PageSize as varchar(50))<br />
&nbsp;exec('select top <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#39;&#43;&#64;&#73;&#100;&#49;&#43;&#64;&#70;&#100;&#83;&#104;&#111;&#119;&#43;&#39;">'+@Id1+@FdShow+'</a> from <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#39;&#43;&#64;&#81;&#117;&#101;&#114;&#121;&#83;&#116;&#114;&#43;&#64;&#70;&#100;&#79;&#114;&#100;&#101;&#114;">'+@QueryStr+@FdOrder</a>)<br />
&nbsp;return<br />
end</p>
<p>--如果是表,则检查表中是否有标识更或主键<br />
if @Obj_ID is not null and objectproperty(@Obj_ID,'IsTable')=1<br />
begin<br />
&nbsp;select @Id1=cast(@PageSize as varchar(50))<br />
&nbsp; ,@Id2=cast((@PageCurrent-1)*@PageSize as varchar(50))</p>
<p>&nbsp;select @FdName=name from syscolumns where <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#105;&#100;&#61;&#64;&#79;&#98;&#106;&#95;&#73;&#68;">id=@Obj_ID</a> and status=0x80<br />
&nbsp;if @@rowcount=0&nbsp;&nbsp; --如果表中无标识列,则检查表中是否有主键<br />
&nbsp;begin<br />
&nbsp; if not exists(select 1 from sysobjects where <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#112;&#97;&#114;&#101;&#110;&#116;&#95;&#111;&#98;&#106;&#61;&#64;&#79;&#98;&#106;&#95;&#73;&#68;">parent_obj=@Obj_ID</a> and xtype='PK')<br />
&nbsp;&nbsp; goto lbusetemp&nbsp; --如果表中无主键,则用临时表处理</p>
<p>&nbsp; select @FdName=name from syscolumns where <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#105;&#100;&#61;&#64;&#79;&#98;&#106;&#95;&#73;&#68;">id=@Obj_ID</a> and colid in(<br />
&nbsp;&nbsp; select colid from sysindexkeys where @Obj_ID=id and indid in(<br />
&nbsp;&nbsp;&nbsp; select indid from sysindexes where @Obj_ID=id and name in(<br />
&nbsp;&nbsp;&nbsp;&nbsp; select name from sysobjects where xtype='PK' and <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#112;&#97;&#114;&#101;&#110;&#116;&#95;&#111;&#98;&#106;&#61;&#64;&#79;&#98;&#106;&#95;&#73;&#68;">parent_obj=@Obj_ID</a><br />
&nbsp;&nbsp; )))<br />
&nbsp; if @@rowcount&gt;1&nbsp; --检查表中的主键是否为复合主键<br />
&nbsp; begin<br />
&nbsp;&nbsp; select @strfd='',@strjoin='',@strwhere=''<br />
&nbsp;&nbsp; select @strfd=@strfd+',['+name+']'<br />
&nbsp;&nbsp;&nbsp; ,@strjoin=@strjoin+' and a.['+name+']=b.['+name+']'<br />
&nbsp;&nbsp;&nbsp; ,@strwhere=@strwhere+' and b.['+name+'] is null'<br />
&nbsp;&nbsp;&nbsp; from syscolumns where <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#105;&#100;&#61;&#64;&#79;&#98;&#106;&#95;&#73;&#68;">id=@Obj_ID</a> and colid in(<br />
&nbsp;&nbsp;&nbsp; select colid from sysindexkeys where @Obj_ID=id and indid in(<br />
&nbsp;&nbsp;&nbsp;&nbsp; select indid from sysindexes where @Obj_ID=id and name in(<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select name from sysobjects where xtype='PK' and <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#112;&#97;&#114;&#101;&#110;&#116;&#95;&#111;&#98;&#106;&#61;&#64;&#79;&#98;&#106;&#95;&#73;&#68;">parent_obj=@Obj_ID</a><br />
&nbsp;&nbsp;&nbsp; )))<br />
&nbsp;&nbsp; select @strfd=substring(@strfd,2,2000)<br />
&nbsp;&nbsp;&nbsp; ,@strjoin=substring(@strjoin,5,4000)<br />
&nbsp;&nbsp;&nbsp; ,@strwhere=substring(@strwhere,5,4000)<br />
&nbsp;&nbsp; goto lbusepk<br />
&nbsp; end<br />
&nbsp;end<br />
end<br />
else<br />
&nbsp;goto lbusetemp</p>
<p>/*--使用标识列或主键为单一字段的处理方法--*/<br />
lbuseidentity: <br />
&nbsp;exec('select top <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#39;&#43;&#64;&#73;&#100;&#49;&#43;&#64;&#70;&#100;&#83;&#104;&#111;&#119;&#43;&#39;">'+@Id1+@FdShow+'</a> from <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#39;&#43;&#64;&#81;&#117;&#101;&#114;&#121;&#83;&#116;&#114;">'+@QueryStr</a><br />
&nbsp; +' where <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#39;&#43;&#64;&#70;&#100;&#78;&#97;&#109;&#101;&#43;&#39;">'+@FdName+'</a> not in(select top '<br />
&nbsp; <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#43;&#64;&#73;&#100;&#50;&#43;&#39;">+@Id2+'</a><a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#39;&#43;&#64;&#70;&#100;&#78;&#97;&#109;&#101;&#43;&#39;">'+@FdName+'</a> from <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#39;&#43;&#64;&#81;&#117;&#101;&#114;&#121;&#83;&#116;&#114;&#43;&#64;&#70;&#100;&#79;&#114;&#100;&#101;&#114;">'+@QueryStr+@FdOrder</a><br />
&nbsp; +')'+@FdOrder<br />
&nbsp; )<br />
&nbsp;return</p>
<p>/*--表中有复合主键的处理方法--*/<br />
lbusepk:&nbsp; <br />
&nbsp;exec('select <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#39;&#43;&#64;&#70;&#100;&#83;&#104;&#111;&#119;&#43;&#39;">'+@FdShow+'</a> from(select top <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#39;&#43;&#64;&#73;&#100;&#49;&#43;&#39;">'+@Id1+'</a> a.* from<br />
&nbsp; (select top 100 percent * from <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#39;&#43;&#64;&#81;&#117;&#101;&#114;&#121;&#83;&#116;&#114;&#43;&#64;&#70;&#100;&#79;&#114;&#100;&#101;&#114;&#43;&#39;">'+@QueryStr+@FdOrder+'</a>) a<br />
&nbsp; left join (select top <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#39;&#43;&#64;&#73;&#100;&#50;&#43;&#39;">'+@Id2+'</a><a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#39;&#43;&#64;&#115;&#116;&#114;&#102;&#100;&#43;&#39;">'+@strfd+'</a><br />
&nbsp; from <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#39;&#43;&#64;&#81;&#117;&#101;&#114;&#121;&#83;&#116;&#114;&#43;&#64;&#70;&#100;&#79;&#114;&#100;&#101;&#114;&#43;&#39;">'+@QueryStr+@FdOrder+'</a>) b on <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#39;&#43;&#64;&#115;&#116;&#114;&#106;&#111;&#105;&#110;&#43;&#39;">'+@strjoin+'</a><br />
&nbsp; where <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#39;&#43;&#64;&#115;&#116;&#114;&#119;&#104;&#101;&#114;&#101;&#43;&#39;">'+@strwhere+'</a>) a'<br />
&nbsp; )<br />
&nbsp;return</p>
<p>/*--用临时表处理的方法--*/<br />
lbusetemp:&nbsp; <br />
select @FdName='[ID_'+cast(newid() as varchar(80))+']'<br />
&nbsp;,@Id1=cast(@PageSize*(@PageCurrent-1) as varchar(50))<br />
&nbsp;,@Id2=cast(@PageSize*@PageCurrent-1 as varchar(50))</p>
<p>exec('select <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#39;&#43;&#64;&#70;&#100;&#78;&#97;&#109;&#101;&#43;&#39;&#61;&#105;&#100;&#101;&#110;&#116;&#105;&#116;&#121;&#40;&#105;&#110;&#116;&#44;&#48;&#44;&#49;&#41;&#44;&#39;&#43;&#64;&#70;&#100;&#83;&#104;&#111;&#119;&#43;&#39;">'+@FdName+'=identity(int,0,1),'+@FdShow+'</a><br />
&nbsp; into #tb <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#102;&#114;&#111;&#109;&#39;&#43;&#64;&#81;&#117;&#101;&#114;&#121;&#83;&#116;&#114;&#43;&#64;&#70;&#100;&#79;&#114;&#100;&#101;&#114;&#43;&#39;">from'+@QueryStr+@FdOrder+'</a><br />
&nbsp;select <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#39;&#43;&#64;&#70;&#100;&#83;&#104;&#111;&#119;&#43;&#39;">'+@FdShow+'</a> from #tb where <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#39;&#43;&#64;&#70;&#100;&#78;&#97;&#109;&#101;&#43;&#39;">'+@FdName+'</a> between '<br />
&nbsp;<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#43;&#64;&#73;&#100;&#49;&#43;&#39;">+@Id1+'</a> and <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#39;&#43;&#64;&#73;&#100;&#50;">'+@Id2</a><br />
&nbsp;)<br />
GO<br />
--------------------------------------------------------------------------------------------------------------------------------</p>
<p>这里需要建立一个分页类ResultGatherPro.java<br />
相关说明在相应行的后面<br />
</p>
<p>--------------------------------------------------------------------------------------------------------------------------------</p>
<p><br />
import conn.DBConnManager;//这个是连接池，可以更换其他的。</p>
<p>import javax.servlet.http.HttpServletRequest;<br />
import java.sql.*;<br />
import java.util.*;</p>
<p>public class ResultGatherPro {<br />
&nbsp;&nbsp;&nbsp; private String sql;<br />
&nbsp;&nbsp;&nbsp; private int intPageSize; //每页行数<br />
&nbsp;&nbsp;&nbsp; private int intRowCount;<br />
&nbsp;&nbsp;&nbsp; private int intPageCount;<br />
&nbsp;&nbsp;&nbsp; private int intPage; //页号<br />
&nbsp;&nbsp;&nbsp; private String Counter;<br />
&nbsp;&nbsp;&nbsp; DBConnManager conn = null;<br />
&nbsp;&nbsp;&nbsp; Connection con = null;<br />
&nbsp;&nbsp;&nbsp; CallableStatement stmt = null;<br />
&nbsp;&nbsp;&nbsp; ResultSet rs = null;<br />
&nbsp;&nbsp;&nbsp; Statement st = null;<br />
&nbsp;&nbsp;&nbsp; ResultSet rsc = null;<br />
&nbsp;&nbsp;&nbsp; private String defaultname = "default";</p>
<p>&nbsp;&nbsp;&nbsp; public ResultGatherPro() {</p>
<p>&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; public ResultGatherPro(String sqlcom, int rownum, int pagenum, String counter) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(counter);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sql = sqlcom;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; intPageSize = rownum;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; intPage = pagenum;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Counter = counter;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(sqlcom);<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; public void setUseDB(String dbname)<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.defaultname = dbname;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; public List selectRS(String sqlcom, int rownum, int pagenum, String counter) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(counter);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.sql = sqlcom;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.intPageSize = rownum;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.intPage = pagenum;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.Counter = counter;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(sqlcom);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return selectRS();</p>
<p>&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; public List selectRS() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; List rsall = new ArrayList();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Map rsTree;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; conn = DBConnManager.getInstance();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; con = conn.getConnection(defaultname);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; st = con.createStatement();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rsc = st.executeQuery(Counter);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (rsc.next()) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; intRowCount = rsc.getInt("allrow");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stmt = con.prepareCall("{call p_show('" + sql + "'," + intPageSize + "," + intPage + ")}");//如果用别的数据库就把这个地方修改一下<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rs = stmt.executeQuery();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ResultSetMetaData rsmd = rs.getMetaData();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int numberOfColumns = rsmd.getColumnCount();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //Object[] aa = new Object[numberOfColumns-1];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; intPageCount = (intRowCount + intPageSize - 1) / intPageSize;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (rs.next()) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rsTree = new HashMap(numberOfColumns);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int r = 1; r &lt; numberOfColumns + 1; r++) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rsTree.put(rsmd.getColumnName(r).toLowerCase(), rs.getObject(r));//toLowerCase()这个地方把列名转化为小写是为了和oracle兼容<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rsall.add(rsTree);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (java.lang.Exception ex) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("db conn has a Exception !!!!");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(ex.toString().indexOf("peer")&gt;0||ex.toString().indexOf("reset")&gt;0)&nbsp;//一般连接池都没有自动重连功能，这里是当数据库连接异常后，进行重新初始化连接。不然即使网络正常了，数据库连接也不会恢复<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DBConnManager.reConnect();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ex.printStackTrace();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } finally {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (rsc != null)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rsc.close();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (st != null)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; st.close();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (rs != null)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rs.close();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (stmt != null)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stmt.close();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (conn != null)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; conn.releaseConnection(defaultname, con);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (Exception e) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(e);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return rsall;<br />
&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; public String ChangePage(HttpServletRequest request) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String urlchange = null;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String pagename = request.getRequestURI().substring(request.getRequestURI().lastIndexOf("/") + 1);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String url = getUrl(request);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String dol = "";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (url != null &amp;&amp; !url.equals(""))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dol = "&amp;";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (intPage &gt; 1 &amp;&amp; intPage &lt; intPageCount) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; urlchange = "&lt;a href=" + pagename + "?pagenum=" + (intPage - 1) + dol + url + "&gt;上一页&lt;/a&gt; | &lt;a href=" + pagename + "?pagenum=" + (intPage + 1) + dol + url + "&gt;下一页&lt;/a&gt; | 第" + intPage + "页 | 共" + intPageCount + "页 | 共" + intRowCount + "条";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (intPage == 1 &amp;&amp; intRowCount &lt;= intPageSize) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; urlchange = "上一页 | 下一页 | 第" + intPage + "页 | 共" + intPageCount + "页 | 共" + intRowCount + "条";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (intPage == intPageCount &amp;&amp; intPage != 1) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; urlchange = "&lt;a href=" + pagename + "?pagenum=" + (intPage - 1) + dol + url + "&gt;上一页&lt;/a&gt; 下一页 | 第" + intPage + "页 | 共" + intPageCount + "页 | 共" + intRowCount + "条";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (intPage == 1 &amp;&amp; intRowCount &gt;= intPageSize) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; urlchange = "上一页 | &lt;a href=" + pagename + "?pagenum=" + (intPage + 1) + dol + url + "&gt;下一页&lt;/a&gt; | 第" + intPage + "页 | 共" + intPageCount + "页 | 共" + intRowCount + "条";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; urlchange = "&lt;a href=" + pagename + "&gt;第一页&lt;/a&gt;";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return urlchange;<br />
&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; public String ChangeBar(HttpServletRequest request) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String urlchange = null;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String pagename = request.getRequestURI().substring(request.getRequestURI().lastIndexOf("/") + 1);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String url = getUrl(request);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String dol = "";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (url != null &amp;&amp; !url.equals(""))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dol = "&amp;";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (intPage &gt; 1 &amp;&amp; intPage &lt; intPageCount) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; urlchange = "&lt;a href=" + pagename + "?pagenum=" + (intPage - 1) + dol + url + "&gt;上一页&lt;/a&gt; | &lt;a href=" + pagename + "?pagenum=" + (intPage + 1) + dol + url + "&gt;下一页&lt;/a&gt; | 第" + intPage + "页 | 共" + intPageCount + "页";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (intPage == 1 &amp;&amp; intRowCount &lt;= intPageSize) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; urlchange = "上一页 | 下一页 | 第" + intPage + "页 | 共" + intPageCount + "页";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (intPage == intPageCount &amp;&amp; intPage != 1) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; urlchange = "&lt;a href=" + pagename + "?pagenum=" + (intPage - 1) + dol + url + "&gt;上一页&lt;/a&gt; 下一页 | 第" + intPage + "页 | 共" + intPageCount + "页";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (intPage == 1 &amp;&amp; intRowCount &gt;= intPageSize) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; urlchange = "上一页 | &lt;a href=" + pagename + "?pagenum=" + (intPage + 1) + dol + url + "&gt;下一页&lt;/a&gt; | 第" + intPage + "页 | 共" + intPageCount + "页";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; urlchange = "&lt;a href=" + pagename + "&gt;第一页&lt;/a&gt;";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return urlchange;<br />
&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; public int getTotal() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return intRowCount;<br />
&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; public int getPageCount() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return intPageCount;<br />
&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; public String gotoPage(HttpServletRequest request) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String url = getUrl(request);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String javascript = "&lt;script&gt;function checksearch(sform)\n{if(sform.pagenum.value==\"\" || sform.pagenum.value==\"0\"){alert('请输正确入页数！');sform.pagenum.focus();return false;}\nif(isNaN(sform.pagenum.value)){alert('请输入数字！');sform.pagenum.focus();return false;}}&lt;/script&gt;";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String form = "&lt;table&nbsp; border='0' cellpadding='0' cellspacing='0'&gt;\n" + javascript;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; form += "&lt;form&nbsp;&nbsp; action='' onSubmit='return checksearch(this)'&gt;\n&lt;tr&gt;&lt;td width='40' align='center'&gt;\n&lt;input name='pagenum' type='text' size='3' class='gotext'&gt;\n ";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (url != null) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (url.indexOf("&amp;") &gt; 0) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String[] param = new String[(url.split("&amp;")).length];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; param = url.split("&amp;");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; param.length; i++) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; form += "&lt;input type='hidden' name='" + param[i].substring(0, param[i].indexOf("=")) + "' value='" + param[i].substring(param[i].indexOf("=") + 1) + "'&gt;\n";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (url.indexOf("=") &gt; 0) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; form += "&lt;input type='hidden' name='" + url.substring(0, url.indexOf("=")) + "' value='" + url.substring(url.indexOf("=") + 1) + "'&gt;\n";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; form += "&lt;/td&gt;&lt;td width='25' align='center'&gt;&lt;input type='submit' name='Submit' value='GO' class='gobtn'&gt;\n&lt;/td&gt;\n&lt;/tr&gt;\n&lt;/form&gt;\n&lt;/table&gt;";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return form;<br />
&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; private String getUrl(HttpServletRequest request) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String url = "";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Enumeration param = request.getParameterNames();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (param.hasMoreElements()) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String pname = param.nextElement().toString();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!pname.equalsIgnoreCase("pagenum") &amp;&amp; !pname.equalsIgnoreCase("submit"))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; url += pname + "=" + request.getParameter(pname) + "&amp;";</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (url.endsWith("&amp;")) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; url = url.substring(0, url.lastIndexOf("&amp;"));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return url;<br />
&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; public String intercept(String str, int num, String last) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (str.length() &lt;= num)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return str;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return str.substring(0, num) + last;<br />
&nbsp;&nbsp;&nbsp; }</p>
<p><br />
}</p>
<p>&nbsp;</p>
<p>--------------------------------------------------------------------------------------------------------</p>
<p>在action里可以这样调用<br />
可以看到action里没有做对传递参数的处理，只需要把request整个传到分页类里就可以了<br />
--------------------------------------------------------------------------------------------------------------</p>
<p>&nbsp;&nbsp;&nbsp;String sql = "select top 100 percent * from usertable";<br />
&nbsp;&nbsp;&nbsp;String sqlcount = "select count(*) from usertable";//为了得到总行数<br />
&nbsp;&nbsp;&nbsp;int pagesize= 18;<br />
&nbsp;&nbsp;&nbsp;int pagenum = 1;<br />
&nbsp;&nbsp;&nbsp;if(request.getParameter("pagenum")!=null)<br />
&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;pagenum = java.lang.Integer.parseInt(request.getParameter("pagenum"));<br />
&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;ResultGatherPro rs = new ResultGatherPro(sql,pagesize,pagenum,sqlcount);<br />
&nbsp;&nbsp;&nbsp;request.setAttribute("liststill",rs.selectRS());<br />
&nbsp;&nbsp;&nbsp;request.setAttribute("changepage",rs.ChangePage(request));<br />
&nbsp;&nbsp;&nbsp;request.setAttribute("gotopage",rs.gotoPage(request));</p>
<p>-----------------------------------------------------------------------------------------------------------------------------------</p>
<p>最后 jsp里可以这样写</p>
<p>-------------------------------------------------------------------------------------------------------------------------</p>
<p>&lt;logic:iterate id="listuser" name="liststill" type="Map"&gt;<br />
&lt;bean:write name='listuser' property='username'/&gt;&nbsp;&nbsp;&nbsp;<br />
&lt;bean:write name='listuser' property='useremail'/&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&lt;/logic:iterate&gt; </p>
<p>&lt;bean:write name='changepage' filter="false"/&gt;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;bean:write name='gotopage' filter="false"/&gt;<br />
上面两个一定要设置filter="false" 不然会过滤html部分<br />
<br />
<br />
<br />
如果用mysql数据库<br />
将分页类中<br />
con.prepareCall("{call p_show('" + sql + "'," + intPageSize + "," + intPage + ")}");<br />
改成<br />
con.prepareCall(sql+" limit "+(intPage-1)*intPageSize+","+intPageSize);<br />
<br />
<br />
如果用oracle数据库<br />
改成<br />
con.prepareCall("SELECT * FROM(SELECT A.*, rownum r FROM("+sql+") A WHERE rownum &lt;= "+intPage*intPageSize+") B WHERE r &gt; "+(intPage-1)<br />
*intPageSize);<br />
<br />
最好不要用把所有记录都读出来然后在其中进行分页的方法</p>
</div>
<img src ="http://www.blogjava.net/HappyJava/aggbug/177429.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/HappyJava/" target="_blank">李建軍</a> 2008-01-24 10:26 <a href="http://www.blogjava.net/HappyJava/articles/177429.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>