今天到了Struts2学习的第二天,今天总体内容来说比较少,所以博主能够好好休息一下,这篇写完还早,准备看个电影,哈哈哈哈;
Struts2的页面跳转方式(各种方式背后的源码其实还是我们在Servlet中写的):
转发:> 根据前面学习,我们知道Struts2的页面跳转方式的配置在struts.xml中action配置中的result中的type属性,这次我们来具体看看:
测试代码:
1 | public class Demo1Action extends ActionSupport{ |
配置信息:
1 | <!-- 转发 --> |
配置信息:(注意action中的name属性不同):
1 | <!-- 重定向 --> |
转发到action(注意是转发到action):
测试代码:
1 | public class Demo3Action extends ActionSupport{ |
配置信息:
1 | <!-- 转发到Action --> |
配置信息:
1 | <!-- 重定向到action --> |
Struts2访问ServletAPI的方式:
之前我们是在Servlet中写代码,有requets,session……等对象,但是我们在action对象中如何去获取Servlet中的这些类呢?
访问Servlet的原理:
这是什么意思呢?
就是Struts2中有一个ActionContext对象,算是Struts2的上下文对象吧,它会帮你获取到原生的ServletAPI并且将其储存起来,你需要的时候就去创建ActionContext对象,从中获取Servlet的Api
注意:Struts2是线程安全的,它通过ThreadLocal类达到空间换取安全的目的,而synchranized(忘了咋写,尴尬)是通过时间换取安全的,两者目的相同,实现不同,具体可以百度ThreadLocal类看其原理,其次我们得知道,其实各个域对象其实是个map集合(点到这);
ActionContext访问(推荐):
1 | public class Demo5Action extends ActionSupport{ |
让我们跟进ActionContext.getContext()的getContext()这段源码是这样:
1 | public static ActionContext getContext() { |
再次跟进actionContext.get()的actionContext会看到:
1 | static ThreadLocal<ActionContext> actionContext = new ThreadLocal<ActionContext>(); |
是不是跟我说的一样:是使用ThreadLocal来获得Servlet的原生api
通过ServletActionContext访问:
1 | import javax.servlet.ServletContext; |
这种其实没有价值,因为它需要去依赖Servlet的一些jar包,我们写代码讲究低耦合,高内聚,所以并不推荐
我们跟进ServletActionContext.getRequest()这段代码的getRequest()的源码:
1 | public static HttpServletRequest getRequest() { |
我们又发现了ActionContext对象,所以这种方法的本质其实还是通过ActionContext来获取的,最后一种方法也是这样,说Struts2有三种访问Servlet的方式的人只不过是个初学者,本质都是这一个;
通过实现接口的方式访问:
1 | public class Demo7Action extends ActionSupport implements ServletRequestAware{ |
注意:这种方式实现的接口后缀都是Aware,需要实现一个方法,这个方法就一行代码,简单的一皮,只需设置就行,还需创建设置的本地变量
1 | public void setServletRequest(HttpServletRequest request) { |
这个时候我们去到struts-default.xml文件中去找默认拦截器配置拦截器
找到这段:
1 | <interceptor-stack name="defaultStack"> |
其中有个:
这个是声明,我们看上面有它的定义:
1 | <interceptor name="servletConfig" class="org.apache.struts2.interceptor.ServletConfigInterceptor"/> |
复制后面的org.apache.struts2.interceptor.ServletConfigInterceptor,
然后Ctrl+Shift+T,查找这个类(注意关联源码)
进去后是这样:
1 | /* |
看intercept方法,里面是不是又出现了ActionContext,还是通过ActionContext来获取Servlet的原生API的
Struts2获得参数的方式:
扩展:
分清MVC和三层架构,两个不一样
Action的生命周期:
1.每次请求到来时,都会创建一个新的Action实例
2.Action是线程安全的.可以使用成员变量接收参数
属性驱动获得参数:
表单:
1 | <form action="${pageContext.request.contextPath}/Demo8Action"> |
代码:
1 | //struts2如何获得参数---方式一: |
注意:这种方式还行,每个属性都需要get和set方法;
对象驱动获得参数:
注意表单(name属性):
1 | <form action="${pageContext.request.contextPath}/Demo9Action"> |
代码:
1 | public class Demo9Action extends ActionSupport { |
模型驱动获得参数:
表单(这次表单没变):
1 | <form action="${pageContext.request.contextPath}/Demo10Action"> |
代码:
1 | //struts2如何获得参数---方式三 |
封装集合类参数:
表单:
1 | <form action="${pageContext.request.contextPath}/Demo11Action" method="post"> |
代码:
1 | package yp.itcast.c_param; |