一、 结果页面跳转
使用<result>
元素的type属性和name属性
- name属性:指定逻辑视图的名称,默认值为success
- type属性:指定返回的视图资源的类型,不同类型代表不同的输出结果,默认值为dispatcher
<struts>
<package name="result" namespace="/" extends="struts-default" >
<!-- 转发 -->
<action name="Demo1Action" class="com.aiit.result.Demo1Action" method="execute" >
<result name="success" type="dispatcher" >/hello.jsp</result>
</action>
<!-- 重定向 -->
<action name="Demo2Action" class="com.aiit.result.Demo2Action" method="execute" >
<result name="success" type="redirect" >/hello.jsp</result>
</action>
<!-- 转发到Action -->
<action name="Demo3Action" class="com.aiit.result.Demo3Action" method="execute" >
<result name="success" type="chain">
<!-- action的名字 -->
<param name="actionName">Demo1Action</param>
<!-- action所在的命名空间 -->
<param name="namespace">/</param>
</result>
</action>
<!-- 重定向到Action -->
<action name="Demo4Action" class="com.aiit.result.Demo4Action" method="execute" >
<result name="success" type="redirectAction">
<!-- action的名字 -->
<param name="actionName">Demo1Action</param>
<!-- action所在的命名空间 -->
<param name="namespace">/</param>
</result>
</action>
</package>
</struts>
以上分别为由一个Action转达到jsp,一个Aciton重定向到jsp。由一个Action转发到另外一个Action。由一个Action重定向到另一个Action.
二、 Struts访问Servlet的API
在Struts2中,Action不能直接访问ServletAPI。在Action中完全不访问ServletAPI几乎不可能,因为我们经常需要使用Servlet中session和request
1,通过ActionContext类访问
Struts2框架提供了ActionContext类来访问Servlet API,ActionContext是Action执行的上下文对象,在ActionContext中保存了Action执行所需要的所有对象。下面列举ActionContext类访问ServletAPI的几个常用方法
方法声明 | 功能描述 |
---|---|
void put(String key,Object value) | 将key-value键值对放入ActionContext中,模拟ServletAPI中的HttpServletRequest的SetAttribute()方法 |
Object get(String key) 值 | 通过参数 key 来查找当前ActionContext 中的值 |
Map<String,Object> getApplication() | 返回一个Application 级的Map对象 |
static ActionContext getContext() | 获取当前线程的ActionContext对象 |
Map<String,Object> getParameters( ) | 返回一个包含所有 HttpServletRequest参数信息的Map对象 |
Map<String,Object> getSession() | 返回一个Map类型的HttpSession对象 |
void setApplication(Map<String,Object> application) | 设置Application上下文,application |
void setSession(Map<String,Object>session) | 设置一个Map类型的Session值。 |
Action的生命周期:每次请求时都会创建一个与请求对应的ActionContext对象,请求处理完ActionContext销毁
如何获得ActionContext :struts2设计的是,将ActionContext对象创建好之后,将ActionContext与当前线程绑定,我们要获得ActionContext。只需要从ThreadLocal中获得即可。
//request (struts不推荐使用原生的request域)
//Map<String, Object> requestScope = (Map<String, Object>) ActionContext.getContext().get("request");
//推荐
ActionContext.getContext().put("name", "requestTom");
//session域
Map<String, Object> sessionScope = ActionContext.getContext().getSession();
sessionScope.put("name", "sessionTom");
//application
Map<String, Object> applicationScope = ActionContext.getContext().getApplication();
applicationScope.put("name", "applicationTom");
此时我们在jsp中取出数据
<body>
request:${ requestScope.name }<br/>
session:${ sessionScope.name }<br/>
application:${ applicationScope.name }
</body>
2, 通过ServletActionContext访问
为了直接访问ServletAPI,struts2框架提供了ServletActionContext
类,该类包含了几个常用的静态方法。查看源码
public static HttpServletRequest getRequest() {
return (HttpServletRequest) ActionContext.getContext().get(HTTP_REQUEST);
}
该工具也是通过ActionContext类来获取这些对象
-
static HttpServletRequest getRequest():获得web应用的HttpServletRequest对象
-
static HttpServletResponse getResponse():获得web应用HttpServletResponse对象
-
static ServletContext getServletContext ():获得web应用的ServletContext对象
-
static PageContext getPageContext ():获得web应用的PageContext对象
//原生request
HttpServletRequest request = ServletActionContext.getRequest();
//原生session
HttpSession session = request.getSession();
//原生response
HttpServletResponse response = ServletActionContext.getResponse();
//原生SerletContext
ServletContext servletContext = ServletActionContext.getServletContext();
不推荐使用以上方法,struts2本身设计就是为了减少耦合度,脱离原生的Servlet.
3, 通过接口访问
public class Demo7Action extends ActionSupport implements ServletRequestAware,ServletResponseAware{
private HttpServletRequest request;
private HttpServletResponse response;
@Override
public String execute() throws Exception {
System.out.println("此为原生的request"+request);
System.out.println("此为原生的response"+response);
return super.execute();
}
@Override
public void setServletRequest(HttpServletRequest request) {
this.request = request;
}
@Override
public void setServletResponse(HttpServletResponse response) {
this.response =response;
}
}
三、 strutsMVC
- 普通MVC分别指:
- M:Service层和Dao层
- C:web层
- V:视图层,表示HTML,JSP等
- strutsMVC:
- M:Action。
- C:filter
- V:result
四、 Action的生命周期
struts是线程安全的,以往的一个服务器中只有一个Servlet,这可能导致并发问题,即多个用户访问Servlet,使用参数等都会出现覆盖问题。Servlet的解决方式是在方法中定义一些常量,因为不同的人访问一个方法。常量都会被刷新。
Action中,每次请求到来时,都会创建一个新的Action实例,且Action是线程安全的,可以使用成员变量来接受参数
public class Demo8Action extends ActionSupport {
private String name;
public Demo8Action(){
super();
System.out.println("demo8Action被创建");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String execute() throws Exception {
System.out.println("name参数值"+name);
return SUCCESS;
}
}
此时我们在浏览器中输入一些参数。构造方法都会创建一个新的对象
五、 struts的参数接受方式
方式一:属性驱动获取参数
Action类的书写,此处省略getter/setter方法
private String name;
//自动类型转化,只能转换8大基本数据类型以及对应的包装类
private Integer age;
//支持特定类型字符串转换为Date 例如:yyyy-MM-dd
private Date birthday;
@Override
public String execute() throws Exception {
System.out.println("name参数值"+name+",age参数值:"+age+",age参数值"+age);
return SUCCESS;
}
测试:表单书写参数
<form action="${pageContext.request.contextPath}/Demo8Action">
用户名:<input type="text" name="name"><br/>
年龄:<input type="text" name="age"><br/>
生日:<input type="text" name="birthday"><br/>
<input type="submit" value="提交"><br/>
</form>
方式二:对象驱动
将参数封装到一个对象中
第一步:我们书写一个实体类
public class User {
private String name;
private Integer age;
private Date birthday;
}
第二步:书写Action类
//准备一个User对象
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@Override
public String execute() throws Exception {
System.out.println(user);
return SUCCESS;
}
测试:表单中的参数提交方式(注意name属性)
<form action="${pageContext.request.contextPath}/Demo9Action">
用户名:<input type="text" name="user.name"><br/>
年龄:<input type="text" name="user.age"><br/>
生日:<input type="text" name="user.birthday"><br/>
<input type="submit" value="提交"><br/>
</form>
方式三:模型驱动
Action类需要实现一个接口,
优点,表单的name属性,可以按照原有的方式进行书写,缺点:只能返回一个对象
第一步:实体类准备(略)
第二步:书写Action类(注意泛型)
public class Demo10Action extends ActionSupport implements ModelDriven<User>{
//准备一个User对象
private User user = new User();
@Override
public String execute() throws Exception {
System.out.println(user);
return SUCCESS;
}
@Override
public User getModel() {
// TODO Auto-generated method stub
return user;
}
}
第三步:表单的书写
<form action="${pageContext.request.contextPath}/Demo10Action">
用户名:<input type="text" name="name"><br/>
年龄:<input type="text" name="age"><br/>
生日:<input type="text" name="birthday"><br/>
<input type="submit" value="提交"><br/>
</form>
方式四:集合类型参数封装
第一步:书写一个Action类
public class Demo11Action extends ActionSupport{
//准备一个User对象
private List<String> list ;
private Map<String,String> map;
public Map<String, String> getMap() {
return map;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
public List<String> getList() {
return list;
}
public void setList(List<String> list) {
this.list = list;
}
@Override
public String execute() throws Exception {
System.out.println(list);
System.out.println(map);
return SUCCESS;
}
}
第二步:表单提交
<form action="${pageContext.request.contextPath}/Demo11Action">
集合:<input type="text" name="list"><br/>
<!-- 提交到map的键对应的值中 -->
map:<input type="text" name="map['a']"><br/>
map:<input type="text" name="map"><br/>
<input type="submit" value="提交"><br/>
</form>