GitHub 地址
访问GitHub下载最新源码:https://github.com/JYG0723/Struts2_Action
访问 Servlet Api
Struts2 不再与 Servlet Api 进行耦合,但任提供了三种方式去访问 Servlet Api
- ActionContext :上下文的类,通过它获取相关的对象。Map 方式
- Aware :实现 Aware 接口。
- ServletActionContex:与 ActionContext 类似。
Action 的搜索顺序
- url:
http://127.0.0.1:8080/struts2/path1/path2/student.action
- 首先根据 url 路径判断
namespace
为/path1/path2
的 package 是否存在。- 存在:判断 action 是否存在,如果不存在则去默认
namespace
的 package 里寻找。及namespace
为/
的 package 下。如果还不存在则报错。 - 不存在:检查上一级路径的 package 是否存在(直到默认 namespace),即
namespace
为path1
的 package。如果没有报错。
- 存在:判断 action 是否存在,如果不存在则去默认
动态方法调用
动态方法调用为了解决一个 Action 对应多个请求的处理。以免 Action 太多,Struts2 对其有三种实现方式:
- 指定method属性。容易出现太多 xml文件中出现太多 action,不推荐
- 感叹号方式。官方不推荐,这里不写例子了。(请求写的和屎一样)
- 需要配置常量。并且配置 package 标签的
strict-method-invocation="false"
- 需要配置常量。并且配置 package 标签的
- 通配符方式,相比较而言推荐
- 需要配置 package 标签的
strict-method-invocation="false"
- 需要配置 package 标签的
指定method属性
struts.xml
/result.jsp
/add.jsp
HelloWorldAction
public class HelloWorldAction extends ActionSupport {
public String add() {
return SUCCESS;
}
@Override
public String execute() throws Exception {
System.out.println("执行Action");
return SUCCESS; // = "success"
}
}
url:http://localhost:8080/struts2/add.action
通配符方式
struts.xml
/result.jsp
/{1}.jsp
{1}.jsp
HelloWorldAction
public class HelloWorldAction extends ActionSupport {
public String add() {
return "add";
}
public String update() {
return "update";
}
@Override
public String execute() throws Exception {
System.out.println("执行Action");
return SUCCESS; // = "success"
}
}
url:http://localhost:8080/struts2/helloworld_update.action
多配置文件
helloworld.xml
/result.jsp
/{1}.jsp
/{1}.jsp
struts.xml
默认 Action
默认 Action,即如果用户输入的路径有误,找不到对应的 Action,就可以用该 Action 来向用户展示默认页面。防止出现 404 影响用户体验。
/error.jsp
url:http://localhost:8080/struts2/***.action
Struts2 后缀
struts.xml
url:http://localhost:8080/struts2/helloworld_add.html
url:http://localhost:8080/struts2/helloworld_add
注意:
比较有趣的一点是。默认 Struts2 访问 Action 不加.action
后缀也是可以根据名称访问到对应 Action 的。但是如果配置了该struts.action.extension
常量,并且 value 设值了,那么不添加后缀是访问不到的。如果该 value 没有设值,那么任然可以继续不带尾缀访问对应 Action。
struts.propertis
### 指定后缀为 .action 形式的请求可被 Struts2 处理,默认为action。可配置多个请求后缀,用 , 隔开
struts.action.extension=action,do,struts2,
web.xml
struts2
org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter
struts.action.extension
do
接受参数
Struts2 的 Action 是如何接收参数的:
- 使用 Action 的属性接收参数
- 使用 DomainModel 接受参数
- 使用 ModelDriven 接受参数
Action 的属性接收
LoginAction
public class LoginAction extends ActionSupport {
private String username;
private String password;
public String login() {
System.out.println(username + ":" + password);
return SUCCESS;
}
// getter/setter
}
struts.xml
/success.jsp
login.jsp
DomainModel 接受
LoginAction
public class LoginAction extends ActionSupport {
private User user;
public String login() {
System.out.println(user.getUsername()+ ":" + user.getPassword());
return SUCCESS;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
User
public class User {
private String username;
private String password;
getter/setter
}
login.jsp
ModelDriven 方式接收
LoginAction
public class LoginAction extends ActionSupport implements ModelDriven{
private User user = new User();
public String login() {
System.out.println(user.getUsername()+ ":" + user.getPassword());
return SUCCESS;
}
@Override
public User getModel() {
return user;
}
}
login.jsp
复杂参数请求
User
public class User {
private String username;
private String password;
private List userList;
// getter/setter
}
login.jsp
LoginAction
public class LoginAction extends ActionSupport implements ModelDriven {
private User user = new User();
public String login() {
System.out.println(user.getUsername() + ":" + user.getPassword() + ": 用户名1:"
+ user.getUserList().get(0).getUsername() + ": 用户名2:"
+ user.getUserList().get(1).getUsername());
return SUCCESS;
}
@Override
public User getModel() {
return user;
}
}
处理结果类型
LoginAction
public class LoginAction extends ActionSupport{
···
}
ActionSupport
public class ActionSupport implements Action, Validateable, ValidationAware, TextProvider, LocaleProvider, Serializable {
···
}
Action
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;
}
- SUCCESS:Action 正确的执行完成。返回相应的视图,success 是 name 属性默认值
- NONE:表示 Action 正确的执行完成,但并不返回任何视图
- ERROR:表示 Action 执行失败,返回到错误处理视图
- LOGIN:Action 因为用户没有登录的原因没有正确执行,将返回该登录视图,要求用户进行登录验证
- INPUT :Action 的执行,需要从前段页面获取参数,INPUT 就是代表这个参数输入的界面,一般在应用中,会对这些参数进行验证,如果验证没有通过,将自动返回到该视图。
INPUT 用法示例
struts.xml
/success.jsp
/login.jsp
login.jsp
<%@ taglib prefix="s" uri="/struts-tags" %>>
···
LoginAction
public class LoginAction extends ActionSupport implements ModelDriven {
···
@Override
public void validate() {
if (user.getUsername() == null || "".equals(user.getUsername())) {
this.addFieldError("username", "用户名不能为空");
}
}
}
注意:
这里的addFieldError
方法的username
参数对应 jsp 页面
标签的 name 属性。
result 标签
这里的 type 属性默认是 dispatcher 即转发。页面是通过请求转发调度过去,支持 jsp 引擎。