亚洲日韩中文在线精品第一 ,久久久久亚洲AV无码观看,亚洲一区二区成人http://m.tkk7.com/keweibo/category/26339.html一專 Java 多能 Delphi,Powerbuilder ... zh-cnTue, 06 Sep 2011 02:28:58 GMTTue, 06 Sep 2011 02:28:58 GMT60struts2 + spring, 使用session範圍的Bean的配置事項http://m.tkk7.com/keweibo/articles/358063.htmlKeKeTue, 06 Sep 2011 02:22:00 GMThttp://m.tkk7.com/keweibo/articles/358063.htmlhttp://m.tkk7.com/keweibo/comments/358063.htmlhttp://m.tkk7.com/keweibo/articles/358063.html#Feedback0http://m.tkk7.com/keweibo/comments/commentRss/358063.htmlhttp://m.tkk7.com/keweibo/services/trackbacks/358063.html異常信息:
Scope 'session' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
解決方法:

1. 在web.xml文件中添加listener

<listener>
        <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
2. 相應的spring bean配置中應加入<aop:scoped-proxy/>此行代碼

<bean id="userAction" class="org.gecs.mes.common.action.UserAction" autowire="byName" scope="session">
        <aop:scoped-proxy/>
</bean>



Ke 2011-09-06 10:22 發表評論
]]>
struts2解決No configuration found for the specified action 異常http://m.tkk7.com/keweibo/articles/357973.htmlKeKeMon, 05 Sep 2011 02:16:00 GMThttp://m.tkk7.com/keweibo/articles/357973.htmlhttp://m.tkk7.com/keweibo/comments/357973.htmlhttp://m.tkk7.com/keweibo/articles/357973.html#Feedback0http://m.tkk7.com/keweibo/comments/commentRss/357973.htmlhttp://m.tkk7.com/keweibo/services/trackbacks/357973.html錯誤信息:
2011-09-05 09:55:23,010 WARN  [http-80-1] components.Form (Form.java:308) - No configuration found for the specified action: '/feeder/excelToolList.action' in namespace: '/feeder'. Form action defaulting to 'action' attribute's literal value.
出錯的寫法
<@s.form  action="/feeder/excelToolList.action"  >

更正后如下
<@s.form  action="excelToolList" namespace="/feeder" >

即可解決.


Ke 2011-09-05 10:16 發表評論
]]>
struts2 + JSON 問題http://m.tkk7.com/keweibo/articles/355606.htmlKeKeTue, 02 Aug 2011 09:01:00 GMThttp://m.tkk7.com/keweibo/articles/355606.htmlhttp://m.tkk7.com/keweibo/comments/355606.htmlhttp://m.tkk7.com/keweibo/articles/355606.html#Feedback0http://m.tkk7.com/keweibo/comments/commentRss/355606.htmlhttp://m.tkk7.com/keweibo/services/trackbacks/355606.html

異常形式:

Class org.apache.struts2.json.JSONWriter can not access a member of * 或是 Class com.googlecode.jsonplugin.JSONWriter can not access a member of class*

第一種是struct2.1.8json結合時的異常,第二種是struct2.1.6json結合的異常。

 

具體:

Class org.apache.struts2.json.JSONWriter can not access a member of class oracle.jdbc.driver.BaseResultSet with modifiers "public"

 

解釋:

不能把程序中的某種數據結構串行化成json格式。

 

原因:

struts2action里面的數據轉換成json數據時,會將提供了get方法的屬性都串行化輸出JSON到客戶端。有的時候,很多屬性并不能串行化成json數據,比如這里的oracle.jdbc.driver.BaseResultSet。這時還進行強行轉換就會出現這樣的異常。

 

解決方法:

在不能串行化到json的屬性相應的get方法前加一條json標記 @JSON(serialize=false)。告訴json不需要轉化這個屬性。或者根本不寫這個get方法。

 

后記:

對于不需要在前臺輸出的json數據,也可以用同樣的方法進行處理,從而減少服務器和客戶端間交互的信息量。

可在需要在前臺輸出的屬性的get方法前加上@JSON(name="status")標識,從而為該屬性起了一個別名,在前臺就可以通過status作為屬性名來讀取其值。



Ke 2011-08-02 17:01 發表評論
]]>
struts2+spring+hibernate 懶加載異常:org.hibernate.LazyInitializationException: failed to lazily initializehttp://m.tkk7.com/keweibo/articles/354252.htmlKeKeWed, 13 Jul 2011 05:55:00 GMThttp://m.tkk7.com/keweibo/articles/354252.htmlhttp://m.tkk7.com/keweibo/comments/354252.htmlhttp://m.tkk7.com/keweibo/articles/354252.html#Feedback0http://m.tkk7.com/keweibo/comments/commentRss/354252.htmlhttp://m.tkk7.com/keweibo/services/trackbacks/354252.html兩種處理方法:
一、在映射文件中設置lazy=false。
二、用OpenSessionInViewFilter過濾器,注意hibernateFilter過濾器和struts2過濾器在映射時的先后順序。同時要配置事物處理,否則會導致session處于只讀狀態而不能做修改、刪除的動作。
即在web.xml文件中如下配置:
<!-- OpenSessionInView -->
    <filter>
        <filter-name>OpenSessionInViewFilter</filter-name>
        <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>OpenSessionInViewFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
        
    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
    </filter>
    
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>


Ke 2011-07-13 13:55 發表評論
]]>
[轉]Cannot serialize session attribute--問題的解決http://m.tkk7.com/keweibo/articles/308804.htmlKeKeSat, 09 Jan 2010 02:22:00 GMThttp://m.tkk7.com/keweibo/articles/308804.htmlhttp://m.tkk7.com/keweibo/comments/308804.htmlhttp://m.tkk7.com/keweibo/articles/308804.html#Feedback0http://m.tkk7.com/keweibo/comments/commentRss/308804.htmlhttp://m.tkk7.com/keweibo/services/trackbacks/308804.htmljava.io.NotSerializableException.

在重啟Tomcat 6時發現報此錯誤.

查閱后發現tomcat 5之后重啟服務后tomcat會嘗試恢復session.

下面是方法一(通過配置,使tomcat重啟后不重新恢復session):

 


Tomcat 問題: Cannot serialize session attribute XXX for ..的解決辦法

在關閉和重啟Tomcat 5時, tomcat 會試圖 serialize存在的session資源. 如果 sessions中相關的對象沒有實現 serializable 接口, 就會出現Cannot serialize session attribute XXX  for  異常.

如果你不想看到該異常, 也不想保存session. 那么你可以在項目部署描述文件中(如. test.xml,)(instead of just exploding the war)  的  <Context> tags中間 加上 :
<Manager className="org.apache.catalina.session.PersistentManager"
saveOnRestart="false"/>
這 樣 tomcat 在關閉的時候就不會保存session資源了.


你也可以在server.xml中指定上面的值. 這也所有的程序都使用這個設置了.

 

試試看.

(引自http://m.tkk7.com/51AOP/archive/2006/09/27/71662.html) 

 

方法二:

既然報沒有序列化的錯誤,那我們就把我們的對象序列化了就是了,實現起來也很簡單,就是把要放入session的對象序列化即可

public class YourClassName implements java.io.Serializable{

}

其他內容都完全不需要變.



Ke 2010-01-09 10:22 發表評論
]]>
Struts2中的單Form多圖片提交按鈕(Submit)的使用 (轉)http://m.tkk7.com/keweibo/articles/208402.htmlKeKeMon, 16 Jun 2008 10:41:00 GMThttp://m.tkk7.com/keweibo/articles/208402.htmlhttp://m.tkk7.com/keweibo/comments/208402.htmlhttp://m.tkk7.com/keweibo/articles/208402.html#Feedback0http://m.tkk7.com/keweibo/comments/commentRss/208402.htmlhttp://m.tkk7.com/keweibo/services/trackbacks/208402.html文章來源:http://m.tkk7.com/bukebushuo/archive/2008/06/15/208012.html
在Struts2里面一個Form中如果有多個提交按鈕,比如添加,更新,保存等,
這些按鈕使用一個Action,調用不同的方法,并且在調用前要執行一個JavaScript的檢查。
怎么用這個提交按鈕?
經過總結如下:
先在form標簽頭指定Action的命名空間:
<s:form namespace="/system/usermanager" >
然后如下調用:
                    <s:submit type="image" id="FIND" value="FIND" label="按指定條件檢索用戶信息"
                              src="/issframe/images/btn/btn_find.jpg" cssClass="button_image"
                              onclick="return CheckInputForRequired();" action="user" method="doSearch"/>
上面是一個圖片提交按鈕的示例,因為一般在項目中都是使用圖片按鈕:)
在onclick中執行javascript,記得不要漏掉return。
action就是你要調用的Action在Struts2的配置文件中定義的那個name
例如:<action name="user_*" class="com.system.action.ManagerUserAction" method="{1}"> 注意不包括通配符("_"或者"!"等)。
mothed就是Action類中定義的對應的方法了。

測試環境:Struts2.1.2 Tomcat 5.5.26 MyEclipse 6

Ke 2008-06-16 18:41 發表評論
]]>
(轉)NetBeans 6 和 Struts2 http://m.tkk7.com/keweibo/articles/191337.htmlKeKeMon, 07 Apr 2008 11:06:00 GMThttp://m.tkk7.com/keweibo/articles/191337.htmlhttp://m.tkk7.com/keweibo/comments/191337.htmlhttp://m.tkk7.com/keweibo/articles/191337.html#Feedback0http://m.tkk7.com/keweibo/comments/commentRss/191337.htmlhttp://m.tkk7.com/keweibo/services/trackbacks/191337.html文章來源:http://blog.csdn.net/xhinker/archive/2008/04/04/2252100.aspx

Struts2 NetBeans 6中安家

                          —— NetBeans 6 中使用 Struts2

前言:NetBeans 6 Struts2

每次使用一種java編輯器或IDE(如eclipse)一個多小時后,總是發現自己已經在NetBeans里敲代碼了。至于Struts2,這是一個融合了WebWork Struts1.X 的基于MVCWeb開發框架,使用相當廣泛。

 

在當前的NetBeans6.1中你還找不到Struts2的影子(至少我所使用的版本里沒有,據說已經有人在開發插件了)。不過,這一點也不會妨礙NetBean 6 Struts2走在一起。在后面你會發現,他們倆配合的還是相當默契的。

 

本篇文章就是為了告訴您,如何將NetBeans Struts2撮合在一起(在這里Struts2甚至還可以和JSFVisual Web Pack一起使用)

 

準備工作:

1.       JDK 5.0 (或更高版本);

2.       NetBeans 6 或者 NetBeans 6.1 Beta(本文使用的是NetBeans 6.1 Beta)

3.       Struts2 開發包;

4.       Tomcat 5.5 (或更高版本)。

一.啟動NetBeans 6.1 創建一個Web 工程

 

創建一個 Web Project

   點擊File à New Project;

   選擇Categories 中的Web,再選擇Projects中的 Web Application;

   點擊Next.

如下圖填寫,這里的Server也可以是NetBeans綁定的 Tomcat 6

點擊Next,然后再點擊Next 看到如下界面:

什么都不要選點擊Finish.  工程創建完畢,進入下一部分。

二.創建Struts2 Library 并導入Struts2 開發包

點擊 Tools à Libraries

點擊New Library...

   Library Name: Struts2

   Library Type : Class Library

點擊OK

 

選擇圖中所示的struts2 java

點擊ok 回到主界面。右鍵點擊Libraries 然后選擇Add Library...

點擊Add Library 基本Struts2的開發包已經導入完畢。

三.配置Web.xml

如圖所示;單擊web.xml 然后點擊右側的Filters 單擊Add Filter Element

Filter Name: 可以任意填寫 不過那一串長長的Filter Class 可不太容易記住。只可惜點開Browse...之后也無法選擇Libraries里面的包,不能不說是一個遺憾。希望下一個版本的NetBeans 會修正這一小小的不足。

   Filter Name:Struts2 Filter;

   Filter Class:org.apache.struts2.dispatcher.FilterDispatcher

 

接下來就是Mapping Filter了,點擊Add...

如圖填寫,Struts2 Filter 要和上面的保持一致。URL Pattern里面填寫 *.action 即可

事實上,在其他IDE里面配置Web.xml的時候,你可能要自己動手寫xml(相信大多數程序員都很討厭寫又長又臭的xml. 而且稍微一出錯,能把眼睛看痛)

以上的幾步操作,NetBeans為我們自動生成了以下代碼,您也可以去看看。

現在你可以暫時不用管web.xml了。

四.編寫struts.xml

struts.xml 可以說是整個struts2框架的中心。大多數配置錯誤也出現在struts.xml上。一個jsp頁面提交后不是像傳統的做法那樣直接傳給另一個頁面,而是交由struts.xml進行處理。struts.xml調用后臺action 進行處理后,決定轉向那個頁面.那么我們如何編寫以及在哪里放置struts.xml呢?

我們要將struts.xml放置在Source Packagesdefault package包下。如圖

給文件命名為struts

接下來點擊struts.xml進行編寫,之前我們要在xml文檔的頭部加入

<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd"
>

把原來的<root></root>刪除。換成<struts></struts>   輸入”<p” 然后  Ctrl+Space

這個時候 NetBeans已經完全認識了Struts2(估計它們已經成為好伙伴了)。繼續編寫,如果你怕出錯,或者不愿意太麻煩,按 Ctrl+Space. Netbeans 6.1 會為你解決很多問題。(不得不說的是,NetBean6.0以后的版本在代碼完成方面有了一個很大的提高,速度和智能兩方面都值得稱贊)一路編寫下來。以下是編好的代碼:

<struts>
    
<package name="xhinker" extends="struts-default" >
        
<action name="hello" class="cn.xhinker.struts2.HelloAction">
            
<result>/helloPage.jsp</result>
        
</action>
    
</package>
</struts>

文檔中 action 標簽中的name屬性要特別注意,因為這個是用來標識這個action的。class屬性里的是,action類。當點擊一個jsp頁面里的<a href=”hello.action”>enter</a>的時候。程序會根據hello.action struts.xml里找到name=”hello”的標簽。繼而找到后臺的 HelloAction 類。然后根據HelloAction 實例的返回值,找到result標簽中對應的頁面,實現頁面的轉移。result標簽有一個name屬性如 <result name=”success”>/helloPage.jsp</result>如果不寫 name屬性,則默認為 name=”success”.

 

保存,關閉這個頁面,接下來我們來編寫HelloAction

五,編寫HelloAction類

右鍵單擊Source Package 創建一個java類。

如下填寫:

HelloAction 繼承ActionSupport

package cn.xhinker.struts2;
import com.opensymphony.xwork2.ActionSupport;
public class HelloAction extends ActionSupport{
}

這個時候有人會問,我如何讓NetBeans 幫我override(重寫)父類的方法啊?沒有這樣的按鈕啊?不用找了。Ctrl+Space. 您要的重寫的方法,八九不離十已經顯示在你的面前了:

我們要的就是這個execute()方法。稍微改變一下代碼如下所示:

 public String execute() throws Exception {
        
return this.SUCCESS;
}
  

添加一個字符串變量msg 然后讓NetBeans 自動生成 setter getter方法。如圖在彈出的菜單中選擇Encapsulate Field...即可

生成完畢,這個類就編好了,完整的代碼為:

package cn.xhinker.struts2;
import com.opensymphony.xwork2.ActionSupport;
public class HelloAction extends ActionSupport{
    
private String msg="Hello World";
    
public String execute() throws Exception {
        
return this.SUCCESS;
    }


    
public String getMsg() {
        
return msg;
    }


    
public void setMsg(String msg) {
        
this.msg = msg;
    }

}

進入下一部分。

六.編寫jsp頁面

index.jsp中的body標簽內加入<a href="hello.action">hello</a>

新建一個hello.jsp頁面 添加如圖所示的代碼:

到此為止,你也該啟動那只大花貓 Tomcat了。Build à run  

但愿你沒有遇到麻煩:-)



Ke 2008-04-07 19:06 發表評論
]]>
&lt;s:actionmessage/&gt;標簽顯示Action信息http://m.tkk7.com/keweibo/articles/176142.htmlKeKeFri, 18 Jan 2008 03:23:00 GMThttp://m.tkk7.com/keweibo/articles/176142.htmlhttp://m.tkk7.com/keweibo/comments/176142.htmlhttp://m.tkk7.com/keweibo/articles/176142.html#Feedback0http://m.tkk7.com/keweibo/comments/commentRss/176142.htmlhttp://m.tkk7.com/keweibo/services/trackbacks/176142.html 就是相應Action的配置
<!-- 修改帳號密碼 -->
  <action name="updatePassword" class="userAction" method="updatePassword">
   <result name="input">/account/updatePassword.jsp</result>
   <result name="success" type="redirect" >/account/updatePassword.jsp</result>
  </action>
注意:
如果將result標簽的type屬性設置為redirect則在Action即使使用了

addActionMessage(getText("updatePassword.success"));

在JSP頁面也不能顯示相應的信息


Ke 2008-01-18 11:23 發表評論
]]>
WebWork/struts2中格式化輸出數字和日期的方法http://m.tkk7.com/keweibo/articles/174997.htmlKeKeSun, 13 Jan 2008 09:46:00 GMThttp://m.tkk7.com/keweibo/articles/174997.htmlhttp://m.tkk7.com/keweibo/comments/174997.htmlhttp://m.tkk7.com/keweibo/articles/174997.html#Feedback0http://m.tkk7.com/keweibo/comments/commentRss/174997.htmlhttp://m.tkk7.com/keweibo/services/trackbacks/174997.html轉:  http://m.tkk7.com/aoxj/archive/2006/08/14/63461.html
前言:大概在去年6月的時候,我們團隊開始使用webwork來替代struts,剛開始大家都沒有經驗,為了格式化輸出時間和數字,想出了很多現在看來笨笨的傻傻的方法。后來俺找到了這個方法,試驗了一下之后發了下面這個email給了team member, 今天一位同事問起這個問題,俺從數以千計的已發送郵件中找到了這個東西,想想決定整理出來。給大家分享一下,順便給我自己做個備份,呵呵,后者基本上是俺寫blog的一個重要用途。

    分享一個在WebWork中如何格式化顯示數字和日期的方法:


具體的做法這里有詳細的說明:
http://wiki.opensymphony.com/display/WW1/How+to+format+dates+and+numbers?showComments=true


   下面是項目中推薦使用的時間格式:
#format
global.format.date={0,date,yyyy-MM-dd}
global.format.time={0,date,HH:mm:ss}
global.format.datetime={0,date,yyyy-MM-dd HH:mm:ss}

注意的是如果使用Carlender來保存時間,因為上面要求傳入的是Data對象,因此需要使用Carlender.getTime()方法
從Carlender中獲取Date:

<ww:text name="'global.format.date'">
    <ww:param value="'birthday.time()'"/>
</ww:text>

這里使用的是<ww:param/>標簽來傳遞參數,雖然也可以使用 <ww:text name="'format.date'" value0= "'birthday.time()'"/>
但是后面的這個方法在webwork的新版本中已經被要求不要使用,大家還是盡量使用 <ww:param/>標簽

禁用value0屬性的說明:
大家可以找到text標簽的源代碼,在com.opensymphony.webwork.views.jsp.ui.TextTag中:
public void setValue0(String aName) {
        LOG.warn("The value attributes of TextTag are deprecated.");
        value1Attr = aName;
    }

 


對于數字的格式化,這里有兩個參考:
global.format.percent = {0,number,##0.00'%'}
global.format.money = {0,number,$##0.00}

考慮目前在項目中使用最多的是顯示附件大小,定義以下格式:
global.format.size.k={0,number,##0.00'K'}
global.format.size.m={0,number,##0.00'M'}
global.format.size.g={0,number,##0.00'G'}

如action有方法
public long getFilesize();  返回的大小是以byte為單位,在顯示時通常是以k或M顯示
則顯示時:
<ww:text name="'global.format.size.k'">
    <ww:param value="filesize/1024"/>
</ww:text>
<ww:text name="'global.format.size.m'">
    <ww:param value="filesize/1048576"/>
</ww:text>
<ww:text name="'global.format.size.g'">
    <ww:param value="filesize/1073741824"/>
</ww:text>

比較遺憾的是似乎沒有辦法在資源文件中進行這個/1024的運算,試過{0/1024,number,##0.00'K'} 無法解析。只好在jsp里面用 value="filesize/1024"來計算實際值。不知道這里有沒有別的更好的實現方式?

恩,順便再介紹一下當時俺們team想出來的笨笨的方法,不要見笑啊,以上面的顯示文件大小為例,想到的方法大致有以下幾種:
1. 直接輸出字符串的結果
   getFileSizeString(), 在里面用java代碼判斷大小并生成諸如"1.2k", "31.2M"的結果返回
2. 提供多個函數
  getFileSizeByte(), getFileSizeK(), getFileSizeM(), getFileSizeG()
3.使用javascript在client端格式化
      <script type = "text/javascript">     
      var resultNum = <ww:property value="fileSize" />;
       resultNum = format(resultNum);//類似的函數  
      document.write(resultNum);
     </script>
4.使用自定義標簽

--------------------------------------------------------------------------------------------------------------
struts2中格式化輸出數字和日期的方法

資源文件
......
#格式化數字或時間輸出
global.format.date={0,date,yyyy-MM-dd}
global.format.money={0,number,¥##0.00 '元'}
......
JSP文件
格式化時間:  <s:text name="global.format.date"><s:param value="publishTime"></s:param></s:text>
格式化數字:  <s:text name="global.format.money"><s:param value="price"/></s:text>



Ke 2008-01-13 17:46 發表評論
]]>
Struts 2與AJAX(第三部分)http://m.tkk7.com/keweibo/articles/162756.htmlKeKeFri, 23 Nov 2007 16:05:00 GMThttp://m.tkk7.com/keweibo/articles/162756.htmlhttp://m.tkk7.com/keweibo/comments/162756.htmlhttp://m.tkk7.com/keweibo/articles/162756.html#Feedback0http://m.tkk7.com/keweibo/comments/commentRss/162756.htmlhttp://m.tkk7.com/keweibo/services/trackbacks/162756.html文章來源:http://www.javaeye.com/topic/128976
很久沒有更新BLOG了,前一段時間公司的項目比較忙,另外我還和一位出版社的朋友談寫書的事情,所以一直沒有時間,完成《Struts 2與AJAX》。后來寫書的事情吹了,趁今天有點空閑就把它完成。

在大家看這部分文章之前,我想對于寫書的事情說兩句,或者應該叫發牢騷才對。通過這次寫書失敗的經歷,我明白為什么國內的IT書籍多數是濫于充數、粗制濫造、缺乏經典。其實說白了就是一個“錢”字作怪。為了市場,很多編輯可能會“建議”你去“抄考”一些國內相對暢銷的同類書籍,例如寫Struts就一定要按所謂的MVC進行目錄分類,美其名曰“容易入門”。我認為“MVC”的概念雖然重要,但對初學者而言,需要對編程有一定的了解才容易明白此概念。另外,為了“實用”,不惜使用相同的技術重復編寫不同的范例。可能是我不太了解讀者的心理吧。

言歸正傳,在上兩部分的《Struts 2與AJAX》中我介紹了Struts 2與DOJO結合實現AJAX的知識,本文將介紹在Struts 2中使用DWR實現AJAX表單校驗。

什么是DWR

DWR(Direct Web Remoting)是在Java EE中較流行的AJAX框架,它的最大優勢就是可以像使用本地的Javascript函數一樣,調用服務器上的Java方法。如下圖所示:

DWR工作原理
圖1 DWR工作原理

其實DWR原理也不復雜,它先在web.xml中配置一個Servlet,映射到特定的路徑(通常是%CONTEXT_PATH%/dwr/*)。這個Servlet的作用就是初始化要暴露給Javascript調用的Java類(通過dwr.xml進行配置),并生成相應的代理的Javascript類代碼。在XHR請求到來的時候,Servlet負責將請求的參數變成對應的Java對象,并以其為參數調用目標Java方法,并將返回值轉化為Javascript代碼。詳情請參考:http://getahead.ltd.uk/dwr/

Struts 2與DWR

在Struts 2.0.x中使用DWR實現AJAX表單校驗。在大家掌握了DWR的原理后,下面我想詳細介紹一下實現的步驟。

首先,到以下站點https://dwr.dev.java.net/files/documents/2427/47455/dwr.jar下載DWR的1.1.4版本的JAR包。需要注意的是,DWR雖然已經發布2.0版本,但它與1.1.4有很大的區別,所以請大家不要使用2.0版本,否則會出現異常的;

接著,新建WEB工程,將下圖所示的JAR包加入到工程的“Build Path”中;

依賴的JAR包
圖2 依賴的JAR包

接下來,配置web.xml文件,內容如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_9" version="2.4"
    xmlns
="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation
="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

   
<display-name>Struts 2 AJAX Part 3</display-name>

   
<filter>
       
<filter-name>struts-cleanup</filter-name>
       
<filter-class>
            org.apache.struts2.dispatcher.ActionContextCleanUp
       
</filter-class>
   
</filter>

   
<filter-mapping>
       
<filter-name>struts-cleanup</filter-name>
       
<url-pattern>/*</url-pattern>
   
</filter-mapping>

   
<filter>
       
<filter-name>struts2</filter-name>
       
<filter-class>
            org.apache.struts2.dispatcher.FilterDispatcher
       
</filter-class>
   
</filter>

   
<filter-mapping>
       
<filter-name>struts2</filter-name>
       
<url-pattern>/*</url-pattern>
   
</filter-mapping>
   
<!--</span><span style="COLOR: #008000"> 開始DWR配置 </span><span style="COLOR: #008000">-->
   
<servlet>
       
<servlet-name>dwr</servlet-name>
       
<servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>
       
<init-param>
           
<param-name>debug</param-name>
           
<param-value>true</param-value>
       
</init-param>
   
</servlet>

   
<servlet-mapping>
       
<servlet-name>dwr</servlet-name>
       
<url-pattern>/dwr/*</url-pattern>
   
</servlet-mapping>
   
<!--</span><span style="COLOR: #008000"> 結束DWR配置 </span><span style="COLOR: #008000">-->
   
<welcome-file-list>
       
<welcome-file>index.html</welcome-file>
   
</welcome-file-list>

</web-app>
清單1 WebContent/WEB-INF/web.xml

然后是DWR的配置文件:

<?xml version="1.0" encoding="UTF-8"?>

<!--</span><span style="COLOR: #008000"> START SNIPPET: dwr </span><span style="COLOR: #008000">-->
<!DOCTYPE dwr PUBLIC 
    "-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN" 
    "http://www.getahead.ltd.uk/dwr/dwr10.dtd"
>

<dwr>
   
<allow>
       
<create creator="new" javascript="validator">
           
<param name="class" value="org.apache.struts2.validators.DWRValidator"/>
       
</create>
       
<convert converter="bean" match="com.opensymphony.xwork2.ValidationAwareSupport"/>
   
</allow>

   
<signatures>
       
<![CDATA[</span><span style="COLOR: #808080"><br />         import java.util.Map;<br />         import org.apache.struts2.validators.DWRValidator;<br /> <br />         DWRValidator.doPost(String, String, Map<String, String>);<br />         </span><span style="COLOR: #0000ff">]>
   
</signatures>
</dwr>
<!--</span><span style="COLOR: #008000"> END SNIPPET: dwr </span><span style="COLOR: #008000">-->
清單2 WebContent/WEB-INF/dwr.xml

通過以上配置,我們可以將DWRValidator中的方法暴露為Javascript可以調用的遠程接口。

在正確完成以上步驟之后,我們發布運行一下應用程序,在瀏覽器地址欄中輸入http://localhost:8080/Struts2_Ajax3/dwr/,應該會出現如下頁面:

DWR Servlet默認輸出頁面
圖3 DWR Servlet默認輸出頁面

 接下來,我們要開始編寫Action類了,代碼如下:

package tutorial;

import com.opensymphony.xwork2.ActionSupport;

public class AjaxValidation extends ActionSupport {
   
private static final long serialVersionUID = -7901311649275887920L;

   
private String name;
   
private String password;
   
private int age;
   
   
public int getAge() {
       
return age;
   }

   
   
public void setAge(int age) {
       
this.age = age;
   }

   
   
public String getName() {
       
return name;
   }

   
   
public void setName(String name) {
       
this.name = name;
   }

   
   
public String getPassword() {
       
return password;
   }

   
   
public void setPassword(String password) {
       
this.password = password;
   }

   
   @Override
   
public String execute() {        
       
return SUCCESS;
   }

}
清單3 src/tutorial/AjaxValidation.java

上述代碼一目了然,相信大家已經很熟悉了。下面,我們再來看看表單校驗的配置代碼:

<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN" "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
<validators>
   
<validator type="regex">
       
<param name="fieldName">password</param>
       
<param name="expression">
           
<![CDATA[</span><span style="COLOR: #808080">(?!^[0-9]*$)(?!^[a-zA-Z]*$)^([a-zA-Z0-9]{8,10})$</span><span style="COLOR: #0000ff">]>
       
</param>
       
<message>Password must be between 8 and 10 characters, contain at least one digit and one alphabetic character, and must not contain special characters</message>
   
</validator>    
   
<field name="name">
       
<field-validator type="requiredstring">
           
<message>You must enter a name</message>
       
</field-validator>
   
</field>
   
<field name="age">
       
<field-validator type="int">
           
<param name="min">18</param>
           
<param name="max">127</param>
           
<message>Age must be between 18 and 127</message>
       
</field-validator>
   
</field>
</validators>
清單4 src/tutorial/AjaxValidation-validation.xml

對于AjaxValidation類的name、password和age三個字段,我分別用了非空、正規表達式和范圍驗證。正規表達式(?!^[0-9]*$)(?!^[a-zA-Z]*$)^([a-zA-Z0-9]{8,10})$的作用是保證密碼由至少包括一個數字和一個字母,且不能含有符號的長度為8到10的字符串組成。它也是所謂強密碼(Strong Password)的普通實現。

接下來的是JSP的代碼,內容如下:

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding
="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
   
<head>
       
<title>Struts 2 AJAX - Validation</title>
       
<s:head theme="ajax" />
   
</head>
   
<body>
       
<h2>
            AJAX Validation Using DWR
       
</h2>
       
<s:form method="post" validate="true" theme="ajax">
           
<s:textfield label="Name" name="name" />
           
<s:password label="Password" name="password" />
           
<s:textfield label="Age" name="age" />
           
<s:submit />
       
</s:form>
   
</body>
</html>
清單5 WebContent/AjaxValidation.jsp

以上代碼也不復雜,不過需要的是注意的是除了要加入外,也必須加入validate="true" theme="ajax"的屬性。

最后是Struts 2的配置文件,內容如下所示:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd"
>

<struts>
   
<package name="Struts2_AJAX_DEMO" extends="struts-default">
       
<action name="AjaxValidation" class="tutorial.AjaxValidation">
           
<result name="input">AjaxValidation.jsp</result>
           
<result>AjaxValidation.jsp</result>
       
</action>
   
</package>
</struts>
清單6 src/struts.xml

最后發布運應用程序,在瀏覽器地址欄中輸入http://localhost:8080/Struts2_Ajax3/AjaxValidation!input.action出現如下圖所示頁面:

AjaxValidation頁面輸出
圖4 AjaxValidation頁面輸出

在文本框中輸入錯誤的值使頁面出現錯誤提示信息,如下圖所示:

AjaxValidation頁面錯誤提示
圖5 AjaxValidation頁面錯誤提示

可能有朋友會問怎么知道這是通過AJAX進行校驗的呢?在這里我向大家推薦一個AJAX開發必備的工具——Firebug。Firebug是Firefox的一個功能強大的插件,它可以準確地輸出和定位Javascript的錯誤、通過直觀的方式查看HTML文檔的DOM及其樣式、所見即所得的編輯方式,更值得一贊的是它可以方便地對Javascript進行跟蹤和調試,如果你希望這進一步了解這個工具,請安裝Firefox 2.0以上版本,并使用它瀏覽以下網址http://www.getfirebug.com

在安裝完成Firebug之后,在Firefox中打開http://localhost:8080/Struts2_Ajax3/AjaxValidation!input.action,按“F12”鍵找開Firebug窗口,如果你第一次使用Firebug,請點擊其窗口中的鏈接“Enable Firebug”激活插件。之后,點擊“Net”,并在出現的菜單中點擊選中“XHR”。然后將光標移入文本框,再將光標移出使文本框失去焦點,你可以看到Firebug窗口會多出一項記錄,如下圖所示:

Firebug中查看XHR請求
圖6 Firebug中查看XHR請求

這就證明你在文本框失去焦出時,Struts 2會發送XHR請求到服務器以對該文本框值進行校驗。有興趣的朋友可以通過Firebug,研究XHR的請求與響應,這樣可以加深對DWR工作原理的理解。

何時使用AJAX表單校驗

雖然在Struts 2實現AJAX表單校驗是一件非常簡單的事,但我建議大家不要在所有的場合都使用這個功能,原因可以分為以下幾個方面:

  1. AJAX校驗在服務器上進行數據校驗,可能會比較耗時;
  2. AJAX校驗可能會過于頻繁,加重服務器的負載;
  3. 一些普通的校驗,只需要使用純Javascript便可以實現。

讀到這里,有的朋友可能會問:“那么什么時候才應該使用AJAX表單校驗呢?”答案其實很簡單,當我們的校驗在頁面加載時還不能夠確定的情況下,就應該使用這個功能。例如,注冊用戶時,校驗用戶名是否已經存在;或者校驗涉及過多的頁務邏輯等。

現在讓我們來改造一下上述例子,對于name我們可以使用AJAX校驗,但對于其它的字段應該使用純Javascript的校驗。

在tutorial.AjaxValidation類加入如下方法:

   @Override
   
public void validate() {
       Set
<String> users = new HashSet<String>();
       users.add(
"max");
       users.add(
"scott");
http://www.blogjav


Ke 2007-11-24 00:05 發表評論
]]>
Struts2攔截器的使用http://m.tkk7.com/keweibo/articles/162558.htmlKeKeFri, 23 Nov 2007 02:35:00 GMThttp://m.tkk7.com/keweibo/articles/162558.htmlhttp://m.tkk7.com/keweibo/comments/162558.htmlhttp://m.tkk7.com/keweibo/articles/162558.html#Feedback0http://m.tkk7.com/keweibo/comments/commentRss/162558.htmlhttp://m.tkk7.com/keweibo/services/trackbacks/162558.html閱讀全文

Ke 2007-11-23 10:35 發表評論
]]>
表單標志使用小技巧http://m.tkk7.com/keweibo/articles/162555.htmlKeKeFri, 23 Nov 2007 02:33:00 GMThttp://m.tkk7.com/keweibo/articles/162555.htmlhttp://m.tkk7.com/keweibo/comments/162555.htmlhttp://m.tkk7.com/keweibo/articles/162555.html#Feedback0http://m.tkk7.com/keweibo/comments/commentRss/162555.htmlhttp://m.tkk7.com/keweibo/services/trackbacks/162555.htmlStruts 2為大家提供了不少常用的很酷的表單標志,簡化了我們程序員的工作。不過,由于這些都是新標志,大家可能在使用上還存在不少疑問。本文將就朋友們的回復、留言或Email上的問題,分別對這些酷標志進行講述。
下面我將分別對這些標志進行講述:

   Struts 2的表單標志在輸出(render)HTML時,使用了模板的概念,增加了復雜性(因為它不像Struts 1.x的表單標志,它通常都是一個標志對應HTML的一個元素),因此大家在使用時,需要一些技巧:
  1. Struts 2的UI標志的表單標志默認是以表格布局,按鈕是右對齊的。如果你不喜歡此風格,你可以簡單地將<s:form />標志的“theme”屬性設為“simple”,然后用以往的做法自已布局表單元素(注意:此法有利有弊,弊就是當你將“theme”屬性設為“simple”時,表單標志以最簡單方式輸出HTML,所以你可能失去一些默認輸出提供的便利,如:友好的錯誤信息的顯示,或客戶端的表單驗證等)。當然更好的做法是通過CSS或自定義主題(theme)然后應用到整個應用程序,這樣可以獲得一致的頁面風格,加強用戶體驗(我會在以后的文章對此進行講解);
  2. 當你在頁面上加入某些標志(如:<s:doubleselect />等)時,應該通過action來訪問頁面,而不是通過*.jsp的URL直接訪問。

1、<s:checkboxlist />

大家對<s:checkboxlist />的最大的疑問可能是:“如何在默認情況下,選中某些checkbox?”

答案其實很簡單,只需要將其“value”屬性設為你的要選中的值,如以代碼所示:

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
   
<title>Struts 2 Cool Tags - &lt;s:checkboxlist/ &gt;</title>
   
<s:head />
</head>
<body>    
   
<h2>&lt;s:checkboxlist/&gt;</h2>
   
<s:form action="Store" >
       
<s:checkboxlist name="skills1" 
                        label
="Skills 1" 
                        list
="{ 'Java', '.Net', 'RoR', 'PHP' }" 
                        value
="{ 'Java', '.Net' }" />
       
<s:checkboxlist name="skills2" 
                        label
="Skills 2" 
                        list
="#{ 1:'Java', 2: '.Net', 3: 'RoR', 4: 'PHP' }" 
                        listKey
="key" 
                        listValue
="value" 
                        value
="{ 1, 2, 3 }"/>
   
</s:form>
</body>
</html>
清單1 WebContent/checkboxlist.jsp

分布運行應用程序,在瀏覽器中鍵入:http://localhost:8080/Struts2_CoolTags/checkboxlist.jsp,出現如下圖所示頁面:

checkboxlist.jsp頁面
清單2 checkboxlist.jsp頁面

2、<s:doubleselect />

大家看Struts 2的showcase的例子,<s:doubleselect />的用法如下所示:

    <s:doubleselect
           
tooltip="Choose Your State"
            label
="State"
            name
="region" list="{'North', 'South'}"
            value
="'South'"
            doubleValue
="'Florida'"
            doubleList
="top == 'North' ? {'Oregon', 'Washington'} : {'Texas', 'Florida'}" 
            doubleName
="state"
            headerKey
="-1"
            headerValue
="---------- Please Select ----------"
            emptyOption
="true" />
清單3 Showcase中<s:doubleselect />

很多朋友問:“上面的‘list’屬性只有兩個值,如果我有三個或更多的值,‘doublelist’屬性應該如何設定呢?”

我建議的做法是先定義一個Map類型的對象,鍵為“list”的集合,值則為“doubleList”的集合,然后“doubleList”的OGNL寫成“#myMap[top]”,如以下代碼所示:

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
   
<title>Struts 2 Cool Tags - &lt;s:doubeselect/ &gt;</title>
   
<s:head />
</head>
<body>    
   
<h2>&lt;s:doubleselect/&gt;</h2>
   
<s:form action="Store" >
       
<s:set name="foobar" 
               value
="#{'Java': {'Spring', 'Hibernate', 'Struts 2'}, '.Net': {'Linq', ' ASP.NET 2.0'}, 'Database': {'Oracle', 'SQL Server', 'DB2', 'MySQL'}}" />
       
<s:doubleselect list="#foobar.keySet()"
                          doubleName
="technology" 
                          doubleList
="#foobar[top]" 
                          label
="Technology" />
   
</s:form>
</body>
</html>
清單4 WebContent/doubleselect.jsp

分布運行應用程序,在瀏覽器中鍵入:http://localhost:8080/Struts2_CoolTags/doubleselect.action,出現如下圖所示頁面:

doubleselect.jsp頁面
清單5 doubleselect.jsp頁面

3、<s: token />

這個標志可能大家不常用,不過本人認為它還是挺有用的。在使用Struts 1.x時,因為跳轉通常是用Forward(而不是Redirect)實現的,所以當用戶完成請求后,按“F5”刷新頁面時,就會重新提交上次的請求,這樣經常會出錯。要解決這個問題,<s:token />可以幫你忙。

實現原理

在頁面加載時,<s: token />產生一個GUID(Globally Unique Identifier,全局唯一標識符)值的隱藏輸入框如:

<input type="hidden" name="struts.token.name" value="struts.token"/>
<input type="hidden" name="struts.token" value="BXPNNDG6BB11ZXHPI4E106CZ5K7VNMHR"/>
清單6 <s:token />的HTML輸出

同時,將GUID放到會話(session)中;在執行action之前,“token”攔截器將會話token與請求token比較,如果兩者相同,則將會話中的token刪除并往下執行,否則向actionErrors加入錯誤信息。如此一來,如果用戶通過某種手段提交了兩次相同的請求,兩個token就會不同。

具體實現

首先看一下Action的代碼:

package tutorial;

import com.opensymphony.xwork2.ActionSupport;

public class CoolTagAction extends ActionSupport {    
   
private static final long serialVersionUID = 6820659617470261780L;
   
   
private String message;
       
   
public String getMessage() {
       
return message;
   }


   
public void setMessage(String message) {
       
this.message = message;
   }

   
   @Override
   
public String execute() {
       System.out.println(
"Executing action, your message is " + message);
       
return SUCCESS;
   }
   
}
清單7 src/tutorial/CoolTagAction.java

以上代碼一目了然,再看看JSP的寫法:

%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
   
<title>Struts 2 Cool Tags - &lt;s:token/ &gt;</title>
   
<s:head />
</head>
<body>    
   
<h2>&lt;s:token/&gt;</h2>
   
<s:actionerror />
   
<s:form action="Token" >
       
<s:textfield name="message" label="Message" />
       
<s:token />
       
<s:submit />
   
</s:form>
</body>
</html>
清單8 WebContent/token.jsp

JSP也很簡單,就是加入<s:token />標志。接下來是Actoin配置的XML片段:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd"
>

<struts>
   
<package name="Struts2_COOL_TAGS_DEMO" extends="struts-default">
       
<action name="Token" class="tutorial.CoolTagAction">
           
<interceptor-ref name="defaultStack" />
           
<interceptor-ref name="token" />
           
<result name="invalid.token">/token.jsp</result>                        
           
<result>/token.jsp</result>
       
</action>
       
<action name="*">
           
<result>/{1}.jsp</result>
       
</action>
   
</package>
</struts>
清單9 src/struts.xml

以上XML片段值注意的是加入了“token”攔截器和“invalid.token”結果,因為“token”攔截器在會話token與請求token不一致時,將會直接返回“invalid.token”結果。

發布運行應用程序,在瀏覽器中鍵入:http://localhost:8080/Struts2_CoolTags/token.jsp,出現如下圖所示頁面:

正常顯示的token.jsp頁面
清單10 正常顯示的token.jsp頁面

隨便填點東西并提交頁面,一切正常返回以上頁面,然后按“F5”刷新頁面,在彈出的對話框中點擊“Retry”,出現如下圖所示頁面:

重復提交出錯顯示
清單11 重復提交出錯顯示

4、<s:datetimepicker />、<s:optiontransferselect />和<s:updownselect />

這幾個標志的使用相對簡單,所以我想小舉一例即可,以下是JSP的代碼:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
   
<title>Struts 2 Cool Tags - Others</title>
   
<s:head />
</head>
<body>    
   
<h2>Others</h2>
   
<s:form action="Store" >
       
<s:datetimepicker name="birthday" label="Birthday" />
       
<s:updownselect
           
label = "Favourite Countries"
            list
="#{'england':'England', 'america':'America', 'germany':'Germany'}"
            name
="prioritisedFavouriteCountries"
            headerKey
="-1"
            headerValue
="--- Please Order Them Accordingly ---"
            emptyOption
="true" />
       
<s:optiontransferselect            
           
label="Favourite Cartoons Characters"
            name
="leftSideCartoonCharacters" 
            leftTitle
="Left Title"
            rightTitle
="Right Title"
            list
="{'Popeye', 'He-Man', 'Spiderman'}" 
            multiple
="true"
            headerKey
="headerKey"
            headerValue
="--- Please Select ---"
            emptyOption
="true"
            doubleList
="{'Superman', 'Mickey Mouse', 'Donald Duck'}" 
            doubleName
="rightSideCartoonCharacters"
            doubleHeaderKey
="doubleHeaderKey"
            doubleHeaderValue
="--- Please Select ---" 
            doubleEmptyOption
="true"
            doubleMultiple
="true" />
   
</s:form>
</body>
</html>
清單12 WebContent\others.jsp頁面

發布運行應用程序,在瀏覽器中鍵入:http://localhost:8080/Struts2_CoolTags/others.jsp,出現如下圖所示頁面:

點擊查看大圖
清單13 其它表單標志頁面

總結

Struts 2在標志上的確比Struts 1.x豐富了許多,同時模板機制也給程序員帶來不少方便(如果你不太喜歡個性化的風格)。另外,Struts 2還有一些AJAX(如<s: autocompleter />等)的標志和非表單的UI標志(如<s: tree />等),我會在以后的文章中講述其使用。



Ke 2007-11-23 10:33 發表評論
]]>
struts2中使用displayTags的問題(ParametersInterceptor - [setParameters]: Unexpected Exception)http://m.tkk7.com/keweibo/articles/161226.htmlKeKeSat, 17 Nov 2007 07:21:00 GMThttp://m.tkk7.com/keweibo/articles/161226.htmlhttp://m.tkk7.com/keweibo/comments/161226.htmlhttp://m.tkk7.com/keweibo/articles/161226.html#Feedback11http://m.tkk7.com/keweibo/comments/commentRss/161226.htmlhttp://m.tkk7.com/keweibo/services/trackbacks/161226.html ERROR - ParametersInterceptor - [setParameters]: Unexpected Exception caught setting 'd-49653-p' on 'class dgut.ke.actions.SubjectAction: Error setting expression 'd-49653-p' with value '[Ljava.lang.String;@d73256'

在網上的搜了一下,在一些中文網頁上幾乎都找不到相關的信息,結果在一個英語網站上看到了以下信息:

I use struts2.0.9 and displaytag,xwork-2.0.4.jar,when I click next page of
displaytag,it will raise flowing warning:

Warn: ParametersInterceptor - [setParameters]: Unexpected Exception caught
setting 'd-1332698-p' on 'class Test.TestAction: Error setting expression
'd-1332698-p' with value '[Ljava.lang.String;@14bf534'
RE:
It's a warning that occurs because you're using displaytags.

Don't worry about it, it won't hurt you, and messing with it will just make
bad things happen (you know the kind of thing, long nights trying to work
out things like why table sorting isn't working, why data isn't being
displayed, and why the world is so unfair).

In the words of a nice policeman; "Move along, there's nothing to see here"

-----Original Message-----
From: red phoenix [mailto:rodphoenix@...]
Sent: 26 September 2007 16:29
To: Struts Users Mailing List
Subject: Error: ParametersInterceptor - [setParameters]


I use struts2.0.9 and displaytag,xwork-2.0.4.jar,when I click next page of
displaytag,it will raise flowing warning:

Warn: ParametersInterceptor - [setParameters]: Unexpected Exception caught
setting 'd-1332698-p' on 'class Test.TestAction: Error setting expression
'd-1332698-p' with value '[Ljava.lang.String;@14bf534'

Why raise above waring? How to solve it?
Thanks!
Add the following line to your struts.xml file.
d-.*-p

Example:
        <interceptor-stack name="creditDefaultStack">
                <interceptor-ref name="creditException" />
                <interceptor-ref name="alias" />
                <interceptor-ref name="servlet-config" />
                <interceptor-ref name="prepare" />
                <interceptor-ref name="i18n" />
                <interceptor-ref name="chain" />
                <interceptor-ref name="debugging" />
                <interceptor-ref name="profiling" />
                <interceptor-ref name="scoped-model-driven" />
                <interceptor-ref name="model-driven" />
                <interceptor-ref name="checkbox" />
                <interceptor-ref name="static-params" />
                <interceptor-ref name="params">
                        dojo\..*
                        d-.*-p </interceptor-ref>
                <interceptor-ref name="conversionError" />
                <interceptor-ref name="validation">
               
  cancel,execute,delete,edit,list,start
               
                </interceptor-ref>
                <interceptor-ref name="workflow">
                       
                                input,back,cancel,browse
                       
                </interceptor-ref>
                    </interceptor-stack>
                </interceptors>
                <default-interceptor-ref name="creditDefaultStack" />
照上面的說法去做,由于本人能力有限,還是未能解決.去下個高點的版本試試看,期待能解決!



Ke 2007-11-17 15:21 發表評論
]]>
Struts 2中的OGNLhttp://m.tkk7.com/keweibo/articles/159957.htmlKeKeMon, 12 Nov 2007 06:08:00 GMThttp://m.tkk7.com/keweibo/articles/159957.htmlhttp://m.tkk7.com/keweibo/comments/159957.htmlhttp://m.tkk7.com/keweibo/articles/159957.html#Feedback1http://m.tkk7.com/keweibo/comments/commentRss/159957.htmlhttp://m.tkk7.com/keweibo/services/trackbacks/159957.html閱讀全文

Ke 2007-11-12 14:08 發表評論
]]>
struts 2.0 中一些重要tag的用法及常用屬性介紹http://m.tkk7.com/keweibo/articles/150838.htmlKeKeSun, 07 Oct 2007 06:33:00 GMThttp://m.tkk7.com/keweibo/articles/150838.htmlhttp://m.tkk7.com/keweibo/comments/150838.htmlhttp://m.tkk7.com/keweibo/articles/150838.html#Feedback0http://m.tkk7.com/keweibo/comments/commentRss/150838.htmlhttp://m.tkk7.com/keweibo/services/trackbacks/150838.html struts 2.0 中一些重要tag的用法及常用屬性介紹 作者:lijie250    文章來源:http://www.wangmeng.cn/Article/SOFTDEVELOP/JAVA/200705/2672.html

首先 要注意的是
struts2中tag支持jsp,freeMarker ,velocity

因此,tag也有三種形式
例如:
JSP下的form標簽: <s:form action="example">
velocity的form標簽: #sform ("action=example")
freeMarker下的form標簽: <@s.form action="example">

下面以JSP使用的標簽為例:
1 <s:head>
 這個標簽用在<head></head>中,
將會引入struts tag用到的一些css和js文件
 需要注意的是,如果任何ui tag或者ajax tag的theme屬性值是ajax
 那么<s:head>必須有theme屬性 并且它的值是ajax
 這將會額外地引入與ajax相關的js文件,比如dojo.js

2 <s:form>
 類似于struts 1.x 的<html:form>
 validate屬性:默認是false
如果設為true 那么struts2框架會自動生成一個javascript的驗證方法,
 并且根據validation.xml的配置客戶端驗證。
如果這個頁面沒有<s:head>標簽將會產生js錯誤
 namespace屬性:指定這個form需要提交到哪個namespace

<s:submit>
 theme屬性:指明theme="ajax" 會使用ajax功能,通過異步方式傳輸數據
 targets屬性:指定異步方式返回的數據顯示的位置 ,
 例如<div id="div1"></div>....
<s:submit theme="ajax" targets="div1" name="nn"/>
 formId屬性:允許遠程提交表單,
即<s:submit>標簽的位置并不在<s:form></s:form>范圍內
 indicator屬性:指定一個indicator,例如<img id="indicator" src=...
 在使用異步方式的時候,會產生一個表示正在loading的小圖片

4 <s:autocompleter>自動填充器
 theme屬性:如果theme值是simple,表示使用普通方式。
如果是ajax表示使用異步方式
 list屬性:指定使用的數據集合。
它的值可以是action中的一個屬性,直接在標簽中指定
  例如:list="{'apple','banana','grape','pear'}"
 indicator屬性: 指定一個indicator,theme屬性必須是ajax,否則沒有意義
 href屬性:使用的數據集合從url中獲取,
例如href="%{exampleList}"表示使用了一個<s:url>已經定義過的url:
<s:url id="exampleList"> 
 searchType屬性:默認是startstring,也可以指定為startword或者substring,
表示自動填充的查詢方式
 delay屬性:指定動作等待多少毫秒
 loadMinimumCount屬性:當loadOnTextChange為true時,
 loadMinimumCount表示輸入了多少個字符后,才開始重新加載數據集合,
  這時theme屬性必須是ajax,否則沒有意義

5 <s:actionerror />
    作用大致相當于struts 1.x中的 <html:errors/>
  類似的還有<s:actionmessage />

6 <s:fielderror>
         字段驗證錯誤的報錯信息
         <s:fielderror>
         <s:param>field1</s:param>
         <s:param>field2</s:param>
    </s:fielderror>
    表示只顯示field1,field2的錯誤信息,
如果沒有<s:param/>表示顯示全部
    錯誤信息的內容由action的.properties文件指定

7 <s:textfield/>
  輸入框
  label屬性:顯示一段文字,
例如<s:textfield label="find"/>會自動生成HTML代碼:find:<input type="text"/>
  labelposition屬性:top/left,顯示label的位置,
可以使用top將文字顯示在輸入框的上面
                                 默認是left

8 <s:token />
  生成一個令牌 ,防止用戶重復提交表單



Ke 2007-10-07 14:33 發表評論
]]>
struts2 interceptor 問題(請教高手)http://m.tkk7.com/keweibo/articles/150747.htmlKeKeSat, 06 Oct 2007 13:54:00 GMThttp://m.tkk7.com/keweibo/articles/150747.htmlhttp://m.tkk7.com/keweibo/comments/150747.htmlhttp://m.tkk7.com/keweibo/articles/150747.html#Feedback0http://m.tkk7.com/keweibo/comments/commentRss/150747.htmlhttp://m.tkk7.com/keweibo/services/trackbacks/150747.html今天寫了一個自定義攔截器.卻遇到了以下問題

package dgut.ke.interceptors;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;

import dgut.ke.model.Catalog;
import dgut.ke.model.Publish;
import dgut.ke.model.Subject;
import dgut.ke.service.ICatalogService;
import dgut.ke.service.IPublishService;
import dgut.ke.service.ISubjectService;

public class AddBookInterceptor extends MethodFilterInterceptor {

 /**
  *
  */
 private static final long serialVersionUID = 1135497226250835266L;

 private ISubjectService subjectService ;
 private ICatalogService catalogService ;
 private IPublishService publishService ;

 public ICatalogService getCatalogService() {
  return catalogService;
 }

 public IPublishService getPublishService() {
  return publishService;
 }

 public ISubjectService getSubjectService() {
  return subjectService;
 }

 public void setCatalogService(ICatalogService catalogService) {
  this.catalogService = catalogService;
 }

 public void setPublishService(IPublishService publishService) {
  this.publishService = publishService;
 }

 public void setSubjectService(ISubjectService subjectService) {
  this.subjectService = subjectService;
 }

 @Override
 protected String doIntercept(ActionInvocation invoation) throws Exception {
  // TODO 自動生成方法存根
  System.out.println("-------- 攔截器開始執行 ----------");
  List<Subject> subject_list = (ArrayList<Subject>)subjectService.findAll();
  List<Catalog> catalog_list = (ArrayList<Catalog>)catalogService.findAll();
  List<Publish> pubish_list =  (ArrayList<Publish>)publishService.findAll();

  //ActionContext act = ActionContext.getContext() ;
  ActionContext act = invocation.getInvocationContext() ;
  HttpServletRequest request = (HttpServletRequest) act.get(ServletActionContext.HTTP_REQUEST) ;
  request.setAttribute("subject_list", subject_list) ;
  request.setAttribute("catalog_list", catalog_list) ;
  request.setAttribute("publish_list", pubish_list) ;
  System.out.println("-------- 攔截器執行結束 ----------");
  return Action.INPUT;
 }

}
為了實現request.setAttribute(String str, Object obj) ;.最先是讓上面的類實現ServletRequestAware 接口.
但是在運行的時候卻出現了空指針異常。后來改成以上的代碼就可以正常運行,但是還是
不太明白
曾經在一本書上看到一段話:構建interceptor最重要的原則:interceptor必須是無狀態的,并且不能
夠使用任何ActionInvocation提供范圍以外的API



Ke 2007-10-06 21:54 發表評論
]]>
struts2的struts.properties配置文件詳解http://m.tkk7.com/keweibo/articles/150352.htmlKeKeThu, 04 Oct 2007 05:47:00 GMThttp://m.tkk7.com/keweibo/articles/150352.htmlhttp://m.tkk7.com/keweibo/comments/150352.htmlhttp://m.tkk7.com/keweibo/articles/150352.html#Feedback0http://m.tkk7.com/keweibo/comments/commentRss/150352.htmlhttp://m.tkk7.com/keweibo/services/trackbacks/150352.html           The URL extension to use to determine if the request is meant for a Struts action 
           用URL擴展名來確定是否這個請求是被用作Struts action,其實也就是設置 action的后綴,例如login.do的'do'字。

struts.configuration
          The org.apache.struts2.config.Configuration implementation class
            org.apache.struts2.config.Configuration接口名

struts.configuration.files
          A list of configuration files automatically loaded by Struts 
           struts自動加載的一個配置文件列表

struts.configuration.xml.reload
          Whether to reload the XML configuration or not
           是否加載xml配置(true,false)

struts.continuations.package
           The package containing actions that use Rife continuations
           含有actions的完整連續的package名稱

struts.custom.i18n.resources
          Location of additional localization properties files to load 
           加載附加的國際化屬性文件(不包含.properties后綴)

struts.custom.properties
          Location of additional configuration properties files to load
           加載附加的配置文件的位置


struts.devMode
          Whether Struts is in development mode or not
           是否為struts開發模式

struts.dispatcher.parametersWorkaround
          Whether to use a Servlet request parameter workaround necessary for some versions of WebLogic
            (某些版本的weblogic專用)是否使用一個servlet請求參數工作區(PARAMETERSWORKAROUND)

struts.enable.DynamicMethodInvocation
          Allows one to disable dynamic method invocation from the URL
            允許動態方法調用

struts.freemarker.manager.classname
          The org.apache.struts2.views.freemarker.FreemarkerManager implementation class 
           org.apache.struts2.views.freemarker.FreemarkerManager接口名

struts.i18n.encoding
          The encoding to use for localization messages
           國際化信息內碼

struts.i18n.reload
          Whether the localization messages should automatically be reloaded
           是否國際化信息自動加載 

struts.locale
          The default locale for the Struts application
           默認的國際化地區信息

struts.mapper.class
          The org.apache.struts2.dispatcher.mapper.ActionMapper implementation class
            org.apache.struts2.dispatcher.mapper.ActionMapper接口

struts.multipart.maxSize
          The maximize size of a multipart request (file upload)
           multipart請求信息的最大尺寸(文件上傳用) 

struts.multipart.parser
          The org.apache.struts2.dispatcher.multipart.
          MultiPartRequest parser implementation for a multipart request (file upload) 
          專為multipart請求信息使用的org.apache.struts2.dispatcher.multipart.MultiPartRequest解析器接口(文件上傳用)


struts.multipart.saveDir
          The directory to use for storing uploaded files 
           設置存儲上傳文件的目錄夾

struts.objectFactory
          The com.opensymphony.xwork2.ObjectFactory implementation class
           com.opensymphony.xwork2.ObjectFactory接口(spring)

struts.objectFactory.spring.autoWire
          Whether Spring should autoWire or not
           是否自動綁定Spring

struts.objectFactory.spring.useClassCache
          Whether Spring should use its class cache or not
           是否spring應該使用自身的cache 

struts.objectTypeDeterminer
          The com.opensymphony.xwork2.util.ObjectTypeDeterminer implementation class
            com.opensymphony.xwork2.util.ObjectTypeDeterminer接口

struts.serve.static.browserCache
  If static content served by the Struts filter should set browser caching header properties or not 
           是否struts過濾器中提供的靜態內容應該被瀏覽器緩存在頭部屬性中

struts.serve.static
          Whether the Struts filter should serve static content or not 
           是否struts過濾器應該提供靜態內容

struts.tag.altSyntax
          Whether to use the alterative syntax for the tags or not 
           是否可以用替代的語法替代tags

struts.ui.templateDir
          The directory containing UI templates
           UI templates的目錄夾 

struts.ui.theme
          The default UI template theme
           默認的UI template主題

struts.url.http.port
          The HTTP port used by Struts URLs
           設置http端口

struts.url.https.port
          The HTTPS port used by Struts URLs 
           設置https端口

struts.url.includeParams
          The default includeParams method to generate Struts URLs 
          在url中產生 默認的includeParams


struts.velocity.configfile
          The Velocity configuration file path
           velocity配置文件路徑

struts.velocity.contexts
          List of Velocity context names
           velocity的context列表


struts.velocity.manager.classname
          org.apache.struts2.views.velocity.VelocityManager implementation class
           org.apache.struts2.views.velocity.VelocityManager接口名

struts.velocity.toolboxlocation
          The location of the Velocity toolbox
           velocity工具盒的位置 
struts.xslt.nocache
          Whether or not XSLT templates should not be cached
           是否XSLT模版應該被緩存

Ke 2007-10-04 13:47 發表評論
]]>
在Struts2中實現文件上傳(二)http://m.tkk7.com/keweibo/articles/146616.htmlKeKeWed, 19 Sep 2007 14:14:00 GMThttp://m.tkk7.com/keweibo/articles/146616.htmlhttp://m.tkk7.com/keweibo/comments/146616.htmlhttp://m.tkk7.com/keweibo/articles/146616.html#Feedback0http://m.tkk7.com/keweibo/comments/commentRss/146616.htmlhttp://m.tkk7.com/keweibo/services/trackbacks/146616.html

在Struts2中實現文件上傳(二)

 發布者:[IT電子教育門戶]   

發布運行應用程序,在瀏覽器地址欄中鍵入:http://localhost:8080/Struts2_Fileupload/FileUpload.jsp,出現圖示頁面:

 
清單7 FileUpload頁面

選擇圖片文件,填寫Caption并按下Submit按鈕提交,出現圖示頁面:

 
清單8 上傳成功頁面

更多配置
在運行上述例子,如果您留心一點的話,應該會發現服務器控制臺有如下輸出:

Mar 20 , 2007 4 : 08 : 43 PM org.apache.struts2.dispatcher.Dispatcher getSaveDir
INFO: Unable to find 'struts.multipart.saveDir' property setting. Defaulting to javax.servlet.context.tempdir
Mar 20 , 2007 4 : 08 : 43 PM org.apache.struts2.interceptor.FileUploadInterceptor intercept
INFO: Removing file myFile C:\Program Files\Tomcat 5.5 \work\Catalina\localhost\Struts2_Fileupload\upload_251447c2_1116e355841__7ff7_00000006.tmp 清單9 服務器控制臺輸出
上述信息告訴我們,struts.multipart.saveDir沒有配置。struts.multipart.saveDir用于指定存放臨時文件的文件夾,該配置寫在struts.properties文件中。例如,如果在struts.properties文件加入如下代碼:

struts.multipart.saveDir = /tmp 清單10 struts配置
這樣上傳的文件就會臨時保存到你根目錄下的tmp文件夾中(一般為c:\tmp),如果此文件夾不存在,Struts 2會自動創建一個。

錯誤處理
上述例子實現的圖片上傳的功能,所以應該阻止用戶上傳非圖片類型的文件。在Struts 2中如何實現這點呢?其實這也很簡單,對上述例子作如下修改即可。

首先修改FileUpload.jsp,在<body>與<s:form>之間加入“<s:fielderror />”,用于在頁面上輸出錯誤信息。

然后修改struts.xml文件,將Action fileUpload的定義改為如下所示:

        < action name ="fileUpload" class ="tutorial.FileUploadAction" >
            < interceptor-ref name ="fileUpload" >
                < param name ="allowedTypes" >
                    image/bmp,image/png,image/gif,image/jpeg
                </ param >
            </ interceptor-ref >
            < interceptor-ref name ="defaultStack" />           
            < result name ="input" > /FileUpload.jsp </ result >
            < result name ="success" > /ShowUpload.jsp </ result >
        </ action > 清單11 修改后的配置文件
顯而易見,起作用就是fileUpload攔截器的allowTypes參數。另外,配置還引入defaultStack它會幫我們添加驗證等功能,所以在出錯之后會跳轉到名稱為“input”的結果,也即是FileUpload.jsp。

發布運行應用程序,出錯時,頁面如下圖所示:

 
清單12 出錯提示頁面

上面的出錯提示是Struts 2默認的,大多數情況下,我們都需要自定義和國際化這些信息。通過在全局的國際資源文件中加入“struts.messages.error.content.type.not.allowed=The file you uploaded is not a image”,可以實現以上提及的需求。對此有疑問的朋友可以參考我之前的文章《在Struts 2.0中國際化(i18n)您的應用程序》。

實現之后的出錯頁面如下圖所示:

 
清單13 自定義出錯提示頁面

同樣的做法,你可以使用參數“maximumSize”來限制上傳文件的大小,它對應的字符資源名為:“struts.messages.error.file.too.large”。

字符資源“struts.messages.error.uploading”用提示一般的上傳出錯信息。

多文件上傳
與單文件上傳相似,Struts 2實現多文件上傳也很簡單。你可以將多個<s:file />綁定Action的數組或列表。如下例所示。

< s:form action ="doMultipleUploadUsingList" method ="POST" enctype ="multipart/form-data" >
    < s:file label ="File (1)" name ="upload" />
    < s:file label ="File (2)" name ="upload" />
    < s:file label ="FIle (3)" name ="upload" />
    < s:submit />
</ s:form > 清單14 多文件上傳JSP代碼片段
如果你希望綁定到數組,Action的代碼應類似:

     private File[] uploads;
     private String[] uploadFileNames;
     private String[] uploadContentTypes;

     public File[] getUpload()  { return this .uploads; }
      public void setUpload(File[] upload)  { this .uploads = upload; }
 
      public String[] getUploadFileName()  { return this .uploadFileNames; }
      public void setUploadFileName(String[] uploadFileName)  { this .uploadFileNames = uploadFileName; }
 
      public String[] getUploadContentType()  { return this .uploadContentTypes; }
      public void setUploadContentType(String[] uploadContentType)  { this .uploadContentTypes = uploadContentType; } 清單15 多文件上傳數組綁定Action代碼片段
如果你想綁定到列表,則應類似:

     private List < File > uploads = new ArrayList < File > ();
     private List < String > uploadFileNames = new ArrayList < String > ();
     private List < String > uploadContentTypes = new ArrayList < String > ();

     public List < File > getUpload()  {
         return this .uploads;
    }
      public void setUpload(List < File > uploads)  {
         this .uploads = uploads;
    }
 
      public List < String > getUploadFileName()  {
         return this .uploadFileNames;
    }
      public void setUploadFileName(List < String > uploadFileNames)  {
         this .uploadFileNames = uploadFileNames;
    }
 
      public List < String > getUploadContentType()  {
         return this .uploadContentTypes;
    }
      public void setUploadContentType(List < String > contentTypes)  {
         this .uploadContentTypes = contentTypes;
    } 清單16 多文件上傳列表綁定Action代碼片段
總結
在Struts 2中實現文件上傳的確是輕而易舉,您要做的只是使用<s:file />與Action的屬性綁定。這又一次有力地證明了Struts 2的簡單易用。



Ke 2007-09-19 22:14 發表評論
]]>
在Struts2中實現文件上傳(一)http://m.tkk7.com/keweibo/articles/146615.htmlKeKeWed, 19 Sep 2007 14:11:00 GMThttp://m.tkk7.com/keweibo/articles/146615.htmlhttp://m.tkk7.com/keweibo/comments/146615.htmlhttp://m.tkk7.com/keweibo/articles/146615.html#Feedback0http://m.tkk7.com/keweibo/comments/commentRss/146615.htmlhttp://m.tkk7.com/keweibo/services/trackbacks/146615.html

在Struts2中實現文件上傳(一)

轉自:http://www.mldn.cn/articleview/2007-8-22/article_view_2245.htm

前一陣子有些朋友在電子郵件中問關于Struts 2實現文件上傳的問題, 所以今天我們就來討論一下這個問題。

實現原理
Struts 2是通過Commons FileUpload文件上傳。Commons FileUpload通過將HTTP的數據保存到臨時文件夾,然后Struts使用fileUpload攔截器將文件綁定到Action的實例中。從而我們就能夠以本地文件方式的操作瀏覽器上傳的文件。

具體實現
前段時間Apache發布了Struts 2.0.6 GA,所以本文的實現是以該版本的Struts作為框架的。以下是例子所依賴類包的列表:

依賴類包的列表 
清單1 依賴類包的列表

首先,創建文件上傳頁面FileUpload.jsp,內容如下:

<% @ page language = " java " contentType = " text/html; charset=utf-8 " pageEncoding = " utf-8 " %>
<% @ taglib prefix = " s " uri = " /struts-tags " %>

<! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
< html xmlns ="http://www.w3.org/1999/xhtml" >
< head >
    < title > Struts 2 File Upload </ title >
</ head >
< body >
    < s:form action ="fileUpload" method ="POST" enctype ="multipart/form-data" >
        < s:file name ="myFile" label ="Image File" />
        < s:textfield name ="caption" label ="Caption" />       
        < s:submit />
    </ s:form >
</ body >
</ html > 清單2 FileUpload.jsp
在FileUpload.jsp中,先將表單的提交方式設為POST,然后將enctype設為multipart/form-data,這并沒有什么特別之處。接下來,<s:file/>標志將文件上傳控件綁定到Action的myFile屬性。

其次是FileUploadAction.java代碼:

 package tutorial;

 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.Date;

 import org.apache.struts2.ServletActionContext;

 import com.opensymphony.xwork2.ActionSupport;

 public class FileUploadAction extends ActionSupport  {
     private static final long serialVersionUID = 572146812454l ;
     private static final int BUFFER_SIZE = 16 * 1024 ;
   
     private File myFile;
     private String contentType;
     private String fileName;
     private String imageFileName;
     private String caption;
   
     public void setMyFileContentType(String contentType)  {
         this .contentType = contentType;
    }
   
     public void setMyFileFileName(String fileName)  {
         this .fileName = fileName;
    }
       
     public void setMyFile(File myFile)  {
         this .myFile = myFile;
    }
   
     public String getImageFileName()  {
         return imageFileName;
    }
   
     public String getCaption()  {
         return caption;
    }
 
      public void setCaption(String caption)  {
         this .caption = caption;
    }
   
     private static void copy(File src, File dst)  {
         try  {
            InputStream in = null ;
            OutputStream out = null ;
             try  {               
                in = new BufferedInputStream( new FileInputStream(src), BUFFER_SIZE);
                out = new BufferedOutputStream( new FileOutputStream(dst), BUFFER_SIZE);
                 byte [] buffer = new byte [BUFFER_SIZE];
                 while (in.read(buffer) > 0 )  {
                    out.write(buffer);
                }
             } finally  {
                 if ( null != in)  {
                    in.close();
                }
                  if ( null != out)  {
                    out.close();
                }
            }
         } catch (Exception e)  {
            e.printStackTrace();
        }
    }
   
     private static String getExtention(String fileName)  {
         int pos = fileName.lastIndexOf( " . " );
         return fileName.substring(pos);
    }
 
    @Override
     public String execute()      {       
        imageFileName = new Date().getTime() + getExtention(fileName);
        File imageFile = new File(ServletActionContext.getServletContext().getRealPath( " /UploadImages " ) + " / " + imageFileName);
        copy(myFile, imageFile);
         return SUCCESS;
    }
   
} 清單3 tutorial/FileUploadAction.java
在FileUploadAction中我分別寫了setMyFileContentType、setMyFileFileName、setMyFile和setCaption四個Setter方法,后兩者很容易明白,分別對應FileUpload.jsp中的<s:file/>和<s:textfield/>標志。但是前兩者并沒有顯式地與任何的頁面標志綁定,那么它們的值又是從何而來的呢?其實,<s:file/>標志不僅僅是綁定到myFile,還有myFileContentType(上傳文件的MIME類型)和myFileFileName(上傳文件的文件名,該文件名不包括文件的路徑)。因此,<s:file name="xxx" />對應Action類里面的xxx、xxxContentType和xxxFileName三個屬性。

FileUploadAction作用是將瀏覽器上傳的文件拷貝到WEB應用程序的UploadImages文件夾下,新文件的名稱是由系統時間與上傳文件的后綴組成,該名稱將被賦給imageFileName屬性,以便上傳成功的跳轉頁面使用。

下面我們就來看看上傳成功的頁面:

<% @ page language = " java " contentType = " text/html; charset=utf-8 " pageEncoding = " utf-8 " %>
<% @ taglib prefix = " s " uri = " /struts-tags " %>

<! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
< html xmlns ="http://www.w3.org/1999/xhtml" >
< head >
    < title > Struts 2 File Upload </ title >
</ head >
< body >
    < div style ="padding: 3px; border: solid 1px #cccccc; text-align: center" >
        < img src ='UploadImages/<s:property value ="imageFileName" /> ' />
        < br />
        < s:property value ="caption" />
    </ div >
</ body >
</ html > 清單4 ShowUpload.jsp
ShowUpload.jsp獲得imageFileName,將其UploadImages組成URL,從而將上傳的圖像顯示出來。

然后是Action的配置文件:

<? xml version="1.0" encoding="UTF-8" ?>

<! DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd" >

< struts >
    < package name ="fileUploadDemo" extends ="struts-default" >
        < action name ="fileUpload" class ="tutorial.FileUploadAction" >
            < interceptor-ref name ="fileUploadStack" />
            < result name ="success" > /ShowUpload.jsp </ result >
        </ action >
    </ package >
</ struts > 清單5 struts.xml
fileUpload Action顯式地應用fileUploadStack的攔截器。

最后是web.xml配置文件:

<? xml version="1.0" encoding="UTF-8" ?>
< web-app id ="WebApp_9" version ="2.4"
    xmlns ="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation ="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" >

    < display-name > Struts 2 Fileupload </ display-name >

    < filter >
        < filter-name > struts-cleanup </ filter-name >
        < filter-class >
            org.apache.struts2.dispatcher.ActionContextCleanUp
        </ filter-class >
    </ filter >
   
    < filter >
        < filter-name > struts2 </ filter-name >
        < filter-class >
            org.apache.struts2.dispatcher.FilterDispatcher
        </ filter-class >
    </ filter >
   
    < filter-mapping >
        < filter-name > struts-cleanup </ filter-name >
        < url-pattern > /* </ url-pattern >
    </ filter-mapping >

    < filter-mapping >
        < filter-name > struts2 </ filter-name >
        < url-pattern > /* </ url-pattern >
    </ filter-mapping >

    < welcome-file-list >
        < welcome-file > index.html </ welcome-file >
    </ welcome-file-list >

</ web-app >



Ke 2007-09-19 22:11 發表評論
]]>
主站蜘蛛池模板: 亚洲精品456在线播放| 岛国岛国免费V片在线观看| 免费一级肉体全黄毛片| 日韩午夜理论免费TV影院| 国产青草亚洲香蕉精品久久| 亚洲精品国产福利在线观看| 国产亚洲成人在线播放va| 成人午夜免费福利| 在线看片免费人成视久网| 中国国语毛片免费观看视频| 黄色免费网站在线看| 亚洲精品无码一区二区| 亚洲中文字幕人成乱码| 18亚洲男同志videos网站| 国产AV无码专区亚洲精品| 亚洲精品乱码久久久久久不卡| 曰皮全部过程视频免费国产30分钟| 日本免费xxxx| 亚洲视频在线观看免费视频| 国产婷婷成人久久Av免费高清| 一区二区3区免费视频| 国产精品亚洲专区在线播放 | 亚洲成在人线在线播放无码| 亚洲神级电影国语版| 亚洲伊人tv综合网色| 亚洲AV无码久久精品蜜桃| 亚洲毛片αv无线播放一区| 久久亚洲国产成人精品无码区| 亚洲第一页日韩专区| 亚洲成a人一区二区三区| 国产一卡二卡≡卡四卡免费乱码 | 亚洲好看的理论片电影| 亚洲AV一宅男色影视| 亚洲成a人片在线观看无码专区| 狠狠综合久久综合88亚洲| 亚洲色欲久久久综合网东京热| 久久久久久亚洲精品不卡| 亚洲日韩精品无码一区二区三区| 国产成人亚洲影院在线观看| 亚洲中文字幕不卡无码| 久久精品视频亚洲|