一、struts2探索
学习完一定需要实际去运行,这样才能有更加深刻的理解!
1、几个主要的默认配置文
1)struts-default.xml配置文件
路径:struts2的strut2-core.jsr文件中
2)default.properties
路径:strut2-core.jar的org.apache.struts2包中
2、如何覆盖几个主要的默认文件的内容
1)方法一:在自己写 的Struts.xml,通过<constant>标签来描述。
2)通过在root目录下,新建struts.properties文件,重写需要覆盖的属性!
### Struts default properties
###(can be overridden by a struts.properties file in the root of the classpath)
3、关于加载
可以在strut2-core.jar的org.apache.struts2包中default.properties文件中看到
默认加载的配置文件为struts-defult.xml,struts-plugin.xml和struts.xml文件
4、若在struts.xml中的包中如果加上了namespace
<package name="struts2" extends="struts-default" namespace="/hello">
那么在jsp中提交到这个包下的action的话,我们就需要在jsp页面中修改
原来的如action=“register”
修改为action=“/hello/register.action”
5、在strut.xml中包含其他文件
万一项目比较大,可以把strut.xml模块化的方式配置
可以生成的struts1.xml、struts2.xml
然后用<include>标签把它们包含的进来!
6、MVC理解的struct
C:核心控制器ServletDispathe
业务控制器action:业务调用,只把接口调用没和逻辑写在里面。没有具体的实现!
7、模型驱动
1)目前action如register.action,文件,它就是让它与jsp页面的属性或叫字段一一对应
叫属性驱动。
2)模型驱动:有点类似struts1.0 的actionForm
本struts2.o的模型驱动的实现过程:
A、首先建立一个pojo类
package com.test.bean; import java.util.Date; public class User { private String username; private String password; private String repassword; private int age; private Date birthday; private Date graduation; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getRepassword() { return repassword; } public void setRepassword(String repassword) { this.repassword = repassword; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public Date getGraduation() { return graduation; } public void setGraduation(Date graduation) { this.graduation = graduation; } }
B、RegisterAction修改为RegisterAction2
package com.test.action; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.ModelDriven; import com.opensymphony.xwork2.Preparable; //Preparable内含prepare(),可以写一些执行action之前的方法 import com.test.bean.User; public class RegisterAction2 extends ActionSupport implements ModelDriven<User>,Preparable { private User user = new User(); public User getModel() { return user; } public void prepare() throws Exception { System.out.println("hello world"); } @Override public String execute() throws Exception { return SUCCESS; } }
C、修改Strut2.xml文件
<action name="register" class="com.test.action.RegisterAction2">
8、推荐属性驱动
原因一:就像struts1那样,即使有formAction,它只是和前台web页面对应的,我们在书写持久层如hibernate时,还是需要在来一个
pojo或叫javabean,所以说到底还是属性驱动比较方便!
9、修改错误提示信息位置
struts2默认的错误显示是显示在表格头部的 ,若想在显示时直接显示在相应字段旁边,在相应的位置加如下代码!
<td>
<s:fielderror cssStyle="color:red">
<s:param>username</s:param>
</s:fielderror>
</td>
10、表单重复提交
1)在rejister.jsp
的form表单中加一个标签
<S:token></s:token>
2)在struts.xml中的name为registrer的action加上
<interceptor-ref name="token"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
3)完成以上两部后重复提交,会报以下错误:invalid.taken,即重复提交时,需要配置错误处理
在struts.xml中的name为registrer的action加上重复提交报错提示页面!
<result name="invalid.token">/register2.jsp</result>
4)这个错误信息,struts2是放在action里面的
需要在register.jsp
加上以下错误显示的代码
<s:actinerror cssStyle="color:blue">
5)经过以上四步骤后,重复提交就会在相应的register2页面报不能重复提交的错误信息
但是该错误信息是struts2默认的,在struts-message.xml就第一行可以看到。
如果想要显示中文,可以国际化一下
在我们项目的root目录下已建立的文件message_zh_CN.properties文件中加一行
struts.messages.invalid.token = \u8bf7\u4e0d\u8981\u91cd\u590d\u63d0\u4ea4\u8868\u5355
二、Action中servelt如何测试
1、一般的junit测试方法无法提供servelt,可以通过以下两种工具:
1)第一种方式:apache项目中jakarta项目中Cactus(jakarta项目是一个很好的项目,里面有很多小项目,像性能测试JMeter)
2)第二种方式:Mock
2、struts2一般已经可以脱离servelt了,可以直接用junit测试
不过有些地方还是需要耦合,struts2提供下面的类:
有三种方法获得的servlet相关的东西
1)方法一:使用ActionContext类
使用方法:
A、在action类中
ActionContext.getContext().put("zhangsan","helloworld")
//该方法相当于httpServeltReques的setAttribute()方法。
//而且该方法有以下好处:一是将session保存成一个map了,这样我们也可以直接用junit测试
但是该方法没有办法获得httpServletResponse相应的这个对象,这样的话常见方法二
B、在jsp页面中我们增加
张三:${requestScope.zhangsan}
2)方法二:实现ActionContextAware接口(该接口ServletRequestAware及ServletResponseAware相似)
该接口中了有方法setSevletRequest()
使用方法:
A、在longinAction.java中增加以下代码:
private HttpSevletRequest request;
Public void setServletRequest(HttpSevletRequest request){
this.request=requst;
}
这个方法会有是struts2框架自己调用的 ,内部运用 了IOC
这样的话可以直接在action类中使用request对象了。
B、同样在longinAction.java中增加response对象,以下代码:
private HttpSevletResponse response;
Public void setServletResponse(HttpSevletResponse response){
this.response=response;
}
这个方法会有是struts2框架自己调用的 ,内部运用 了IOC
这样的话可以直接在action类中使用response对象了。
同时可以设置Cookie
Cookie cookie=new Cookie("userName",this.getUseerName());
cookie.setMaxAge(1000);
response.addCookie(cookie);
return SUCCESS;
在jsp页面中显示cookie
cookie: ${cookie.userName.value}
3)方法三:ServletActionContext类
HttpServletResponse response=ServletActionContext.getResponse();
总结:方法一和方法三用的较多,首选方法一,其次用方法三。方法二不介意使用。
三、struts2探索续
1、动态方法调用
方法一:在jsp页面中
action="login!hello.action"
即提交表单时,不再去执行对应action中excute()方法,而是去执行hello()方法。
该方法等价于在jsp页面中不使用"!"后面部分,在strut.xml方法中
<action name="login" class="com.test.action.LoginAction "method="hello">
2、关于重定向等
1)了解在struts-default.xml文件中,结果试图默认默认true的是name="dispatcher"
<package name="struts-default" abstract="true"> <result-types> <result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/> <result-type name="dispatcher" class="org.apache.struts2.dispatcher.ServletDispatcherResult" default="true"/> <result-type name="freemarker" class="org.apache.struts2.views.freemarker.FreemarkerResult"/> <result-type name="httpheader" class="org.apache.struts2.dispatcher.HttpHeaderResult"/> <result-type name="redirect" class="org.apache.struts2.dispatcher.ServletRedirectResult"/> <result-type name="redirectAction" class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/> <result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/> <result-type name="velocity" class="org.apache.struts2.dispatcher.VelocityResult"/> <result-type name="xslt" class="org.apache.struts2.views.xslt.XSLTResult"/> <result-type name="plainText" class="org.apache.struts2.dispatcher.PlainTextResult" /> </result-types>
2)其中的redirect和redirectAction都表方从定向(他们两个的区别是一个重定向到视图,另一个重定向到action)
重定向到话了request的内容将不会被保存,他将表示另一个请求。