1、Struts2的基本流程
Struts2框架大致分为三部分:
。核心控制器StrutsPerpareAndExecuteFilter,Struts2框架提供
。业务控制器 ,用户自己实现
。用户实现的业务逻辑组建,用户自己实现
Struts2应用中的Action用于处理用户请求的Action实例,并不是用户自己实现业务控制器,而是Action代理。因为用户实现的业务控制器并没有ServletAPI耦合,显然无法处理用户请求。而Stuts2框架提供了系列拦截器,该拦截器负责将HttpServletRequest请求中的请求参数解析出来,传入Action中,并调用execute方法来处理用户请求。
struts.xml文件知识点讲解
1、默认情况下,Struts2框架会自动加载放在WEB-INF/classes路径下的struts.xml文件。但由于随着应用程序的扩大,系统中Action数量也大量增多,导致struts.xml配置臃肿。此时我们可以将struts.xml配置文件分解成多个配置文件,然后在struts.xml文件包含这些文件就可以了。使用<include />元素完成。
<struts>
<include file="struts1.xml"></include>
...
</struts>
应该避免两个文件中有相同的Package设置,后者会覆盖前者。我就是这样,报nasmespace....错误。
2、struts-default.xml是Struts2框架的默认配置文件,Struts2框架每次都会自动加载该文件。
<package name="default" namespace="/" extends="struts-default"> <action name="login" class="org.crazyit.action.LoginAction"> <result name="success">/detils.jsp</result> <result name="error">/error.jsp</result> </action> </package>
3、struts.xml和struts.properties是Struts2两个核心配置文件。
struts.xml主要负责管理Action映射以及该Action包含的result定义。
struts.propertites主要定义Struts2框架的一些常量,采用键值对的方式,就是一种properties文件。在项目的src目录下添加。
在Struts2中有三种配置常量的方式
①.在struts.properties中配置。例如: struts.devMode = false
②.在web.xml中配置核心Filter时通过初始化参数来配置常量。
例如:
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
<init-param>
<param-name>struts.custom.i18n.resources</param-name>
<param-value>mess</param-value>
</init-param>
</filter>
③.在struts.xml中通过<constant />元素来配置常量。
<constant name="struts.custom.i18n.resources" value="mess"></constant>
对此Struts2对常量的加载顺序如下
1、struts-default.xml 2、struts-plugin.xml 3、struts.xml 4、struts.properties 5、web.xml
4、包配置package元素
package中有以下属性:name:包的唯一标识
extends:可选属性,指定继承其他包
namespace:可选属性,该包的命名空间
abstract:定义是否是抽象包,抽象包中不能包含Action的定义。例如:abstract=“true”
----------命名空间 namespace
Struts2允许以命名空间来管理Action。统一命名空间不能有相同的Action,不同的命名空间可以有同名的Action。Struts2不能单独为一个Action提供命名空间,而是通过为包指定命名空间。
当某个包指定了命名空间之后,该包下Action处理的URL应该是命名空间+Action
默认命名空间 namespace=“” :可以处理任何模块下的Action
根命名空间 namespace=“/”
5、Struts2的Action
· Struts2通常直接用Action来封装HTTP请求参数,因此Action应该包含与参数相对的属性,并为属性提供getter和setter方法。
· 由于系统是通过getter和setter方法来处理请求参数的,因此也可以不包含属性。
· Action既可以封装请求参数,也可以封装处理结果的属性。
· 为了让用户开发Action更规范,Struts2提供了一个Action接口。
public interface Action { /** * The action execution was successful. Show result * view to the end user. */ public static final String SUCCESS = "success"; /** * The action execution was successful but do not * show a view. This is useful for actions that are * handling the view in another fashion like redirect. */ public static final String NONE = "none"; /** * The action execution was a failure. * Show an error view, possibly asking the * user to retry entering data. */ public static final String ERROR = "error"; /** * The action execution require more input * in order to succeed. * This result is typically used if a form * handling action has been executed so as * to provide defaults for a form. The * form associated with the handler should be * shown to the end user. * <p/> * This result is also used if the given input * params are invalid, meaning the user * should try providing input again. */ public static final String INPUT = "input"; /** * The action could not execute, since the * user most was not logged in. The login view * should be shown. */ public static final String LOGIN = "login"; /** * Where the logic of the action is executed. * * @return a string representing the logical result of the execution. * See constants in this interface for a list of standard result values. * @throws Exception thrown if a system level exception occurs. * <b>Note:</b> Application level exceptions should be handled by returning * an error value, such as <code>Action.ERROR</code>. */ public String execute() throws Exception; }
另外Struts2还为Action提供了实现类ActionSupport。若Action中没有配置class时,默认ActionSupport作为处理类。
6、Action访问Servlet Api
ActionContext 是 Action 执行的上下文对象, 在 ActionContext 中保存了 Action 执行所需要的所有对象, 包括 parameters, request, session, application 等.
获取系统的ActionContext实例 : ActionContext.getContext()
获取 HttpSession 对应的 Map 对象: public Map getSession() 。与之对应的是setSession(Map session)方法
获取 ServletContext 对应的 Map 对象:public Map getApplication()。与之对应的是setApplication(map Application)方法
获取请求参数对应的 Map 对象:public Map getParameters()
获取 HttpServletRequest 对应的 Map 对象:public Object get(Object key):。与之对应还有put()方法
ActionContext 类中没有提供类似 getRequest() 这样的方法来获取 HttpServletRequest 对应的 Map 对象. 要得到 HttpServletRequest 对应的 Map 对象, 可以通过为 get() 方法传递 “request” 参数实现。
public String execute() throws Exception{ ActionContext act=ActionContext.getContext(); Integer counter=(Integer) act.getApplication().get("counter"); if(counter==null ){ counter=1; }else{ counter=counter+1; } act.getApplication().put("counter", counter); act.getSession().put("username", getUsername()); if(getUsername().equals("wangning")&& getPassword().equals("123456")){ act.put("tip", "你已经成功登陆!"); return "success"; }else{ act.put("tip", "登陆失败!"); return "error"; } }
<s:property value="tip"/>
${applicationScope.counter }人在线
${sessionScope.username }登陆
7、虽然ActionContext可以用来访问Servlet Api 。但不能直接访问Servlet Api实例。因此Struts2提供了如下接口:
①、ServletContextAware:实现该接口的Action可以访问Web应用的ServletContext实例。
②、ServletRequestAware:实现该接口的Action可以访问用户请求的HttpServletRequest实例。
③、ServletResponseAware:实现该接口的Action可以访问服务器相应的HttpServletResponse实例。
8、配置逻辑试图与物理师徒之间的映射关系是通过<result />元素来定义的。
9、Struts2的Action默认处理类是ActionSupport。我们也可以在struts.xml中手动修改
<package name="default1" namespace="/" extends="struts-default">
<default-class-ref class="org.crazyit.action.LoginAction"></default-class-ref>
<action name="login" class="org.crazyit.action.LoginAction">
<result name="success">/detils.jsp</result>
<result name="error">/error.jsp</result>
</action>
</package>
10、动态方法调用(DMI)
形式: action=“action!methodName.action”
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <%@ taglib prefix="s" uri="/struts-tags"%> <!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> <script type="text/javascript"> function regist(){ targetForm=document.forms[0]; targetForm.action="login!regist"; targetForm.submit(); } </script> <body> <!-- <form action="login" method="post"> 用户名:<input type="text" name="username"><br> 密码:<input type="password" name="password"><br> <input type="submit" value="登陆"> <input type="reset" value="重置"> </form> --> <s:form action="login"> <s:textfield name="username" label="用户名"></s:textfield> <s:password name="password" label="密 码"></s:password> <s:submit value="登陆"></s:submit> <s:submit value="注册" type="button" onclick="regist()"></s:submit> <s:reset value="重置"></s:reset> </s:form> </body> </html>
<action name="login" class="org.crazyit.action.LoginAction"> <result name="success">/detils.jsp</result> <result name="error">/error.jsp</result> </action> <action name="regist" class="org.crazyit.action.LoginAction" method="regist"> <result name="success">/detils.jsp</result> <result name="error">/error.jsp</result> </action>
使用动态方法之前,应该开启Struts2的动态方法调用设置:<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>,否则nasmespace....错误。
11、使用通配符是另外一种动态方法调用。
<package name="sports" namespace="/" extends="struts-default"> <action name="runAction" class="org.sports.action.SportsAction" method="{1}"> <result>/sportDetils.jsp</result> </action> <action name="*Action" class="org.sports.action.SportsAction" method="{1}"> <result>/sportDetils.jsp</result> </action> <action name="*" class="org.sports.action.SportsAction" method="{1}"> <result>/sportDetils.jsp</result> </action> </package>
通配符可以在name属性中使用,然后再class和method属性中使用表达式。
以上代码如果是runAction,则调用runAction请求。如果是danceAction,则调用*Action处理。*Action和*都匹配,二者谁在前,调用谁。
12、Struts2中允许定义了一个默认的Action,在用户的URL请求找不到匹配的Action时,则调用默认的Action来处理用户请求。
<default-action-ref name="runAction"></default-action-ref>
13、配置结果
Struts2根据<result/>所在的位置不同,提供了两种结果
局部结果:<result />元素作为<action/>子元素来配置
全局结果:<result />元素作为<global-results/>子元素来配置
<package name="sports" namespace="/" extends="struts-default"> <default-action-ref name="runAction"></default-action-ref> <global-results> <result>/error.jsp</result> </global-results> <action name="runAction" class="org.sports.action.SportsAction" method="{1}"> <result>/sportDetils.jsp</result> </action> <action name="*Action" class="org.sports.action.SportsAction" method="{1}"> <result>/sportDetils.jsp</result> </action> <action name="*" class="org.sports.action.SportsAction" method="{1}"> <result>/sportDetils.jsp</result> </action> </package>
14、几种结果类型
<action name="resultAction" class="org.crazyit.action.ResultAction"> <!-- 结果类型: dispatcher 1.dispatcher 结果类型是最常用的结果类型, 也是 struts 框架默认的结果类型 2.该结果类型有一个 location 参数, 它是一个默认参数 等同于 <result name="result1" type="dispatcher"> <param name="location">/content/login.jsp</param></result> 3.dispatcher 结果类型将把控制权转发给应用程序里的指定资源. 4.dispatcher 结果类型不能把控制权转发给一个外部资源. 若需要把控制权重定向到一个外部资源, 应该使用 redirect 结果类型 实际请求地址不变 --> <result name="result0" type="dispatcher">/login.jsp</result> <!-- 结果类型: redirect 1.redirect 结果类型将把响应重定向到另一个资源, 而不是转发给该资源. 2.redirect 结果类型接受下面这些参数: -location: 用来给出重定向的目的地.它是默认属性 -parse: 用来表明是否把 location 参数的值视为一个 OGNL 表达式来解释. 默认值为 true 3.redirect 结果类型可以把响应重定向到一个外部资源 实际请求地址发生转变。 --> <result name="result1" type="redirect"> <param name="location">/error.jsp</param> </result> <!-- 结果类型: redirectAction 1.redirectAction 结果类型把响应重定向到另一个 Action 2.redirectAction 结果类型接受下面这些参数: -actionName: 指定 “目的地” action 的名字. 它是默认属性 -namespace: 用来指定 “目的地” action 的命名空间. 如果没有配置该参数, Struts 会把当前 Action 所在的命名空间作为 “目的地” 的命名空间 --> <result name="result2" type="redirectAction"> <param name="actionName">testAction</param> <param name="namespace">/</param> </result> <!-- 结果类型: chain 1.chain 结果类型的基本用途是构成一个 action 链: 前一个 action 把控制权转发给后一个 action, 而前一个 action 的状态在后一个 action 中依然保持 2.chain 结果类型接受下面这些参数: -actionName: 指定目标 action 的名字. 它是默认属性 -namespace: 用来指定 “目的地” action 的命名空间. 如果没有配置该参数, Struts 会把当前 action 所在的命名空间作为 “目的地” 的命名空间 -method: 指定目标 action 方法. 默认值为 execute --> <result name="result3" type="chain"> <param name="actionName">testAction</param> <param name="namespace">/</param> </result> </action> </package> <package name="testPackage" namespace="/" extends="struts-default"> <action name="testAction" class="org.crazyit.action.TestAction"> <result>/error.jsp</result> </action> </package>
15、Struts2的异常机制
execute()方法可以抛出全部的异常,这意味着我们重写该方法时,完全无需进行任何异常处理,而是将异常交给Struts2框架处理。Struts2框架接受到异常之后,根据struts.xml文件配置的异常映射,转入指定的视图资源。
可以在struts.xml文件中通过<exception-mapping/>元素配置。
指定两个属性:
①exception:指明异常类型 ② result :异常映射结果配置
根据<exception-mapping/>所处的位置不同又可以分为两种。
局部异常映射:<exception-mapping/>作为<action/>子元素
全局异常映射:<exception-mapping/>作为<global-exception-mappings>元素的子元素