structs2是基于MVC开发模型的web层框架 servlet技术的封装
structs1也是MVC开发模式的框架。struts2并不是struts1的升级版。
struts2是基于webwork的升级版。struts2=webwork+structs1
目标: 一个项目只对应一个Servlet处理类
<!-- 配置启动strut2的全局过滤器 -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
编写不同的业务Action类
在src目录下(类路径的根目录下),新建一个struts.xml,配置Action对象
项目启动:
1)创建核心过滤器StrutsPrepareAndExecuteFilter对象
2)执行核心过滤器的init方法
读取了依次以下的配置:
struts-default.xml [struts2框架的默认配置文件(不需要自定修改)]
struts-plugin.xml [struts2的插件配置文件]
struts.xml [我们写的业务配置文件(包含配置的Action)]
访问资源:
3) 在内存中查询对应的Action配置,得到class内容,创建Action对象。
4)读取Action配置的method内容,执行Action对象对应的方法。
过滤器: 可以过滤任何类型的请求(html、servlet、jsp)和响应。加入通用的代码逻辑。
拦截器: 是sturts2的特有功能。只能过滤Action!!在执行Action的时候加入通用的代码
包含读取其他xml文件:
<include file="config/struts-book.xml"></include>
<include file="config/struts-user.xml"></include>
struts2的Action三种使用方式
1 不实现Action接口
2 实现Action接口
1)定义了默认的execute方法的标准 2)提供了项目中常用的视图标记
3 继承ActionSupport类(推荐)
1)提供了常用的视图标记 2)提供了数据校验功能
路径通配符
好处: 大大地减少action的配置
<action name="user_*" class="gz.itcast.b_path.UserAction" method="{1}">
<result name="{1}">/{1}.jsp</result>
</action>
<action name="*_*" class="gz.itcast.b_path.{1}Action" method="{2}">
<result name="{2}">/{1}/{2}.jsp</result>
</action>
strus2的常量配置
<constant name="struts.i18n.encoding" value="UTF-8"/>
<constant name="struts.action.extension" value="do"/>
设置浏览器是否缓存静态内容,默认值为true(生产环境下使用),开发阶段最好关闭
<constant name="struts.serve.static.browserCache" value="false"/>
当struts的配置文件修改后,是否自动重新加载该文件,默认false(生产环境下使用),开发阶段最好打开
<constant name="struts.configuration.xml.reload" value="true"/>
开发模式下使用,这样可以打印出更详细的错误信息
<constant name="struts.devMode" value="true" />
默认的视图主题
<constant name="struts.ui.theme" value="simple" />
与spring集成时,指定由spring负责action对象的创建
<constant name="struts.objectFactory" value="spring" />
该属性设置Struts 2是否支持动态方法调用,该属性的默认值是true
<constant name="struts.enable.DynamicMethodInvocation" value="false"/>
上传文件的大小限制
<constant name="struts.multipart.maxSize" value=“10701096"/>
通过struts.xml文件声明<constant name="struts.action.extension" value="action,do,,"></constant>修改常量配置。
struts2的全局视图配置和默认配置
<global-results>
<result name="success">/login.jsp</result>
</global-results>
action的局部视图会覆盖全局视图
action的默认配置:
name: 必填项
class: 可选项,默认:ActionSupport类该类继承自struts-default (<default-class-ref class="com.opensymphony.xwork2.ActionSupport" />)
method: 可选
result:
name: 可选。默认配置: success
type: 可选。默认配置: dispatcher
<!-- 全部使用默认配置的action的作用 :专门用于转发到WEB-INF下的页面 -->
<action name="book">
<result>/WEB-INF/jsp/login.jsp</result>
</action>
Action的属性注入:
在Action类中声明一个成员变量,提供一个该变量的setter方法,用于接收xml配置文件传入内容
在action中配置param
<action name="upload" class="gz.itcast.d_ioc.UploadAction" method="upload">
<param name="savePath">e:/images/</param>
<result>/login.jsp</result>
</action>
数据共享的三种方式
第一种方式
ServletActionContext类
getRequest() HttpServletRequest
getRequest().getSession() HttpSession
getServletContext() ServletContext
注意:
1)该方式依赖servlet的api,耦合比较高
2)如果要通过域对象来获取域对象的相关信息必须使用该方式
第二种方式
ActionContext类 ActionContext.getContext中
getContextMap() : 获取操作request域对象数据的map集合
getSession() : 获取操作session域对象数据的map集合
getApplication() 获取操作context域对象数据的map集合
注意:
1)不依赖servlet的api,耦合性低
2)只能用在Action对象的一个方法中。不能在所有方法中都是用同一个ActionContext
第三种方式
使用 RequestAware , SessionAware ApplicationAware 接口
注入操作对应域对象数据的Map集合
public class BaseAction extends ActionSupport implements
RequestAware,SessionAware,ApplicationAware{
public void setRequest(Map<String, Object> request) {
this.requestMap = request;
}
public void setSession(Map<String, Object> session) {
this.sessionMap = session;
}
public void setApplication(Map<String, Object> application) {
this.contextMap = application;
}
}
注意:
1)不依赖servlet的api
2)可以在Action对象的所有方法中共享Map集合
数据的封装:
<form action="${pageContext.request.contextPath }/data/user_register.action" method="post">
用户名: <input type="text" name="user.name"/><br/>
密码: <input type="password" name="user.password"/><br/>
性别: <input type="radio" name="user.gender" value="男"/>男
<input type="radio" name="user.gender" value="女"/>女<br/>
爱好:
<input type="checkbox" name="user.hobit" value="篮球"/>篮球
<input type="checkbox" name="user.hobit" value="足球"/>足球
<input type="checkbox" name="user.hobit" value="羽毛球"/>羽毛球<br/>
<input type="submit" value="注册"/>
</form>
public class UserAction2 extends ActionSupport{
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
请求参数的封装通过struts2的ParametersInterceptor拦截器进行赋值.
文件上传:
private File attach;
private String attachContentType;
private String attachFileName;
private String info;
private String savePath;
FileUtils.copyFile(attach, new File(savePath+attachFileName));
<action name="upload" class="gz.itcast.h_upload_down.UploadAction" >
<!-- 往FileUploadInterceptor拦截器的属性注入值(调用setter方法) -->
<interceptor-ref name="defaultStack">
<param name="fileUpload.allowedTypes">image/jpeg,image/jpg</param>
<param name="fileUpload.allowedExtensions">jpg,jpeg,gif</param>
</interceptor-ref>
<param name="savePath">e:/images/</param>
<result>/login.jsp</result>
<result name="input">/error.jsp</result>
</action>
文件下载
视图类型一定是stream类型
<action name="down_*" class="gz.itcast.h_upload_down.DownAction" method="{1}">
<param name="serverPath">e:/images/</param>
<result name="list">/listFile.jsp</result>
<result name="down" type="stream">
<!-- 返回给浏览器的文件类型。返回通用的二进制 -->
<param name="contentType">application/octet-stream</param>
<!-- 返回给浏览器的输入流 -->
<param name="inputName">inputStream</param>
<param name="contentDisposition">attachment;filename=${name}</param>
<param name="bufferSize">1024</param>
</result>
</action>
public InputStream getInputStream(){
try {
FileInputStream fis = new FileInputStream(new File(serverPath+name));
return fis;
} catch (FileNotFoundException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
public String getName() {
return name;
}