Struts2【开发Action】(二)

得到域对象


Struts怎么把数据保存在域对象中呢???Struts提供了三种方式


一、得到Servlet API


我们可以通过ServletActionContext得到Servlet API


由于每个用户拥有一个Action对象,那么底层为了维护用户拿到的是当前线程的request等对象,使用ThreadLocal来维护当前线程下的request、response等对象…


//通过ServletActionContext得到Servlet API
        javax.servlet.ServletContext context = ServletActionContext.getServletContext();
        HttpServletRequest request = ServletActionContext.getRequest();
        HttpSession session = request.getSession();
        HttpServletResponse response = ServletActionContext.getResponse();



二、ActionContext类


我们还可以通过ActionContext类来得到request、response、session、application被Struts封装的Map集合


//得到ActionContext 对象
        ActionContext context = ActionContext.getContext();
        Map<String, Object> session = context.getSession();
        Map<String, Object> application = context.getApplication();
        //这是request的Map
        Map<String, Object> request = context.getContextMap();



三、实现接口


当web容器发现该Action实现了Aware接口,会把相对应的资源通过Aware接口注射进去,实际上就是一种IOC。


Aware实际就是一种拦截器,拦截代码在执行Action之前执行、将资源注射到Action中

实现SessionAware, RequestAware, ApplicationAware接口,它就要在程序中实现三个方法:


private Map<String, Object> request;
    private Map<String, Object> session;
    private Map<String, Object> application;
    @Override
    public void setApplication(Map<String, Object> map) {
        this.application = map;
    }
    @Override
    public void setRequest(Map<String, Object> map) {
        this.request = map;
    }
    @Override
    public void setSession(Map<String, Object> map) {
        this.session = map;
    }


通过这些方法,我们就可以得到对应的Map对象…..


小总结


那么,我们有三种方法可以得到Servlet对应的对象,那么该使用哪一种呢???


分析:


  • 第一种方法:需要导入Servlet的包,与Struts耦合了
  • 第二种方法:只能在业务方法中使用ActionContext类得到对应的Map对象,如果有多个方法,那么每个方法都需要写类似的代码
  • 第三种方法:可以在类上定义成员变量,以至于整个类都能使用。但是需要实现类、实现对应的方法


如果我们需要使用到对象的其他方法,类似getContextPath()之类的,那么只能使用第一种


如果我们就按照平常的开发,我们就使用第二种【获取简单,没有耦合】


至于第三种,当我们将来可能开发BaseAction的时候,就使用它!



日期转换问题


前面博文已经讲解了,Struts2为我们实现了数据自动封装…由上篇的例子我们可以看出,表单提交过去的数据全都是String类型的,但是经过Struts自动封装,就改成是JavaBean对应成员变量的类型了。


但是呢,日期类型只支持是yyyy-MM-dd这种格式的,因为我们在上个例子中直接使用的是Struts支持的格式,因此没有报错…本篇博文就是讲解Struts如何对日期类型的格式更好地支持


当我们使用的是yyyyMMdd这种格式的时候,我们看看Struts的自动封装能不能解析出相对应的日期

Struts2【开发Action】(二)这里写图片描述


直接抛出了异常

Struts2【开发Action】(二)这里写图片描述Struts2【开发Action】(二)这里写图片描述

分析


那么,我们怎么让Struts能够支持更多的日期格式呢??比如,我想Struts在自动封装数据的时候支持yyyyMMdd,yyyy年MM月dd日这样的日期格式…..


Struts提供了转换器给我们使用,也就是,我们可以自定义转换器,我们定义了什么格式,Struts就可以根据对应的格式进行自动封装


当我们写完自定义转换器,是需要向Struts说明我们写了,不然的话,Struts是不知道我们自定义了转换器类的…


也就是说,我们要想实现类型转换,需要两步


  • 编写自定义转换器类
  • 告诉Struts我们写了转换器类

自定义转换器类


一般地,我们想要编写自定义转换器类,都是实现StrutsTypeConverter类的….


/**
 * Created by ozc on 2017/5/1.
 * 自定义异常转换器类
 *
 * 我们要实现的就是:在Struts转换的时候,
 *
 */
public class MyConvter extends StrutsTypeConverter {
    //需求,当Struts自动封装数据时,也支持yyyyMMdd,yyyy年MM月dd日等格式的支持\
    SimpleDateFormat[] format = {new SimpleDateFormat("yyyy-MM-dd"), new SimpleDateFormat("yyyyMMdd"), new SimpleDateFormat("yyyy年MM月dd日")};
    /**
     * 把String转换为指定的类型 【String To Date】
     *
     *
     * @param map
     *            当前上下文环境
     * @param strings
     *            jsp表单提交的字符串的值
     * @param aClass
     *            要转换为的目标类型
     */
    @Override
    public Object convertFromString(Map map, String[] strings, Class aClass) {
        //判断是否有值
        if (strings == null) {
            return null;
        }
        //判断是否是日期类型的
        if (Date.class != aClass) {
            return null;
        }
        //遍历循环
        for (SimpleDateFormat dateFormat : format) {
            try {
                //解析传递进来的第一个就行啦
                dateFormat.parse(strings[0]);
            } catch (ParseException e) {
                //如果格式不对,那么就跳出当前的循环
                continue;
            }
        }
        return null;
    }
    @Override
    public String convertToString(Map map, Object o) {
        return null;
    }
}


告诉Struts,我写了转换器类


告诉Struts我写了一个转换器类,也分两种方式


  • 定义了局部转换器类,就当前包下的Action类有效
  • 定义了全局转换器类,整个项目有效


全局转换器


步骤:


  • 在src目录下创建一个名为xwork-conversion.properties的文件
  • 配置文件的内容:需要转换的类类型=转换器类的全名java.util.Date=qwer.MyConvter



局部转换器类


步骤:


  • 在当前的Action包下创建名为Action名-conversion.properties的文件
  • 文件的内容为:需要转换的字段【如果是JavaBean里的字段,需要写上JavaBean的】=转换器类的全名user.birthday=qwer.MyConvter



效果

Struts2【开发Action】(二)

这里写图片描述

Struts2【开发Action】(二)

这里写图片描述

上一篇:E-MapReduce的Presto组件默认支持访问oss数据


下一篇:IT解决方案如何为网络基础设施做好应对灾难的准备