[关闭]
@liayun 2016-10-01T15:39:38.000000Z 字数 9185 阅读 1370

Struts2框架进阶(二)

Struts2框架学习


现在我们进入了Struts2框架学习的进阶二了,总觉得该说点什么但又不知道该说什么,直接进入正文。
Struts1框架中,在请求参数中传入执行的方法,那么开发人员编写的Action得继承DispatchAction,然后在其配置文件中配置这样的action:

  1. <action path=".../manage" type="...DispatchAction" parameter="method" >
  2. </action>

访问上面action的URL路径应该是这样的:.../manage?method=addUI
Struts2提供了两种方法来实现在请求参数中传入执行的方法的需求。

下面将详细讲解这两种方法。

动态方法的调用

如果Action中存在多个方法时,我们可以使用!+方法名调用指定方法。如下:

  1. public class HelloWorldAction {
  2. private String message;
  3. ....
  4. public String execute() throws Exception{
  5. this.message = "我的第一个struts2应用";
  6. return "success";
  7. }
  8. public String other() throws Exception{
  9. this.message = "第二个方法";
  10. return "success";
  11. }
  12. }

假设访问上面action的URL路径为:/struts/test/helloworld.action,要访问action的other()方法,我们可以这样调用:/struts/test/helloworld!other.action
例,我们首先在cn.itcast.action包下创建一个Action——HelloWorldAction.action。

  1. public class HelloWorldAction {
  2. private String msg;
  3. public String getMsg() {
  4. return msg;
  5. }
  6. public String addUI() {
  7. this.msg = "addUI";
  8. return "success";
  9. }
  10. public String execute() { // execute()的返回值必须是String类型
  11. this.msg = "execute";
  12. return "success";
  13. }
  14. }

接下来在类路径下(即src目录下)创建Struts2框架的配置文件——struts.xml。

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE struts PUBLIC
  3. "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
  4. "http://struts.apache.org/dtds/struts-2.3.dtd">
  5. <struts>
  6. <constant name="struts.action.extension" value="do,action" />
  7. <package name="employee" namespace="/control/employee" extends="struts-default">
  8. <action name="list" class="cn.itcast.action.HelloWorldAction" method="execute">
  9. <result name="success">/WEB-INF/page/message.jsp</result>
  10. </action>
  11. </package>
  12. </struts>

最后在WEB-INF/page/目录下创建一个jsp页面——message.jsp。

  1. <%@ page language="java" contentType="text/html; charset=UTF-8"
  2. pageEncoding="UTF-8"%>
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  4. <html>
  5. <head>
  6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  7. <title>Insert title here</title>
  8. </head>
  9. <body>
  10. ${msg }
  11. </body>
  12. </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关闭动态方法调用。如:

  1. <constant name="struts.enable.DynamicMethodInvocation" value="false"/>

使用通配符定义action

我们可以使用通配符定义action,因此我们可以将struts.xml文件的内容修改为:

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE struts PUBLIC
  3. "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
  4. "http://struts.apache.org/dtds/struts-2.3.dtd">
  5. <struts>
  6. <constant name="struts.enable.DynamicMethodInvocation" value="false" />
  7. <constant name="struts.action.extension" value="do,action" />
  8. <package name="employee" namespace="/control/employee" extends="struts-default">
  9. <action name="list_*" class="cn.itcast.action.HelloWorldAction" method="{1}">
  10. <result name="success">/WEB-INF/page/message.jsp</result>
  11. </action>
  12. </package>
  13. </struts>

注意:list_*_*可以有多个,如list_*_*,class属性中以及result标签内容中都可以使用{1}
这样,要访问HelloWorldAction.java中的addUI()方法,可以通过这样的URL访问:http://localhost:8080/Struts2/control/employee/list_addUI.action;若要访问HelloWorldAction.java中的execute()方法,可以通过这样的URL访问:

接收请求参数

采用基本类型接受请求参数(get/post)

假设请求路径为:http://localhost:8080/Struts2/control/employee/list_execute.action?id=23&name=李阿昀
那我们就要修改HelloWorldAction类的代码为:

  1. public class HelloWorldAction {
  2. private Integer id;
  3. private String name;
  4. public Integer getId() {
  5. return id;
  6. }
  7. public void setId(Integer id) {
  8. this.id = id;
  9. }
  10. public String getName() {
  11. return name;
  12. }
  13. public void setName(String name) {
  14. this.name = name;
  15. }
  16. public String addUI() {
  17. return "success";
  18. }
  19. public String execute() { // execute()的返回值必须是String类型
  20. return "success";
  21. }
  22. }

注意:Struts2通过反射技术调用与请求参数同名的属性的setter方法来获取请求参数值
struts.xml文件内容不用修改,只需修改message.jsp页面的内容为:

  1. <%@ page language="java" contentType="text/html; charset=UTF-8"
  2. pageEncoding="UTF-8"%>
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  4. <html>
  5. <head>
  6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  7. <title>Insert title here</title>
  8. </head>
  9. <body>
  10. id=${id }<br/>
  11. name=${name }
  12. </body>
  13. </html>

这样当我们通过浏览器访问URL地址(http://localhost:8080/Struts2/control/employee/list_execute.action?id=23&name=李阿昀)时,会看到这样的结果:
要记得插图
上面是通过get提交方式提交请求参数,如果是使用post提交方式提交请求参数,那又是一种什么情况?
我们可以这样做,在WebRoot根目录下创建网站首页——index.jsp。

  1. <%@page import="java.util.Date"%>
  2. <%@ page language="java" contentType="text/html; charset=UTF-8"
  3. pageEncoding="UTF-8"%>
  4. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  5. <html>
  6. <head>
  7. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  8. <title>Insert title here</title>
  9. </head>
  10. <body>
  11. <form action="<%=request.getContextPath() %>/control/employee/list_execute.action" method="post">
  12. id:<input type="text" name="id"><br/>
  13. name:<input type="text" name="name"><br/>
  14. <input type="submit" value="发送">
  15. </form>
  16. </body>
  17. </html>

这样,当我们通过浏览器访问该项目的首页时,填入id和name输入项的值,点击发送按钮,此时就意味着我们是使用post提交方式提交请求参数的。点击发送按钮后同样也可以看到我们所填入的值。

采用复合类型接受请求参数

假设请求路径为:http://localhost:8080/Struts2/control/employee/list_execute.action?person.id=23&person.name=李阿昀
那我们就要修改HelloWorldAction类的代码为:

  1. public class HelloWorldAction {
  2. private Person person; // 一般采用复合类型接收请求参数
  3. public Person getPerson() {
  4. return person;
  5. }
  6. public void setPerson(Person person) {
  7. this.person = person;
  8. }
  9. public String addUI() {
  10. return "success";
  11. }
  12. public String execute() { // execute()的返回值必须是String类型
  13. return "success";
  14. }
  15. }

接下来我们就要在cn.itcast.bean包下创建Person类了——Person.java。

  1. public class Person {
  2. private String name;
  3. private Integer id;
  4. public String getName() {
  5. return name;
  6. }
  7. public void setName(String name) {
  8. this.name = name;
  9. }
  10. public Integer getId() {
  11. return id;
  12. }
  13. public void setId(Integer id) {
  14. this.id = id;
  15. }
  16. }

struts.xml文件内容同样不用修改,只需修改index.jsp页面的内容为:

  1. <%@page import="java.util.Date"%>
  2. <%@ page language="java" contentType="text/html; charset=UTF-8"
  3. pageEncoding="UTF-8"%>
  4. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  5. <html>
  6. <head>
  7. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  8. <title>Insert title here</title>
  9. </head>
  10. <body>
  11. <form action="<%=request.getContextPath() %>/control/employee/list_execute.action" method="post">
  12. id:<input type="text" name="person.id"><br/>
  13. name:<input type="text" name="person.name"><br/>
  14. <input type="submit" value="发送">
  15. </form>
  16. </body>
  17. </html>

并且message.jsp页面的内容还要修改为:

  1. <%@ page language="java" contentType="text/html; charset=UTF-8"
  2. pageEncoding="UTF-8"%>
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  4. <html>
  5. <head>
  6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  7. <title>Insert title here</title>
  8. </head>
  9. <body>
  10. id=${person.id }<br/>
  11. name=${person.name }
  12. </body>
  13. </html>

这样,当我们通过浏览器访问该项目的首页时,填入id和name输入项的值,点击发送按钮,此时就意味着我们是使用post提交方式提交请求参数的。点击发送按钮后同样也可以看到我们所填入的值。
若在Person类中只有一个有参构造函数,即Person类的代码为:

  1. public class Person {
  2. private String name;
  3. private Integer id;
  4. public Person(String name, Integer id) {
  5. this.name = name;
  6. this.id = id;
  7. }
  8. public String getName() {
  9. return name;
  10. }
  11. public void setName(String name) {
  12. this.name = name;
  13. }
  14. public Integer getId() {
  15. return id;
  16. }
  17. public void setId(Integer id) {
  18. this.id = id;
  19. }
  20. }

提示:Person类中没有默认构造函数,控制台打印错误,jsp页面部分内容不显示
这样,当我们通过浏览器访问该项目的首页时,填入id和name输入项的值,点击发送按钮,发现message.jsp页面中部分内容不显示,但是Eclipse的控制台打印错误:

  1. java.lang.InstantiationException: cn.itcast.bean.Person
  2. at java.lang.Class.newInstance(Unknown Source)
  3. ...

报异常的原因是:Struts2首先通过反射技术调用Person的默认构造器创建Person对象,然后再通过反射技术调用Person中与请求参数同名的属性的setter方法来获取请求参数值。

总结

在Action类中定义与请求参数同名属性,Struts2会自动接收请求参数并赋予同名属性;而Struts1在formbean中使用与请求参数同名的属性,并且有setter、getter方法。

自定义类型转换器

Struts2有两种类型的转换器:

我们举一个例子来说明自定义类型转换器这个知识点。我们首先将HelloWorldAction类的代码修改为:

  1. public class HelloWorldAction {
  2. private Date birthday;
  3. public Date getBirthday() {
  4. return birthday;
  5. }
  6. public void setBirthday(Date birthday) {
  7. System.out.println(birthday);
  8. this.birthday = birthday;
  9. }
  10. public String addUI() {
  11. return "success";
  12. }
  13. public String execute() { // execute()的返回值必须是String类型
  14. return "success";
  15. }
  16. }

struts.xml配置文件的内容仍不变,为:

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE struts PUBLIC
  3. "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
  4. "http://struts.apache.org/dtds/struts-2.3.dtd">
  5. <struts>
  6. <constant name="struts.enable.DynamicMethodInvocation" value="false" />
  7. <constant name="struts.action.extension" value="do,action" />
  8. <package name="employee" namespace="/control/employee" extends="struts-default">
  9. <action name="list_*" class="cn.itcast.action.HelloWorldAction" method="{1}">
  10. <result name="success">/WEB-INF/page/message.jsp</result>
  11. </action>
  12. </package>
  13. </struts>

最后修改message.jsp页面的内容为:

  1. <%@ page language="java" contentType="text/html; charset=UTF-8"
  2. pageEncoding="UTF-8"%>
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  4. <html>
  5. <head>
  6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  7. <title>Insert title here</title>
  8. </head>
  9. <body>
  10. ${birthday }
  11. </body>
  12. </html>
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注