@liayun
2016-10-01T23:39:38.000000Z
字数 9185
阅读 1469
Struts2框架学习
现在我们进入了Struts2框架学习的进阶二了,总觉得该说点什么但又不知道该说什么,直接进入正文。
Struts1框架中,在请求参数中传入执行的方法,那么开发人员编写的Action得继承DispatchAction,然后在其配置文件中配置这样的action:
<action path=".../manage" type="...DispatchAction" parameter="method" >
</action>
访问上面action的URL路径应该是这样的:.../manage?method=addUI。
Struts2提供了两种方法来实现在请求参数中传入执行的方法的需求。
动态方法
URL中action名称后面加上"!+方法名"。例如:http://.../manage!other.action。Struts2.1已经不建议使用了,有可能以后的版本都不能用了。在struts.xml中设置常量(动态方法禁用掉)
<constant name="struts.enable.DynamicMethodInvocation" value="false"/>
该方法就不再可用了。
下面将详细讲解这两种方法。
如果Action中存在多个方法时,我们可以使用!+方法名调用指定方法。如下:
public class HelloWorldAction {
private String message;
....
public String execute() throws Exception{
this.message = "我的第一个struts2应用";
return "success";
}
public String other() throws Exception{
this.message = "第二个方法";
return "success";
}
}
假设访问上面action的URL路径为:/struts/test/helloworld.action,要访问action的other()方法,我们可以这样调用:/struts/test/helloworld!other.action。
例,我们首先在cn.itcast.action包下创建一个Action——HelloWorldAction.action。
public class HelloWorldAction {
private String msg;
public String getMsg() {
return msg;
}
public String addUI() {
this.msg = "addUI";
return "success";
}
public String execute() { // execute()的返回值必须是String类型
this.msg = "execute";
return "success";
}
}
接下来在类路径下(即src目录下)创建Struts2框架的配置文件——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.action.extension" value="do,action" />
<package name="employee" namespace="/control/employee" extends="struts-default">
<action name="list" class="cn.itcast.action.HelloWorldAction" method="execute">
<result name="success">/WEB-INF/page/message.jsp</result>
</action>
</package>
</struts>
最后在WEB-INF/page/目录下创建一个jsp页面——message.jsp。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
${msg }
</body>
</html>
我们一般都会通过浏览器访问这个URL地址:http://localhost:8080/Struts2/control/employee/list.action,当我们访问该URL地址时,默认调用的是HelloWorldAction.java的execute()方法,但是我们定要访问HelloWorldAction.java的addUI()方法,那该怎么破呢?我们可以这样调用:http://localhost:8080/Struts2/control/employee/list!addUI.action,但是会马上发现报异常:
警告: Could not find action or result: /Struts2/control/employee/list!addUI.action
There is no Action mapped for namespace [/control/employee] and action name [list!addUI] associated with context path [/Struts2]. - [unknown location]
或许是在Struts2.3.24这个版本中不再支持这种动态方法的调用了,并且我们也不推荐使用这种动态方法的调用。
如果不想使用这种动态方法调用,我们可以通过常量struts.enable.DynamicMethodInvocation关闭动态方法调用。如:
<constant name="struts.enable.DynamicMethodInvocation" value="false"/>
我们可以使用通配符定义action,因此我们可以将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.enable.DynamicMethodInvocation" value="false" />
<constant name="struts.action.extension" value="do,action" />
<package name="employee" namespace="/control/employee" extends="struts-default">
<action name="list_*" class="cn.itcast.action.HelloWorldAction" method="{1}">
<result name="success">/WEB-INF/page/message.jsp</result>
</action>
</package>
</struts>
注意:list_*
中_*
可以有多个,如list_*_*
,class属性中以及result标签内容中都可以使用{1}。
这样,要访问HelloWorldAction.java中的addUI()方法,可以通过这样的URL访问:http://localhost:8080/Struts2/control/employee/list_addUI.action;若要访问HelloWorldAction.java中的execute()方法,可以通过这样的URL访问:
假设请求路径为:http://localhost:8080/Struts2/control/employee/list_execute.action?id=23&name=李阿昀。
那我们就要修改HelloWorldAction类的代码为:
public class HelloWorldAction {
private Integer id;
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String addUI() {
return "success";
}
public String execute() { // execute()的返回值必须是String类型
return "success";
}
}
注意:Struts2通过反射技术调用与请求参数同名的属性的setter方法来获取请求参数值。
struts.xml文件内容不用修改,只需修改message.jsp页面的内容为:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
id=${id }<br/>
name=${name }
</body>
</html>
这样当我们通过浏览器访问URL地址(http://localhost:8080/Struts2/control/employee/list_execute.action?id=23&name=李阿昀)时,会看到这样的结果:
要记得插图
上面是通过get提交方式提交请求参数,如果是使用post提交方式提交请求参数,那又是一种什么情况?
我们可以这样做,在WebRoot根目录下创建网站首页——index.jsp。
<%@page import="java.util.Date"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="<%=request.getContextPath() %>/control/employee/list_execute.action" method="post">
id:<input type="text" name="id"><br/>
name:<input type="text" name="name"><br/>
<input type="submit" value="发送">
</form>
</body>
</html>
这样,当我们通过浏览器访问该项目的首页时,填入id和name输入项的值,点击发送按钮,此时就意味着我们是使用post提交方式提交请求参数的。点击发送按钮后同样也可以看到我们所填入的值。
假设请求路径为:http://localhost:8080/Struts2/control/employee/list_execute.action?person.id=23&person.name=李阿昀。
那我们就要修改HelloWorldAction类的代码为:
public class HelloWorldAction {
private Person person; // 一般采用复合类型接收请求参数
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
public String addUI() {
return "success";
}
public String execute() { // execute()的返回值必须是String类型
return "success";
}
}
接下来我们就要在cn.itcast.bean包下创建Person类了——Person.java。
public class Person {
private String name;
private Integer id;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
}
struts.xml文件内容同样不用修改,只需修改index.jsp页面的内容为:
<%@page import="java.util.Date"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="<%=request.getContextPath() %>/control/employee/list_execute.action" method="post">
id:<input type="text" name="person.id"><br/>
name:<input type="text" name="person.name"><br/>
<input type="submit" value="发送">
</form>
</body>
</html>
并且message.jsp页面的内容还要修改为:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
id=${person.id }<br/>
name=${person.name }
</body>
</html>
这样,当我们通过浏览器访问该项目的首页时,填入id和name输入项的值,点击发送按钮,此时就意味着我们是使用post提交方式提交请求参数的。点击发送按钮后同样也可以看到我们所填入的值。
若在Person类中只有一个有参构造函数,即Person类的代码为:
public class Person {
private String name;
private Integer id;
public Person(String name, Integer id) {
this.name = name;
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
}
提示:Person类中没有默认构造函数,控制台打印错误,jsp页面部分内容不显示。
这样,当我们通过浏览器访问该项目的首页时,填入id和name输入项的值,点击发送按钮,发现message.jsp页面中部分内容不显示,但是Eclipse的控制台打印错误:
java.lang.InstantiationException: cn.itcast.bean.Person
at java.lang.Class.newInstance(Unknown Source)
...
报异常的原因是:Struts2首先通过反射技术调用Person的默认构造器创建Person对象,然后再通过反射技术调用Person中与请求参数同名的属性的setter方法来获取请求参数值。
在Action类中定义与请求参数同名属性,Struts2会自动接收请求参数并赋予同名属性;而Struts1在formbean中使用与请求参数同名的属性,并且有setter、getter方法。
Struts2有两种类型的转换器:
我们举一个例子来说明自定义类型转换器这个知识点。我们首先将HelloWorldAction类的代码修改为:
public class HelloWorldAction {
private Date birthday;
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
System.out.println(birthday);
this.birthday = birthday;
}
public String addUI() {
return "success";
}
public String execute() { // execute()的返回值必须是String类型
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.enable.DynamicMethodInvocation" value="false" />
<constant name="struts.action.extension" value="do,action" />
<package name="employee" namespace="/control/employee" extends="struts-default">
<action name="list_*" class="cn.itcast.action.HelloWorldAction" method="{1}">
<result name="success">/WEB-INF/page/message.jsp</result>
</action>
</package>
</struts>
最后修改message.jsp页面的内容为:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
${birthday }
</body>
</html>