Struts开发笔记二

配置细节问题

  • struts.xml中默认配置

    <default-action-ref name="default"></default-action-ref>
    <default-class-ref class="com.example.struts2.DefaultAction"> </default-class-ref>
    
    <action name="default">
        <result name="success">/index.jsp</result>
    </action>
    
    • 通用界面配置 —如果某个action中没有对应的result,默认跳转到default.jsp中

      <global-results>
          <result>/default.jsp</result>
      </global-results>
      
  • struts.xml模块分离

    <include file="struts-user.xml"></include>
    复制 创建struts-user的xml文件
    
  • 常用常量配置

    <constant name="struts.action.extension" value="action,do,"/> 
    <constant name="struts.devMode" value="true" />  提供详细报错页面,修改struts.xml后不需要重启服务器 (要求)
    
    <constant name="struts.serve.static.browserCache" value="false"/> false不缓存,true浏览器会缓存静态内容,产品环境设置true、开发环境设置false 
    
  • 全局异常

    <global-exception-mappings>
        <exception-mapping result="error" exception="java.lang.Exception"
            name="ErrorAction"></exception-mapping>
    </global-exception-mappings>
    

文件上传

企业常用文件上传技术 : jspSmartUpload(主要应用 JSP model1 时代) 、
fileupload (Apache commons项目中一个组件)、
Servlet3.0 集成文件上传 Part类
文件上传 enctype=”multipart/form-data”
是 MIME协议定义多部分请求体 (消息体)

private File upload;
private String uploadContentType;
private String uploadFileName;

public void setUpload(File upload) {
    this.upload = upload;
}

public void setUploadFileName(String uploadFileName) {
    this.uploadFileName = uploadFileName;
}

public void setUploadContentType(String uploadContentType) {
    this.uploadContentType = uploadContentType;
}

@Override
public String execute() throws Exception {
    // 查询
    String realPath = ServletActionContext.getServletContext().getRealPath(
            "/upload");
    // 路径
    String targetPath = realPath + File.separator + uploadFileName;
    // 开始上传
    File targetFile = new File(targetPath);
    FileUtils.copyFile(upload, targetFile);

    return NONE;
}

多文件上传

private File[] upload;
private String[] uploadContentType;
private String[] uploadFileName;

// 查询
String realPath = ServletActionContext.getServletContext().getRealPath("/upload");
for (int i = 0; i < uploadFileName.length; i++) {
    String targetPath = realPath + File.separator + uploadFileName[i];
    File targetFile = new File(targetPath);
    FileUtils.copyFile(upload[i], targetFile);
        }
ServletActionContext.getRequest().setAttribute("name", "上传成功");

文件下载

配置xml

    <action name="download" class="com.example.demo6.DownloadAction">
        <result name="success" type="stream">
            <!-- 也是OGNL表达式在配置文件中的写法 setContentType(action中的getContentType()) -->
            <param name="contentType">${contentType}</param>
            <param name="contentDisposition">${contentDisposition}</param>
        </result>
    </action>


/**
 * 获取请求参数中的文件名称
 */
public void setFileName(String fileName) {

    try {
        this.fileName = new String(fileName.getBytes("ISO-8859-1"), "UTF-8");
        ServletActionContext.getRequest().setAttribute("name", fileName);
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }

    // 进行转码
}

//获取了输入流
public InputStream getInputStream() throws FileNotFoundException {
    // 第一步:得到文件的真实路径
    String realPath = ServletActionContext.getServletContext().getRealPath(
            "/upload");
    // 第二步:拼接下载的文件路径
    String downloadPath = realPath + File.separator + fileName;
    // 接下来获取这个输入流
    return new FileInputStream(downloadPath);
}

/**
 * 获取数据类型
 * @return
 */
public String getContentType() {
    return      ServletActionContext.getServletContext().getMimeType(fileName);
}

//获取下载的头信息
public String getContentDisposition() throws IOException {
    // 如何得到客户端浏览器版本
    String agent = ServletActionContext.getRequest()
            .getHeader("user-agent");
    return "attachment;filename=" + encodeDownloadFilename(fileName, agent);
}

注解方式使用Struts2

注意:Action类必须在以.action后缀结尾的位置

@ParentPackage("struts-default")
@Namespace("/test")
public class HelloAnnotationAction extends ActionSupport {

@Action(value = "hehe", results = @Result(location = "/index.jsp", name = "success"))
public String execute() throws Exception {
    System.out.println("被访问到了");
    return SUCCESS;
}
}

Struts校验

  • 第一种方式 代码校验(简单校验,实际项目中应用较少)

    代码校验 validate方法
    
    @Override
    public void validate() {
        // 进行验证
        if (TextUtils.isEmpty(user.getUsername())) {
            this.addFieldError("username", "用户名不能为空");
        } else {
            if (user.getUsername().length() < 3
                    || user.getUsername().length() > 8) {
                this.addFieldError("username", "用户名长度必须3-8位");
            }
        }
        if (TextUtils.isEmpty(user.getPassword())) {
            this.addFieldError("password", "密码不能为空");
        }
    }
    
    代码校验某个方法 login
    
    public void validateLogin() {
    // 进行验证
    if (TextUtils.isEmpty(user.getUsername())) {
        this.addFieldError("username", "用户名不能为空");
    } else {
        if (user.getUsername().length() < 3
                || user.getUsername().length() > 8) {
            this.addFieldError("username", "用户名长度必须3-8位");
        }
    }
    if (TextUtils.isEmpty(user.getPassword())) {
        this.addFieldError("password", "密码不能为空");
        }
    }
    
    struts.xml中定义这个action
    
    <action name="validate" class="com.example.demo2.ValidateAction"
        method="login">
        <result name="input">/demo2/login.jsp</result>
        <result name="success">/index.jsp</result>
    </action>
    
  • xml校验 实际项目中有较多应用

    在当前要校验的action中,创建xxx-validation.xml,源码在
    xwork-core-2.3.32.jar中的
    com.opensymphony.xwork2.validator.validators
    default.xml中进行了配置,根据default找到适合自己判断的需求
    
    
    <?xml version="1.0" encoding="UTF-8"?>
    
    <!DOCTYPE validators PUBLIC
            "-//Apache Struts//XWork Validator 1.0.3//EN"
            "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">
    <validators></validators>
    
    内建校验器
    * required (必填校验器,要求被校验的属性值不能为null)
    * requiredstring (必填字符串校验器,要求被校验的属性值不能为null,并且长度大于0,默认情况下会对字符串去前后空格)
    * stringlength (字符串长度校验器,要求被校验的属性值必须在指定的范围内,否则校验失败,minLength参数指定最小长度,maxLength参数指定最大长度,trim参数指定校验field之前是否去除字符串前后的空格)
    * regex (正则表达式校验器,检查被校验的属性值是否匹配一个正则表达式,expression参数指定正则表达式,caseSensitive参数指定进行正则表达式匹配时,是否区分大小写,默认值为true)
    * int(整数校验器,要求field的整数值必须在指定范围内,min指定最小值,max指定最大值)
    * double(双精度浮点数校验器,要求field的双精度浮点数必须在指定范围内,min指定最小值,max指定最大值)
    * fieldexpression (字段OGNL表达式校验器,要求field满足一个ognl表达式,expression参数指定ognl表达式,该逻辑表达式基于ValueStack进行求值,返回true时校验通过,否则不通过)
    * email(邮件地址校验器,要求如果被校验的属性值非空,则必须是合法的邮件地址)
    * url(网址校验器,要求如果被校验的属性值非空,则必须是合法的url地址)
    * date(日期校验器,要求field的日期值必须在指定范围内,min指定最小值,max指定最大值)
    
    案例
    required  必填校验器
    <field-validator type="required">
           <message>性别不能为空!</message>
    </field-validator>
    
    requiredstring  必填字符串校验器
    <field-validator type="requiredstring">
           <param name="trim">true</param>
           <message>用户名不能为空!</message>
    </field-validator>
    
    stringlength:字符串长度校验器
    <field-validator type="stringlength">
        <param name="maxLength">10</param>
        <param name="minLength">2</param>
        <param name="trim">true</param>
        <message><![CDATA[产品名称应在2-10个字符之间]]></message>
    </field-validator>
    
    int:整数校验器
    <field-validator type="int">
        <param name="min">1</param>
        <param name="max">150</param>
        <message>年龄必须在1-150之间</message>
    </field-validator>
    
    date: 日期校验器
    <field-validator type="date">
        <param name="min">1900-01-01</param>
        <param name="max">2050-02-21</param>
        <message>生日必须在${min}到${max}之间</message>
    </field-validator>
    
    url:  网络路径校验器
    <field-validator type="url">
        <message>传智播客的主页地址必须是一个有效网址</message>
    </field-validator>
    
    email:邮件地址校验器
    <field-validator type="email">
        <message>电子邮件地址无效</message>
    </field-validator>
    
    regex:正则表达式校验器
    <field-validator type="regex">
         <param name="expression"><![CDATA[^13\d{9}$]]></param>
         <message>手机号格式不正确!</message>
    </field-validator>
    
    fieldexpression : 字段表达式校验
    <field-validator type="fieldexpression">
           <param name="expression"><![CDATA[(password==repassword)]]></param>
           <message>两次密码输入不一致</message>
    </field-validator>
    

国际化 i18n

在当前src下创建properties文件 

基本名称_语言(小写)_国家(大写).properties 

messages_en_US.properties
messages_zh_CN.properties

值栈 ValueStack

  • 什么是值栈?

    ValueStack 是 struts2 提供一个接口,实现类 OgnlValueStack ---- 值栈对象 (OGNL是从值栈中获取数据的 )
    
    每个Action实例都有一个ValueStack对象 (一个请求 对应 一个ValueStack对象 )
    
    在其中保存当前Action 对象和其他相关对象 (值栈中 是有Action 引用的 )
    
    Struts 框架把 ValueStack 对象保存在名为 “struts.valueStack” 的请求
    属性中,request中 (值栈对象 是 request一个属性)
    
    
    valueStack vs = request.getAttribute("struts.valueStack");
    
  • 值栈的内部结构?

    ObjectStack  (root): Struts  把动作和相关对象压入 ObjectStack 中--List
    
    ContextMap   (context): Struts 把各种各样的映射关系(一些 Map 类型的对象) 压入 
    
    ContextMap 中
    
    Struts 会把下面这些映射压入 ContextMap 中
    
    parameters: 该 Map 中包含当前请求的请求参数  ?name=xxx
    
    request: 该 Map 中包含当前 request 对象中的所有属性
    
    session: 该 Map 中包含当前 session 对象中的所有属性
    
    application:该 Map 中包含当前 application  对象中的所有属性
    
    attr: 该 Map 按如下顺序来检索某个属性: request, session, application
    
  • 值栈ValueStack 和 ActionContext关系? --- 值栈的创建

    * 创建ActionContext 对象过程中,创建 值栈对象ValueStack 
    
    * ActionContext对象 对 ValueStack对象 有引用的 (在程序中 通过 ActionContext 获得 值栈对象 ) 
    
  • 如何获得值栈对象?

    方式一  了解
    ValueStack valueStack = 
    (ValueStack) ServletActionContext.getRequest().
    getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);
    
    方式二 掌握
    
    ValueStack valueStack2 = ActionContext.getContext().getValueStack();
    
  • 向值栈保存数据?

    方式一
    valueStack.push("zhiyuanyuan");
    
    方式二
    valueStack.set("name", "zhiyuan");
    
  • 在页面通过struts2标签 获取值栈内容?

普通字符串形式

    在jsp中 通过 <s:debug /> 查看值栈的内容 

    取出没有key值且在栈顶下边的数据
    <s:property value="[1].top" /> 

    取出栈顶的数据map类型----两种方式
    <s:property value="[0].top.name" />-----<s:property value="name"/>

    //取出request域中的数据
    <s:property value="#request.sex" />

对象存储方式取值

    //获取栈顶中的对象的username
    <s:property value="username" />


    //获取栈中第二个元素对象的username
    <s:property value="[1].top.username" />
    //获取u对象中的username

    User u;
    public User getU() {
    return u;
    }
    u = new User();
    u.setUsername("wangwu");
    u.setPassword("12345");

    <s:property value="u.username" />
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值