引言
Action是应用的核心,开发者需要提供大量的Action类并在struts.xml文件中配置Action。Action类包含了对用户请求的逻辑处理,Action类也被称为业务控制类。那么特使如何实现的呢?
首先先看代码
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class LoginAction extends ActionSupport {
private String userName;
private String pass;
public String getUsername(){
return userName;
}
public void setUser(String username) {
userName = username;
}
public String getPassword(){
return pass;
}
public void setPassword(String password){
this.pass=password;
}
public String execute() throws Exception {
if(getUsername().equals("aaa")&&getPassword().equals("aaa")){
return SUCCESS;
}else{
return ERROR;
}
}
}
该Action类中含有两个请求参数 userName和pass;并且为其提供了setter和getter方法。其中execute()方法就是处理用户请求的逻辑控制方法。
该类不仅可以封装请求参数还可以封装处理结果。
Action接口和ActionSupport基类
Action接口
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package com.opensymphony.xwork2;
public interface Action {
String SUCCESS = "success";
String NONE = "none";
String ERROR = "error";
String INPUT = "input";
String LOGIN = "login";
String execute() throws Exception;
}
该接口的规范规定了Action类应该包含一个execute方法,该方法返回一个字符串。并且该接口定义了五个字符串常量,他们的作用是统一execute方法的返回值。
ActionSupport基类
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package com.opensymphony.xwork2;
import com.opensymphony.xwork2.inject.Container;
import com.opensymphony.xwork2.inject.Inject;
import com.opensymphony.xwork2.interceptor.ValidationAware;
import com.opensymphony.xwork2.util.ValueStack;
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;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class ActionSupport implements Action, Validateable, ValidationAware, TextProvider, LocaleProvider, Serializable {
private static final Logger LOG = LogManager.getLogger(ActionSupport.class);
private final ValidationAwareSupport validationAware = new ValidationAwareSupport();
private transient TextProvider textProvider;
private transient LocaleProvider localeProvider;
protected Container container;
public ActionSupport() {
}
//收集错误提示信息
public void setActionErrors(Collection<String> errorMessages) {
this.validationAware.setActionErrors(errorMessages);
}
//返回错误提示信息
public Collection<String> getActionErrors() {
return this.validationAware.getActionErrors();
}
//收集普通提示信息的方法
public void setActionMessages(Collection<String> messages) {
this.validationAware.setActionMessages(messages);
}
//返回普通提示信息的方法
public Collection<String> getActionMessages() {
return this.validationAware.getActionMessages();
}
//设置表单域校验错误信息
public void setFieldErrors(Map<String, List<String>> errorMap) {
this.validationAware.setFieldErrors(errorMap);
}
//返回表单域校验错误信息
public Map<String, List<String>> getFieldErrors() {
return this.validationAware.getFieldErrors();
}
//控制Locale 的相关信息
public Locale getLocale() {
return this.getLocaleProvider().getLocale();
}
public boolean isValidLocaleString(String localeStr) {
return this.getLocaleProvider().isValidLocaleString(localeStr);
}
public boolean isValidLocale(Locale locale) {
return this.getLocaleProvider().isValidLocale(locale);
}
public boolean hasKey(String key) {
return this.getTextProvider().hasKey(key);
}
public String getText(String aTextName) {
return this.getTextProvider().getText(aTextName);
}
//返回国际化信息的方法
public String getText(String aTextName, String defaultValue) {
return this.getTextProvider().getText(aTextName, defaultValue);
}
public String getText(String aTextName, String defaultValue, String obj) {
return this.getTextProvider().getText(aTextName, defaultValue, obj);
}
public String getText(String aTextName, List<?> args) {
return this.getTextProvider().getText(aTextName, args);
}
public String getText(String key, String[] args) {
return this.getTextProvider().getText(key, args);
}
public String getText(String aTextName, String defaultValue, List<?> args) {
return this.getTextProvider().getText(aTextName, defaultValue, args);
}
public String getText(String key, String defaultValue, String[] args) {
return this.getTextProvider().getText(key, defaultValue, args);
}
public String getText(String key, String defaultValue, List<?> args, ValueStack stack) {
return this.getTextProvider().getText(key, defaultValue, args, stack);
}
public String getText(String key, String defaultValue, String[] args, ValueStack stack) {
return this.getTextProvider().getText(key, defaultValue, args, stack);
}
public String getFormatted(String key, String expr) {
Map<String, Object> conversionErrors = ActionContext.getContext().getConversionErrors();
if (conversionErrors.containsKey(expr)) {
String[] vals = (String[])((String[])conversionErrors.get(expr));
return vals[0];
} else {
ValueStack valueStack = ActionContext.getContext().getValueStack();
Object val = valueStack.findValue(expr);
return this.getText(key, Arrays.asList(val));
}
}
//用于访问国际化资源包的方法
public ResourceBundle getTexts() {
return this.getTextProvider().getTexts();
}
public ResourceBundle getTexts(String aBundleName) {
return this.getTextProvider().getTexts(aBundleName);
}
//添加错误提示信息的方法
public void addActionError(String anErrorMessage) {
this.validationAware.addActionError(anErrorMessage);
}
//添加普通提示信息的方法
public void addActionMessage(String aMessage) {
this.validationAware.addActionMessage(aMessage);
}
//添加字段校验失败的错误信息
public void addFieldError(String fieldName, String errorMessage) {
this.validationAware.addFieldError(fieldName, errorMessage);
}
//默认的input 方法,直接返回INPUT 字符串
public String input() throws Exception {
return "input";
}
//默认的处理用户请求的方法, 直接返回SUCCESS 字符串
public String execute() throws Exception {
return "success";
}
public boolean hasActionErrors() {
return this.validationAware.hasActionErrors();
}
public boolean hasActionMessages() {
return this.validationAware.hasActionMessages();
}
public boolean hasErrors() {
return this.validationAware.hasErrors();
}
public boolean hasFieldErrors() {
return this.validationAware.hasFieldErrors();
}
public void clearFieldErrors() {
this.validationAware.clearFieldErrors();
}
public void clearActionErrors() {
this.validationAware.clearActionErrors();
}
public void clearMessages() {
this.validationAware.clearMessages();
}
public void clearErrors() {
this.validationAware.clearErrors();
}
//清除所有错误信息的方法
public void clearErrorsAndMessages() {
this.validationAware.clearErrorsAndMessages();
}
//包含空的输入校验方法
public void validate() {
}
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
public void pause(String result) {
}
protected TextProvider getTextProvider() {
if (this.textProvider == null) {
Container container = this.getContainer();
TextProviderFactory tpf = (TextProviderFactory)container.getInstance(TextProviderFactory.class);
this.textProvider = tpf.createInstance(this.getClass());
}
return this.textProvider;
}
protected LocaleProvider getLocaleProvider() {
if (this.localeProvider == null) {
Container container = this.getContainer();
LocaleProviderFactory localeProviderFactory = (LocaleProviderFactory)container.getInstance(LocaleProviderFactory.class);
this.localeProvider = localeProviderFactory.createLocaleProvider();
}
return this.localeProvider;
}
protected Container getContainer() {
if (this.container == null) {
this.container = ActionContext.getContext().getContainer();
if (this.container != null) {
boolean devMode = Boolean.parseBoolean((String)this.container.getInstance(String.class, "struts.devMode"));
if (devMode) {
LOG.warn("Container is null, action was created manually? Fallback to ActionContext");
} else {
LOG.debug("Container is null, action was created manually? Fallback to ActionContext");
}
} else {
LOG.warn("Container is null, action was created out of ActionContext scope?!?");
}
}
return this.container;
}
@Inject
public void setContainer(Container container) {
this.container = container;
}
}
Action访问ServletAPI
Struts2提供了一个ActionContext类,从而使Action可以访问Servlet API
ActionContext类常用方法
public Object get(String key) {
return this.context.get(key);
}//该方法类似于调用HtψServletRequest 的getAttribute(String name)方法
public HttpParameters getParameters() {
return (HttpParameters)this.get("com.opensymphony.xwork2.ActionContext.parameters");
}//获取所有的请求参数。类似于调HttpServletRequest 对象的getParameterMap ()方法。
public static ActionContext getContext() {
return (ActionContext)actionContext.get();
}//静态方法,获取系统的ActionContext 实例。
public Map<String, Object> getApplication() {
return (Map)this.get("com.opensymphony.xwork2.ActionContext.application");
}//返回一个Map 对象,该对象模拟了该应用的ServletContext 实例。
public void setApplication(Map<String, Object> application) {
this.put("com.opensymphony.xwork2.ActionContext.application", application);
}
//直接传入一个Map 实例,将该Map 实例里的key- value 对转换成叩plication 的属性名、属性值。
public void setSession(Map<String, Object> session) {
this.put("com.opensymphony.xwork2.ActionContext.session", session);
}
//直接传入一个Map 实例,将该Map 实例里的key-value 对转换成session 的属性名、属性值。
public Map<String, Object> getSession() {
return (Map)this.get("com.opensymphony.xwork2.ActionContext.session");
}//返回一个Map 对象,该Map 对象模拟了HtφSession 实例。
实例
将在Action类中通过ActionContext访问Servlet API,向Action中示范向request,session和application范围设置属性值
修改LoginAction
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class LoginAction extends ActionSupport {
private String userName;
private String pass;
public String getUsername(){
return userName;
}
public void setUser(String username) {
userName = username;
}
public String getPassword(){
return pass;
}
public void setPassword(String password){
this.pass=password;
}
public String execute() throws Exception {
ActionContext ctx=ActionContext.getContext();
Integer counter=(Integer)ctx.getApplication().get("counter");
if(counter==null){
counter=1;
}else{
counter+=1;
}
ctx.getApplication().put("counter",counter);
ctx.getSession().put("user",getUsername());
if(getUsername().equals("aaa")&&getPassword().equals("aaa")){
ctx.put("tip","服务器提示:您已成功登录");
return SUCCESS;
}else{
ctx.put("tip","服务器提示:登陆失败");
return ERROR;
}
}
}
<%--
Created by IntelliJ IDEA.
User: gao
Date: 2020/3/12
Time: 13:38
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
本站访问次数为:${applicationScope.counter}<br/>
${sessionScope.user},你已经登陆<br/>
${requestScope.tip}
</body>
</html>
如果这一遇到疑惑,请看上一篇
Action直接访问Servlet API
Struts2提供了ServletContextAware和ServletRequestAware和ServletResponseAware接口供其直接访问ServletAPI
修改LoginAction
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
public class LoginAction implements Action, ServletResponseAware {
private String userName;
private String pass;
private HttpServletResponse response;
public String getUsername(){
return userName;
}
public void setUser(String username) {
userName = username;
}
public String getPassword(){
return pass;
}
public void setPassword(String password){
this.pass=password;
}
public String execute() throws Exception {
ActionContext ctx=ActionContext.getContext();
Integer counter=(Integer)ctx.getApplication().get("counter");
if(counter==null){
counter=1;
}else{
counter+=1;
}
ctx.getApplication().put("counter",counter);
ctx.getSession().put("user",getUsername());
if(getUsername().equals("aaa")&&getPassword().equals("aaa")){
try{
Cookie c=new Cookie("user",getUsername());
c.setMaxAge(60*60);
response.addCookie(c);
}catch (Exception e){
System.out.println(e);
}
ctx.put("tip","服务器提示:您已成功登录");
return SUCCESS;
}else{
ctx.put("tip","服务器提示:登陆失败");
return ERROR;
}
}
@Override
public void setServletResponse(javax.servlet.http.HttpServletResponse httpServletResponse) {
this.response=response;
}
}
使用ServletActionContext访问ServletAPI
点击链接加入群聊【程序员技术交流群】:添加链接描述