一、ActionSupport類
com.opensymphony.xwork2.ActionSupport類時默認的動作類。
只要某個動作聲明沒有給出一個動作類,Struts就會替它創建一個這個類的實例。
在編寫動作類時也需要對這個類進行擴展。
該類提供了許多默認方法。這些方法包括獲取國際化信息的方法、數據校驗的方法、默認的處理用戶請求的方法等。。
如果讓開發者的Action類繼承該ActionSupport類,就會大大簡化Action類的開發。
以下是ActionSupport類的源碼:
package com.opensymphony.xwork2;
import com.opensymphony.xwork2.inject.Container;
import com.opensymphony.xwork2.inject.Inject;
import com.opensymphony.xwork2.util.ValueStack;
import com.opensymphony.xwork2.util.logging.Logger;
import com.opensymphony.xwork2.util.logging.LoggerFactory;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
public class ActionSupport implements Action, Validateable, ValidationAware, TextProvider, LocaleProvider, Serializable {
protected static Logger LOG = LoggerFactory.getLogger(ActionSupport.class);
private final ValidationAwareSupport validationAware = new ValidationAwareSupport();
private transient TextProvider textProvider;
private Container container;
public void setActionErrors(Collection<String> errorMessages) {
validationAware.setActionErrors(errorMessages);
}
public Collection<String> getActionErrors() {
return validationAware.getActionErrors();
}
public void setActionMessages(Collection<String> messages) {
validationAware.setActionMessages(messages);
}
public Collection<String> getActionMessages() {
return validationAware.getActionMessages();
}
/**
* @deprecated Use {@link #getActionErrors()}.
*/
@Deprecated
public Collection<String> getErrorMessages() {
return getActionErrors();
}
/**
* @deprecated Use {@link #getFieldErrors()}.
*/
@Deprecated
public Map<String, List<String>> getErrors() {
return getFieldErrors();
}
/*設置表單域校驗錯誤信息*/
public void setFieldErrors(Map<String, List<String>> errorMap) {
validationAware.setFieldErrors(errorMap);
}
/*返回表單域錯誤校驗信息*/
public Map<String, List<String>> getFieldErrors() {
return validationAware.getFieldErrors();
}
/*控制local的想關信息*/
public Locale getLocale() {
ActionContext ctx = ActionContext.getContext();
if (ctx != null) {
return ctx.getLocale();
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("Action context not initialized");
}
return null;
}
}
public boolean hasKey(String key) {
return getTextProvider().hasKey(key);
}
public String getText(String aTextName) {
return getTextProvider().getText(aTextName);
}
/*返回國際化信息的方法*/
public String getText(String aTextName, String defaultValue) {
return getTextProvider().getText(aTextName, defaultValue);
}
public String getText(String aTextName, String defaultValue, String obj) {
return getTextProvider().getText(aTextName, defaultValue, obj);
}
public String getText(String aTextName, List<?> args) {
return getTextProvider().getText(aTextName, args);
}
public String getText(String key, String[] args) {
return getTextProvider().getText(key, args);
}
public String getText(String aTextName, String defaultValue, List<?> args) {
return getTextProvider().getText(aTextName, defaultValue, args);
}
public String getText(String key, String defaultValue, String[] args) {
return getTextProvider().getText(key, defaultValue, args);
}
public String getText(String key, String defaultValue, List<?> args, ValueStack stack) {
return getTextProvider().getText(key, defaultValue, args, stack);
}
public String getText(String key, String defaultValue, String[] args, ValueStack stack) {
return getTextProvider().getText(key, defaultValue, args, stack);
}
/**
* Dedicated method to support I10N and conversion errors
*
* @param key message which contains formatting string
* @param expr that should be formatted
* @return formatted expr with format specified by key
*/
public String getFormatted(String key, String expr) {
Map<String, Object> conversionErrors = ActionContext.getContext().getConversionErrors();
if (conversionErrors.containsKey(expr)) {
String[] vals = (String[]) conversionErrors.get(expr);
return vals[0];
} else {
final ValueStack valueStack = ActionContext.getContext().getValueStack();
final Object val = valueStack.findValue(expr);
return getText(key, Arrays.asList(val));
}
}
/*用於訪問國際化資源包的方法*/
public ResourceBundle getTexts() {
return getTextProvider().getTexts();
}
public ResourceBundle getTexts(String aBundleName) {
return getTextProvider().getTexts(aBundleName);
}
/*添加錯誤信息*/
public void addActionError(String anErrorMessage) {
validationAware.addActionError(anErrorMessage);
}
public void addActionMessage(String aMessage) {
validationAware.addActionMessage(aMessage);
}
/*添加校驗字段的錯誤信息*/
public void addFieldError(String fieldName, String errorMessage) {
validationAware.addFieldError(fieldName, errorMessage);
}
/*默認input方法,訪問INPUT字符串*/
public String input() throws Exception {
return INPUT;
}
/*默認處理用戶請求的execute方法,直接返回SUCCESS字符串*/
public String execute() throws Exception {
return SUCCESS;
}
public boolean hasActionErrors() {
return validationAware.hasActionErrors();
}
public boolean hasActionMessages() {
return validationAware.hasActionMessages();
}
public boolean hasErrors() {
return validationAware.hasErrors();
}
public boolean hasFieldErrors() {
return validationAware.hasFieldErrors();
}
public void clearFieldErrors() {
validationAware.clearFieldErrors();
}
public void clearActionErrors() {
validationAware.clearActionErrors();
}
public void clearMessages() {
validationAware.clearMessages();
}
public void clearErrors() {
validationAware.clearErrors();
}
/*清空錯誤信息的方法*/
public void clearErrorsAndMessages() {
validationAware.clearErrorsAndMessages();
}
/*空校驗方法*/
public void validate() {
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
public void pause(String result) {
}
private TextProvider getTextProvider() {
if (textProvider == null) {
TextProviderFactory tpf = new TextProviderFactory();
if (container != null) {
container.inject(tpf);
}
textProvider = tpf.createInstance(getClass(), this);
}
return textProvider;
}
@Inject
public void setContainer(Container container) {
this.container = container;
}
}
ActionSupport類中除execute方法以外,還有許多其它方法提供給程序員使用。
eg:
如果想用自己的代碼對用戶輸入進行驗證,你需要覆蓋validate方法;
如果想從屬性文件裏提取本地化的消息,可以選用getText方法的衆多重載形式中的一種。
二、Action接口
爲了讓用戶開發的Action類更加規範,Struts2提供了一個Action接口,這個接口定義了Struts2的Action處理類應該實現的規範。下面是標準Action接口的代碼:
package com.opensymphony.xwork2;
public interface Action {
public static final String SUCCESS = "success";
public static final String NONE = "none";
public static final String ERROR = "error";
public static final String INPUT = "input";
public static final String LOGIN = "login";
/*定義處理用戶請求的execute方法*/
public String execute() throws Exception;
}
該接口只定義了一個用於處理用戶請求的execute方法和5個靜態字段。execute方法必須返回一個字符串。5個靜態字段的作用是統一該方法的返回值;
補充:
如果想自己動手實現Action接口,而不是對ActionSupport類進行擴展,就必須自己提供一個execute方法的實現;
一般來說,對ActionSupport類進行擴展要比自行實現Action接口簡單的多。
也即,對ActionSupport類進行擴展有助於編寫動作類。