zoukankan      html  css  js  c++  java
  • Struts2框架(二)

    一、Struts2配置

    1.Struts2的Action的开发的几种方式

      方式1:继承ActionSupport。(推荐使用)如果使用Struts2的数据校验功能,必须继承此类。

      方式2:实现Action接口。

      方式3:不继承任何类,不实现任何接口。

    2.通配符

      在Struts2的配置信息中,可以用*与{1}可以优化配置。

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
        "http://struts.apache.org/dtds/struts-2.3.dtd">
    
    <struts>
    
        <package name="config" namespace="/user" extends="struts-default" abstract="false">
            
            <!-- 
            <action name="login" class="cn.itcast.a_config.UserAction" method="login">
                <result name="success">/index.jsp</result>            
            </action>
            <action name="register" class="cn.itcast.a_config.UserAction" method="register">
                <result name="success">/index.jsp</result>            
            </action>
             -->        
             
             <!-- 使用通配符优化上面的步骤 -->
             <!-- http://localhost:8080/struts02/user_login -->
             <action name="user_*" class="cn.itcast.a_config.UserAction" method="{1}">
                <result name="{1}">/{1}.jsp</result>            
            </action>
            
        </package>    
        
    </struts>

    3.Struts2中路径匹配原则

      http://localhost:8080/struts02/user/a/b/user_login

      Tomcat:

        localhost:找到访问哪一台机器

        8080:找到tomcat

        struts02:找到项目名称

        /user/a/b:先看有没有这个名称空间,没找到,继续向下。找到就返回。

        /user/a:先看有没有这个名称空间,没找到,继续向下。找到就返回。

        /user:先看有没有这个名称空间,没找到,继续向下。找到就返回。

        /:默认名称空间,还没找到,报错!  找到就返回。

    4.Struts2常量

      Struts中默认访问后缀:

        Struts1中默认访问后缀是*.do

        Struts2中默认访问后缀是*.action

      如何修改默认访问后缀:

        1.Struts2的.action访问后缀在哪里定义?

          struts2-core-2.3.24.1.jar/org.apache.struts2/default.properties

          struts.action.extension=action

        2.在Struts.xml中通过常量修改

          <constant name="struts.action.extension" value="action,do,"></constant>

          指定访问后缀为action/do/没有访问后缀都可以

          value="action,do,"  访问后缀:action/do/不带后缀

          value="action,do"  访问后缀:action或do

          value="action"      访问后缀:只能是action

    指定默认编码集,作用于HttpServletRequest的setCharacterEncoding方法和freemarker、velocity的输出。
    <constant name="struts.i18n.encoding" value="UTF-8"/>
    
    自定义后缀修改常量
    <constant name="struts.action.extension" value="do"/>
    
    设置浏览器是否缓存静态内容,默认值为true(生产环境下使用),开发阶段最好关闭。
    <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"/>
    
    该属性设置Struts2是否支持动态方法调用,该属性的默认值是true。如果需要关闭动态方法的调用,则可设置该属性为false。
    <constant name="struts.enable.DynamicMethodInvocation" value="false"/>
    
    上传文件的大小限制
    <constant name="struts.multipart.maxSize" value="10701096"/>

     动态方法调用语法:actionName + !即为动态方法调用,如:

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
        "http://struts.apache.org/dtds/struts-2.3.dtd">
    
    <struts>
    
        <package name="config2" namespace="/" extends="struts-default">
        
            <!-- 动态方法调用: http://locahost:8080/struts02/user!login -->
            <action name="user" class="cn.yly.UserAction">
                <result name="success">/index.jsp</result>            
            </action>
            
        </package>    
        
    </struts>

    5.全局跳转视图配置、配置的各项默认值

      全局视图配置:

                    <!-- 配置全局跳转视图 -->
            <global-results>
                <result name="success">/index.jsp</result>
            </global-results>            

      配置各项目默认值:

    <!-- 配置各项默认值 -->
             <!-- 
                  name  只配置了访问路径名称
                  class 默认执行的action在struts-default有配置
                          <default-class-ref class="com.opensymphony.xwork2.ActionSupport" />
                  method  默认为execute
                  默认的方法execute返回值为success,对应的页面去全局视图找。
                  
              -->
             <action name="test"></action>
    <!-- 什么情况不配置class? 即处理的aciton -->
            <!-- 答案: 当只是需要跳转到WEB-INF下资源的时候。 -->
             <action name="test2">
                 <result name="success">/WEB-INF/index.jsp</result>
             </action>

    二、Struts中数据处理

      对数据操作的所有方法:(把数据保存到域中)

      方式一:直接获取servletapi。核心类:ServletActionContext提供的静态方法。

      方式二:通过ActionContext获取不同(代表request/session/application)的map。

      方式三:实现接口的方法:(RequestAware / SessionAware / ApplicationAware)。

    // 1. 请求数据封装; 2. 调用Service处理业务逻辑,拿到结果数据
            
            // 3. 数据保存到域中
            
            
            // Struts中对数据操作,方式1: 直接拿到ServletApi, 执行操作
            HttpServletRequest request = ServletActionContext.getRequest();
            HttpSession session = request.getSession();
            ServletContext application = ServletActionContext.getServletContext();
            // 操作
            request.setAttribute("request_data", "request_data1");
            session.setAttribute("session_data", "session_data1");
            application.setAttribute("application_data", "application_data1");
    // 【推荐:解耦的方式实现对数据的操作】
            // Struts中对数据操作,方式2: 通过ActionContext类 
            ActionContext ac = ActionContext.getContext();
            // 得到Struts对HttpServletRequest对象进行了封装,封装为一个map
            // 拿到表示request对象的map
             Map<String,Object> request =  ac.getContextMap(); 
             // 拿到表示session对象的map
             Map<String, Object> session = ac.getSession();
             // 拿到表示servletContext对象的map
             Map<String, Object> application = ac.getApplication();
             
             // 数据
             request.put("request_data", "request_data1_actionContext");
            session.put("session_data", "session_data1_actionContext");
            application.put("application_data", "application_data1_actionContext");
    /**
     * 数据处理, 方式3: 实现接口的方法
     * @author Jie.Yuan
     *
     */
    public class DataAction extends ActionSupport implements RequestAware, SessionAware, ApplicationAware{
        
        private Map<String, Object> request;
        private Map<String, Object> session;
        private Map<String, Object> application;
        
        // struts运行时候,会把代表request的map对象注入
        @Override
        public void setRequest(Map<String, Object> request) {
            this.request = request;
        }
        
        // 注入session
        @Override
        public void setSession(Map<String, Object> session) {
            this.session = session;
        }
        
        // 注入application
        @Override
        public void setApplication(Map<String, Object> application) {
            this.application = application;
        }
    
    
        @Override
        public String execute() throws Exception {
            
             // 数据
             request.put("request_data", "request_data1_actionAware");
            session.put("session_data", "session_data1_actionAware");
            application.put("application_data", "application_data1_actionAware");        
            return SUCCESS;
        }
    
    }

    三、请求数据自动封装

      方式一:JSP表单数据填充到action中的属性。一定要set方法,get方法可以不用。

      方式二:JSP表单数据填充到action的对象中的属性。对象类型一定要set和get方法。

      实现原理:参数拦截器

    四、类型转换

      Struts中JSP提交的数据,struts会自动转换为action中属性的类型;对于基本数据类型以及日期类型会自动转换;日期类型只支持yyyy-MM-dd格式。

      如果是其它格式,需要自定义类型转换器:

        局部类型转换器

        全局类型转换器

      

      Struts转换器API:

        TypeConverter  转换器接口

          DefaultTypeConverter  默认类型转换器类

            StrutsTypeConverter  用户编写的转换器类,继承此类即可

      局部类型转换器类:

      转换器开发步骤:

        1.写转换器类:继承StrutsTypeConverter

        2.配置转化器类(告诉struts应用自己的转换器类)

          ==>在同包的action目录下新建一个properties文件。

          ==>命名规则:ActionClassName-conversion.properties

            举例:com.yly.type/UserAction-conversion.properties

          ==>内容:

              user.birth=转换器类全路径(com.yly.type.MyConverter)

      

      全局类型转换器类:

        需要写一个转换器,给所有的Action用!

        配置全局类型转化器:

          ==》src/xwork-conversion.properties

          ==》内容:

               java.util.Date=转换器类(com.yly.type.MyConverter)

     五、文件上传

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title></title>
    </head>
    <body>
    <form action="${pageContext.request.contextPath}/fileUploadAction" method="post" enctype="multipart/form-data">
        用户名:<input type="text" name="userName"/><br/>
        文件:<input type="file" name="file1"/><br/>
        <input type="submit" value="提交"/>
    </form>
    </body>
    </html>
    package com.yly;
    
    import com.opensymphony.xwork2.ActionSupport;
    import org.apache.commons.io.FileUtils;
    import org.apache.struts2.ServletActionContext;
    
    import java.io.File;
    
    
    public class UploadAction extends ActionSupport {
        private File file1;
        private String file1FileName;
        private String file1ContentType;
    
        public File getFile1() {
            return file1;
        }
    
        public void setFile1(File file1) {
            this.file1 = file1;
        }
    
        public String getFile1FileName() {
            return file1FileName;
        }
    
        public void setFile1FileName(String file1FileName) {
            this.file1FileName = file1FileName;
        }
    
        public String getFile1ContentType() {
            return file1ContentType;
        }
    
        public void setFile1ContentType(String file1ContentType) {
            this.file1ContentType = file1ContentType;
        }
    
        @Override
        public String execute() throws Exception {
            //获取上传的目录的路径
            String path = ServletActionContext.getServletContext().getRealPath("/upload");
            File file = new File(path, file1FileName);
            FileUtils.copyFile(file1, file);
            return "success";
        }
    }

    文件上传大小限制:

      Struts默认支持的文件上传最大是2M。通过常量修改:

        <constant name="struts.multipart.maxSize" value="31457280"/>

    限制上传文件的类型:

      需求:只允许txt/jpg文件类型上传。

      拦截器:注入参数限制文件上传

    <!-- 注意: action 的名称不能用关键字"fileUpload" -->
            <action name="fileUploadAction" class="cn.itcast.e_fileupload.FileUpload">
            
                <!-- 限制运行上传的文件的类型 -->
                <interceptor-ref name="defaultStack">
                    
                    <!-- 限制运行的文件的扩展名 -->
                    <param name="fileUpload.allowedExtensions">txt,jpg,jar</param>
                    
                    <!-- 限制运行的类型   【与上面同时使用,取交集】
                    <param name="fileUpload.allowedTypes">text/plain</param>
                    -->
                    
                </interceptor-ref>
                
                <result name="success">/e/success.jsp</result>
                
                <!-- 配置错误视图 -->
                <result name="input">/e/error.jsp</result>
            </action>

    错误提示:

      当文件上传出现错误的时候,struts内部会返回input视图(错误视图),所以就需要我们在struts.xml中配置input视图对应的错误页面!

    六、Struts的文件下载

    package com.yly;
    
    import com.opensymphony.xwork2.ActionContext;
    import com.opensymphony.xwork2.ActionSupport;
    import org.apache.struts2.ServletActionContext;
    import org.apache.struts2.dispatcher.RequestMap;
    
    import java.io.File;
    import java.io.InputStream;
    import java.io.UnsupportedEncodingException;
    import java.net.URLEncoder;
    
    /**
     * 文件下载
     * 1.显示所有要下载文件的列表
     * 2.文件下载
     */
    public class DownAction extends ActionSupport {
        /**
         * 显示所有要下载的文件列表
         *
         * @return
         * @throws Exception
         */
        public String list() throws Exception {
            //得到upload目录
            String path = ServletActionContext.getServletContext().getRealPath("/upload");
            //目录对象
            File file = new File(path);
            //得到所有要下载的文件的文件名
            String[] fileNames = file.list();
            //保存
            ActionContext ac = ActionContext.getContext();
            RequestMap requestMap = (RequestMap) ac.get("request");
            requestMap.put("fileNames", fileNames);
            return "list";
        }
    
        //1.获取要下载文件的文件名
        private String fileName;
    
        public void setFileName(String fileName) {
            //处理传入的参数中文问题(get提交)
            try {
                fileName = new String(fileName.getBytes("ISO8859-1"), "UTF-8");
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException(e);
            }
            //把处理好的文件名赋值
            this.fileName = fileName;
        }
    
        /**
         * 2.文件下载提交的业务方法(在struts.xml中配置返回stream)
         *
         * @return
         * @throws Exception
         */
        public String down() throws Exception {
    
            return "download";
        }
    
        //3.返回文件流的方法
        public InputStream getAttrInputStream() {
            return ServletActionContext.getServletContext().getResourceAsStream("/upload/" + fileName);
        }
    
        //4.下载显示的文件名(浏览器显示的文件名)
        public String getDownFileName() {
            //需要进行中文编码
            try {
                fileName = URLEncoder.encode(fileName, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException(e);
            }
            return fileName;
        }
    }
    <?xml version="1.0" encoding="UTF-8"?>
    
    <!DOCTYPE struts PUBLIC
            "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
            "http://struts.apache.org/dtds/struts-2.3.dtd">
    
    <struts>
        <package name="upload" extends="struts-default">
            <action name="fileUploadAction" class="com.yly.UploadAction" method="execute">
                <result name="success">/index.jsp</result>
            </action>
    
            <action name="down_*" class="com.yly.DownAction" method="{1}">
                <result name="list">/list.jsp</result>
    
                <result name="download" type="stream">
                    <!-- 运行下载的文件类型:指定为所有的二进制文件类型 -->
                    <param name="contentType">application/octet-stream</param>
    
                    <!-- 对应的是Action中的属性:返回流的属性【其实就是getAttrInputStream()】 -->
                    <param name="inputName">attrInputStream</param>
    
                    <!-- 下载头,包括:浏览器显示的文件名 -->
                    <param name="contentDisposition">attachment;filename=${downFileName}</param>
    
                    <!-- 缓冲区大小设置 -->
                    <param name="bufferSize">1024</param>
                </result>
            </action>
        </package>
    </struts>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <html>
    <head>
        <title>下载列表</title>
    </head>
    <body>
    <table border="1">
        <tr>
            <th>编号</th>
            <th>文件名</th>
            <th>操作</th>
        </tr>
        <c:forEach var="fileName" items="${fileNames}" varStatus="vs">
            <tr>
                <td>${vs.count}</td>
                <td>${fileName}</td>
                <td>
                    <c:url var="url" value="down_down">
                        <c:param name="fileName" value="${fileName}"></c:param>
                    </c:url>
                    <a href="${url}">下载</a>
                </td>
            </tr>
        </c:forEach>
    </table>
    </body>
    </html>

        

  • 相关阅读:
    kafka与Rocketmq的区别【转】
    k8s故障解决干货文档链接
    利用local nginx搭建k8s-1.17.4高可用kubernetes集群
    生产gitlab还原步骤
    jenkins备份和还原
    ASP.NET Core3.1使用IdentityServer4中间件系列随笔(二):创建API项目,配置IdentityServer保护API资源
    使用Feign出现404错误问题
    高并发系统限流-漏桶算法和令牌桶算法
    框架-springmvc源码分析(二)
    框架-springmvc源码分析(一)
  • 原文地址:https://www.cnblogs.com/FlySheep/p/4898426.html
Copyright © 2011-2022 走看看