久久午夜精品,国产一区二区,精品久久久久人成http://www.aygfsteel.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範(fàn)圍的Bean的配置事項http://www.aygfsteel.com/keweibo/articles/358063.htmlKeKeTue, 06 Sep 2011 02:22:00 GMThttp://www.aygfsteel.com/keweibo/articles/358063.htmlhttp://www.aygfsteel.com/keweibo/comments/358063.htmlhttp://www.aygfsteel.com/keweibo/articles/358063.html#Feedback0http://www.aygfsteel.com/keweibo/comments/commentRss/358063.htmlhttp://www.aygfsteel.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. 相應(yīng)的spring bean配置中應(yīng)加入<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 發(fā)表評論
]]>
struts2解決No configuration found for the specified action 異常http://www.aygfsteel.com/keweibo/articles/357973.htmlKeKeMon, 05 Sep 2011 02:16:00 GMThttp://www.aygfsteel.com/keweibo/articles/357973.htmlhttp://www.aygfsteel.com/keweibo/comments/357973.htmlhttp://www.aygfsteel.com/keweibo/articles/357973.html#Feedback0http://www.aygfsteel.com/keweibo/comments/commentRss/357973.htmlhttp://www.aygfsteel.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 發(fā)表評論
]]>
struts2 + JSON 問題http://www.aygfsteel.com/keweibo/articles/355606.htmlKeKeTue, 02 Aug 2011 09:01:00 GMThttp://www.aygfsteel.com/keweibo/articles/355606.htmlhttp://www.aygfsteel.com/keweibo/comments/355606.htmlhttp://www.aygfsteel.com/keweibo/articles/355606.html#Feedback0http://www.aygfsteel.com/keweibo/comments/commentRss/355606.htmlhttp://www.aygfsteel.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結(jié)合時的異常,第二種是struct2.1.6json結(jié)合的異常。

 

具體:

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

 

解釋:

不能把程序中的某種數(shù)據(jù)結(jié)構(gòu)串行化成json格式。

 

原因:

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

 

解決方法:

在不能串行化到json的屬性相應(yīng)的get方法前加一條json標(biāo)記 @JSON(serialize=false)。告訴json不需要轉(zhuǎn)化這個屬性?;蛘吒静粚戇@個get方法。

 

后記:

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

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



Ke 2011-08-02 17:01 發(fā)表評論
]]>
struts2+spring+hibernate 懶加載異常:org.hibernate.LazyInitializationException: failed to lazily initializehttp://www.aygfsteel.com/keweibo/articles/354252.htmlKeKeWed, 13 Jul 2011 05:55:00 GMThttp://www.aygfsteel.com/keweibo/articles/354252.htmlhttp://www.aygfsteel.com/keweibo/comments/354252.htmlhttp://www.aygfsteel.com/keweibo/articles/354252.html#Feedback0http://www.aygfsteel.com/keweibo/comments/commentRss/354252.htmlhttp://www.aygfsteel.com/keweibo/services/trackbacks/354252.html兩種處理方法:
一、在映射文件中設(shè)置lazy=false。
二、用OpenSessionInViewFilter過濾器,注意hibernateFilter過濾器和struts2過濾器在映射時的先后順序。同時要配置事物處理,否則會導(dǎo)致session處于只讀狀態(tài)而不能做修改、刪除的動作。
即在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 發(fā)表評論
]]>
[轉(zhuǎn)]Cannot serialize session attribute--問題的解決http://www.aygfsteel.com/keweibo/articles/308804.htmlKeKeSat, 09 Jan 2010 02:22:00 GMThttp://www.aygfsteel.com/keweibo/articles/308804.htmlhttp://www.aygfsteel.com/keweibo/comments/308804.htmlhttp://www.aygfsteel.com/keweibo/articles/308804.html#Feedback0http://www.aygfsteel.com/keweibo/comments/commentRss/308804.htmlhttp://www.aygfsteel.com/keweibo/services/trackbacks/308804.htmljava.io.NotSerializableException.

在重啟Tomcat 6時發(fā)現(xiàn)報此錯誤.

查閱后發(fā)現(xiàn)tomcat 5之后重啟服務(wù)后tomcat會嘗試恢復(fù)session.

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

 


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

在關(guān)閉和重啟Tomcat 5時, tomcat 會試圖 serialize存在的session資源. 如果 sessions中相關(guān)的對象沒有實現(xiàn) serializable 接口, 就會出現(xiàn)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 在關(guān)閉的時候就不會保存session資源了.


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

 

試試看.

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

 

方法二:

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

public class YourClassName implements java.io.Serializable{

}

其他內(nèi)容都完全不需要變.



Ke 2010-01-09 10:22 發(fā)表評論
]]>
Struts2中的單Form多圖片提交按鈕(Submit)的使用 (轉(zhuǎn))http://www.aygfsteel.com/keweibo/articles/208402.htmlKeKeMon, 16 Jun 2008 10:41:00 GMThttp://www.aygfsteel.com/keweibo/articles/208402.htmlhttp://www.aygfsteel.com/keweibo/comments/208402.htmlhttp://www.aygfsteel.com/keweibo/articles/208402.html#Feedback0http://www.aygfsteel.com/keweibo/comments/commentRss/208402.htmlhttp://www.aygfsteel.com/keweibo/services/trackbacks/208402.html文章來源:http://www.aygfsteel.com/bukebushuo/archive/2008/06/15/208012.html
在Struts2里面一個Form中如果有多個提交按鈕,比如添加,更新,保存等,
這些按鈕使用一個Action,調(diào)用不同的方法,并且在調(diào)用前要執(zhí)行一個JavaScript的檢查。
怎么用這個提交按鈕?
經(jīng)過總結(jié)如下:
先在form標(biāo)簽頭指定Action的命名空間:
<s:form namespace="/system/usermanager" >
然后如下調(diào)用:
                    <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中執(zhí)行javascript,記得不要漏掉return。
action就是你要調(diào)用的Action在Struts2的配置文件中定義的那個name
例如:<action name="user_*" class="com.system.action.ManagerUserAction" method="{1}"> 注意不包括通配符("_"或者"!"等)。
mothed就是Action類中定義的對應(yīng)的方法了。

測試環(huán)境:Struts2.1.2 Tomcat 5.5.26 MyEclipse 6

Ke 2008-06-16 18:41 發(fā)表評論
]]>
(轉(zhuǎn))NetBeans 6 和 Struts2 http://www.aygfsteel.com/keweibo/articles/191337.htmlKeKeMon, 07 Apr 2008 11:06:00 GMThttp://www.aygfsteel.com/keweibo/articles/191337.htmlhttp://www.aygfsteel.com/keweibo/comments/191337.htmlhttp://www.aygfsteel.com/keweibo/articles/191337.html#Feedback0http://www.aygfsteel.com/keweibo/comments/commentRss/191337.htmlhttp://www.aygfsteel.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)一個多小時后,總是發(fā)現(xiàn)自己已經(jīng)在NetBeans里敲代碼了。至于Struts2,這是一個融合了WebWork Struts1.X 的基于MVCWeb開發(fā)框架,使用相當(dāng)廣泛。

 

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

 

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

 

準(zhǔn)備工作:

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

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

3.       Struts2 開發(fā)包;

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

一.啟動NetBeans 6.1 創(chuàng)建一個Web 工程

 

創(chuàng)建一個 Web Project

   點擊File à New Project;

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

   點擊Next.

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

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

什么都不要選點擊Finish.  工程創(chuàng)建完畢,進(jìn)入下一部分。

二.創(chuàng)建Struts2 Library 并導(dǎo)入Struts2 開發(fā)包

點擊 Tools à Libraries

點擊New Library...

   Library Name: Struts2

   Library Type : Class Library

點擊OK

 

選擇圖中所示的struts2 java

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

點擊Add Library 基本Struts2的開發(fā)包已經(jīng)導(dǎo)入完畢。

三.配置Web.xml

如圖所示;單擊web.xml 然后點擊右側(cè)的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(相信大多數(shù)程序員都很討厭寫又長又臭的xml. 而且稍微一出錯,能把眼睛看痛)

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

現(xiàn)在你可以暫時不用管web.xml了。

四.編寫struts.xml

struts.xml 可以說是整個struts2框架的中心。大多數(shù)配置錯誤也出現(xiàn)在struts.xml上。一個jsp頁面提交后不是像傳統(tǒng)的做法那樣直接傳給另一個頁面,而是交由struts.xml進(jìn)行處理。struts.xml調(diào)用后臺action 進(jìn)行處理后,決定轉(zhuǎn)向那個頁面.那么我們?nèi)绾尉帉懸约霸谀睦锓胖?/span>struts.xml呢?

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

給文件命名為struts

接下來點擊struts.xml進(jìn)行編寫,之前我們要在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已經(jīng)完全認(rèn)識了Struts2(估計它們已經(jīng)成為好伙伴了)。繼續(xù)編寫,如果你怕出錯,或者不愿意太麻煩,按 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 標(biāo)簽中的name屬性要特別注意,因為這個是用來標(biāo)識這個action的。class屬性里的是,action類。當(dāng)點擊一個jsp頁面里的<a href=”hello.action”>enter</a>的時候。程序會根據(jù)hello.action struts.xml里找到name=”hello”的標(biāo)簽。繼而找到后臺的 HelloAction 類。然后根據(jù)HelloAction 實例的返回值,找到result標(biāo)簽中對應(yīng)的頁面,實現(xiàn)頁面的轉(zhuǎn)移。result標(biāo)簽有一個name屬性如 <result name=”success”>/helloPage.jsp</result>如果不寫 name屬性,則默認(rèn)為 name=”success”.

 

保存,關(guān)閉這個頁面,接下來我們來編寫HelloAction

五,編寫HelloAction類

右鍵單擊Source Package 創(chuàng)建一個java類。

如下填寫:

HelloAction 繼承ActionSupport

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

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

我們要的就是這個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;
    }

}

進(jìn)入下一部分。

六.編寫jsp頁面

index.jsp中的body標(biāo)簽內(nèi)加入<a href="hello.action">hello</a>

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

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

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



Ke 2008-04-07 19:06 發(fā)表評論
]]>
&lt;s:actionmessage/&gt;標(biāo)簽顯示Action信息http://www.aygfsteel.com/keweibo/articles/176142.htmlKeKeFri, 18 Jan 2008 03:23:00 GMThttp://www.aygfsteel.com/keweibo/articles/176142.htmlhttp://www.aygfsteel.com/keweibo/comments/176142.htmlhttp://www.aygfsteel.com/keweibo/articles/176142.html#Feedback0http://www.aygfsteel.com/keweibo/comments/commentRss/176142.htmlhttp://www.aygfsteel.com/keweibo/services/trackbacks/176142.html 就是相應(yīng)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標(biāo)簽的type屬性設(shè)置為redirect則在Action即使使用了

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

在JSP頁面也不能顯示相應(yīng)的信息


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

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


具體的做法這里有詳細(xì)的說明:
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/>標(biāo)簽來傳遞參數(shù),雖然也可以使用 <ww:text name="'format.date'" value0= "'birthday.time()'"/>
但是后面的這個方法在webwork的新版本中已經(jīng)被要求不要使用,大家還是盡量使用 <ww:param/>標(biāo)簽

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

 


對于數(shù)字的格式化,這里有兩個參考:
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>

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

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

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

資源文件
......
#格式化數(shù)字或時間輸出
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>
格式化數(shù)字:  <s:text name="global.format.money"><s:param value="price"/></s:text>



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

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

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

什么是DWR

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

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

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

Struts 2與DWR

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

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

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

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

接下來,配置web.xml文件,內(nèi)容如下:

<?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"> 結(jié)束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可以調(diào)用的遠(yuǎn)程接口。

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

DWR Servlet默認(rèn)輸出頁面
圖3 DWR Servlet默認(rèn)輸出頁面

 接下來,我們要開始編寫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

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

<!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三個字段,我分別用了非空、正規(guī)表達(dá)式和范圍驗證。正規(guī)表達(dá)式(?!^[0-9]*$)(?!^[a-zA-Z]*$)^([a-zA-Z0-9]{8,10})$的作用是保證密碼由至少包括一個數(shù)字和一個字母,且不能含有符號的長度為8到10的字符串組成。它也是所謂強(qiáng)密碼(Strong Password)的普通實現(xiàn)。

接下來的是JSP的代碼,內(nèi)容如下:

<%@ 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

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

最后是Struts 2的配置文件,內(nèi)容如下所示:

<?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

最后發(fā)布運(yùn)應(yīng)用程序,在瀏覽器地址欄中輸入http://localhost:8080/Struts2_Ajax3/AjaxValidation!input.action出現(xiàn)如下圖所示頁面:

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

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

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

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

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

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

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

何時使用AJAX表單校驗

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

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

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

現(xiàn)在讓我們來改造一下上述例子,對于name我們可以使用AJAX校驗,但對于其它的字段應(yīng)該使用純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 發(fā)表評論
]]>
Struts2攔截器的使用http://www.aygfsteel.com/keweibo/articles/162558.htmlKeKeFri, 23 Nov 2007 02:35:00 GMThttp://www.aygfsteel.com/keweibo/articles/162558.htmlhttp://www.aygfsteel.com/keweibo/comments/162558.htmlhttp://www.aygfsteel.com/keweibo/articles/162558.html#Feedback0http://www.aygfsteel.com/keweibo/comments/commentRss/162558.htmlhttp://www.aygfsteel.com/keweibo/services/trackbacks/162558.html閱讀全文

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

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

1、<s:checkboxlist />

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

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

<%@ 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

分布運(yùn)行應(yīng)用程序,在瀏覽器中鍵入:http://localhost:8080/Struts2_CoolTags/checkboxlist.jsp,出現(xiàn)如下圖所示頁面:

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’屬性應(yīng)該如何設(shè)定呢?”

我建議的做法是先定義一個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

分布運(yùn)行應(yīng)用程序,在瀏覽器中鍵入:http://localhost:8080/Struts2_CoolTags/doubleselect.action,出現(xiàn)如下圖所示頁面:

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

3、<s: token />

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

實現(xiàn)原理

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

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

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

具體實現(xiàn)

首先看一下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 />標(biāo)志。接下來是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”結(jié)果,因為“token”攔截器在會話token與請求token不一致時,將會直接返回“invalid.token”結(jié)果。

發(fā)布運(yùn)行應(yīng)用程序,在瀏覽器中鍵入:http://localhost:8080/Struts2_CoolTags/token.jsp,出現(xiàn)如下圖所示頁面:

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

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

重復(fù)提交出錯顯示
清單11 重復(fù)提交出錯顯示

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

這幾個標(biāo)志的使用相對簡單,所以我想小舉一例即可,以下是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頁面

發(fā)布運(yùn)行應(yīng)用程序,在瀏覽器中鍵入:http://localhost:8080/Struts2_CoolTags/others.jsp,出現(xiàn)如下圖所示頁面:

點擊查看大圖
清單13 其它表單標(biāo)志頁面

總結(jié)

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



Ke 2007-11-23 10:33 發(fā)表評論
]]>
struts2中使用displayTags的問題(ParametersInterceptor - [setParameters]: Unexpected Exception)http://www.aygfsteel.com/keweibo/articles/161226.htmlKeKeSat, 17 Nov 2007 07:21:00 GMThttp://www.aygfsteel.com/keweibo/articles/161226.htmlhttp://www.aygfsteel.com/keweibo/comments/161226.htmlhttp://www.aygfsteel.com/keweibo/articles/161226.html#Feedback11http://www.aygfsteel.com/keweibo/comments/commentRss/161226.htmlhttp://www.aygfsteel.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'

在網(wǎng)上的搜了一下,在一些中文網(wǎng)頁上幾乎都找不到相關(guān)的信息,結(jié)果在一個英語網(wǎng)站上看到了以下信息:

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 發(fā)表評論
]]>
Struts 2中的OGNLhttp://www.aygfsteel.com/keweibo/articles/159957.htmlKeKeMon, 12 Nov 2007 06:08:00 GMThttp://www.aygfsteel.com/keweibo/articles/159957.htmlhttp://www.aygfsteel.com/keweibo/comments/159957.htmlhttp://www.aygfsteel.com/keweibo/articles/159957.html#Feedback1http://www.aygfsteel.com/keweibo/comments/commentRss/159957.htmlhttp://www.aygfsteel.com/keweibo/services/trackbacks/159957.html閱讀全文

Ke 2007-11-12 14:08 發(fā)表評論
]]>
struts 2.0 中一些重要tag的用法及常用屬性介紹http://www.aygfsteel.com/keweibo/articles/150838.htmlKeKeSun, 07 Oct 2007 06:33:00 GMThttp://www.aygfsteel.com/keweibo/articles/150838.htmlhttp://www.aygfsteel.com/keweibo/comments/150838.htmlhttp://www.aygfsteel.com/keweibo/articles/150838.html#Feedback0http://www.aygfsteel.com/keweibo/comments/commentRss/150838.htmlhttp://www.aygfsteel.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標(biāo)簽: <s:form action="example">
velocity的form標(biāo)簽: #sform ("action=example")
freeMarker下的form標(biāo)簽: <@s.form action="example">

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

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

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

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

5 <s:actionerror />
    作用大致相當(dāng)于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/>表示顯示全部
    錯誤信息的內(nèi)容由action的.properties文件指定

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

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



Ke 2007-10-07 14:33 發(fā)表評論
]]>
struts2 interceptor 問題(請教高手)http://www.aygfsteel.com/keweibo/articles/150747.htmlKeKeSat, 06 Oct 2007 13:54:00 GMThttp://www.aygfsteel.com/keweibo/articles/150747.htmlhttp://www.aygfsteel.com/keweibo/comments/150747.htmlhttp://www.aygfsteel.com/keweibo/articles/150747.html#Feedback0http://www.aygfsteel.com/keweibo/comments/commentRss/150747.htmlhttp://www.aygfsteel.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("-------- 攔截器開始執(zhí)行 ----------");
  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("-------- 攔截器執(zhí)行結(jié)束 ----------");
  return Action.INPUT;
 }

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



Ke 2007-10-06 21:54 發(fā)表評論
]]>
struts2的struts.properties配置文件詳解http://www.aygfsteel.com/keweibo/articles/150352.htmlKeKeThu, 04 Oct 2007 05:47:00 GMThttp://www.aygfsteel.com/keweibo/articles/150352.htmlhttp://www.aygfsteel.com/keweibo/comments/150352.htmlhttp://www.aygfsteel.com/keweibo/articles/150352.html#Feedback0http://www.aygfsteel.com/keweibo/comments/commentRss/150352.htmlhttp://www.aygfsteel.com/keweibo/services/trackbacks/150352.html           The URL extension to use to determine if the request is meant for a Struts action 
           用URL擴(kuò)展名來確定是否這個請求是被用作Struts action,其實也就是設(shè)置 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的完整連續(xù)的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開發(fā)模式

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

struts.enable.DynamicMethodInvocation
          Allows one to disable dynamic method invocation from the URL
            允許動態(tài)方法調(diào)用

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
           國際化信息內(nèi)碼

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

struts.locale
          The default locale for the Struts application
           默認(rèn)的國際化地區(qū)信息

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 
           設(shè)置存儲上傳文件的目錄夾

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應(yīng)該使用自身的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過濾器中提供的靜態(tài)內(nèi)容應(yīng)該被瀏覽器緩存在頭部屬性中

struts.serve.static
          Whether the Struts filter should serve static content or not 
           是否struts過濾器應(yīng)該提供靜態(tài)內(nèi)容

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
           默認(rèn)的UI template主題

struts.url.http.port
          The HTTP port used by Struts URLs
           設(shè)置http端口

struts.url.https.port
          The HTTPS port used by Struts URLs 
           設(shè)置https端口

struts.url.includeParams
          The default includeParams method to generate Struts URLs 
          在url中產(chǎn)生 默認(rèn)的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模版應(yīng)該被緩存

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

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

 發(fā)布者:[IT電子教育門戶]   

發(fā)布運(yùn)行應(yīng)用程序,在瀏覽器地址欄中鍵入:http://localhost:8080/Struts2_Fileupload/FileUpload.jsp,出現(xiàn)圖示頁面:

 
清單7 FileUpload頁面

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

 
清單8 上傳成功頁面

更多配置
在運(yùn)行上述例子,如果您留心一點的話,應(yīng)該會發(fā)現(xiàn)服務(wù)器控制臺有如下輸出:

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 服務(wù)器控制臺輸出
上述信息告訴我們,struts.multipart.saveDir沒有配置。struts.multipart.saveDir用于指定存放臨時文件的文件夾,該配置寫在struts.properties文件中。例如,如果在struts.properties文件加入如下代碼:

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

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

首先修改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參數(shù)。另外,配置還引入defaultStack它會幫我們添加驗證等功能,所以在出錯之后會跳轉(zhuǎn)到名稱為“input”的結(jié)果,也即是FileUpload.jsp。

發(fā)布運(yùn)行應(yīng)用程序,出錯時,頁面如下圖所示:

 
清單12 出錯提示頁面

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

實現(xiàn)之后的出錯頁面如下圖所示:

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

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

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

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

< 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代碼片段
如果你希望綁定到數(shù)組,Action的代碼應(yīng)類似:

     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 多文件上傳數(shù)組綁定Action代碼片段
如果你想綁定到列表,則應(yīng)類似:

     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代碼片段
總結(jié)
在Struts 2中實現(xiàn)文件上傳的確是輕而易舉,您要做的只是使用<s:file />與Action的屬性綁定。這又一次有力地證明了Struts 2的簡單易用。



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

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

轉(zhuǎn)自:http://www.mldn.cn/articleview/2007-8-22/article_view_2245.htm

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

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

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

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

首先,創(chuàng)建文件上傳頁面FileUpload.jsp,內(nèi)容如下:

<% @ 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中,先將表單的提交方式設(shè)為POST,然后將enctype設(shè)為multipart/form-data,這并沒有什么特別之處。接下來,<s:file/>標(biāo)志將文件上傳控件綁定到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方法,后兩者很容易明白,分別對應(yīng)FileUpload.jsp中的<s:file/>和<s:textfield/>標(biāo)志。但是前兩者并沒有顯式地與任何的頁面標(biāo)志綁定,那么它們的值又是從何而來的呢?其實,<s:file/>標(biāo)志不僅僅是綁定到myFile,還有myFileContentType(上傳文件的MIME類型)和myFileFileName(上傳文件的文件名,該文件名不包括文件的路徑)。因此,<s:file name="xxx" />對應(yīng)Action類里面的xxx、xxxContentType和xxxFileName三個屬性。

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

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

<% @ 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顯式地應(yīng)用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 發(fā)表評論
]]>
主站蜘蛛池模板: 精河县| 将乐县| 富蕴县| 九江市| 富裕县| 宿州市| 宁南县| 溧水县| 满城县| 甘南县| 莒南县| 舞钢市| 尼木县| 志丹县| 双柏县| 时尚| 石泉县| 宜兰县| 波密县| 岐山县| 乡城县| 信阳市| 伊金霍洛旗| 个旧市| 桐柏县| 寿宁县| 阳曲县| 策勒县| 新田县| 曲周县| 宜宾市| 南陵县| 麦盖提县| 南靖县| 五峰| 庄河市| 云霄县| 西藏| 江都市| 高唐县| 文山县|