写给自己的话
好记性不如烂笔头,不可能说看了一遍视频就可以完全掌握的。留下这篇笔记,便于今后的复习吧。
1、 访问ServletAPI
访问ServletAPI(response,request,)的三种方式:
- ActionContext方式
- 实现***Aware接口
- ServletActionContext
2、Action的搜索顺序
以http://localhost:8080/struts2/path1/path2/path3/student.action为例。
- 第一步:先判断package是否存在,如:path1/path2/path3。如果存在,进入第二步,否则检查上一级路径下的package是否(直到默认的package),然后重复第一步。
- 第二步:判断action是否存在,如果不存在,则去默认的namespace的package里面寻找。要是还没有,就报错!
心得:package里面的命名空间最好还是按照自己action对应的位置写,这样不仅高效管理,还利于代码的维护。
3、动态方法调用
释义:动态方法调用就是为了解决一个action对应多个请求的处理,以免action太多。
我的理解就是:让一个action类中execute方法,调用action中其他的定义的方法。这样就可以不用针对一个请求写一个对应的action了,减少了action类的个数,使得代码维护更容易!
动态方法调用的三种方式:
- 指定method的属性:在struts.xml的action标签内进行method值得设置就可以了。(method的值就是我们要进行调用的方法的名称)这时一个action类可以被多个action映射,只要action的name不同就可以了。
-
感叹号方式: 使用前提是在struts.xml内声明一个标签
<constant name="struts.enable.DynamicMethodInvocation" value="truw"></constant>
。然后在只需要在这一个action中的result标签内写上该方法的返回值即可(注意要一一对应才行。)//如下:在action类中定义了 public String add() { return "add"; } public String update() { return "update"; } //则这时只需要在struts.xml中如下: <package name="default" namespace="/" extends="struts-default"> <action name="default" class="action.HelloWorld"> <result>/result.jsp</result> <result name="add">/add.jsp</result> <result name="update">/update.jsp</result> </action> </package>
这样访问这个链接的时候如果仍然是http://localhost:8080/HelloWorld/HelloWorld.action的话,就会跳转到第一个result标签对应的result.jsp页面。
如果想要访问add方法对应的那个页面,就需要如下http://localhost:8080/HelloWorld/HelloWorld!add.action就可以了。同样update方法的动态调用同样如此。 -
通配符方式: 这个方式的使用方式如下
<package name="default" namespace="/" extends="struts-default"> <!--下划线的作用就是分隔而已,而*则是对应了method中的第一个{1},如果name="helloworld_*_*",则method="{1}{2}"--> <action name="helloworld_*" method="{1}" class="action.HelloWorld"> <result>/result.jsp</result> <result name="add">/{1}.jsp</result> <result name="update">/{1}.jsp</result> </action> </package>
然后访问对应页面的时候只需要输入http://localhost:8080/HelloWorld/helloworld_add.action即可。
下面是进阶版的通配符的使用:<package name="default" namespace="/" extends="struts-default"> <!--我们应该尤其注意其{数字}对应的是哪一个通配符。下面的这种方式可以使用一个action完成所有的操作哦--> <action name="*_*" method="{2}" class="action.{1}"> <result>/result.jsp</result> <result name="add">/{2}.jsp</result> <result name="update">/{2}.jsp</result> </action> </package>
使用的时候http://localhost:8080/HelloWorld/HelloWorld_add.action.其中的HelloWorld就是第一个通配符对应的action类中在action标签中的name值(注意其大小写,应符合在类中的名称)。add代表的就是第二个通配符了,对应result标签的name值即可。
总结:指定method仍然会有大量的action标签;感叹号方式官方不建议使用;通配符的方式最为实用
4、指定多个配置文件
为了解决一个struts.xml文件过大,我们可以使用include标签将完成了不同模块的moudle_struts.xml文件整合到总的struts.xml文件中。
<struts>
<include file="moudle1.xml"></include>
<include file="moudle2.xml"></include>
···
</struts>
5、默认Action
官方解释就是一个给定的类似于404错误的默认的显示页面
<package name="default" namespace="/" extends="struts-default">
<!--name就是对应的action的名称,如下-->
<default-action-ref name="index"></default-action-ref>
<action name="index">
<result>/XX.jsp</result>
</package>
6、Struts2后缀相关
更改后缀的好处是可以伪造“页面”。改成.do;.html;···
下面是更改后缀的几种方式:
- struts.xml中的constant标签:
<constant name="struts.action.extension" value="html"></constant>
- struts.properties文件内:struts.action.extension = action,do,html···
-
在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.action.extension</param-name> <param-value>do,action,html···</param-value> </init-param> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
总结:有后缀了url上就需要带上相应的后缀;后缀名为null的时候访问页面就可以不带后缀。
7、在action中如何接收参数
常用的接收参数的方式有:
- 使用action的属性接收参数:比如一个表单,表单中的那些值要在相应的action类中声明为其属性,类似于bean的方式实现getter和setter的方法。这样在action标签中的method中对应的方法名就可以获取表单中提交的数据了。
-
使用DomainModel接收参数:第一种方式面对一个表单可能会写上好多的属性,这样维护起来很麻烦,所以可以定义一个bean,然后再action类中使用这个bean作为其整体的属性即可。然后在表单中指定这个属性即可。如下:
<!--注意这里面的user.username中的user就是在LoginAction类中的属性 --> <form action="LoginAction.action" method="login"> UserName:<input type="text" name="user.username"> Password:<input type="password" value="user.password"> <input type="submit" value="Submit"> </form> // 下面是LoginAction类的内容 public class LoginAction extends ActionSupport { private User user;//尤其注意是user,小写。且对应于表单的那个user.无需实例化!!! public String login(User user){ System.out.println(user.getUsername); return SUCCESS; } public User getUser() { return this.user; } public void setUser(User user) { this.user = user; } }
- 使用ModelDriven接收参数:需要实现ModelDriven接口,里面的泛型就是我们的bean类型。然后去除User的getter和setter方法,再对User进行实例化,在getModel方法中进行返回即可。然后最重要的一点就是表单中就不需要再指定了,可以直接写username,或者password了。
7、处理结果请求
Struts2的处理流程如下:
用户请求 –> Struts框架 –> 控制器(Action)–> Struts框架 –> 视图资源(jsp)
下面看一个小例子<result name="success">/Success.jsp</result>
result元素中的name就是result元素的逻辑的视图名称。
如果省略了name属性,系统将采用默认的name属性success。
系统共内置了五个特殊的字符串属性值,位于com.opensymphony.xwork.Action下,分别是:
- SUCCESS:Action正确的执行完成,返回相应的视图,此为默认
- NONE:表示Action的正确的执行完成,但是并不返回任何视图
- ERROR:表示Action的执行失败,返回到错误处理视图
- LOGIN:Action因为用户没有登录的原因而没有正确的执行,将返回该登陆视图,要求用户进行登录验证
- INPUT:Action的执行,需要从前端界面获取参数,INPUT就是代表这个参数的输入页面,一般在应用中会对这些参数进行验证,如果炎症没有通过,将自动返回到这个视图。
了解了这些常量之后,下面就正式的进入处理结果的部分。
处理结果是在struts.xml中result标签进行配置的。分为局部结果(将result作为action的子标签进行配置)和全局结果(将result标签作为global-results【需要在一个package进行支撑】的子标签进行配置)