首页 > 代码库 > 第四章 Struts2深入

第四章 Struts2深入

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深入