package limitstudy.corestruts2.tag;
import org.apache.struts2.components.UIBean;
import org.apache.struts2.views.annotations.StrutsTag;
import org.apache.struts2.views.annotations.StrutsTagAttribute;
import com.opensymphony.xwork2.util.ValueStack;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@StrutsTag(name="mm", tldTagClass="limitstudy.corestruts2.tag.MMTag", description="MM")
public class MM extends UIBean {
private String message;
public MM(ValueStack stack, HttpServletRequest request, HttpServletResponse response) {
super(stack, request, response);
}
@Override
protected String getDefaultTemplate() {
return "mm";
}
@StrutsTagAttribute(description="set message", type="String")
public void setMessage(String message) {
this.message = message;
}
@Override
protected void evaluateExtraParams() {
super.evaluateExtraParams();
if (null != message) {
addParameter("message", findString(message));
}
}
}
* strutsTag注解指明了該UIBean的名字 和Tag類的類名。
* getDefaultTemplate()方法用于返回模板的名 字,Struts2會自動在后面加入.ftl擴展名以找到特定的模板文件。
* setXXX,設置UIBean的屬性,一般Tag中有幾個這樣的屬性,這里就有幾個。@StrutsTagAttribute(description="set message", type="String") 注解,說明該屬性是字符串(也可以是其它),這一步很重要。
* 覆寫evaluateExtraParams() 方法,在UIBean初始化后會調用這個方法來初始化設定參數,如addParameter方法,會在freemarker里的parameters里加 入一個key value。這里要注意findString,還有相關的findxxxx方法,它們是已經封裝好了的解釋ognl語法的工具,具體是怎么樣的,大家可以 查看一下UIBean的api doc。
然后是Tag部份:
package limitstudy.corestruts2.tag;
import org.apache.struts2.views.jsp.ui.AbstractUITag;
import org.apache.struts2.components.Component;
import com.opensymphony.xwork2.util.ValueStack;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MMTag extends AbstractUITag {
private String message;
@Override
public Component getBean(ValueStack stack, HttpServletRequest request, HttpServletResponse response) {
return new MM(stack, request, response);
}
@Override
protected void populateParams() {
super.populateParams();
MM mm = (MM)component;
mm.setMessage(message);
}
public void setMessage(String message) {
this.message = message;
}
}
* getBean()返回該Tag中的UIBean。
* populateParams()初始化參數,一般用來初始化UIBean(Component)。
* setXXXX設置屬性,和jsp tag是一樣的。
在/WEB-INF/tlds/下建立current.tld文件(文名隨你喜歡):
<?xml version="1.0" encoding="UTF-8"?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd">
<description>test</description>
<tlib-version>2.0</tlib-version>
<short-name>cur</short-name>
<uri>/cur</uri>
<tag>
<name>mm</name>
<tag-class>limitstudy.corestruts2.tag.MMTag</tag-class>
<body-content>JSP</body-content>
<attribute>
<name>message</name>
<required>true</required>
</attribute>
</tag>
</taglib>
在源代碼目錄中建立template/simple目錄(這個目錄名和你的theme有關),然后在里面建一個 mm.ftl文件:
<a href="http://www.yinsha.com">${parameters.message?html}</a>
建一個action測試一下,視圖文件:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ taglib prefix="cur" uri="/cur" %>
<html>
<head>
<title><s:property value="message" /></title>
</head>
<body>
<cur:mm message="haoahahhahaha" />
</body>
</html>
完。
PS: 寫得有些粗鄙,所以,如有問題的,可以留言。
http://devilkirin.javaeye.com/blog/427395
http://xiaojianhx.javaeye.com/blog/482888<s:autocompleter></s:autocompleter>-----自動完成<s:combobox>標簽的內容,這個是ajax
B:
<s:bean name=""></s:bean>-----類似于struts1.x中的,JavaBean的值
C:
<s:checkbox></s:checkbox>-----復選框
<s:checkboxlist list=""></s:checkboxlist>-----多選框
<s:combobox list=""></s:combobox>-----下拉框
<s:component></s:component>-----圖像符號
D:
<s:date name="time" format="yyyy/MM/dd"/>-----獲取日期格式
<s:datetimepicker></s:datetimepicker>-----日期輸入框
<s:debug></s:debug>-----顯示錯誤信息
<s:div></s:div>-----表示一個塊,類似于html的<div></div>
<s:doubleselect list="#appVar3" listKey="id" listValue="name" name="" doubleName="chinagra.chinagraCategory.id" -----雙下拉框
doubleId="mid" doubleList="#appVar4.get(top.id)" doubleListKey="id" doubleListValue="title" theme="simple"/>
List<Category> categories = chinagraService.searchProblemCategories();;
Map<Long, List<ChinagraCategory>> chinagraCategories = new HashMap<Long, List<ChinagraCategory>>();
for(Category category : categories) {
chinagraCategories.put(category.getId(), chinagraCategoryService.queryByType(category.getId().toString()));
}
E:
<s:if test=""></s:if>
<s:elseif test=""></s:elseif>
<s:else></s:else>-----這3個標簽一起使用,表示條件判斷
F:
<s:fielderror></s:fielderror>-----顯示文件錯誤信息
<s:file></s:file>-----文件上傳
<s:form action=""></s:form>-----獲取相應form的值
G:
<s:generator separator="'aaa,bbb,ccc,ddd'" val=",">
<s:iterator>
<s:property/>
</s:iterator>
</s:generator>----和<s:iterator>標簽一起使用
H:
<s:head/>-----在<head></head>里使用,表示頭文件結束
<s:hidden name="user.name" value="junly"/></s:hidden>-----隱藏值
I:
<s:i18n name=""></s:i18n>-----加載資源包到值堆棧
<s:include value=""></s:include>-----包含一個輸出,servlet或jsp頁面
<s:inputtransferselect list=""></s:inputtransferselect>-----獲取form的一個輸入
<s:iterator value="userlist" var="user" status="s">
<s:if test="#s.index == 0">
<s:property value="name"/>
</s:if>
<s:property value="#s.even"/>
<s:property value="#s.odd"/>
<s:property value="#s.first"/>
<s:property value="#s.last"/>
<s:property value="#s.count"/>
</s:iterator>-----用于遍歷集合
<s:if test="#list.size > 0 "></s:if>-----判斷 ActionContext.getContext().put("list", lists);
<s:elseif test="list.size > 0 "></s:elseif>
<s:else></s:else>
<s:if test="searchCondition.filter!=null">
L:
<s:label></s:label>-----只讀的標簽
M:
<s:merge></s:merge>-----合并遍歷集合出來的值
O:
<s:optgroup></s:optgroup>-----獲取標簽組
<s:optiontransferselect doubleList="" list="" doubleName=""></s:optiontransferselect>-----左右選擇框
P:
<s:param name="pageSize" value="pageSize"/></s:param>-----為其他標簽提供參數
<s:password></s:password>-----密碼輸入框
<s:property value="user.name" />-----得到'value'的屬性
<s:push value=""></s:push>-----value的值push到棧中,從而使property標簽的能夠獲取value的屬性
R:
<s:radio name="type" list="#{0:'拍賣會',1:'展會'}" value="0"></s:radio>-----單選按鈕
<s:reset></s:reset>-----重置按鈕
S:
<s:select list=""></s:select>-----單選框
<s:set name=""></s:set>-----賦予變量一個特定范圍內的值
<s:sort comparator=""></s:sort>-----通過屬性給list分類
<s:submit></s:submit>-----提交按鈕
<s:subset source="#subList" start="1" count="2">-----為遍歷集合輸出子集
<s:iterator>
<s:property/>
</s:iterator>
</s:subset>
T:
<s:tabbedPanel id=""></s:tabbedPanel>-----表格框
<s:table></s:table>-----表格
<s:text name="error"/></s:text>-----I18n文本信息
<s:textarea></s:textarea>-----文本域輸入框
<s:textfield></s:textfield>-----文本輸入框
<s:token></s:token>-----攔截器
<s:tree></s:tree>-----樹
<s:treenode label=""></s:treenode>-----樹的結構
U:
<s:updownselect list=""></s:updownselect>-----多選擇框
<s:url value="/academy/get-detail.action?academyInfo.id=${id}"></s:url>-----創建url
<s:url action="search-big.action" escapeAmp="false" namespace="/problem">
<s:param name="name" value="%{'all'}"/>
<s:param name="id" value="0"/>
<s:param name="sex" value="user.sex"/>
</s:url>
JSTL語法及參數
JSTL包含以下的標簽:
常用的標簽:如<c:out>、<c:remove>、<c:catch>、<c:set>等
條件標簽:如<c:if><c:when>、<c:choose>、<c:otherwise>等
URL標簽:如<c:import>、<c:redirect>和<c:url>等
XML標簽:如<xml:out>等
國際化輸出標簽:如<fmt:timeZone>等
SQL標簽:如<sql:query>、<sql:update>、<sql:transaction>等
一般用途的標簽:
1.<c:out>
沒有Body時的語法
<c:out value=”value” [escapeXml=”{true|false}”] [default=”defaultValue”]/>
有Body時的語法
<c:out value=”value” [escapeXml=”{true|false}”]>
這里是Body部分
</c:out>
名字 類型 描述
value Object 將要輸出的表達式
escapeXml boolean 確定以下字符:<,>,&,’,”在字符串中是否被除數,默認為true
default Object 如果vaule計算后的結果是null,那么輸出這個默認值
2.<c:set>
這個標簽用于在某個范圍(page、request、session、application等)中使用某個名字設定特定的值,或者設定某個已經存在的javabean對象的屬性。他類似于<%request.setAttrbute(“name”,”value”);%>
語法1:使用value屬性設定一個特定范圍中的屬性。
<c:set value=”value” var=”varName” [scope=”{page|request|session|application}”]/>
語法2:使用value屬性設定一個特定范圍中的屬性,并帶有一個Body。
<c:set var=”varName” [scope=”{page|request|session|application}”]>
Body部分
</c:set>
語法3:設置某個特定對象的一個屬性。
<c:set value=”value” target=”target” property=”propertyName”/>
語法4:設置某個特定對象的一個屬性,并帶有一個Body。
<c:set target=”target” property=”propertyName”>
Body部分
</c:set>
名字 類型 描述
value Object 將要計算的表到式。
var String 用于表示value 值的屬性,如果要在其他標簽中使用,就是通過這 個var指定的值來進行的。它相當于在標簽定義了一個變量,并且這個變量只能在標簽中的一個。
scope String var的有效范圍,可以是page|request|session|application中的一個
target String 將要設置屬性的對象,它必須是javabean或則java.util.Map對象
property Object 待設定的Target對象中的屬性名字,比如在javabean中有個name屬性,提供了setUserId方法,那么這里填userId。
3.<c:remove>
<c:remove var=”varName” [scope=”{page|request|session|application}”]/>
4.<c:catch>
這個標簽相當于捕獲在它里邊的標簽拋出的異常對象
<c:catch [var=”varName”]> //var是異常的名字
內容
</c:catch>
條件標簽
1. <c:if>
語法1:無Body情況
<c:if test=”testCondition” var=”varName” [scope=”page|request|session|application”]/>
語法2:有Body的情況
<c:if test=”testCondition” var=”varName” [scope=”page|request|session|application”]>
Body內容
</c:if>
名字 類型 描述
test Boolean 表達式的條件,相當于if()中的條件判斷語句。
var String 表示這個語句的名字。
scope String var這個變量的作用范圍。
2.<c:choose>
語法:<c:choose>
Body內容(<c:when>和<c:otherwise>子標簽)
</c:choose>
注意:它的Body只能由以下元素組成:
1) 空格
2) 0或多個<c:when>子標簽,<c:when>必須在<c:otherwise>標簽之前出現.
3) 0個或多個<c:otherwise>子標簽。
<c:choose>
<c:when test="${param.age>70}">
歡迎老年人
</c:when>
<c:when test="${param.age<70 and param.age>35}">
歡迎中年人
</c:when>
<c:otherwise>
您的年齡有誤!
</c:otherwise>
</c:choose>
3.<c:when>
代表的是<c:choose>的一個條件分支,只能在<c:choose>中使用
語法:<c:when test=”testCondition”> //test是boolean類型,用于判斷條件真假
Body語句
</c:when>
4.<c:otherwise>
代表的是<c:choose>中的最后選擇。必須在最后出現
<c:otherwise>
內容
</c:otherwise>
迭代標簽
1.<c:forEach>
語法1:在Collection中迭代
<c:forEach[var=”varName”] items=”collection” [varStatus=”varStatusName”]
[begin=”begin”] [end=”end”] [step=”step”]
Body內容
</c:foeEach>
語法2:迭代固定的次數.
<c:forEach [var=”varName”] [varStatus=”varStatusName”]
[begin=”begin”] [end=”end”] [step=”step”]
Body內容
</c:foeEach>
名字 類型 描述
var String 迭代的參數,它是標簽參數,在其他標簽中通過它來引用這個標簽中的內容。
Items Collection、ArrayList、 要迭代的items集合.
Iterator、Map、String、
Eunmeration等
VarStatus String 表示迭代的狀態,可以訪問迭代自身的信息
Begin int 表示開始迭代的位置。
End int 表示結束迭代的位置。
Step int 表示迭代移動的步長,默認為1。
URL相關的標簽
1.<c:import>
語法1:資源的內容使用String對象向外暴露
<c:import url=”url” [context=”context”]
[var=”varName”] [scope=”{page|request|session|application}”] [charEncoding=”charEncoding”]>
內容
</c:import>
語法2:資源的內容使用Reader對象向外暴露。
<c:import url=”url” [context=”context”]
varReader=”varReaderName” [charEncoding=”charEncoding”]>
內容
</c:import>
名字 類型 描述
url String 待導入資源的URL,可以是相對路徑和絕對路徑,并且可以導入其他主機資源
context String 當使用相對路徑訪問外部context資源時,context指定了這個資源的名字。
var String 參數的名字。
scope String var參數的作用范圍。
cahrEncoding String 輸入資源的字符編碼。
varReader String 這個參數的類型是Reader,用于讀取資源。
2.<c:redirct>
語法1:沒有Body的情況.
<c:redirect url=”value” [context=”context”]/>
語法2:有Body情況下,在Body中指定查詢的參數
<c:redirect url=”value” [context=”context”]>
<c:param name=”name” value=”value”/>
</c:redirect>
3.<c:url>
語法1:沒有Body
<c:url value=”value” [context=”context”] [var=”varName”] [scope=”{page|request|session+application}”]/>
語法2:有Body
<c:url value=”value” [context=”context”] [var=”varName”] [scope=”{page|request|session+application}”]>
<c:param name=”name” value=”value”/>
</c:url>
名字 類型 描述
value String URL值
context String 當使用相對路徑訪問外部context資源時,context指定了這個資源的名字
var String 標識這個URL標量。
Scope String 變量作用范圍。
SQL相關的標簽
1.<sql:setDataSource>
2.<sql:query>
3.<sql:update>
4.<transaction>
5.<param>
public class SystemException extends RuntimeException{
//自定義key
private String key;
//自定義參數
private Object[] values;
//實現父類的構造方法
public SystemException() {
super();
}
public SystemException(String message, Throwable cause) {
super(message, cause);
}
public SystemException(String message) {
super(message);
}
public SystemException(Throwable cause) {
super(cause);
}
//自定義構造方法
public SystemException(String message, String key) {
super(message);
this.key=key;
}
//自定義構造方法,帶一個參數
public SystemException(String message, String key,Object value) {
super(message);
this.key=key;
this.values=new Object[]{value};
}
//自定義構造方法,帶多個參數
public SystemException(String message, String key,Object[] values) {
super(message);
this.key=key;
this.values=values;
}
//相應的get方法
public String getKey() {
return key;
}
public Object[] getValues() {
return values;
}
}
2 自定義異常處理器 SystemExceptionHandler.java
//作用:截獲SystemException,并根據SystemException中的信息動態創建ActionMessage等這些錯誤信息,
將其存在request中
public class SystemExceptionHandler extends ExceptionHandler{
/**
* 處理SystemException異常
*/
@Override
public ActionForward execute(Exception ex,//拋出的異常
ExceptionConfig config,//struts-config.xml中的配置信息
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) throws ServletException {
ActionForward forward=null;
//創建ActionForward
if(config.getPath()!=null){
//有path屬性,則根據path創建
forward=new ActionForward(config.getPath());
}else {
//沒有path屬性,則根據input屬性創建
forward=mapping.getInputForward();
}
if(ex instanceof SystemException){
SystemException se=(SystemException)ex;
//key可有可無,所以取出key進行判斷
String key=se.getKey();
ActionMessage error=null;
//如果自定義的key為空,用struts的
if(key==null){
//拿出error.default和message,創建ActionMessage對象
error=new ActionMessage(config.getKey(),se.getMessage());
}else {
//如果自定義的key有值
if(se.getValues()!=null){
error=new ActionMessage(key,se.getValues());
}else {
//如果自定義的key有值,則根據key創建ActionMessage對象
error=new ActionMessage(key);
}
}
//將這個ActionMessage放到request中。key為自定義的,error為ActionMessage對象
//forward是要轉到什么地方,根據path屬性創建。"request"為scope的一個,也可以
//用config.getScope()
this.storeException(request, key, error, forward, config.getScope());
return forward;
}
return super.execute(ex, config, mapping, form, request, response);
}
}
3 編寫配置文件 struts-config.xml
<global-exceptions>
<exception key="error.default"
type="java.lang.Exception"
scope="request"
path="/common/exception.jsp"
<!-- 自定義的異常處理類 -->
handler="org.oa.common.SystemExceptionHandler"/>
</global-exceptions>
4 編寫資源文件 ApplicationResources.properties
error.default={0}
error.org.del=Can't Del Orgnation,id is {0}!
5 業務代碼
throw new org.oa.common.SystemException("存在子機構,不允許刪除!","error.org.del",org.getOname());
<logic:empty name="attr2">
21<br>
</logic:empty>
<logic:notEmpty name="attr2">
22<br>
</logic:notEmpty>
<logic:present name="attr2">
23<br>
</logic:present>
<logic:notPresent name="attr2">
24<br>
</logic:notPresent>
<logic:empty name="attr3">
31<br>
</logic:empty>
<logic:notEmpty name="attr3">
32<br>
</logic:notEmpty>
<logic:present name="attr3">
33<br>
</logic:present>
<logic:notPresent name="attr3">
34<br>
</logic:notPresent>
結果:
11空
14不存在
21空
23存在
31空
33存在
-----------------------------------------||
html:equal/html:notEqual
html:greaterEqual大于等于
html:greaterThan大于
html:lessEqual小于等于
html:lessThan小于
-----------------------------------------||
logic:iterate(循環)
name:對應的bean,是一個集合類型
property:對應的集合類型的屬性
scope:變量的scope
id:臨時變量名
offset:循環起始位置
indexId:集合中當前無素的下標
length:控制長度
單循環
<logic:iterate id="username" scope="request" name="對應的bean,是一個集合類型">
output every username:${username }<br>
</logic:iterate>
雙循環
<logic:iterate id="user" scope="request" name="list" offset="2" indexId="i">
${user.username }<br>
<logic:iterate id="love" name="user" property="loves">
${love }
</logic:iterate><br>
</logic:iterate><br>
logic:
tiles標記
----------------------------------------------------------------
html標簽
<html:form action="/login" method="post">
username:<html:text property="username" value="123"/>
password:<html:password property="password"/>
sex:<html:radio property="sex" value="0" />男
<html:radio property="sex" value="1" />女
likes:<html:checkbox property="0" value="0">吃飯</html:checkbox>
<html:checkbox property="0" value="1">吃飯</html:checkbox>
xueli:<html:select property="xueli">
<html:option value="0">小學</html:option>
<html:option value="1">小學</html:option>
<html:optionsCollection property="qxlist" label="qx" value="qxid"/>
//<html:optionsCollection name="qxlist" label="qx" value="qxid"/>
1.
</html:select>
<html:submit value="提交"/>
</html:form>
// Build the forward from the exception mapping if it exists
// or from the form input
if (ae.getPath() != null) {
forward = new ActionForward(ae.getPath());
} else {
forward = mapping.getInputForward();
}
// Figure out the error
if (ex instanceof ModuleException) {
error = ((ModuleException) ex).getActionMessage();
property = ((ModuleException) ex).getProperty();
} else {
//改修這個地方
//----------------------------------------------
ErrorCodeException ece=(ErrorCodeException)ex;
String errorCode=ece.getErrorCode();
Object[] args=ece.getArgs();
error = new ActionMessage(errorCode, args);
property = error.getKey();
//------------------------------------------------
//error = new ActionMessage(ae.getKey(), ex.getMessage());
//property = error.getKey();
}
this.logException(ex);
// Store the exception
request.setAttribute(Globals.EXCEPTION_KEY, ex);
this.storeException(request, property, error, forward, ae.getScope());
if (!response.isCommitted()) {
return forward;
}
return null;
}
}
5 頁面直接拋出異常
public void login(String username,String password){
if(!"admin".equals(username)){
throw new ErrorCodeException("user.not.found",username,age);
}
}
---------------------------------------------------------------------
二 方法:
1 定義MessageResources.propertices資源文件
內容:error.exception={0}
2 在struts-config中配置<exception/>
<exception key="error.exception" type="com.bjsxt.struts.ErrorCodeException"/>
3 編寫異常類ErrorCodeException繼承RuntimeException
public class ErrorCodeException extends RuntimeException {
public ErrorCodeException(String msg){
super(msg);
}
}
4 頁面直接拋出異常
public void login(String username,String password){
if(!"admin".equals(username)){
throw new ErrorCodeException("名稱"+usrname+"錯誤!");
}
}
--------------------------------------------------------------------------
1 ApplicationResources.properties文件
num2Meg=is not a double
2 struts-config.xml
<message-resources parameter="ApplicationResources" />
3 ActionMessages errs=new ActionMessages();
errs.add("num1Error",new ActionMessage("num2Meg"));
//errs.add(ActionMessages.GLOBAL_MESSAGE,new ActionMessage("num2Meg"));
this.saveErrors(request,errs);
頁面
<html:errors property="num1Error"/>
//<html:errors/>//全局不能指定property
errs.header="<script>alert("
errs.footer=")</script>"
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
try {
d=sdf.parse(value.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
return d;
}
}
2 利用servlet的init()方法注冊轉換器到ConvertUtils(com.sun.org.apache.commons.beanutils.ConvertUtils)
public class UtilDateConverterInitServlet extends HttpServlet {
public void init() throws ServletException {
System.out.println("UtilDateConverterInitServlet.init()");
ConvertUtils.register(new UtilDateConverter(),Date.class);
}
}
3 配置servlet,并設</load-on-startup>值
<servlet>
<servlet-name>UtilDateConverterInitServlet</servlet-name>
<servlet-class>com.bjsxt.servlet.UtilDateConverterInitServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>UtilDateConverterInitServlet</servlet-name>
<url-pattern>/servlet/UtilDateConverterInitServlet</url-pattern>
</servlet-mapping>
------------------------------------------------------------------------
方法二:
1 編寫UtilDateConverter轉換器類,
實現Converter接口的convert方法(com.sun.org.apache.commons.beanutils.Converter)
(同上)
2 編寫UtilDateConverterInitWithPlugIn類實現PlugIn接口的init()方法
public class UtilDateConverterInitWithPlugIn implements PlugIn {
public void destroy() {
}
public void init(ActionServlet arg0, ModuleConfig arg1)
throws ServletException {
System.out.println("UtilDateConverterInitServlet.init()");
ConvertUtils.register(new UtilDateConverter(),Date.class);
}
}
3 在struts-config.xml文件中配置<plug-in>標簽
<plug-in className="com.bjsxt.servlet.UtilDateConverterInitWithPlugIn"/>
屬性名及類型一致才可以拷貝
可以通過BeanUtils.copyProperties(userbean目標對象,form源對象)方法進行對象的復制
1 讀敢配置 (初始化ModuleConfig對象)
Struts框架總控制器(ActionServlet)是一個Servlet,在web.xml中配置成自動啟動的Servlet。
讀取配置文件(struts-config.xml)的配置信息,為不同的Struts模塊初始化相應的ModuleConfig
對名:ActionConfig,
ControlConfig,
FormBeanConfig,
MessageResourcesConfig
2 發送請求
請求上傳WEB服務器(處理.do的請求)
3 填充FORM(實例化,復位,填充數據,校驗,保存)
(*.do請求)從ActionConfig中找出對應該請求的Action子類,如沒有對應的Action,控制器直接轉發給
JSP或靜態頁面。如有對應的Action且這個Action有一個相應的ActionForm.
ActionForm被實例化并用http請求的數據填充其屬性,并且保存在ServletContext中(request或session中),
這樣它們就可以被其它Action對象或者JSP調用。
4 派發請求
控制器根據配置信息ActionConfig將請求派發到具體的Action,相應的FormBean一并傳給這個Action的execute()方法.
5 處理業務
Action一般只包含一個execute方法,它負責執行相應的業務邏輯(調用其它業務模塊).完畢返回一個ActionForward對象,
控制器通過該ActionForward對象來進行轉發工作
6 返回響應
Action根據業務處理的不同結果返回一個目標響應對象給總控制器,該目標響應對象對應一個具體的JSP頁面或另一Action.
7 查找響應(可以是一個Action)
8 響應用戶
-----------------------------------------------------------------------------------------------------------
組件
ActionSerlet,Action Classes,Action Mapping(此處包括ActionForward),ActionForm Bean.
Struts中的MVC:
1 模型(Model):本質上來說在Struts中Model是一個商業邏輯類,開發者實現商業邏輯。
2 視圖(View):View是由與控制器Servlet配合工作的一整套JSP定制標簽庫構成,利用他們可以快速建立應用系統的界面。
3 控制器(Controller),前端控制器是一個Servlet,它將客戶端請求轉發到相應的后端控制器Action類。
注意:官方認為ActionForm Bean應為控制層(Controller)組件,自已寫的JavaBeans為模型(Model)
-----------------------------------------------------------------------------------
ActionServlet(中心控制器)
定義:繼承自javax.servlet.http.HttpServlet類,是中心控制器(總控制器)。它提供一個中心位置來處理全部的終端請求。
作用:接受請求,填充數據,派發請求,響應用戶。
配置:在web.xml文件聲明。
例子:
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
注意:struts-config.xml文件系統默主調用,可以不<init-param>配置
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
-------------------------------------------------------------------
Action
發出該action請求時初始化,不是在讀取配置時,并且只初始化一次。
Action是線程不安全的,因為所有的請求共享一個別action實例。
所以:不要用實例變量或者類變是共享只是針對某個請求的數據
注意資源操作的同步性。
應用:
統計一個action訪問次數
public class CountAction extends Action {
private Integer count=0;
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
synchronized(count){//加鎖
count++;
}
PrintWriter out=response.getWriter();
out.print("count="+count);
return null;
}
}
----------------------------------------------------
ActionMapping
是對struts-config.xml中action標簽中所有屬性的封裝類。
mapping.getName()(String)
mapping.getPath()(String)
mapping.getType()(String)
String[] forwardNames=mapping.findForwards();
for(String forward:forwardNames){
ActionForward forward=mapping.findForward(forward);
String forwardPath=forward.getPath();
}
相應的set方法不能使用。
-----------------------------------------------------
ActionForward(導航器)
ActionForward對象是配置對象。這些配置對象擁有獨一無二的標識以允許他們按照name屬性來檢索。
name:邏輯名稱
path:頁面或者模塊訪問路徑。
redirect:默認為false.設為true時為容器外跳轉,相當于response.sendRedirect();
在xml文件中的path中要寫絕對路徑。
--------------------------------------------------------------
ActionForm工作原理
步驟:
(1)檢查Action的映射,確定Action中已經配置了對ActionForm的映射
(2)根據name屬性,查找form bean中的配置信息
(3)檢查Action的form bean的使用范圍,確定在此范圍下(request,session),是否已經有些form bean的實例。
(4)假如當前范圍下,已經存在了些form bean的實例,而是對當前請求來說,是同一種類型的話,就重用。
(5)否則,就重新構建一個form bean的實例(調用構造方法),并且保存在一定作用范圍。
(6)form bean的reset()方法被調用
在作數據收集前被調用,是一個重置的方法.
(7)調用對應的setter方法,對狀態屬性賦值
(8)如果validatede的屬性設置為true,就調用form bean的validate()方法。
該方法進行表單的服務器端驗證.
(9)如果validate()方法沒有返回任何錯誤,控制器將ActionForm作為參數,傳給Action實例的execute()方法并執行。
注意:直接從ActionFrom類繼承的reset()和validate()方法,并不能實現什么處理功能,所以重新覆蓋。
注意:
1 無參構造方法必須有
2 Scope缺省值是session
3 調用setter方法,實質上是對應的標準set方法
分析:
4 從過程去查看
HttpSessionAttributeListener
ServletRequestAttributeListener
5 從結果去查看
---------------------------------------------------
ActionForm
reset()方法,用于恢復屬性,在重新復值前由controller調用。
valldate()方法,用于校驗屬性,返回ActionErrors,如果成功返回null,默認返回null.
關閉校驗功能設置struts-config.xml中<action>標簽的validate屬性為false.
validate
----------------------------------------------------------
struts-config.xml文件中的action標簽
1 attribute屬性
用來存取form的關鍵字,缺省值與name一樣,如果設了必須用該屬性。
2 validate屬性(action中的屬性)
用來控制是否校驗表單,缺省為false,false不校驗。
3 input屬性
當表單校驗失敗時將請求轉發的URL(或目標模塊,可以為另一個別action),結合validate屬性使用,為相對路徑。
在ActionForm類的validate方法中手動添加錯誤
public ActionErrors validate(ActionMapping mapping,HttpServletRequest request){
ActionErrors errors=new ActionErrors();
ActionMessage message=new ActionMessage("error");//應為鍵值對
errors.add("error",message);
return errors;
}
---------------------------------------------------------------------------
struts-config.xml文件中的<global-forwards>全局跳轉標簽
<global-forwards>
<forward name="error" path="Error.jsp"/>
</global-forwards>
使用方式同action中的forwar標簽
癥狀: action中無法正常進行跳轉.
原因: 驗證值時驗證報錯.
解決辦法:
1) 給 Action 加入 input 的結果;
2) 去除所有證驗相關的攔截器,包括默認的validation
調試方法:在 input 中加入調試
<s:fielderror/>
<s:debug />
<a href="javascript:void(0);" onclick="toggleDebug('debug');return false;">[調試信息]</a>
可顯示下列信息:
Invalid field value for field "attachment".
fieldErrors {attachment=[Invalid field value for field "attachment".]}
3) Action 不再繼承自 ActionSupport(里面有 ValidationAware 接口), 而轉而只實現 Action 接口即可.