一年前接触Struts2,是从李刚的这本书开始,现在拿出来回顾一下,知识真的需要经常回顾的,要不半年就记得精光。
下面摘录一些重要知识点
ActionContext类去访问HttpSession
ActionContext.getContext().getSession().put(para, value);
与Spring框架结合时,通过依赖注入管理业务逻辑组件
用ValueStack封闭请求与返回的信息 框架用标签库来进行处理以简化前端程序
对国际化的支持很到位,不像EXTJS那样复杂 ,其基本思想还是在输出国际化信息的地方用KEY值替代,而将实际的值放到国际化资源文件里,当文件里包括非西欧字符时,要用native2ascii进行处理 其本命名格式
basename_语言代码_国家代码.properties 支持JSP临时加载与全局属性加载 struts.coustom.i18n.resources = basename 两种方式输出国际化信息 <s:text name="messageKey"/> <s:proerty value="%{getText("messageKey")}"/> 注:系统会根据客户端的语言/区域设置自动加载不同的资料文件 可以通过编程修改,指定加载某一语言的资源文件 从而达到在前端界面中让用户自己选择语言,
而不是依靠客户端系统的设置来进行选择
提供两种校检方式: 1 重写ActionSupport中的validate() 2 定义配置文件 ActionName_validate.xml 与Action 的class位于同一路径 struts2框架的三个核心组成部分: FilterDispatcher 业务控制器组件 Action 业务逻辑组件 (可通过Spring IOC进行管理) 配置文件: web.xml 配置过滤器 struts.xml 配置action struts.properties 配置框架大量的属性 包的配置 通过包管理ACTION 可继承父包中的拦截器(AOP编程思想的体现) 命名空间只有一个级别 默认的命名空间的ACTION可处理任何模块下的请求 ActionContext类 访问 HttpServletRequest/HttpServletResponse HttpSession ServletContext 对应JSP内置对象 request/response session application 同时提供 ServletRequestAware ServletResponseAware ServletContextAware 接口,实现这些接口的类 可以访问上面的对象 一个ACTION可有多个方法,通过配置method方法指定 配置ACTION时,可以对name class method 三个属性使用通配符 注:要注意出现多个可满足匹配时,是先找到先 匹配 通过配置<default-action-ref>来配置默认action 提供两种结果 1局部结果 <result>配置在<action>下 2全局结果 <result>配置在<global-results>下 框架提供14种结果类型: stream chain dispatcher rediect plaintext xslt ......... 重定向与转发的差别: 前者会丢失请求的参数和处理结果 模型驱动:采用单独的MODEL来封闭参数 JavaBean ,Action要实现ModelDriven中的getModel()方法 属性驱动:采用ACTION中的属性来传递请求参数和处理结果 提供两种异常处理方式: 1 手动捕获 try-catch 2 声明式配置 struts.xml <exception-mapping>, 又分:全局异常 配置在action下 与部局异常 配置在<global-exception-mappings>元素下 名称相同时,局部覆盖全局 在异常处理页面显示异常信息: <s:property value="exception"/> or <s:property value="exceptionStack"/> 类型转换: 所有MVC框架都是表现层的解决方案,收集参数并传递给应用逻辑组件 传递的参数只能是字符串,但java是强类型 语言,所以要进行类型转换 基于OGNL语言实现的,所有类型转换器必须实现TypeConverter接口 struts2提供StrutsTypeConverter类,两上要重写的方法:convertToString and convertFromString eg.将前台的 usename password两个字段的字符串值 -----> 一个User对象 (要自己编写这个局部类型转换器) 但是一种更简单的将前端字段的字符串组成复合类型或对象的方法,就是使用OGNL语言, 将字段名设置为对象或复合类型 的属性就是了 Action: User user; Jsp: <input type="text" name="user.name"/> 不过对User有要求: 提供空的构造函数 提供setter方法 Struts2提供conversionError拦截器,配置在default-stack里,有类型转换错误时,抛出异常,转向input指向的视图 <s:fielderror/>输出错误信息 数据校检: 客户端校检:拒绝误操作输入提交到服务器处理 如空字符 数字格式等 服务端校检:防止非法数据进入程序,引起异常 文件的上传和下载 JAVA领域里著名的文件上传项目:commos-fileupload and cos 表单中enctype指明编码方式:有三种 applicaton/x-www-unencoded multipart/form-data text/plain struts 中的ACTION中有两种方式实现文件上传:手动和配置 手动: 在ACTION中读取请求的输入流,然后存储(可使用常用的上传框架) 配置:默认使用jakarta的commons-fileupload 框架,只要ACTION提供以下属性 File upload; String xxxFileName; String xxxContentType; Action中的配置与其它无异,且可以对上传文件类型和大小进行配置 <param name="allowtypes"> ...</param> //maxmumSize 配置文件上传的临时文件路径:struts-multipart-saveDir 同时上传多个文件:将上面配置的三个属性改为数组 File[] upload; 或是使用List List<File> upload; struts2 下载 Action中指定一个 InputStream downloadFile; getter方法读取要下载的文件,并返回输入流 配置: inputName <result name="success" type="stream"> <param name="inputName">downloadFile</param> <param name="contentType">img/gif</param> <param name="contentDisposition">inline;filename="xxxx.gif"</param> <param name="buffersize">123400</param></result>
软件领域的一条重要原则:DRP Don't Repeat yourself!
可以说Interceptor 是这个框架的核心,下面回顾一下拦截器的基本原理:
拦截器是通过代理的方式来实现的。JDK只能对实现了接口的实例生成代理。
书上P210对此做了详细的说明 public interface Dog() { public void info(); public void run(); } public class DogImpl() implements Dog { public void info() { System.out.println("I am a dog"); } public void run() { System.out.println("I can run swfit"); } } 拦截Dog实例的拦截器 public class DogIntercepter() { public void method1() { System.out.println("do before info() "); } public void method2(){ System.out.println("do after info()"); } } 最关键的是下面这个类,它实现了拦截器与所要拦截的对象的关联。 public class ProxyHandler implements InvocationHandler { private Object target; DogIntercepter di = new DogIntercepter(); //执行代理的目标方法时,该方法会被自动调用 public Object invoke(Object proxy, Method method, Object[] args) throws Exception { Object result = null; if(method.getName().equals("info")) { di.method1(); result = method.invoke(target, args); di.method2(); } else { result = method.invoke(target, args); } return result; } public void setTarger(Object o) { this.target = o; } } 上面这个类有两个地方关联: 与拦截器 and 与被拦截的方法 可以把这种关联放在配置文件中
最后要一个代理工厂来生成代理 public class MyProxyFactory { public static Object getProxy(Object object) { ProxyHandler handler = new ProxyHandler(); handler.setTarget(object); return Proxy.newProxyInstance(DogImpl.class.getClassLoader(), object.getClass().getInterfaces(), handler); } }