@liayun
2016-10-01T13:38:31.000000Z
字数 12519
阅读 1915
Struts2框架学习
Struts2框架入门之后,我们就要踏上Struts2框架漫漫的进阶之路了。我们以Struts2框架入门中的案例开始吧!
假设某用户的请求路径的URL是http://localhost:8080/Struts2/path1/path2/path3/test.action,那么Struts2框架是怎么搜索到相应的Action来处理用户的请求呢?答案为:
我们将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>
<package name="itcast" namespace="/test" extends="struts-default">
</package>
<package name="it" extends="struts-default">
<action name="helloworld" class="cn.itcast.action.HelloWorldAction" method="execute">
<result name="success">/WEB-INF/page/hello.jsp</result>
</action>
</package>
</struts>
这样,当我们在浏览器中输入URL地址,如http://localhost:8080/Struts2/test/sadsa/dsadfs/233432/helloworld.action时,依然会看到这样的结果:
记得插图
对于Struts2框架入门案例中的struts.xml配置文件中的这段代码:
<package name="itcast" namespace="/test" extends="struts-default">
<action name="helloworld" class="cn.itcast.action.HelloWorldAction" method="execute">
<result name="success">/WEB-INF/page/hello.jsp</result>
</action>
</package>
在Struts1中,通过path属性指定访问该action的URL路径。但在Struts2中,情况就不是这样的了,访问Struts2中的action的URL路径由两部份组成:包的命名空间+action的名称,例如访问上面例子中名为helloworld的Action的URL路径为:/test/helloworld (注意:完整路径为:http://localhost:端口/内容路径/test/helloworld.action)。
Action配置中的各项默认值:
例如我们在Struts2框架入门案例中的struts.xml配置文件中配置如下Action:
<action name="addUI">
<result>/WEB-INF/page/employeeAdd.jsp</result>
</action>
接着在WEB-INF/page/目录下创建employeeAdd.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>
<form action="/xxx">
姓名:<input type="text" name="xxx">
</form>
</body>
</html>
这样,当我们通过浏览器访问http://localhost:8080/Struts2/test/addUI.action该地址时,会跳转到employeeAdd.jsp页面。
试看下面的这样一段代码:
<action name="helloworld" class="cn.itcast.action.HelloWorldAction" method="execute">
<result name="success">/WEB-INF/page/hello.jsp</result>
</action>
result配置类似于Struts1中的forward,但Struts2中提供了多种结果类型,如:dispatcher(默认值)(对应Struts1中的内部请求转发)、redirect、redirectAction、plainText。
下面我们就要来详讲Struts2中提供的多种结果类型。
dispatcher这种结果类型就是Struts2中默认的结果类型,对应Struts1中的内部请求转发,如:
<action path="/control/employee/addUI" ... >
<forward name="add">/index.jsp</forward> <!-- 内部转发使用这种方式,对应Struts2中的dispatcher -->
</action>
没什么好讲的。
浏览器重定向就是使用redirect这种结果类型。在Struts1中的浏览器重定向是这样写的:
<action path="/control/employee/addUI" ... >
<forward name="add" redirect="true">/index.jsp</forward> <!--浏览器重定向使用这种方式-->
</action>
在Struts2中若要实现浏览器重定向,则必定要使用redirect这种结果类型。我们在Struts2框架入门案例中的struts.xml配置文件中配置如下Action:
<action name="redirect">
<result type="redirect">/employeeAdd.jsp</result>
</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>
<package name="itcast" namespace="/control/employee" extends="struts-default">
<action name="helloworld" class="cn.itcast.action.HelloWorldAction" method="execute">
<result name="success">/WEB-INF/page/hello.jsp</result>
</action>
<action name="addUI">
<result>/WEB-INF/page/employeeAdd.jsp</result>
</action>
<action name="redirect">
<result type="redirect">/employeeAdd.jsp</result>
</action>
</package>
</struts>
由于用户是无法访问到WEB-INF中的文件的,所以重定向的时候不能重定向到WEB-INF中的jsp中,所以我们要把employeeAdd.jsp这个页面移到WebRoot根目录下。
这样,当我们通过浏览器访问http://localhost:8080/Struts2/control/employee/redirect.action该地址时,浏览器会重定向到employeeAdd.jsp页面。
有时我们希望浏览器重定向到某个页面(如employeeAdd.jsp页面)时,传递一个参数(如用户名)进去。那我们应该怎么办呢?
我们先将HelloWorldAction类的代码修改为:
public class HelloWorldAction {
private String msg;
private String username;
public String getMessage() {
return msg;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String execute() {
this.username = "李阿昀";
this.msg = "我的第一个struts2应用";
return "success";
}
}
由于在result中可以使用${属性名}表达式访问action中的属性,表达式里的属性名对应action中的属性,所以我们可以这样编写代码:
<result type="redirect">/view.jsp?id=${id }</result>
那么,此时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>
<package name="itcast" namespace="/control/employee" extends="struts-default">
<action name="list" class="cn.itcast.action.HelloWorldAction" method="execute">
<result name="success" type="redirect">/employeeAdd.jsp?username=${username }</result>
</action>
<action name="addUI">
<result>/WEB-INF/page/employeeAdd.jsp</result>
</action>
<action name="redirect">
<result type="redirect">/employeeAdd.jsp</result>
</action>
</package>
</struts>
接下来,我们就要在employeeAdd.jsp中使用从URL中传过来的参数username:${param.username }。
<%@page import="java.net.URLDecoder"%>
<%@ 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>
${param.username }
<form action="/xxx">
姓名:<input type="text" name="xxx">
</form>
</body>
</html>
这时,当我们通过浏览器访问http://localhost:8080/Struts2/control/employee/list.action该地址,发现浏览器中URL以及jsp页面出现乱码。原因:tomcat接收到来自URL的用UTF-8编码后的字符串,会使用ISO8859-1进行编码(注意tomcat8内部使用的是UTF-8进行编码的,所以无须多此一举),所以出现乱码。解决方法:以get方式提交过来的中文参数,先得到ISO8859-1的二进制数组,再转成字符串。这样在employeeAdd.jsp页面中,要显示用户名,就要换成这句代码:
<%= URLDecoder.decode(new String(request.getParameter("username").getBytes("ISO-8859-1"), "UTF-8"), "UTF-8") %>
除此之外,HelloWorldAction类的代码还应修改为:
public class HelloWorldAction {
private String msg;
private String username;
public String getMessage() {
return msg;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String execute() throws Exception { // execute()的返回值必须是String类型
this.username = URLEncoder.encode("李阿昀", "UTF-8"); // 不能再URL中直接传字符串,所以应该编码
this.msg = "我的第一个struts2应用";
return "success";
}
}
至此,浏览器中URL以及jsp页面出现的中文乱码问题就得以解决了。
重定向到某个Action就要使用redirectAction这种结果类型。
如果重定向的action在同一个包下:
例如,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>
<package name="itcast" namespace="/control/employee" extends="struts-default">
<action name="list" class="cn.itcast.action.HelloWorldAction" method="execute">
<result name="success" type="redirect">/employeeAdd.jsp?username=${username }</result>
</action>
<action name="addUI">
<result>/WEB-INF/page/employeeAdd.jsp</result>
</action>
<action name="redirect">
<result type="redirect">/employeeAdd.jsp</result>
</action>
<action name="redirectAction">
<result type="redirectAction">/list</result>
</action>
</package>
</struts>
这样,当我们通过浏览器访问http://localhost:8080/Struts2/control/employee/redirectAction.action该地址时,经过两次重定向之后就到了employeeAdd.jsp页面中。
如果重定向的action在别的命名空间下:
例如,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>
<package name="itcast" namespace="/control/employee" extends="struts-default">
<action name="list" class="cn.itcast.action.HelloWorldAction" method="execute">
<result name="success" type="redirect">/employeeAdd.jsp?username=${username }</result>
</action>
<action name="addUI">
<result>/WEB-INF/page/employeeAdd.jsp</result>
</action>
<action name="redirect">
<result type="redirect">/employeeAdd.jsp</result>
</action>
<action name="redirectAction">
<result type="redirectAction">
<param name="actionName">xxx</param> <!-- 为redirectAction这个类型所对应的Java类的属性注入值 -->
<param name="namespace">/control/department</param>
</result>
</action>
</package>
<package name="other" namespace="/control/department" extends="struts-default">
<action name="xxx">
<result>/WEB-INF/page/hello.jsp</result>
</action>
</package>
</struts>
这样,当我们通过浏览器访问http://localhost:8080/Struts2/control/employee/redirectAction.action该地址时,经过一次重定向和一次内部请求转发之后就能看到employeeAdd.jsp页面中的内容了。
plainText显示原始文件内容,例如:当我们需要原样显示jsp文件源码的时候,可以使用该类型。
我们可以在Struts2框架入门案例中的struts.xml配置文件配置这样一个Action:
<action name="plainText">
<result type="plainText">
<param name="location">/index.jsp</param> <!-- 指定请求路径 -->
<param name="charSet">UTF-8</param> <!-- 指定读取文件的编码 -->
</result>
</action>
接下来,我们就要在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>
<%= new Date() %> 中国
</body>
</html>
这样,当我们通过浏览器访问http://localhost:8080/Struts2/control/employee/plainText.action该地址时,就能看到index.jsp文件的源码了。
Struts2为Actoin中的属性提供了依赖注入功能,在Struts2的配置文件中,我们可以很方便地为Action的属性注入值。注意:属性必须提供setter方法。
我们先将HelloWorldAction类的代码修改为:
public class HelloWorldAction {
private String savepath;
public String getSavepath() {
return savepath;
}
public void setSavepath(String savepath) {
this.savepath = savepath;
}
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>
<package name="itcast" namespace="/control/employee" extends="struts-default">
<action name="list" class="cn.itcast.action.HelloWorldAction" method="execute">
<param name="savepath">/images</param>
<result name="success">/WEB-INF/page/message.jsp</result>
</action>
</package>
</struts>
上面通过<param>
结点为Action的savepath属性注入“/images”。
最后我们要在WEB-INF/page/目录下创建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>
结果<br/>
${savepath }
</body>
</html>
提示:可在message.jsp页面中使用EL表达式:${savePath }
。
这样,,当我们通过浏览器访问http://localhost:8080/Struts2/control/employee/list.action该地址时,就能看到如下结果:
要记得插图
默认处理的后缀是可以通过常量"struts.action.extension"进行修改的,如下配置Struts2只处理以.do为后缀的请求路径:
<struts>
<constant name="struts.action.extension" value="do"/>
</struts>
如果用户需要指定多个请求后缀,则多个后缀之间以英文逗号(,)隔开。如:
<constant name="struts.action.extension" value="do,action"/>
常量可以在struts.xml或struts.properties中配置,建议在struts.xml中配置,两种配置方式如下:
在struts.xml文件中配置
<struts>
<constant name="struts.action.extension" value="do"/>
</struts>
在struts.properties文件中配置
struts.action.extension=do
通常,Struts2按如下搜索顺序加载Struts2常量:
如果在多个文件中配置了同一个常量,则后一个文件中配置的常量值会覆盖前面文件中配置的常量值。
Struts2常用的常量有:
<constant name="struts.i18n.encoding" value="UTF-8"/>
指定默认编码集,作用于HttpServletRequest的setCharacterEncoding方法和freemarker、velocity的输出。
<constant name="struts.action.extension" value="do"/>
该属性指定需要Struts2处理的请求后缀,该属性的默认值是action,即所有匹配*.action的请求都由Struts2处理。如果用户需要指定多个请求后缀,则多个后缀之间以英文逗号(,)隔开。
<constant name="struts.serve.static.browserCache" value="false"/>
设置浏览器是否缓存静态内容,默认值为true(生产环境下使用),开发阶段最好关闭。
<constant name="struts.configuration.xml.reload" value="true"/>
当Struts2的配置文件修改后,系统是否自动重新加载该文件,默认值为false(生产环境下使用),开发阶段最好打开。修改了struts.xml,不需重启服务器。
<constant name="struts.devMode" value="true" />
开发模式下使用,这样可以打印出更详细的错误信息。
<constant name="struts.ui.theme" value="simple" />
默认的视图主题。
<constant name="struts.objectFactory" value="spring" />
与Spring集成时,指定由Spring负责action对象的创建。
<constant name="struts.enable.DynamicMethodInvocation" value="false"/>
该属性设置Struts2是否支持动态方法调用,该属性的默认值是true。如果需要关闭动态方法调用,则可设置该属性为false。
<constant name="struts.multipart.maxSize" value="10701096">
上传文件(总)的大小限制。