1. 程式人生 > >實現Action(二)——Action介面和ActionSupport基類

實現Action(二)——Action介面和ActionSupport基類

本文摘自:李剛 著 《輕量級 Java EE企業應用實戰 Struts2+Spring+hibernate整合開發》

續 實現Action(一)

        為了讓使用者開發的Action類更加規範,Struts2提供了一個Action介面,這個介面定義了Struts2的Action處理類應該實現的規範。下面是標準Action介面的程式碼:

package ppp;

public interface Action {

	//定義Action接口裡包含的一些結果字串
	public static final String ERROR = "error";
	public static final String INPUT = "input";
	public static final String LOGIN = "login";
	public static final String NONE = "none";
	public static final String SUCCESS = "success";
	
	//定義處理使用者請求的execute()方法
	public String execute() throws Exception;
}


        上面的Action接口裡只定義了一個execute()方法,該介面規範規定了Action類應該包含一個execute()方法,該方法返回一個字串,此外,該介面還定義了5個字串常量,他的作用是統一execute()方法的返回值。

        例如,當Action類處理使用者處理成功後,有人喜歡返回welcome字串,有人喜歡返回success字串,如此不利於專案的統一管理,Struts2的Action介面定義加上了如上的5個字串常量:ERROR,NONE,INPUT,LOGIN,SUCCESS等,分別代表了特定的含義。當然,如果開發者依然希望使用特定的字串作為邏輯檢視名,開發者依然可以返回自己的檢視名。

        另外,Struts2還為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.Collection;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;

/**
* Provides a default implementation for the most common actions.
* See the documentation for all the interfaces this class implements for more detailed information.
*/
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();
}
//控制locale的相關資訊
public Locale getLocale() {
ActionContext ctx = ActionContext.getContext();
if (ctx != null) {
return ctx.getLocale();
} else {
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<Object> 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<Object> 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<Object> 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);
}
//用於訪問國際化資源包的方法
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;
}
public String doDefault() throws Exception {
return SUCCESS;
}
/**
* A default implementation that does nothing an returns "success".
* <p/>
* Subclasses should override this method to provide their business logic.
* <p/>
* See also {@link com.opensymphony.xwork2.Action#execute()}.
*
* @return returns {@link #SUCCESS}
* @throws Exception can be thrown by subclasses.
*/
//預設處理使用者請求的方法,直接返回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();
}
/**
* Clears field errors. Useful for Continuations and other situations
* where you might want to clear parts of the state on the same action.
*/
public void clearFieldErrors() {
validationAware.clearFieldErrors();
}
/**
* Clears action errors. Useful for Continuations and other situations
* where you might want to clear parts of the state on the same action.
*/
public void clearActionErrors() {
validationAware.clearActionErrors();
}
/**
* Clears messages. Useful for Continuations and other situations
* where you might want to clear parts of the state on the same action.
*/
public void clearMessages() {
validationAware.clearMessages();
}
/**
* Clears all errors. Useful for Continuations and other situations
* where you might want to clear parts of the state on the same action.
*/
public void clearErrors() {
validationAware.clearErrors();
}
/**
* Clears all errors and messages. Useful for Continuations and other situations
* where you might want to clear parts of the state on the same action.
*/
//清理錯誤資訊的方法
public void clearErrorsAndMessages() {
validationAware.clearErrorsAndMessages();
}
/**
* A default implementation that validates nothing.
* Subclasses should override this method to provide validations.
*/
//包含空校驗的方法
public void validate() {
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
/**
* <!-- START SNIPPET: pause-method -->
* Stops the action invocation immediately (by throwing a PauseException) and causes the action invocation to return
* the specified result, such as {@link #SUCCESS}, {@link #INPUT}, etc.
* <p/>
* <p/>
* The next time this action is invoked (and using the same continuation ID), the method will resume immediately
* after where this method was called, with the entire call stack in the execute method restored.
* <p/>
* <p/>
* Note: this method can <b>only</b> be called within the {@link #execute()} method.
* <!-- END SNIPPET: pause-method -->
*
* @param result the result to return - the same type of return value in the {@link #execute()} method.
*/
public void pause(String result) {
}
/**
* If called first time it will create {@link com.opensymphony.xwork2.TextProviderFactory},
* inject dependency (if {@link com.opensymphony.xwork2.inject.Container} is accesible) into in,
* then will create new {@link com.opensymphony.xwork2.TextProvider} and store it in a field
* for future references and at the returns reference to that field
*
* @return reference to field with TextProvider
*/
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是一個預設的Action實現類,該類裡已經提供了許多預設方法,這些方法包括獲取國際化資訊的方法、資料校驗的方法、預設的處理使用者請求的方法等,實際上,ActionSupport是Struts2的預設的Action處理類,如果讓開發者的Action類繼承該ActionSupport類,則會大大簡化Action的開發。