Struts学习2

来源:互联网 发布:扮猪吃老虎 网游 知乎 编辑:程序博客网 时间:2024/04/28 12:43

Strut配置

strutsk2的action开发的几种方式

方式一:继承ActionSupport(一般用第一种)

public class UserAction2 extends ActionSupport

方式二:实现Action接口

public class UserAction3 implements Action {    // Action中业务处理方法    public String login() {        System.out.println("UserAction.login()");        return "success";    }    @Override    public String execute() throws Exception {        return null;    }}

接口中的内容:

    public static final String SUCCESS = "success";    public static final String NONE = "none";    public static final String ERROR = "error";    public static final String INPUT = "input";    public static final String LOGIN = "login";    public String execute() throws Exception;

方式三:不继承

public class UserAction {    //接受url中的参数,名字要一致    private String userName;    public void setUserName(String userName) {        this.userName = userName;    }    // Action中业务处理方法    public String login() {        System.out.println("UserAction.login()" + userName);        return "login";    }    public String register() {        System.out.println("register()" + userName);        return "register";    }}

通配符

stucts配置中可以用*代表访问的方法

 <!-- 使用通配符优化上面的步骤 --> <!-- 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 name="config" namespace="/user" extends="struts-default" abstract="false">

访问路径可以是:
user中间可以加其他路径,但放前面不行

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

strut常量

strut1默认访问后缀:*.do
strut2默认访问后缀:*.action(就是路径后面可以加这个)

如何修改默认访问后缀:
.action的定义地方:struts/static/default.properties
在struts.xml中可以添加常量来修改值(提取constant.xml)

    <!-- 一、全局配置 -->    <!-- 0. 请求数据编码 -->     <constant name="struts.i18n.encoding" value="UTF-8"/>    <!-- 1. 修改Struts默认的访问后缀 -->    <constant name="struts.action.extension" value="action,do,"></constant>    <!-- 2. 修改xml自动重新加载 -->    <constant name="struts.configuration.xml.reload" value="true"/>    <!-- 3. 开启动态方法调用 (默认不开启)-->    <constant name="struts.enable.DynamicMethodInvocation" value="true"/>    <!-- 4. 修改上传文件的最大大小为30M -->    <constant name="struts.multipart.maxSize" value="31457280"/>

配置默认值

<struts>    <package name="config2" namespace="/" extends="struts-default">        <!-- 动态方法调用: http://locahost:8080/struts02/user!login         <action name="user" class="cn.itcast.b_config2.UserAction">            <result name="success">/index.jsp</result>                  </action>        -->         <!-- 配置全局跳转视图 -->        <global-results>            <result name="success">/index.jsp</result>        </global-results>        <!-- 通配符: http://locahost:8080/struts02/user_login -->        <action name="user_*" class="cn.itcast.b_config2.UserAction" method="{1}">        </action>        <!--         <action name="test" class="cn.itcast.b_config2.TestAction" method="execute">            返回结果标记success对应的页面再当前action中没有配置,            所以会去找全局配置有是否有success标记对应的页面        </action>         -->         <!-- 配置各项默认值 -->         <!--              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" type="redirect">/WEB-INF/index.jsp</result>         </action>    </package>  </struts>

数据处理

方式一、二

/** * 数据处理 * @author Jie.Yuan * */public class DataAction_bak extends ActionSupport{    @Override    public String execute() throws Exception {          // 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");             return SUCCESS;    }}

方式3:

/** * 数据处理, 方式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;    }}

请求数据自动封装

方式1:Jsp表单数据填充到action中的属性,在action设定各属性的set方法

也可以单独封装成bean类,并成为action的一个类成员(注意此时action中的对象属性一定要同时有get和set方法,没有get会出错),请求的时候写成:

该工作原理是param拦截器起作用。

  <body>    <form action="${pageContext.request.contextPath }/user_register.action" method="post">        用户名:<input type="text" name="user.name"><br/>        密码:<input type="text" name="user.pwd"><br/>        年龄:<input type="text" name="user.age"><br/>        生日:<input type="text" name="user.birth"><br/>        <input type="submit" value="注册">    </form>  </body>

类型转换

请求参数自动转换为需要的类型参数:

对于基本数据类型和日期类型(yy-mm-dd)而已自动转换

自定义类型转换器:
Struts转换器API:
|–TypeConverter
|–Default TypeConverter

转换器开发步骤:

1. 写转换器类2. 配置    在同包的action目录下,新建一个properties文件,名字为:UserAction-conversion. properties内容为:
    user.birth=转换器全路径(包名+类)

总结:这个转换器其他Action能否用?
不能用,因为这个转换器是局部的

全局类型转化器,在src下定义xwork-conversion.properties:

java.util.Date=cn.itcast.d_type.MyConverter
/** * 自定义类型转换器类 *  * @author Jie.Yuan *  */public class MyConverter extends StrutsTypeConverter {    // 新需求: 要求项目中要支持的格式,如: yyyy-MM-dd/yyyyMMdd/yyyy年MM月dd日..    // 先定义项目中支持的转换的格式    DateFormat[] df = { new SimpleDateFormat("yyyy-MM-dd"),            new SimpleDateFormat("yyyyMMdd"),            new SimpleDateFormat("yyyy年MM月dd日") };    /**     * 把String转换为指定的类型 【String To Date】     *      * @param context     *            当前上下文环境     * @param values     *            jsp表单提交的字符串的值     * @param toClass     *            要转换为的目标类型     */    @Override    public Object convertFromString(Map context, String[] values, Class toClass) {        // 判断: 内容不能为空        if (values == null || values.length == 0) {            return null;        }        // 判断类型必须为Date        if (Date.class != toClass) {            return null;        }        // 迭代:转换失败继续下一个格式的转换; 转换成功就直接返回        for (int i=0; i<df.length; i++) {            try {                return df[i].parse(values[0]);            } catch (ParseException e) {                continue;            }        }        return null;    }    @Override    public String convertToString(Map context, Object o) {        return null;    }}

文件上传下载

错误提示:
当文件上传错误时候,struts内部会返回input错误,可以配置input错误的显示。
最大大小可以在常量中配置
前台:

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

配置:

<struts>    <package name="upload_" extends="struts-default">        <!-- 注意: 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>        <action name="down_*" class="cn.itcast.e_fileupload.DownAction" method="{1}">            <!-- 列表展示 -->            <result name="list">/e/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>
public class FileUpload extends ActionSupport {    // 对应表单:<input type="file" name="file1">    private File file1;     // 文件名    private String file1FileName;    // 文件的类型(MIME)    private String file1ContentType;    public void setFile1(File file1) {        this.file1 = file1;    }    public void setFile1FileName(String file1FileName) {        this.file1FileName = file1FileName;    }    public void setFile1ContentType(String file1ContentType) {        this.file1ContentType = file1ContentType;    }    @Override    public String execute() throws Exception {        /******拿到上传的文件,进行处理******/        // 把文件上传到upload目录        // 获取上传的目录路径        String path = ServletActionContext.getServletContext().getRealPath("/upload");        // 创建目标文件对象        File destFile = new File(path,file1FileName);        // 把上传的文件,拷贝到目标文件中        FileUtils.copyFile(file1, destFile);        return SUCCESS;    }}

Struts文件下载方式:

/** * 文件下载 * 1. 显示所有要下载文件的列表 * 2. 文件下载 * @author Jie.Yuan * */public class DownAction extends ActionSupport {    /*************1. 显示所有要下载文件的列表*********************/    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();        // 得到代表request的map (第二种方式)        Map<String,Object> request= (Map<String, Object>) ac.get("request");        request.put("fileNames", fileNames);        return "list";    }    /*************2. 文件下载*********************/    // 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)    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;    }}

下载的jsp:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html>  <head>    <base href="<%=basePath%>">    <title>下载列表</title>    <meta http-equiv="pragma" content="no-cache">    <meta http-equiv="cache-control" content="no-cache">    <meta http-equiv="expires" content="0">      </head>  <body>    <table border="1" align="center">        <tr>            <td>编号</td>            <td>文件名</td>            <td>操作</td>        </tr>        <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>        <c:forEach var="fileName" items="${fileNames}" varStatus="vs">            <tr>                <td>${vs.count }</td>                <td>${fileName }</td>                <td>                    <!-- 构建一个url -->                    <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>
0 0
原创粉丝点击