﻿<?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-Hello , my kaleidoscope !-文章分类-技术文章柜子</title><link>http://www2.blogjava.net/gip/category/3620.html</link><description>Java</description><language>zh-cn</language><lastBuildDate>Thu, 01 Mar 2007 19:30:12 GMT</lastBuildDate><pubDate>Thu, 01 Mar 2007 19:30:12 GMT</pubDate><ttl>60</ttl><item><title>  使用Ajax的挑战</title><link>http://www.blogjava.net/gip/articles/19028.html</link><dc:creator>我的万花@</dc:creator><author>我的万花@</author><pubDate>Wed, 09 Nov 2005 10:37:00 GMT</pubDate><guid>http://www.blogjava.net/gip/articles/19028.html</guid><wfw:comment>http://www.blogjava.net/gip/comments/19028.html</wfw:comment><comments>http://www.blogjava.net/gip/articles/19028.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/gip/comments/commentRss/19028.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/gip/services/trackbacks/19028.html</trackback:ping><description><![CDATA[<TABLE cellSpacing=0 cellPadding=0 width="95%" align=center border=0>
<TBODY>
<TR>
<TD width="99%">
<TD width="1%">
<TR>
<TD width="99%"><BR>
<P><FONT face="宋体,Arial, Helvetica, sans-serif" color=#000000 size=2></FONT><FONT face="黑体,Arial, Helvetica, sans-serif" color=#000000 size=4>使用Ajax的挑战 </FONT><FONT color=gray size=1>阅读次数220</FONT> 
<P align=right>出处 不详&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</P>
<P></P>
<HR noShade>

<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD vAlign=top width="86%">与任何技术一样，使用Ajax在相当多的方面都可能范错误。我在这儿讨论的问题目前都缺少解决方案，并将会随着Ajax的成熟而解决或提高。随着开发Ajax应用经验的不断获取，开发者社区中将会出现最好的实践经验与指导方针。<BR><BR>　　1、XMLHttpRequest的有效性<BR><BR>　　Ajax开发者面对的一个最大问题是当XMLHttpRequest不可用时如何反应。虽然大部分现代浏览器支持XMLHttpRequest，但还是有少量的用户，他们的浏览器不能支持，或由于浏览器安全设置而阻止对XMLHttpRequest的使用。若你的Web应用发布于公司内部的Intranet上，你很可能可以指定支持哪种浏览器，并可以确保XMLHttpRequest是可用的。若你在公共WEB上发布，则你必须意识到由于假定XMLHttpRequest是可用的，所有就阻止了老浏览器、手持设备浏览器等等用户来使用你的系统。<BR><BR>　　然而，你应该尽力保证应用系统“正常降级”使用，在系统中保留适用于不支持XMLHttpRequest的浏览器的功能。在购物车例子中，最好的方法是有一个Add to Cart按钮，可以进行常规的提交处理，并刷新页面来反映购物车状态的变化。Ajax行卫可以在页面被载入时通过JavaScript添加到页面中，只在XMLHttpRequest可用的情况下，为每个Add to Cart按钮加上JavaScript处理函数。另一个方法是在用户登录时检测XMLHttpRequest，再决定是提供Ajax版本还是常规基于form提交的版本。<BR><BR>　　2、可用性考虑<BR><BR>　　围绕着Ajax应用的大部分问题都是很普通的问题。例如，让用户知道他们的输入已经被注册并处理，是很重要的，因为在XMLHttpRequest处理过程中并不能提供通常的漏斗旋转光标。一种方法是将“确认”按扭上的文本替换为“正在更新中…”，以避免用户在等待响应时多次点击按钮。<BR><BR>　　另一个问题是，用户可能没有注意到他们正在观看的页面已经被更新。可以通过使用各种视觉技巧来将用户的眼光吸引到页面的更新区域。还有一个问题是通过Ajax更新页面打断了浏览器“退回前页”按钮的正常工作，地址栏中的URL不能反映页面的全部状态，并且不能使用书签功能。参见Resource章节中列出的网站地址上的文章来了解更多Ajax应用关于可用性方面的问题。<BR><BR>　　3、服务器负载<BR><BR>　　使用Ajax界面代替传统的基于form的界面可能戏剧性地增加传递到服务器的请求数量。例如，一个普通的Google搜索给服务器造成一次命中，并在用户确认搜索表单时发生。然而，Google Suggest，将会试图自动完成你的搜索词，在用户打字时将会往服务器发送多个请求。在开发一个Ajax应用时，要注意到你将会发送多少请求到用户器端，以及服务器的负载指标。你可以通过在客户端适当地缓存请求、与服务器响应来缓减负载压力。你也应该在设计Ajax应用时尽量在客户端处理更多的逻辑，而不用与服务器端通讯。<BR><BR>　　4、处理异步<BR><BR>　　一定要记住，没有任何东西可以保证XMLHttpRequest将会按照它们被发送的顺序来依次结束。实际上，你在设计系统时，脑子里应该始终假定它们不会按原来顺序结束。在购物车例子中，使用了一个最后更新的时间戳来保证最新的数据不会被改写。这个非常基本的方法可以在购物车场景中工作，但可能不能在其它情况下工作。在设计时刻就要考虑你该如何处理异步服务器响应。<BR><BR>　　结论<BR><BR>　　你现在应该对于Ajax的基本原则有了一个良好的了解，另外，你应该理解一些更高级的随Ajax方法而来的设计问题。创建一个成功的Ajax应用需要一系列的方法—从JavaScript UI设计到服务器端架构—但是你现在应该已经具备了需要使用到的Ajax核心知识。</TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><img src ="http://www.blogjava.net/gip/aggbug/19028.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/gip/" target="_blank">我的万花@</a> 2005-11-09 18:37 <a href="http://www.blogjava.net/gip/articles/19028.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>被sql骗了</title><link>http://www.blogjava.net/gip/articles/19027.html</link><dc:creator>我的万花@</dc:creator><author>我的万花@</author><pubDate>Wed, 09 Nov 2005 10:35:00 GMT</pubDate><guid>http://www.blogjava.net/gip/articles/19027.html</guid><wfw:comment>http://www.blogjava.net/gip/comments/19027.html</wfw:comment><comments>http://www.blogjava.net/gip/articles/19027.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/gip/comments/commentRss/19027.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/gip/services/trackbacks/19027.html</trackback:ping><description><![CDATA[我们开发的是一套大型门户系统，因为是Internet访问的，所以，Statement会出现安全问题，这个在<BR><BR>http://blog.csdn.net/hongbo781202/archive/2005/09/19/485092.aspx里面已经讨论过了，然后我抄一段ORACLE电子杂志的话给大家看看：“除了缓冲的问题之外，至少还有一个更好的原因使我们在企业应用程序中更喜欢使用 PreparedStatement对象,那就是安全性。传递给PreparedStatement对象的参数可以被强制进行类型转换，使开发人员可以确保在插入或查询数据时与底层的数据库格式匹配。<BR>当处理公共Web站点上的用户传来的数据的时候，安全性的问题就变得极为重要。传递给 PreparedStatement的字符串参数会自动被驱动器忽略。最简单的情况下，这就意味着当你的程序试着将字符串“DAngelo”插入到 VARCHAR2中时，该语句将不会识别第一个“，”，从而导致悲惨的失败。几乎很少有必要创建你自己的字符串忽略代码。<BR>在Web环境中，有恶意的用户会利用那些设计不完善的、不能正确处理字符串的应用程序。特别是在公共Web站点上,在没有首先通过PreparedStatement对象处理的情况下，所有的用户输入都不应该传递给SQL语句。此外，在用户有机会修改SQL语句的地方，如HTML的隐藏区域或一个查询字符串上，SQL语句都不应该被显示出来。”。这段话和我们群里面的讨论一模一样。<BR><BR>关于性能问题，再给大家看段话：“通常认为PreparedStatement 对象比Statement对象更有效,特别是如果带有不同参数的同一SQL语句被多次执行的时候。PreparedStatement对象允许数据库预编译SQL语句，这样在随后的运行中可以节省时间并增加代码的可读性。<BR>然而，在Oracle环境中，开发人员实际上有更大的灵活性。当使用 Statement或PreparedStatement对象时，Oracle数据库会缓存SQL语句以便以后使用。在一些情况下,由于驱动器自身需要额外的处理和在Java应用程序和Oracle服务器间增加的网络活动，执行PreparedStatement对象实际上会花更长的时间。”<BR><BR>实际上，我的测试结果是：在同一SQL执行5次的情况下，PrepareStatement比Statement要慢3%.<BR><BR>我们再看看http://www.oreilly.com/catalog/jorajdbc/chapter/ch19.html<BR>里面有详细的图表说明为什么Statement比PreparedStatement快。结论是：一个prepared statement要执行65次以上才能赶上一个普通statement的执行效率。<BR><BR>另外一个问题就是Index的使用，基本的原则就是： 如果是多列Index，一般应该保证这几个列都在查询条件中。而且对于单列Index，只有满足查询出来的结果命中率在20%以下，使用索引会才会加快速度！ 否则可能会越Index越慢哦!<BR><BR>根据经验看，上面的结论对Oracle,Sybase,Mysql,Informix都成立，好可怕啊，不知道我前两年的程序怎么做的，原来我前两年都是在谎言的边缘度过！ <img src ="http://www.blogjava.net/gip/aggbug/19027.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/gip/" target="_blank">我的万花@</a> 2005-11-09 18:35 <a href="http://www.blogjava.net/gip/articles/19027.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用FileUpload组件上传文件</title><link>http://www.blogjava.net/gip/articles/14285.html</link><dc:creator>我的万花@</dc:creator><author>我的万花@</author><pubDate>Wed, 28 Sep 2005 03:51:00 GMT</pubDate><guid>http://www.blogjava.net/gip/articles/14285.html</guid><wfw:comment>http://www.blogjava.net/gip/comments/14285.html</wfw:comment><comments>http://www.blogjava.net/gip/articles/14285.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/gip/comments/commentRss/14285.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/gip/services/trackbacks/14285.html</trackback:ping><description><![CDATA[<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD>
<TABLE cellSpacing=0 cellPadding=0 width="100%" bgColor=#ffffff border=0>
<TBODY>
<TR>
<TD class=title1 align=middle width="100%" bgColor=#eeeeee colSpan=3 height=40><B>使用FileUpload组件上传文件</B></TD></TR>
<TR>
<TD align=middle width="100%" bgColor=#eeeeee><A href="http://www.javaresearch.org/profile.jsp?user=7864">TonnyHot</A> 整理&nbsp; (参与分：41018，专家分：2878)&nbsp;&nbsp; 发表：2005-02-01 17:24 &nbsp;&nbsp;版本：1.0 &nbsp;&nbsp;阅读：<B>2080</B>次 </TD></TR></TBODY></TABLE></TD></TR><!-- end of article title -->
<TR>
<TD vAlign=top align=middle width="100%"><!--start of article content -->
<TABLE width="98%" border=0>
<TBODY>
<TR>
<TD class=text align=left width="100%"><BR>文件上传在web应用中非常普遍，要在jsp环境中实现文件上传功能是非常容易的，因为网上有许多用java开发的文件上传组件，本文以commons-fileupload组件为例，为jsp应用添加文件上传功能。<BR>common-fileupload组件是apache的一个开源项目之一，可以从<A href="http://jakarta.apache.org/commons/fileupload/">http://jakarta.apache.org/commons/fileupload/</A><BR>下载。用该组件可实现一次上传一个或多个文件，并可限制文件大小。<BR><BR><BR>下载后解压zip包，将commons-fileupload-1.0.jar复制到tomcat的webapps\你的webapp\WEB-INF\lib\下，目录不存在请自建目录。<BR>新建一个servlet:&nbsp;Upload.java用于文件上传：<BR>import&nbsp;java.io.*;<BR>import&nbsp;java.util.*;<BR>import&nbsp;javax.servlet.*;<BR>import&nbsp;javax.servlet.http.*;<BR>import&nbsp;org.apache.commons.fileupload.*;<BR><BR>public&nbsp;class&nbsp;Upload&nbsp;extends&nbsp;HttpServlet&nbsp;{<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;String&nbsp;uploadPath&nbsp;=&nbsp;"C:\\upload\\";&nbsp;//&nbsp;上传文件的目录<BR>&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;String&nbsp;tempPath&nbsp;=&nbsp;"C:\\upload\\tmp\\";&nbsp;//&nbsp;临时文件目录<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;doPost(HttpServletRequest&nbsp;request,<BR>&nbsp;&nbsp;&nbsp;&nbsp;HttpServletResponse&nbsp;response)<BR>&nbsp;&nbsp;&nbsp;&nbsp;throws&nbsp;IOException,&nbsp;ServletException<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>}<BR>在doPost()方法中，当servlet收到浏览器发出的Post请求后，实现文件上传。以下是示例代码：<BR>public&nbsp;void&nbsp;doPost(HttpServletRequest&nbsp;request,<BR>HttpServletResponse&nbsp;response)<BR>throws&nbsp;IOException,&nbsp;ServletException<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DiskFileUpload&nbsp;fu&nbsp;=&nbsp;new&nbsp;DiskFileUpload();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;设置最大文件尺寸，这里是4MB<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fu.setSizeMax(4194304);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;设置缓冲区大小，这里是4kb<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fu.setSizeThreshold(4096);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;设置临时目录：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fu.setRepositoryPath(tempPath);<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;得到所有的文件：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;List&nbsp;fileItems&nbsp;=&nbsp;fu.parseRequest(request);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Iterator&nbsp;i&nbsp;=&nbsp;fileItems.iterator();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;依次处理每一个文件：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(i.hasNext())&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FileItem&nbsp;fi&nbsp;=&nbsp;(FileItem)i.next();<BR>&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;String&nbsp;fileName&nbsp;=&nbsp;fi.getName();<BR>&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;...<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;写入文件，暂定文件名为a.txt，可以从fileName中提取文件名：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fi.write(new&nbsp;File(uploadPath&nbsp;+&nbsp;"a.txt"));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;catch(Exception&nbsp;e)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;可以跳转出错页面<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>}<BR>如果要在配置文件中读取指定的上传文件夹，可以在init()方法中执行：<BR>public&nbsp;void&nbsp;init()&nbsp;throws&nbsp;ServletException&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;uploadPath&nbsp;=&nbsp;....<BR>&nbsp;&nbsp;&nbsp;&nbsp;tempPath&nbsp;=&nbsp;....<BR>&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;文件夹不存在就自动创建：<BR>&nbsp;&nbsp;&nbsp;&nbsp;if(!new&nbsp;File(uploadPath).isDirectory())<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new&nbsp;File(uploadPath).mkdirs();<BR>&nbsp;&nbsp;&nbsp;&nbsp;if(!new&nbsp;File(tempPath).isDirectory())<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new&nbsp;File(tempPath).mkdirs();<BR>}<BR>编译该servlet，注意要指定classpath，确保包含commons-upload-1.0.jar和tomcat\common\lib\servlet-api.jar。<BR>配置servlet，用记事本打开tomcat\webapps\你的webapp\WEB-INF\web.xml，没有的话新建一个。<BR>典型配置如下：<BR>&lt;?xml&nbsp;version="1.0"&nbsp;encoding="ISO-8859-1"?&gt;<BR>&lt;!DOCTYPE&nbsp;web-app<BR>&nbsp;&nbsp;&nbsp;&nbsp;PUBLIC&nbsp;"-//Sun&nbsp;Microsystems,&nbsp;Inc.//DTD&nbsp;Web&nbsp;Application&nbsp;2.3//EN"<BR>&nbsp;&nbsp;&nbsp;&nbsp;"http://java.sun.com/dtd/web-app_2_3.dtd"&gt;<BR><BR>&lt;web-app&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&lt;servlet&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;servlet-name&gt;Upload&lt;/servlet-name&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;servlet-class&gt;Upload&lt;/servlet-class&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&lt;/servlet&gt;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&lt;servlet-mapping&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;servlet-name&gt;Upload&lt;/servlet-name&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;url-pattern&gt;/fileupload&lt;/url-pattern&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&lt;/servlet-mapping&gt;<BR>&lt;/web-app&gt;<BR>配置好servlet后，启动tomcat，写一个简单的html测试：<BR>&lt;form&nbsp;action="fileupload"&nbsp;method="post"<BR>enctype="multipart/form-data"&nbsp;name="form1"&gt;<BR>&nbsp;&nbsp;&lt;input&nbsp;type="file"&nbsp;name="file"&gt;<BR>&nbsp;&nbsp;&lt;input&nbsp;type="submit"&nbsp;name="Submit"&nbsp;value="upload"&gt;<BR>&lt;/form&gt;<BR>注意action="fileupload"其中fileupload是配置servlet时指定的url-pattern。&nbsp;<BR><BR><BR>下面是某个大虾的代码：<BR><BR>这个Upload比smartUpload好用多了.完全是我一个个byte调试出来的,不象smartUpload的bug具多.<BR>调用方法:<BR>Upload&nbsp;up&nbsp;=&nbsp;new&nbsp;Upload();<BR>up.init(request);<BR>/**<BR>此处可以调用setSaveDir(String&nbsp;saveDir);设置保存路径<BR>调用setMaxFileSize(long&nbsp;size)设置上传文件的最大字节.<BR>调用setTagFileName(String)设置上传后文件的名字(只对第一个文件有效)<BR>*/<BR>up.&nbsp;uploadFile();<BR><BR>然后String[]&nbsp;names&nbsp;=&nbsp;up.getFileName();得到上传的文件名,文件绝对路径应该是<BR>保存的目录saveDir+"/"+names[i];<BR>可以通过up.getParameter("field");得到上传的文本或up.getParameterValues("filed")<BR>得到同名字段如多个checkBox的值.<BR>其它的自己试试.<BR><BR>源码:____________________________________________________________<BR>package&nbsp;com.inmsg.beans;<BR><BR>import&nbsp;java.io.*;<BR>import&nbsp;java.util.*;<BR>import&nbsp;javax.servlet.*;<BR>import&nbsp;javax.servlet.http.*;<BR><BR>public&nbsp;class&nbsp;Upload&nbsp;{<BR>&nbsp;&nbsp;private&nbsp;String&nbsp;saveDir&nbsp;=&nbsp;".";&nbsp;//要保存文件的路径<BR>&nbsp;&nbsp;private&nbsp;String&nbsp;contentType&nbsp;=&nbsp;"";&nbsp;//文档类型<BR>&nbsp;&nbsp;private&nbsp;String&nbsp;charset&nbsp;=&nbsp;"";&nbsp;//字符集<BR>&nbsp;&nbsp;private&nbsp;ArrayList&nbsp;tmpFileName&nbsp;=&nbsp;new&nbsp;ArrayList();&nbsp;//临时存放文件名的数据结构<BR>&nbsp;&nbsp;private&nbsp;Hashtable&nbsp;parameter&nbsp;=&nbsp;new&nbsp;Hashtable();&nbsp;//存放参数名和值的数据结构<BR>&nbsp;&nbsp;private&nbsp;ServletContext&nbsp;context;&nbsp;//程序上下文,用于初始化<BR>&nbsp;&nbsp;private&nbsp;HttpServletRequest&nbsp;request;&nbsp;//用于传入请求对象的实例<BR>&nbsp;&nbsp;private&nbsp;String&nbsp;boundary&nbsp;=&nbsp;"";&nbsp;//内存数据的分隔符<BR>&nbsp;&nbsp;private&nbsp;int&nbsp;len&nbsp;=&nbsp;0;&nbsp;//每次从内在中实际读到的字节长度<BR>&nbsp;&nbsp;private&nbsp;String&nbsp;queryString;<BR>&nbsp;&nbsp;private&nbsp;int&nbsp;count;&nbsp;//上载的文件总数<BR>&nbsp;&nbsp;private&nbsp;String[]&nbsp;fileName;&nbsp;//上载的文件名数组<BR>&nbsp;&nbsp;private&nbsp;long&nbsp;maxFileSize&nbsp;=&nbsp;1024&nbsp;*&nbsp;1024&nbsp;*&nbsp;10;&nbsp;//最大文件上载字节;<BR>&nbsp;&nbsp;private&nbsp;String&nbsp;tagFileName&nbsp;=&nbsp;"";<BR><BR>&nbsp;&nbsp;public&nbsp;final&nbsp;void&nbsp;init(HttpServletRequest&nbsp;request)&nbsp;throws&nbsp;ServletException&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;this.request&nbsp;=&nbsp;request;<BR>&nbsp;&nbsp;&nbsp;&nbsp;boundary&nbsp;=&nbsp;request.getContentType().substring(30);&nbsp;//得到内存中数据分界符<BR>&nbsp;&nbsp;&nbsp;&nbsp;queryString&nbsp;=&nbsp;request.getQueryString();<BR>&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;public&nbsp;String&nbsp;getParameter(String&nbsp;s)&nbsp;{&nbsp;//用于得到指定字段的参数值,重写request.getParameter(String&nbsp;s)<BR>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(parameter.isEmpty())&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;null;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;(String)&nbsp;parameter.get(s);<BR>&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;public&nbsp;String[]&nbsp;getParameterValues(String&nbsp;s)&nbsp;{&nbsp;//用于得到指定同名字段的参数数组,重写request.getParameterValues(String&nbsp;s)<BR>&nbsp;&nbsp;&nbsp;&nbsp;ArrayList&nbsp;al&nbsp;=&nbsp;new&nbsp;ArrayList();<BR>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(parameter.isEmpty())&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;null;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;Enumeration&nbsp;e&nbsp;=&nbsp;parameter.keys();<BR>&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(e.hasMoreElements())&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;key&nbsp;=&nbsp;(String)&nbsp;e.nextElement();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(&nbsp;-1&nbsp;!=&nbsp;key.indexOf(s&nbsp;+&nbsp;"||||||||||")&nbsp;||&nbsp;key.equals(s))&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;al.add(parameter.get(key));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(al.size()&nbsp;==&nbsp;0)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;null;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;String[]&nbsp;value&nbsp;=&nbsp;new&nbsp;String[al.size()];<BR>&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(int&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;value.length;&nbsp;i++)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value[i]&nbsp;=&nbsp;(String)&nbsp;al.get(i);<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;value;<BR>&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;public&nbsp;String&nbsp;getQueryString()&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;queryString;<BR>&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;public&nbsp;int&nbsp;getCount()&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;count;<BR>&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;public&nbsp;String[]&nbsp;getFileName()&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;fileName;<BR>&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;public&nbsp;void&nbsp;setMaxFileSize(long&nbsp;size)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;maxFileSize&nbsp;=&nbsp;size;<BR>&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;public&nbsp;void&nbsp;setTagFileName(String&nbsp;filename)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;tagFileName&nbsp;=&nbsp;filename;<BR>&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;public&nbsp;void&nbsp;setSaveDir(String&nbsp;saveDir)&nbsp;{&nbsp;//设置上载文件要保存的路径<BR>&nbsp;&nbsp;&nbsp;&nbsp;this.saveDir&nbsp;=&nbsp;saveDir;<BR>&nbsp;&nbsp;&nbsp;&nbsp;File&nbsp;testdir&nbsp;=&nbsp;new&nbsp;File(saveDir);&nbsp;//为了保证目录存在,如果没有则新建该目录<BR>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(!testdir.exists())&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;testdir.mkdirs();<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;public&nbsp;void&nbsp;setCharset(String&nbsp;charset)&nbsp;{&nbsp;//设置字符集<BR>&nbsp;&nbsp;&nbsp;&nbsp;this.charset&nbsp;=&nbsp;charset;<BR>&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;public&nbsp;boolean&nbsp;uploadFile()&nbsp;throws&nbsp;ServletException,&nbsp;IOException&nbsp;{&nbsp;//用户调用的上载方法<BR>&nbsp;&nbsp;&nbsp;&nbsp;setCharset(request.getCharacterEncoding());<BR>&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;uploadFile(request.getInputStream());<BR>&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;private&nbsp;boolean&nbsp;uploadFile(ServletInputStream&nbsp;servletinputstream)&nbsp;throws&nbsp;//取得央存数据的主方法<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ServletException,&nbsp;IOException&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;line&nbsp;=&nbsp;null;<BR>&nbsp;&nbsp;&nbsp;&nbsp;byte[]&nbsp;buffer&nbsp;=&nbsp;new&nbsp;byte[256];<BR>&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(&nbsp;(line&nbsp;=&nbsp;readLine(buffer,&nbsp;servletinputstream,&nbsp;charset))&nbsp;!=&nbsp;null)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(line.startsWith("Content-Disposition:&nbsp;form-data;"))&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;i&nbsp;=&nbsp;line.indexOf("filename=");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(i&nbsp;&gt;=&nbsp;0)&nbsp;{&nbsp;//如果一段分界符内的描述中有filename=,说明是文件的编码内容<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;fName&nbsp;=&nbsp;getFileName(line);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(fName.equals(""))&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;continue;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(count&nbsp;==&nbsp;0&nbsp;&amp;&amp;&nbsp;tagFileName.length()&nbsp;!=&nbsp;0)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;ext&nbsp;=&nbsp;fName.substring(&nbsp;(fName.lastIndexOf(".")&nbsp;+&nbsp;1));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fName&nbsp;=&nbsp;tagFileName&nbsp;+&nbsp;"."&nbsp;+&nbsp;ext;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmpFileName.add(fName);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;count++;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(&nbsp;(line&nbsp;=&nbsp;readLine(buffer,&nbsp;servletinputstream,&nbsp;charset))&nbsp;!=&nbsp;null)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(line.length()&nbsp;&lt;=&nbsp;2)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;File&nbsp;f&nbsp;=&nbsp;new&nbsp;File(saveDir,&nbsp;fName);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FileOutputStream&nbsp;dos&nbsp;=&nbsp;new&nbsp;FileOutputStream(f);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;long&nbsp;size&nbsp;=&nbsp;0l;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(&nbsp;(line&nbsp;=&nbsp;readLine(buffer,&nbsp;servletinputstream,&nbsp;null))&nbsp;!=&nbsp;null)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(line.indexOf(boundary)&nbsp;!=&nbsp;-1)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<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;size&nbsp;+=&nbsp;len;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(size&nbsp;&gt;&nbsp;maxFileSize)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw&nbsp;new&nbsp;IOException("文件超过"&nbsp;+&nbsp;maxFileSize&nbsp;+&nbsp;"字节!");<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;dos.write(buffer,&nbsp;0,&nbsp;len);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dos.close();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;{&nbsp;//否则是字段编码的内容<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;key&nbsp;=&nbsp;getKey(line);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;value&nbsp;=&nbsp;"";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(&nbsp;(line&nbsp;=&nbsp;readLine(buffer,&nbsp;servletinputstream,&nbsp;charset))&nbsp;!=&nbsp;null)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(line.length()&nbsp;&lt;=&nbsp;2)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(&nbsp;(line&nbsp;=&nbsp;readLine(buffer,&nbsp;servletinputstream,&nbsp;charset))&nbsp;!=&nbsp;null)&nbsp;{<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(line.indexOf(boundary)&nbsp;!=&nbsp;-1)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<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;value&nbsp;+=&nbsp;line;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;put(key,&nbsp;value.trim(),&nbsp;parameter);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(queryString&nbsp;!=&nbsp;null)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String[]&nbsp;each&nbsp;=&nbsp;split(queryString,&nbsp;"&amp;");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(int&nbsp;k&nbsp;=&nbsp;0;&nbsp;k&nbsp;&lt;&nbsp;each.length;&nbsp;k++)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String[]&nbsp;nv&nbsp;=&nbsp;split(each[k],&nbsp;"=");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(nv.length&nbsp;==&nbsp;2)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;put(nv[0],&nbsp;nv[1],&nbsp;parameter);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;fileName&nbsp;=&nbsp;new&nbsp;String[tmpFileName.size()];<BR>&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(int&nbsp;k&nbsp;=&nbsp;0;&nbsp;k&nbsp;&lt;&nbsp;fileName.length;&nbsp;k++)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fileName[k]&nbsp;=&nbsp;(String)&nbsp;tmpFileName.get(k);&nbsp;//把ArrayList中临时文件名倒入数据中供用户调用<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(fileName.length&nbsp;==&nbsp;0)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;false;&nbsp;//如果fileName数据为空说明没有上载任何文件<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;true;<BR>&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;private&nbsp;void&nbsp;put(String&nbsp;key,&nbsp;String&nbsp;value,&nbsp;Hashtable&nbsp;ht)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(!ht.containsKey(key))&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ht.put(key,&nbsp;value);<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;{&nbsp;//如果已经有了同名的KEY,就要把当前的key更名,同时要注意不能构成和KEY同名<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread.currentThread().sleep(1);&nbsp;//为了不在同一ms中产生两个相同的key<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;catch&nbsp;(Exception&nbsp;e)&nbsp;{}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;key&nbsp;+=&nbsp;"||||||||||"&nbsp;+&nbsp;System.currentTimeMillis();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ht.put(key,&nbsp;value);<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;/*<BR>&nbsp;&nbsp;&nbsp;调用ServletInputstream.readLine(byte[]&nbsp;b,int&nbsp;offset,length)方法,该方法是从ServletInputstream流中读一行<BR>&nbsp;&nbsp;&nbsp;到指定的byte数组,为了保证能够容纳一行,该byte[]b不应该小于256,重写的readLine中,调用了一个成员变量len为<BR>&nbsp;&nbsp;&nbsp;实际读到的字节数(有的行不满256),则在文件内容写入时应该从byte数组中写入这个len长度的字节而不是整个byte[]<BR>&nbsp;&nbsp;&nbsp;的长度,但重写的这个方法返回的是String以便分析实际内容,不能返回len,所以把len设为成员变量,在每次读操作时<BR>&nbsp;&nbsp;&nbsp;把实际长度赋给它.<BR>&nbsp;&nbsp;&nbsp;也就是说在处理到文件的内容时数据既要以String形式返回以便分析开始和结束标记,又要同时以byte[]的形式写到文件<BR>&nbsp;&nbsp;&nbsp;输出流中.<BR>&nbsp;&nbsp;&nbsp;*/<BR>&nbsp;&nbsp;private&nbsp;String&nbsp;readLine(byte[]&nbsp;Linebyte,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ServletInputStream&nbsp;servletinputstream,&nbsp;String&nbsp;charset)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;len&nbsp;=&nbsp;servletinputstream.readLine(Linebyte,&nbsp;0,&nbsp;Linebyte.length);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(len&nbsp;==&nbsp;-1)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;null;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(charset&nbsp;==&nbsp;null)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;new&nbsp;String(Linebyte,&nbsp;0,&nbsp;len);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;new&nbsp;String(Linebyte,&nbsp;0,&nbsp;len,&nbsp;charset);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;catch&nbsp;(Exception&nbsp;_ex)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;null;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;private&nbsp;String&nbsp;getFileName(String&nbsp;line)&nbsp;{&nbsp;//从描述字符串中分离出文件名<BR>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(line&nbsp;==&nbsp;null)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;"";<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;i&nbsp;=&nbsp;line.indexOf("filename=");<BR>&nbsp;&nbsp;&nbsp;&nbsp;line&nbsp;=&nbsp;line.substring(i&nbsp;+&nbsp;9).trim();<BR>&nbsp;&nbsp;&nbsp;&nbsp;i&nbsp;=&nbsp;line.lastIndexOf("\\");<BR>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(i&nbsp;&lt;&nbsp;0&nbsp;||&nbsp;i&nbsp;&gt;=&nbsp;line.length()&nbsp;-&nbsp;1)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i&nbsp;=&nbsp;line.lastIndexOf("/");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(line.equals("\"\""))&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;"";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(i&nbsp;&lt;&nbsp;0&nbsp;||&nbsp;i&nbsp;&gt;=&nbsp;line.length()&nbsp;-&nbsp;1)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;line;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;line.substring(i&nbsp;+&nbsp;1,&nbsp;line.length()&nbsp;-&nbsp;1);<BR>&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;private&nbsp;String&nbsp;getKey(String&nbsp;line)&nbsp;{&nbsp;//从描述字符串中分离出字段名<BR>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(line&nbsp;==&nbsp;null)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;"";<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;i&nbsp;=&nbsp;line.indexOf("name=");<BR>&nbsp;&nbsp;&nbsp;&nbsp;line&nbsp;=&nbsp;line.substring(i&nbsp;+&nbsp;5).trim();<BR>&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;line.substring(1,&nbsp;line.length()&nbsp;-&nbsp;1);<BR>&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;public&nbsp;static&nbsp;String[]&nbsp;split(String&nbsp;strOb,&nbsp;String&nbsp;mark)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(strOb&nbsp;==&nbsp;null)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;null;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;StringTokenizer&nbsp;st&nbsp;=&nbsp;new&nbsp;StringTokenizer(strOb,&nbsp;mark);<BR>&nbsp;&nbsp;&nbsp;&nbsp;ArrayList&nbsp;tmp&nbsp;=&nbsp;new&nbsp;ArrayList();<BR>&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(st.hasMoreTokens())&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmp.add(st.nextToken());<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;String[]&nbsp;strArr&nbsp;=&nbsp;new&nbsp;String[tmp.size()];<BR>&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(int&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;tmp.size();&nbsp;i++)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strArr[i]&nbsp;=&nbsp;(String)&nbsp;tmp.get(i);<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;strArr;<BR>&nbsp;&nbsp;}<BR>}<BR><BR><BR>下载其实非常简单，只要如下处理，就不会发生问题。<BR><BR>&nbsp;&nbsp;public&nbsp;void&nbsp;downLoad(String&nbsp;filePath,HttpServletResponse&nbsp;response,boolean&nbsp;isOnLine)<BR>&nbsp;&nbsp;throws&nbsp;Exception{<BR>&nbsp;&nbsp;&nbsp;&nbsp;File&nbsp;f&nbsp;=&nbsp;new&nbsp;File(filePath);<BR>&nbsp;&nbsp;&nbsp;&nbsp;if(!f.exists()){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;response.sendError(404,"File&nbsp;not&nbsp;found!");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;BufferedInputStream&nbsp;br&nbsp;=&nbsp;new&nbsp;BufferedInputStream(new&nbsp;FileInputStream(f));<BR>&nbsp;&nbsp;&nbsp;&nbsp;byte[]&nbsp;buf&nbsp;=&nbsp;new&nbsp;byte[1024];<BR>&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;len&nbsp;=&nbsp;0;<BR>&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;response.reset();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//非常重要<BR>&nbsp;&nbsp;&nbsp;&nbsp;if(isOnLine){&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//在线打开方式<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;URL&nbsp;u&nbsp;=&nbsp;new&nbsp;URL("file:///"+filePath);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;response.setContentType(u.openConnection().getContentType());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;response.setHeader("Content-Disposition",&nbsp;"inline;&nbsp;filename="+f.getName());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//文件名应该编码成UTF-8<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;else{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//纯下载方式<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;response.setContentType("application/x-msdownload");&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;response.setHeader("Content-Disposition",&nbsp;"attachment;&nbsp;filename="&nbsp;+&nbsp;f.getName());&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;OutputStream&nbsp;out&nbsp;=&nbsp;response.getOutputStream();<BR>&nbsp;&nbsp;&nbsp;&nbsp;while((len&nbsp;=&nbsp;br.read(buf))&nbsp;&gt;0)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.write(buf,0,len);<BR>&nbsp;&nbsp;&nbsp;&nbsp;br.close();<BR>&nbsp;&nbsp;&nbsp;&nbsp;out.close();<BR>&nbsp;&nbsp;}&nbsp;<BR><BR>&nbsp;<BR><BR>smartUpload:<BR>上传：在unix/linux系统上，如果上传格式文档，如Wrod,Excel等文档，很多时候打开文档出错。<BR><BR>原因：EOF处理没有判断。<BR><BR>下载：更不用说了，基本上都会出错，下载时会比原文件多出N多个字节。你看看它自带的例子就知道了。下载时一定要这样写：<BR><BR>&lt;%@page&nbsp;xxxxxx%&gt;&lt;%<BR>smartUpload&nbsp;smu=&nbsp;............<BR><BR>如果前面有共它任何指令语句或动作语句写在多行而没有在一行（有病啊，我要是inclide&nbsp;n多个文件都不能分行），那下载的文件肯定有问题。<BR><BR>原因：jsp在编译时默认了文档类型并有默认输出，而smartUpload在输出要下载的文档之前没有清空。&nbsp;<BR></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><img src ="http://www.blogjava.net/gip/aggbug/14285.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/gip/" target="_blank">我的万花@</a> 2005-09-28 11:51 <a href="http://www.blogjava.net/gip/articles/14285.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>