@liayun
2016-10-01T15:39:38.000000Z
字数 9185
阅读 1717
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.Personat 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>