一,基本说明
Action对象主要 对HTTP请求进行处理,在Struts2 API中Action对象是一个接口。
Action对象的方法声明:
public interface Action{
public static final SUCCES=“success”;
public static final NONE=“none”;
public static final ERROR=“error”;
public static final INPUT=“input”;
public static final LOGIN=“login”;
public String execute() throw Eexception;
}
包含了5个静态的成员变量,是Struts2 API为处理结果定义的静态变量:
SUCCESS:代表Action执行成功的返回值,例如在Action执行成功的情况下,需要返回到成功界面,这时可以将返回值设置为SUCCESS
NONE:代表Action执行成功的返回值,在Action执行成功的情况下,不需要返回到成功界面。主要用于处理不需要返回结果页面的业务逻辑
ERROR:代表Action执行失败的返回值
INPUT:代表需要返回到某个输入信息的页面的返回值。例如在修改某些信息时,在叫数据后需要返回到修改页面,这时将Action对象的处理结果的返回值设为INPUT
LOGIN:代表用户登录的返回值。在验证是否登录,验证失败,需要重新登录,这时将Action对象的处理结果的返回值设为LOGIN
二,请求参数的注入原理
在Struts2的框架中,表单提交的数据会自动注入到与Action对象对应的属性,通过Action对象为属性提供的setter方法进行注入,gettter方法进行获取(内部实现是按照JavaBean规范提供的setter和getter方法)
三,Action的基本流程
- 当浏览器向Web容器发送一个HTTP请求,Web容器调用Struts2的过滤器的doFilter()方法
- Struts2接受到HTTP请求,通过内部处理机制,判断这个HTTP请求是否与某个Action对象相匹配。
- 找到了Action,会调用Action的execute()方法,并根据处理的结果返回相应的值。
- Struts2通过Action返回的值查找返回值映射的页面,通过一定的视图回应给浏览器
具体操作方式:是通过在请求Action的URL地址后方加上请求字符串(方法名称),与Action对象中的方法匹配。(Action地址与请求字符串之间以!号分割开)
五,Action相关配置
Struts2框架中的Action对象,是一个控制器的角色。Struts2框架通过Action对象处理HTTP请求,其请求的地址映射需要配置在struts.xml文件中,配置方式采用<action>元素进行配置
<action>包含的属性:
- name:用于配置Action对象被请求的映射(必须要配置的,在建立Action对象的映射时,必须指定它的URL映射地址,否则,请求找不到Action对象)
- class:指定Action对象的类名
- method:设置请求Action对象时,调用Action对象的哪一个方法(调用一个Action对象时,默认情况下,执行的execute()方法,需要调用指定的方法,可以用method属性进行配置)
- converter:指定Action对象类型转化器的类
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 #getActionErrors()}.
*/
@Deprecated
public Collection<String> getErrorMessages() {
return getActionErrors();
}
/**
* @deprecated Use #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();
}
public Locale getLocale() { //控制locale相关信息
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);
}
public String input() throws Exception { //默认Input方法,直接访问input字符串
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 com.opensymphony.xwork2.Action#execute()}.
*
* @return returns #SUCCESS}
* @throws Exception can be thrown by subclasses.
*/
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 #SUCCESS}, #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 #execute()} method.
* <!-- END SNIPPET: pause-method -->
*
* @param result the result to return - the same type of return value in the #execute()} method.
*/
public void pause(String result) {
}
/**
* If called first time it will create com.opensymphony.xwork2.TextProviderFactory},
* inject dependency (if com.opensymphony.xwork2.inject.Container} is accesible) into in,
* then will create new 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;
}
}
<action name="test">
<result>...</result>
</action>
<action name="test" class=“com.opensymphony.xwork2.ActionSupport” method="execute">
<result>...</result>
</action>