这里主要内容是:
- action的方法调用
- 通配符
- 属性接收参数
- 域模型接收参数
- ModelDriven接收参数
一、action的方法调用(method)
相关代码(工程Struts2_0500_ActionMethod
)
UserAction
package com.bjsxt.struts2.user.action;
import com.opensymphony.xwork2.ActionSupport;
public class UserAction extends ActionSupport {
public String add(){
return SUCCESS;
}
}
struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<constant name="struts.devMode" value="true" />
<constant name="struts.enable.DynamicMethodInvocation" value="true"/>
<package name="user" extends="struts-default" namespace="/user">
<action name="userAdd" class="com.bjsxt.struts2.user.action.UserAction" method="add">
<result>/user_add_success.jsp</result>
</action>
<action name="user" class="com.bjsxt.struts2.user.action.UserAction">
<result>/user_add_success.jsp</result>
</action>
</package>
</struts>
index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" isELIgnored="false"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="${pageContext.request.contextPath}/"/>
<title>actionMethod</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
</head>
<body>
第一种方式
<a href="user/userAdd">添加用户</a><br>
第二种方式
<a href="user/user!add">添加用户</a><br>
</body>
</html>
user_add_success.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" isELIgnored="false"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>actionMethod</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
</head>
<body>
User Add Success!
</body>
</html>
说明:
1.action默认是调用execute方法的,但是如果我们在struts.xml
中对其调用方法进行配置,也可以调用其他名字方法,这里我们配置为method="add"
,于是会调用action中的add方法。
2.对于第一种方式,我们指定action中name="userAdd
",当我们链接到userAdd时就会去找action中的add方法。加入我们还有其他方法比如userDel方法,我们也可以这样指定method="del"
,但是当我们要调用的方法较多时,这种配置显然很麻烦,一般不采用,请看第二种方式。
3.第二种方式中,我们没有配置任何method。但是我们在链接中指明调用add方法,此时就会找到action中的add方法,这就是动态链接,如果有其他方法,我们只需要在动态链接地址上加上就行,而配置中不需要做任何改动。一般使用此方法。也就是DMI方式。
4.在struts.xml
中我发现如果不加上这行配置<constant name="struts.enable.DynamicMethodInvocation" value="true"/>
,那么后面的动态链接就会找不到action和方法,暂时不清楚到底是什么原因,网上有说是源码的问题,这留到后面再研究吧。
二、通配符(?)
相关代码(工程Struts2_0600_ActionWildcard
)
struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<constant name="struts.devMode" value="true" />
<constant name="struts.enable.DynamicMethodInvocation" value="true"/>
<package name="actions" extends="struts-default" namespace="/actions">
<action name="Student*" class="com.bjsxt.struts2.action.StudentAction" method="{1}">
<result>/Student{1}_success.jsp</result>
</action>
<action name="*_*" class="com.bjsxt.struts2.action.{1}Action" method="{2}">
<result>/{1}_{2}_success.jsp</result>
</action>
</package>
</struts>
StudentAction.java
package com.bjsxt.struts2.action;
import com.opensymphony.xwork2.ActionSupport;
public class StudentAction extends ActionSupport {
public String add(){
return SUCCESS;
}
public String delete(){
return SUCCESS;
}
}
index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" isELIgnored="false"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="${pageContext.request.contextPath}/"/>
<title>actionWildcard</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
</head>
<body>
使用通配符就爱那个配置量降到最低<br>
<a href="actions/Studentadd">添加学生</a>
<a href="actions/Studentdelete">删除学生</a>
注意:一定要遵循“约定优于配置”的原则
<a href="actions/Teacher_add">添加老师</a>
<a href="actions/Teacher_delete">删除老师</a>
<a href="actions/Course_add">添加课程</a>
<a href="actions/Course_delete">删除课程</a>
</body>
</html>
Studentadd_success.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" isELIgnored="false"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>actionWildcard</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
</head>
<body>
Student Add Success!
</body>
</html>
Studentdelete_success.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" isELIgnored="false"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>actionWildcard</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
</head>
<body>
Student Delete Success!
</body>
</html>
**说明:
- 1.**当我们访问
index.jsp
时,最开始的两个超链接是添加学生和删除学生。而我们在配置文件中第一种配置是
<action name="Student*" class="com.bjsxt.struts2.action.StudentAction" method="{1}">
<result>/Student{1}_success.jsp</result>
</action>
可以发现通配符代表add
,于是这里method="add"
,而
<result>/Studentadd_success.jsp</result>
。这样我们点击添加学生的时候就跳转到Studentadd_success.jsp
。
- 2.从第一种配置中我们可以看到一个通配符可以配置添加和添加两个操作,但是如
index.jsp
后面的几个超链接,我们还是必须要配置很多action,这显然还不够简便,于是我们采用一种约定的方式进行配置,也就是第二种配置:
<action name="*_*" class="com.bjsxt.struts2.action.{1}Action" method="{2}">
<result>/{1}_{2}_success.jsp</result>
</action>
于是这里我们一个配置就可以同时对应学生、老师、课程等多个操作action。这样会很方便。同时:这也告诉我们约定优于配置,既然采用这种方式进行配置,那么我们就必须事先约定好我们的jsp页面和action名字采用一种什么样的约定进行命名,即{1}Action
,比如TeacherAction
。
三、接收参数
相关代码(工程Struts2_0700_ActionAttrParamInput
)
struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<constant name="struts.devMode" value="true" />
<constant name="struts.enable.DynamicMethodInvocation" value="true"/>
<package name="user" extends="struts-default" namespace="/user">
<action name="user" class="com.bjsxt.struts2.user.action.UserAction">
<result>/user_add_success.jsp</result>
</action>
</package>
</struts>
UserAction.java
package com.bjsxt.struts2.user.action;
import com.opensymphony.xwork2.ActionSupport;
public class UserAction extends ActionSupport {
private String name;
private int age ;
public String add(){
System.out.println("name=" + name);
System.out.println("age=" + age);
return SUCCESS;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" isELIgnored="false"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>ActionAttrParamInput</title>
</head>
<body>
使用action属性接收参数<a href="user/user!add?name=a&age=8">添加用户</a>
</body>
</html>
user_add_success.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" isELIgnored="false"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>ActionAttrParamInput</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
</head>
<body>
User Add Success!
</body>
</html>
说明:这里我们采用action属性的方式接收参数。注意,在action中定义属性之后必须要有setter和getter方法。同时我们在建工程的时候一定要确保有web.xml,MyEclipse中建web工程默认是不生成web.xml
的。
四、域模型
通过上面的例子可知,我们要使用属性接收参数在属性很多的时候会很麻烦,比如一个用户,其有名字、密码、地址等等很多信息,此时我们就可以使用域模型进行接收。
相关代码(工程Struts2_0800_DomainModelParamInput
)
struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<constant name="struts.devMode" value="true" />
<constant name="struts.enable.DynamicMethodInvocation" value="true"/>
<package name="user" extends="struts-default" namespace="/user">
<action name="user" class="com.bjsxt.struts2.user.action.UserAction">
<result>/user_add_success.jsp</result>
</action>
</package>
</struts>
UserAction.java
package com.bjsxt.struts2.user.action;
import com.bjsxt.struts2.user.model.User;
import com.opensymphony.xwork2.ActionSupport;
public class UserAction extends ActionSupport {
private User user;
public String add(){
System.out.println("name=" + user.getName());
System.out.println("age=" + user.getAge());
return SUCCESS;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
User.java
package com.bjsxt.struts2.user.model;
public class User {
private String name;
private int age ;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" isELIgnored="false"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>DomainModelParamInput</title>
</head>
<body>
使用域模型接收参数<a href="user/user!add?user.name=a&user.age=8">添加用户</a>
</body>
</html>
user_add_success.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" isELIgnored="false"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>DomainModelParamInput</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
</head>
<body>
User Add Success!
</body>
</html>
说明:
- 1.action中的域模型是不需要我们自己实例化的,struts2会帮我们实例化。
- 2.一定要注意:此时在传递参数的时候配置要做相应的改变:
<body>
使用域模型接收参数<a href="user/user!add?user.name=a&user.age=8">添加用户</a>
</body>
- 3.域模型参数的名字和我们传递参数的名字一定要一致。
最后,可以看到,使用域模型在接收相关参数的时候会更加清晰,同时这里struts2在发现user为null时会自动帮我们实例化。但是有个问题是,当页面传递过来的参数和我们域模型中的参数个数不匹配的时候如何接收?比如页面中对于密码还有一个验证密码,于是就会比我们域模型中的参数个数多一个,此时我们需要用到DTO模型进行接收。
相关代码
UserDTO.java
package com.bjsxt.struts2.user.dto;
public class UserDTO {
private String name;
private String password;
private String confirmingPassword;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getConfirmingPassword() {
return confirmingPassword;
}
public void setConfirmingPassword(String confirmingPassword) {
this.confirmingPassword = confirmingPassword;
}
}
UserAction.java
package com.bjsxt.struts2.user.action;
import com.bjsxt.struts2.user.dto.UserDTO;
import com.opensymphony.xwork2.ActionSupport;
public class UserAction extends ActionSupport {
private UserDTO userDTO ;
public String add(){
/*System.out.println("name=" + user.getName());
System.out.println("age=" + user.getAge());*/
return SUCCESS;
}
public UserDTO getUserDTO() {
return userDTO;
}
public void setUserDTO(UserDTO userDTO) {
this.userDTO = userDTO;
}
}
说明:这里不作深入讲解,我们可以看到我们会使用DTO进行接收,之后我们想要得到相应的User对象时,再从DTO中得到相应的属性值。我们在后面再做详细讲解。
五、ModelDriven
还有一种方式来接收参数,但是并不常用。即实现一个ModelDriven接口。
和之前不一样的地方:
UserAction.java
package com.bjsxt.struts2.user.action;
import com.bjsxt.struts2.user.model.User;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
public class UserAction extends ActionSupport implements ModelDriven<User> {
private User user = new User();
public String add(){
System.out.println("name=" + user.getName());
System.out.println("age=" + user.getAge());
return SUCCESS;
}
@Override
public User getModel() {
return user;
}
}
index.jsp
<body>
使用ModelDriven接收参数<a href="user/user!add?name=a&age=8">添加用户</a>
</body>
说明:这种方式中Model对象必须自己实例化,同时不需要setter和getter方法。而是实现getModel
方法。同时使用泛型。