zoukankan      html  css  js  c++  java
  • Struts2请求数据处理及拦截器(二)

    简介

    以后如果没有特殊的要说,就在简介中介绍一下大概的知识点。今天主要学习封装请求参数及类型转换、用户输入校验、国际化、拦截器

    Struts2封装请求参数的方式

    方式一:
    	Action 本身作为model对象,通过成员setter封装(一个名字为params的拦截器实现的)
    	产生疑问:使用第一种数据封装方式,数据封装到Action属性中,不可能将Action对象传递给 业务层 
      * 需要再定义单独JavaBean ,将Action属性封装到 JavaBean,得出第二种方式
    方式二:
    	动作类和模型分开,在Action中创建Model对象,页面通过ognl表达式封装 (属性驱动)
    方式三:
    	模型驱动
    	模型驱动实际上是由一个拦截器来做的。modelDriven拦截器来做。把getModel方法返回的对象,压入一个叫做ValueStack的栈顶。struts框架就会根据表单的name属性,调用对应栈顶对象的setter方法,从而把请求参数封装进来

    封装复杂类型参数(集合类型 Collection 、 Map)

    1. 封装数据到Collection 对象
    页面:
    	产品名称 <input type="text" name="products[0].name" /><br/>--->注意这里的名字要和Action中的一致
    Action :
    	public class ProductAction extends ActionSupport {
    		private List<Product> products;
    		
    		public List<Product> getProducts() {
    			return products;
    		}
    
    		public void setProducts(List<Product> products) {
    			this.products = products;
    		}
    	}
    2. 封装数据到Map 对象 
    页面:
    	产品名称 <input type="text" name="map['one'].name" /><br/>  =======  one是map的键值
    Action :
    	public class ProductAction2 extends ActionSupport {
    		private Map<String, Product> map;
    
    		public Map<String, Product> getMap() {
    			return map;
    		}
    
    		public void setMap(Map<String, Product> map) {
    			this.map = map;
    		}
    	}

    封装参数--类型转换

    1. 显示或者是数据回显:其他类型----->String
    基本类型自动转换
    	boolean 和 Boolean
    	char和 Character
    	int 和 Integer
    	long 和 Long
    	float 和 Float
    	double 和 Double
    	java.util.Date<-------->String(中国:Struts2默认按照yyyy-MM-dd本地格式进行自动转换)
    # 数组  可以将多个同名参数,转换到数组中
    # 集合  支持将数据保存到 List 或者 Map 集合
    
    总结:在使用Struts2时,基本上不用写任何类型转换器。内置的完全够用
    
    2. 自定义类型转换器
    	a). 实现方式
    	第一种 实现TypeConverter接口
    	第二种 继承 DefaultTypeConverter
    	第三种 继承 StrutsTypeConverter
    	
    	b). 类型转换器 一直都是双向转换 
    		页面提交请求参数,封装到model --- 需要转换
    		model数据 需要在页面 回显  ---- 需要转换
    	c). 注册类型转换器 
    		局部注册 : 只对当前Action有效 (针对属性) 
    		全局注册 : 针对所有Action的日期类型有效 (针对类型 )
    	
    	局部注册 : 在Action类所在包 创建 Action类名-conversion.properties , 格式 : 属性名称=类型转换器的全类名 
    	全局注册 : 在src下创建 xwork-conversion.properties ,格式 : 待转换的类型=类型转换器的全类名
    	
    3. 转换失败时的页面转向和错误消息提示
    	a、配置一个name=”input”的结果视图,一般指向用户输入数据的那个页面
    	b、在jsp中使用struts2的标签显示字段有关的错误
    		<%@ taglib uri="/struts-tags" prefix="s"%>
    		<s:fielderror/>
    	c、配置提示信息为中文的,在动作类所在的包中,建立一个名称为:动作类名.properties的配置文件

    用户输入数据的校验

    1. 校验方式:
    	a:客户端校验。(防君子不防小人)在页面中写js脚本。
    	输入错误的话提醒比较及时
    	减轻服务器的压力
    	b、服务器端校验
    	数据安全
    	***开发中使用:a+b
    	
    2. 服务器端校验
    	# 编程式校验(代码校验):自己编写一个校验代码(缺点:验证规则都写在了代码中)
    		a). 覆盖validate方法,完成对Action的业务方法 数据校验,在jsp中 通过 <s:fieldError/> 显示错误信息 
    			通过代码逻辑判断参数是否有效,如果参数非法 , this.addFieldError (ActionSupport提供)
    			workflow拦截器 跳转回 input页面
    		b). 针对指定的动作进行校验
    			方式一:写了一个validate方法,可以在不需要验证的动作方法前,使用@SkipValidation带有此注解的表示会被忽略验证
    			方式二:validate方法有一定的书写规范。public void validate动作方法名(首字母大写)
    		总结:所有验证不通过或转换不同的过的,框架都会转向name=”input”的结果视图。要显示错误提示,使用<s:fieldError/>,显示字段有关的错误提示
    		
    	# 声明式校验:通过xml配置文件
    		a). 针对动作类中的所有动作进行校验
    			在动作类所在的包中,建立一个名称为:”动作类名-validation.xml”配置文件
    			**引入DTD--xwork-core-2.3.7.jar 中 /com/opensymphony/xwork2/validator/validators/default.xml
    		b). 针对指定的动作进行校验
    			方式一:使用@SkipValidation
    			方式二:声明文件遵循一定的书写规范:
    				动作类名-动作名(struts.xml配置文件中的)-validation.xml
    		c). struts2框架内置的声明式类型验证器
    			* 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指定最大值)
    			
    3. 自定义声明式校验
    	a). 编写一个类:实现Validator接口或者继承ValidatorSupport。如果是验证表单字段有关,建议继承FieldValidatorSuppor
    	b). 要注册校验器,在WEB-INFclasses目录下,建立一个固定名称为validators.xml的配置文件
    	c). 使用校验器在Action所在包 创建Action类名-validation.xml
    	**** 实际开发中很少用到自定义校验器 

    Struts2的国际化

    1. 配置全局国际化消息资源包
    	在struts.xml中
    		添加<constant name="struts.custom.i18n.resources" value="messages"></constant>   messages.properties 在src根目录
    		<constant name="struts.custom.i18n.resources" value="cn.itcast.resources.messages"></constant>   messages.properties 在 cn.itcast.resources 包中
    	在Action动作类中:
    		前提,动作类继承ActionSuppor/this.getText("msg"); 
    	在jsp中使用  :<s:text name="msg" />
    	在配置文件中(校验xml) : <message key="agemsg"></message>
    	
    2. 配置局部消息资源包
    	数据只能在对应Action中使用,在Action类所在包 创建 Action类名.properties  --------- 无需配置
    	局部的比全局的优先级高
    
    3. 包范围的消息资源包
    	数据对包 (包括子包)中的所有Action 都有效 , 在包中创建 package.properties ----- 无需配置 
    	书写有规范的,名称为package_zh_CN.properties,放在类的包中。可以被包中及子包的所有动作类来访问
    4. 临时信息文件 (主要在jsp中 引入国际化信息 )
    	在jsp指定读取 哪个properties文件 
    	<s:i18n name="cn.itcast.struts2.demo7.package">
    		<s:text name="customer"></s:text>
    	</s:i18n>
    	向信息中传递参数  {0} {1} ------------ MessageFormat 动态消息文本 
    	this.getText("required", new String[] { "用户名" });

    struts2中的拦截器(框架功能核心)

    拦截器 的使用 ,源自Spring AOP(面向切面编程)思想 
    	拦截器 采用 责任链 模式 
    	*  在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。
    	*  责任链每一个节点,都可以继续调用下一个节点,也可以阻止流程继续执行 
    		
    在struts2 中可以定义很多个拦截器,将多个拦截器按照特定顺序 组成拦截器栈 (顺序调用 栈中的每一个拦截器 )
    
    1、 struts2 所有拦截器 都必须实现 Interceptor 接口 
    2、 AbstractInterceptor 类实现了 Interceptor 接口. 并为 init, destroy 提供了一个空白的实现
    
    所有实际开发中,自定义拦截器 只需要 继承 AbstractInterceptor类, 提供 intercept 方法实现 
    
    3、 常用struts2 拦截器
    	<interceptor-ref name="modelDriven"/> 模型驱动
    	<interceptor-ref name="fileUpload"/> 文件上传
    	<interceptor-ref name="params"> 参数解析封装 
    	<interceptor-ref name="conversionError"/> 类型转换错误
    	<interceptor-ref name="validation"> 请求参数校验
    	<interceptor-ref name="workflow"> 拦截跳转 input 视图

    综合案例

    案例 : 登陆,对其它Action访问  通过自定义拦截器 进行权限控制 
    	导入jar包 (struts2 jar、c3p0、 dbutils、 mysql驱动)
    	web.xml 
    	struts.xml
    	JDBCUtils 工具类
    
    第一步 : 编写index.jsp 提供 图书增删改查 四个功能 
       编写BookAction ,提供四个业务方法 
       
    第二步: 完成登陆功能    
    
    第三步 :必须要登陆 才能进行图书管理 
    	使用Filter 进行权限控制 ---- 过滤所有web请求 (所有web资源访问)
    	使用拦截器 进行权限控制 ---- 主要拦截对Action访问  (不能拦截JSP)
    
    定义拦截器 继承AbstractInterceptor 
    
    配置拦截器 
    	方式一
    		<!-- 注册拦截器 -->
    		<interceptors>
    			<interceptor name="privilege" class="cn.itcast.interceptor.PrivilegeInterceptor"></interceptor>
    		</interceptors>
    		<action name="book_*" class="cn.itcast.action.BookAction" method="{1}" >
    			<!-- 使用拦截器 -->
    			<!-- 当使用自定义拦截器 后,默认拦截器 就会失效  -->
    			<interceptor-ref name="defaultStack"></interceptor-ref>
    			<interceptor-ref name="privilege"></interceptor-ref>
    		</action>
    	方式二
    		<!-- 注册拦截器 -->
    		<interceptors>
    			<interceptor name="privilege" class="cn.itcast.interceptor.PrivilegeInterceptor"></interceptor>
    			<!-- 自定义拦截器栈 -->
    			<interceptor-stack name="privilegeStack">
    				<interceptor-ref name="defaultStack"></interceptor-ref>
    				<interceptor-ref name="privilege"></interceptor-ref>
    			</interceptor-stack>
    		</interceptors>
    		
    		<!-- 设置当前包 所有Action 都使用 自定义拦截器栈 -->
    		<default-interceptor-ref name="privilegeStack"></default-interceptor-ref>
  • 相关阅读:
    OpenStack local.conf
    Murano Weekly Meeting 2015.07.21
    Python package和folder
    WSGI学习系列eventlet.wsgi
    OpenStack Weekly Rank 2015.07.20
    Eventlet Greenlet
    OpenStack Weekly Meeting 2015.07.17
    OpenStack创建实例错误解决方法
    Linux Shell命令系列(5) VI编辑器
    linux统计使用最多的10个命令
  • 原文地址:https://www.cnblogs.com/codingpark/p/4312108.html
Copyright © 2011-2022 走看看