﻿<?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-Dev Zone-随笔分类-设计/开发</title><link>http://www.blogjava.net/dev/category/1441.html</link><description>&lt;table width="40%"&gt;
&lt;tr&gt;&lt;td width="100%" align="right"&gt;
   &lt;nobr&gt;&lt;i&gt;
偏执狂才能生存，人生/事业的路上需要再坚持一下&lt;br&gt;
但是又怎么说得清坚持的结果，道得尽坚持的含义
   &lt;/i&gt;&lt;/nobr&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</description><language>zh-cn</language><lastBuildDate>Tue, 27 Feb 2007 22:38:04 GMT</lastBuildDate><pubDate>Tue, 27 Feb 2007 22:38:04 GMT</pubDate><ttl>60</ttl><item><title>struts上传文件，验证失败表单数据丢失的原因</title><link>http://www.blogjava.net/dev/archive/2006/03/15/35337.html</link><dc:creator>dev</dc:creator><author>dev</author><pubDate>Tue, 14 Mar 2006 22:10:00 GMT</pubDate><guid>http://www.blogjava.net/dev/archive/2006/03/15/35337.html</guid><wfw:comment>http://www.blogjava.net/dev/comments/35337.html</wfw:comment><comments>http://www.blogjava.net/dev/archive/2006/03/15/35337.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/dev/comments/commentRss/35337.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/dev/services/trackbacks/35337.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 发现一个问题，使用struts进行文件上传，如果有些参数没有完全定义在ActionForm中，需要从request.getParameter获取，在表单提交并且validate失败返回input页面时，这部分需要从request.getPrameter获取的参数数据都丢失了，即使再对request进行multipart解析也不能得到。<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp; 经过分析，发现struts的ActionServlet在接收到multipart请求之后，在RequestProcessor中会对request进行封装：MultiRequestWrapper，然后在Action执行完之后，又将已经封装的request重新还原。以下是部分代码，截直RequestProcessor：<BR><BR>封装：<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">protected</SPAN><SPAN style="COLOR: #000000">&nbsp;HttpServletRequest&nbsp;processMultipart(HttpServletRequest&nbsp;request)&nbsp;</SPAN><SPAN id=Codehighlighter1_78_465_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"></SPAN><SPAN id=Codehighlighter1_78_465_Open_Text><SPAN style="COLOR: #000000">{<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">&nbsp;(</SPAN><SPAN style="COLOR: #000000">!</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">POST</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">.equalsIgnoreCase(request.getMethod()))&nbsp;</SPAN><SPAN id=Codehighlighter1_140_180_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"></SPAN><SPAN id=Codehighlighter1_140_180_Open_Text><SPAN style="COLOR: #000000">{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;(request);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;contentType&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;request.getContentType();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">&nbsp;((contentType&nbsp;</SPAN><SPAN style="COLOR: #000000">!=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">null</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN style="COLOR: #000000">&amp;&amp;</SPAN><SPAN style="COLOR: #000000"><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;contentType.startsWith(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">multipart/form-data</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">))&nbsp;</SPAN><SPAN id=Codehighlighter1_342_411_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"></SPAN><SPAN id=Codehighlighter1_342_411_Open_Text><SPAN style="COLOR: #000000">{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;MultipartRequestWrapper(request));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">else</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN id=Codehighlighter1_418_458_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"></SPAN><SPAN id=Codehighlighter1_418_458_Open_Text><SPAN style="COLOR: #000000">{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;(request);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN></DIV><BR>还原：<BR>&nbsp;&nbsp; 在doForward和doInclude中在forward和include之前都执行了下面的代码：<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">&nbsp;(request&nbsp;</SPAN><SPAN style="COLOR: #0000ff">instanceof</SPAN><SPAN style="COLOR: #000000">&nbsp;MultipartRequestWrapper)&nbsp;</SPAN><SPAN id=Codehighlighter1_56_138_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"></SPAN><SPAN id=Codehighlighter1_56_138_Open_Text><SPAN style="COLOR: #000000">{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;request&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;((MultipartRequestWrapper)&nbsp;request).getRequest();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN></DIV><BR><BR>&nbsp;&nbsp;&nbsp;&nbsp; 问题就出现在这儿。在经过测试之后，发现request只能进行一次multipart解析，这或许和解析request的时候调用了request.inputStream有关，第一次调用之后再调用就不能获取其中的有效内容了。因此发现request在调用CommonsMultipartRequestHandler.handleRequest进行解析后并还原后，调用common-upload对request进行解析已经得不到任何得提交内容了，因此当Form验证失败，返回input页面时，即使再进行multpart解析，也不能通过request.getPrameter取到你想要的数据。而此时，表单中的数据却不会丢失（定义在ActionForm中的表单域），这是因为struts的html系列tag在redisplay时值都是从ActionForm获取的。<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在将RequestProcessor.doForward和doInclude中还原request的语句注释后，问题得到了解决。到目前还不清楚为什么struts要还原request，难道是因为chain的原因？<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; webwork中应该不会出现这个问题，因为webwork中无论ServletDispatcher还是FilterDispatcher在对request wrap之后都没有再还原。<img src ="http://www.blogjava.net/dev/aggbug/35337.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/dev/" target="_blank">dev</a> 2006-03-15 06:10 <a href="http://www.blogjava.net/dev/archive/2006/03/15/35337.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>The output format must have a '{http://xml.apache.org/xalan}content-handler' property！</title><link>http://www.blogjava.net/dev/archive/2006/03/03/33534.html</link><dc:creator>dev</dc:creator><author>dev</author><pubDate>Fri, 03 Mar 2006 11:46:00 GMT</pubDate><guid>http://www.blogjava.net/dev/archive/2006/03/03/33534.html</guid><wfw:comment>http://www.blogjava.net/dev/comments/33534.html</wfw:comment><comments>http://www.blogjava.net/dev/archive/2006/03/03/33534.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/dev/comments/commentRss/33534.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/dev/services/trackbacks/33534.html</trackback:ping><description><![CDATA[tomcat、jdk1.4下出现The output format must have a '{http://xml.apache.org/xalan}content-handler' property!的原因：<BR>&nbsp;&nbsp;&nbsp; 这是因为系统、tomcat或者jdk使用了老版本的xalan.jar。系统如果本身没有使用，而tomcat/common/lib、tomcat/common/endorsed/lib、tomcat/shared/lib下又没有xalan.jar的话，那就是jdk使用了老版本的xalan.jar——在jre\lib\rt.jar里面。下载最新的xalan.jar然后放到tomcat/common/endorsed下即可解决这一问题。<img src ="http://www.blogjava.net/dev/aggbug/33534.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/dev/" target="_blank">dev</a> 2006-03-03 19:46 <a href="http://www.blogjava.net/dev/archive/2006/03/03/33534.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>