4.1 Struts2架构
    1、ActionMapper:
        提供请求和Action之间的映射。根据请求查找是否存在对于的action,如有,翻译描述action映射的ActionMapping对象,没有,返回null
    2、ActionMapping:
        保存了调用action的映射信息,其中必须保存Action的命名空间信息和name属性
    3、ActionProxy:
        在XWork和真正的Action之间充当代理
    4、ActionInvocation:
        表示执行状态,它按顺序保存拦截器,Action,实例,由ActionProxy创建,通过调用invoke()方法开始Action的执行
    5、Interceptor(拦截器):
        是一种可以在请求处理之前或者之后执行的Struts2组件
4.2 Struts2拦截器
    工作原理:
        做一些Action执行前的预处理,可以准备,过滤,改变或者操作任何可以访问的数据,包括Action
        调用ActionInvocation的invoke()方法将控制转交给后续的拦截器或者返回结果字符串终止执行,如果请求不应该继续,可以不调用invoke()方法
            而是直接返回一个控制字符串,通过这种方式,可以停止后续的执行,并且决定哪个结果来呈现给客户端。
        做一些Action执行之后的处理:此时拦截器依然可以改变可以访问的对象和数据,执行此时框架已经选择一个结果呈现给客户端了
    
    拦截器的配置
        1、通过<interceptor.../>元素来定义拦截器
        2、通过<interceptor-ref.../>元素来使用拦截器
        例:
        <package name="default" extends="struts-default" namespace="/">
            <interceptors>
            定义拦截器
                <interceptor name="interceptorName" class="interceptor.MyTimerInterceptor"/>
            定义拦截器栈
                <interceptor-stack name="interceptorStackName">
                指定引用的拦截器
                <interceptor-ref name="interceptorName | interceptorStackName"/>
                </interceptor-stack>
            </interceptors>
            定义默认的拦截器引用
                <default-interceptor-ref name="interceptorName | interceptorStackName"/>
                <action name="actionName" class="interceptor.MyTimerAction">
                    为Action指定拦截器引用
                    <interceptor-ref name="interceptorName | interceptorStackName"/>
                    <result name="success">indexWelcom.jsp</result>
                    <result name="input">index.jsp</result>
                </action>
        </package>
    内置拦截器
        1、params拦截器:将请求中的数据设置到Action的属性上
        2、staticParams拦截器:将在配置文件中通过action元素的子元素Param设置的参数设置到对应的Action属性中
        3、servletConfig拦截器:提供了一种将源于Servlet API 的各种对象注入Action中的方法
            获取ServletAPI对象的接口
                        接口                        作用
                ServletContextAware               设置ServletContext
                ServletRequestAware                 设置HttpServletRequest
                ServletResponseAware            设置HttpServletResponse
                ParameterAware                    设置Map类型的请求参数
                ResquestAware                    设置Map类型的请求HttpServletRequest属性
                SessionAware                    设置Map类型的会话HttpSession属性
                ApplicationAware                设置Map类型的应用程序作用域对象ServletContext
        4、fileUpload拦截器:将文件和元数据从多重请求(multipart/form-data)转换为常规请求数据,以便于将他们设置在对于的Action上
        5、validation拦截器:执行数据校验
        6、workflow拦截器:提供当数据校验错误时终止执行流程的功能
        7、exception拦截器:捕获异常
    拦截器栈
        <interceptor-stack name="defaultStack">
            <interceptor-ref name="exception"/>
            <interceptor-ref name="alias"/>
            <interceptor-ref name="servletConfig"/>
            <interceptor-ref name="prepare"/>
            <interceptor-ref name="il8n"/>
            <interceptor-ref name="chain"/>
            <interceptor-ref name="debugging"/>
            <interceptor-ref name="profiling"/>
            <interceptor-ref name="scopedModelDriven"/>
            <interceptor-ref name="modelDriven"/>
            <interceptor-ref name="fileUpload"/>
            <interceptor-ref name="checkbox"/>
            <interceptor-ref name="staticParams"/>
            <interceptor-ref name="params">
                <param name="excludeParams">dojo\..*</param>
            </interceptor-ref>
            <interceptor-ref name="conversionError"/>
            <interceptor-ref name="validation">
                <param name="excludeMethods">input,back,cancel,browse</param>
            </interceptor-ref>
            <interceptor-ref name="workflow">
                <param name="excludeMethods">input,back,cancel,browse</param>
            </interceptor-ref>
        </interceptor-stack>
    自定义拦截器
        在Struts2中所有拦截器都直接或间接的实现接口om.opensymphony.xwork2.interceptor.Interceptor.
        该接口提供了3各个方法:
            void init():该拦截器初始化之后,在拦截器执行拦截之前,系统回调该方法,此方法只执行一次
            void destroy():在拦截器实例被销毁之前,系统回调该方法
            String intercept(ActionInvocation invocation) throws Exception:是用户需要实现的拦截动作,返回结果字符串
            
        首先编写权限验证拦截器

 public class AuthorizationInterceptor extends AbstractInterceptor {
/**
* 拦截器的拦截方法
*/
@Override
public String intercept(ActionInvocation invocation) throws Exception {
//获取回话信息
@SuppressWarnings("rawtypes")
Map session=invocation.getInvocationContext().getSession();
users user=(users) session.get("login");
if(user==null){
//终止执行,返回登录页面
return Action.LOGIN;
}else{
//继续执行剩余的Action和拦截器
return invocation.invoke();
}
}
}

然后在配置文件中定义拦截器并引用

 <package name="default" extends="struts-default" namespace="/">
<interceptors>
<!-- 定义权限验证拦截器 -->
<interceptor name="myAuthorization" class="interceptor.AuthorizationInterceptor"></interceptor>
<interceptor-stack name="myStack">
<interceptor-ref name="defaultStack"/>
<interceptor-ref name="myAuthorization"/>
</interceptor-stack>
</interceptors>
<!-- 定义默认拦截器 -->
<default-interceptor-ref name="myStack"/>
<default-action-ref name="defaultAction"/>
<!-- 定义全局结果 -->
<global-results>
<result name="login" type="redirect">login.jsp</result>
</global-results>
<action name="defaultAction" class="interceptor.MyTimerAction">
<result name="fail">fail.jsp</result>
</action>
<action name="house" class="interceptor.MyTimerAction">
<result name="success">guanli.jsp</result>
<interceptor-ref name="myStack"></interceptor-ref>
</action>
</package>

4.3 实现文件上传
        UploadAction.java

  public class uploadAction  extends ActionSupport{
//封装上传文件属性
private File upload;
//封装上传文件类型
private String uploadContentType;
//封装上传文件名称
private String uploadFileName;
//封装上传文件的路径
private String savePath; @Override
public String execute()throws Exception{
byte[] buffer=new byte[1024];
//读取文件
FileInputStream fis=new FileInputStream(getUpload());
//保存文件,设置保存目录路径
FileOutputStream fos=new FileOutputStream(getSavePath()+"\\"+this.getUploadFileName());
int length=fis.read(buffer);
while(length>0) {
//每次写入length长度的内容
fos.write(buffer, 0, length);
length=fis.read(buffer);
}
fis.close();
fos.flush();
fos.close();
return "success";
}
//获取上传文件的保存路径
//通过读取存放目录获得保存路径
//省略get/set方法
public String getSavePath() {
return ServletActionContext.getServletContext().getRealPath(savePath);
}
}

配置文件中定义uploadAction

  <action name="download" class="interceptor.FileDownAction">
<param name="savePath">/upload</param>
<result name="success" type="stream">
<param name="contentType">application/octet-stream</param>
<param name="inputName">inputStream</param>
<param name="contentDisposition">attachment;filename="${fileName}"</param>
<param name="bufferSize">4096</param>
</result>
</action>

多文件上传

  public class uploadActions extends ActionSupport{
//封装上传文件属性
private File[] upload;
//封装上传文件类型
private String[] uploadContentType;
//封装上传文件名称
private String[] uploadFileName;
//封装上传文件的路径
private String savePath;
          //省略get/set方法
@Override
public String execute()throws Exception{
byte[] buffer=new byte[1024];
for (int i = 0; i < upload.length; i++) {
//读取文件
FileInputStream fis=new FileInputStream(getUpload()[i]);
//保存文件,设置保存目录路径
FileOutputStream fos=new FileOutputStream(getSavePath()+"\\"+this.getUploadFileName());
int length=fis.read(buffer);
while(length>0) {
//每次写入length长度的内容
fos.write(buffer, 0, length);
length=fis.read(buffer);
}
fis.close();
fos.flush();
fos.close(); }
return "success";
}
}

4.4文件下载
        Stream结果类型
            contentType            设置发送到浏览器的MIME类型
            contentLength        设置文件大小
            contentDisposition    设置响应的HTTP头信息中的content-Disposition参数的值
            inputName            指定Action中提供的inputStream类型的属性名称
            bufferSize            设置读取和下载文件是的缓冲区大小
                
        FileDownAction.java

 public class FileDownAction extends ActionSupport {
//读取下载文件目录
private String inputPath;
//下载文件的文件名
private String fileName;
//读取下载文件的输入流
private InputStream inputStream;
//下载文件类型
private String contentType;
public String getInputPath() {
return inputPath;
}
public void setInputPath(String inputPath) {
this.inputPath = inputPath;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
} public InputStream getInputStream()throws FileNotFoundException {
String path=ServletActionContext.getServletContext().getRealPath(inputPath);
return new BufferedInputStream(new FileInputStream(path+"\\"+fileName));
}
public void setInputStream(InputStream inputStream) {
this.inputStream = inputStream;
}
public String getContentType() {
return contentType;
}
public void setContentType(String contentType) {
this.contentType = contentType;
}
@Override
public String execute()throws Exception{
return "success";
}
}

配置文件

 <action name="download" class="interceptor.FileDownAction">
<param name="savePath">/upload</param>
<result name="success" type="stream">
<param name="contentType">application/octet-stream</param>
<param name="inputName">inputStream</param>
<param name="contentDisposition">attachment;filename="${fileName}"</param>
<param name="bufferSize">4096</param>
</result>
</action>

contentType对应的文件类型
            Word            application/msword
            Execl            Application/vnd.ms-excel
            PPT                Application/vnd.ms-powerpoint
            图片            image/gif、image/bmp、image/jpeg
            文本文件        text/plain
            HTML网页        text/html
            可执行文件        application/octet-stream

第四章 Struts2深入的更多相关文章

  1. 《Django By Example》第四章 中文 翻译 (个人学习,渣翻)

    书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:祝大家新年快乐,这次带来<D ...

  2. 《Linux内核设计与实现》读书笔记 第四章 进程调度

    第四章进程调度 进程调度程序可看做在可运行太进程之间分配有限的处理器时间资源的内核子系统.调度程序是多任务操作系统的基础.通过调度程序的合理调度,系统资源才能最大限度地发挥作用,多进程才会有并发执行的 ...

  3. 《Entity Framework 6 Recipes》中文翻译系列 (20) -----第四章 ASP.NET MVC中使用实体框架之在MVC中构建一个CRUD示例

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 第四章  ASP.NET MVC中使用实体框架 ASP.NET是一个免费的Web框架 ...

  4. 《Entity Framework 6 Recipes》中文翻译系列 (21) -----第四章 ASP.NET MVC中使用实体框架之在页面中创建查询和使用ASP.NET URL路由过虑

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 4.2. 构建一个搜索查询 搜索数据是几乎所有应用的一个基本功能.它一般是动态的,因 ...

  5. 精通Web Analytics 2.0 (6) 第四章:点击流分析的奇妙世界:实际的解决方案

    精通Web Analytics 2.0 : 用户中心科学与在线统计艺术 第四章:点击流分析的奇妙世界:实际的解决方案 到开始实际工作的时候了.哦耶! 在本章中,您将了解到一些最重要的网络分析报告,我将 ...

  6. Java语言程序设计(基础篇) 第四章 数学函数、字符和字符串

    第四章 数学函数.字符和字符串 4.2 常用数学函数 方法分三类:三角函数方法(trigonometric method).指数函数方法(exponent method)和服务方法(service m ...

  7. 《利用python进行数据分析》读书笔记--第四章 numpy基础:数组和矢量计算

    http://www.cnblogs.com/batteryhp/p/5000104.html 第四章 Numpy基础:数组和矢量计算 第一部分:numpy的ndarray:一种多维数组对象 实话说, ...

  8. 05 技术内幕 T-SQL 查询读书笔记(第四章)

    第四章 子查询:在外部查询内嵌套的内部查询(按照期望值的数量分为,标量子查询 scalar subqueries,多值子查询multivalued subqueries)(按照子查询对外部查询的依赖性 ...

  9. 读《编写可维护的JavaScript》第四章总结

    第四章 变量 函数和运算符 4.1 ① 变量声明 变量声明是通过var语句来完成的,并且所有的var语句都提前到包含这段逻辑的函数的顶部执行. function doSomething() { + v ...

随机推荐

  1. ABP入门系列(13)——Redis缓存用起来

    ABP入门系列目录--学习Abp框架之实操演练 源码路径:Github-LearningMpaAbp 1. 引言 创建任务时我们需要指定分配给谁,Demo中我们使用一个下拉列表用来显示当前系统的所有用 ...

  2. Yii 2.0 ActiveForm生成表单 ,控制表单label和filed样式,filed一旦报错,前面lable颜色跟着变,看图,帮你解决

    需要生成如下图的表单样式,图一:

  3. C++ 11 学习1:类型自动推导 auto和decltype

    Cocos 3.x 用了大量的C++ 11 的东西,所以作为一个C++忠实粉丝,有必要对C++ 11进行一个系统的学习. 使用C++11之前,一定要注意自己使用的编译器对C++11的支持情况,有些编译 ...

  4. python之实现批量远程执行命令(堡垒机)

    python远程批量执行 我并不是一个专业的开发,我一直在学习linux运维,对于python也是接触不久,所以代码写的并不是很规范简洁. 前段时间一个同学找我一起做一个自动化运维平台,我对pytho ...

  5. 3361: [Usaco2004 Jan]培根距离

    3361: [Usaco2004 Jan]培根距离 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 16  Solved: 13[Submit][Sta ...

  6. java aes encrypt

    本次使用aes 对称加密算法. 选用aes的原因是,可以还原加密串. 程序如下: public static String encode(String content){ KeyGenerator k ...

  7. linux 私房菜 CH5 笔记

    知识点 linux 大小写敏感 接口的切换 [Ctrl] + [Alt] + [F1] ~ [F6] :文字接口登入 tty1 ~ tty6 终端机: [Ctrl] + [Alt] + [F7] :图 ...

  8. web从入门开始(2)----基础

    HTML文件结构 <html> <head>//网页头标记 <title>放置标题</title> </head> <body> ...

  9. java根据HashMap中的值将其元素排序

    思路:HashMap或Map本身没有排序功能,若要进行较轻松的排序,可利用ArrayList中的sort方法 例子: import java.util.ArrayList; import java.u ...

  10. linux系统和Windows系统共存

    最近接触了linux系统,因为对linux系统一直存在一种敬畏之心,所以决定研究研究 那么今天我在这里呢是要和大家分享一下在Windows存在的情况下安装双系统linux 那么第一步呢,就是斤BIOS ...