struts2的学习笔记二

1.1 Struts2中的请求参数的封装

1.1.1 请求参数的封装

使用Servlet API接收到表单提交的参数,需要自己手动完成封装.

* Action---->Service---->Dao都需要在Action中将数据封装到一个Bean中传递到业务层.

Struts2中提供了一种方式完成对数据的封装.

* 数据的封装分成两大类:

* 属性驱动

* 1.Action中声明属性并提供属性的set方法.

* 2.在页面OGNL表达式形式

* 模型驱动

* 3.实现ModelDriven接口

 

提供set方法的方式:(属性驱动)

页面:

<h1>数据的封装:</h1>

<form action="${ pageContext.request.contextPath }/user1.action" method="post">

用户名:<input type="text" name="username"/><br/>

密码:<input type="password" name="password"><br/>

<input type="submit" value="提交">

</form>

 

Action:

public class UserAction1 extends ActionSupport{

private String username;

private String password;

public void setUsername(String username) {

this.username = username;

}

 

public void setPassword(String password) {

this.password = password;

}

...

}

页面提供OGNL表达式的形式:(属性驱动)

要求:Action中提供对象的get方法.

 

页面:

<h1>数据的封装:OGNL表达式的形式</h1>

<form action="${ pageContext.request.contextPath }/user2.action" method="post">

用户名:<input type="text" name="user.username"/><br/>

密码:<input type="password" name="user.password"><br/>

<input type="submit" value="提交">

</form>

 

Action:

public class UserAction2 extends ActionSupport{

private User user;

public void setUser(User user) {

this.user = user;

}

public User getUser() {

return user;

}

 

@Override

public String execute() throws Exception {

System.out.println(user.getUsername());

System.out.println(user.getPassword());

return NONE;

}

}

 

模型驱动:实现一个接口ModelDriven.

页面:

<h1>数据的封装:模型驱动的形式</h1>

<form action="${ pageContext.request.contextPath }/user3.action" method="post">

用户名:<input type="text" name="username"/><br/>

密码:<input type="password" name="password"><br/>

<input type="submit" value="提交">

</form>

 

Action:

public class UserAction3 extends ActionSupport implements ModelDriven<User>{

private User user = new User();//必须手动构建这个对象

public User getModel() {

return user;

}

@Override

public String execute() throws Exception {

System.out.println(user.getUsername());

System.out.println(user.getPassword());

return NONE;

}

}

 

1.1.2 数据封装的分析:

数据的封装实质上是由拦截器完成的!!!

<interceptor name="params" class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>

 

企业开发中采用第三种形式:

* Struts2的结构中,一部分的结构围绕着模型驱动来设计的.提供了一个单独的拦截器!!!

<interceptor name="modelDriven" class="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/>

 

综合比较第二种和第三种方式:

* 第三种只能封装到一个对象中.

* ModelDriven<User>----只能将数据封装到User对象中.

 

* 第二种更加的灵活,封装到多个对象中.

* <input type=text name=user.username>

* <input type=text name=product.price>

 

1.1.3 复杂数据的封装:

将数据封装到一个List集合中

页面:

<h1>批量添加商品</h1>

<form action="${ pageContext.request.contextPath }/product1.action" method="post">

商品名称:<input type="text" name="products[0].pname"><br/>

商品价格:<input type="text" name="products[0].price"><br/>

商品名称:<input type="text" name="products[1].pname"><br/>

商品价格:<input type="text" name="products[1].price"><br/>

<input type="submit" value="添加">

</form>

 

Action:

public class ProductAction1 extends ActionSupport{

private List<Product> products;

public void setProducts(List<Product> products) {

this.products = products;

}

 

public List<Product> getProducts() {

return products;

}

 

@Override

public String execute() throws Exception {

System.out.println(products);

return NONE;

}

}

 

将数据封装到Map集合

页面:

<h1>批量添加商品</h1>

<form action="${ pageContext.request.contextPath }/product2.action" method="post">

商品名称:<input type="text" name="map['one'].pname"><br/>

商品价格:<input type="text" name="map['one'].price"><br/>

商品名称:<input type="text" name="map['two'].pname"><br/>

商品价格:<input type="text" name="map['two'].price"><br/>

<input type="submit" value="添加">

</form>

 

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;

}

 

@Override

public String execute() throws Exception {

System.out.println(map);

return NONE;

}

}

1.2 数据类型的转换:

1.2.1 Struts2提供了大量内置类型转换器:

boolean Boolean

char Character

int Integer

long Long

float Float

double Double

Date 可以接收 yyyy-MM-dd格式字符串

数组  可以将多个同名参数,转换到数组中

集合  支持将数据保存到 List 或者 Map 集合

 

1.2.2 类型转换过程中的错误处理:

<input type=text name=age>---需要输入的是整数.但是如果输入了abc.将不能完成类型的转换!!!

* 抛异常:java.lang.NoSuchMethodException: cn.itcast.vo.Emp.setAge([Ljava.lang.String;)

* 输入abc---->setAge(String name).但是实体类中没有setAge(String name).抛出了一个没有这个方法异常.

 

当类型转换出错的时候:报一个没有配置INPUT逻辑视图的异常.

* 配置一个INPUT逻辑视图.转向回提交的页面.

* 回显错误信息:

* 引入struts2的标签库:

* 使用<s:fielderror/>标签回显:

* INPUT逻辑视图的原理:

* 这些功能都是由拦截器完成的!!!

1.2.3 自定义类型转换器:(了解)

类型转换本身就是一个双向的过程:

* JSP---->Action:String---->要的类型

* Action---->JSP:要的类型---->String

自定义类型转换器的方式:

1.实现TypeConverter接口

*

2.继承DefaultTypeConverter

*

3.继承StrutsTypeConverter

* convertToString(java.util.Map context, java.lang.Object o)

* convertFromString(java.util.Map context, java.lang.String[] values, java.lang.Class toClass)

 

自定义类型转换器:

public class MyDateConverter extends DefaultTypeConverter{

 

@Override

/*

 * context:

 * value:转换之前的类型

 * toType:要转换成的类型

 */

public Object convertValue(Map<String, Object> context, Object value,

Class toType) {

SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");

if(toType == Date.class){

// JSP --- Action

String[] arrs = (String[]) value;

String s = arrs[0];

Date date = null;

try {

date = dateFormat.parse(s);

} catch (ParseException e) {

e.printStackTrace();

throw new RuntimeException();

}

return date;

}else{

// Action --- JSP

Date date = (Date) value;

String s = dateFormat.format(date);

return s;

}

}

}

 

注册类型转换器:

* 全局注册:

* 针对所有的日期类型的注册:

* src下创建一个文件:xwork-conversion.properties

* 编写:java.util.Date=cn.itcast.action.demo3.MyDateConverter

* 局部注册:

* 模型驱动的方式:

* 在实体类所在的包下创建一个(实体类名)-conversion.properties格式的文件

* Emp-conversion.properties

* 编写:birthday=cn.itcast.action.demo3.MyDateConverter

 

* 属性驱动的set方法的方式:

* Action所在的包下创建一个(Action类名)-conversion.properties格式的

* 编写:birthday=cn.itcast.action.demo3.MyDateConverter

 

类型转换的错误:

* 显示中文错误信息:

* Action所在的包下创建一个属性文件(国际化的处理)

* Action类名_zh_CN.properties

* key=value:invalid.fieldvalue.属性名=中文错误信息

 

1.3 数据的有效性校验:

1.3.1 数据的校验:

前台校验:JS校验.

* JS的校验不是必须的.JS可以被绕行的.JS提升用户体验.

后台校验:编码校验.

* 必须的校验.

 

Struts2框架中提供了2类的数据校验:

* 1.手动编码的方式进行校验:

* 继承ActionSupport

* 重写validate方法:----针对Action中的所有的方法.

* 在这个方法中就可以编写校验的代码了.

 

* 针对Action中的某个方法进行校验:例如校验Actionadd方法 或者 modify的方法.

* 编写一个与validate方法格式相同的方法,方法名称validate要校验的方法名.

* validateAdd()validateModify()

 

* 2.采用配置文件的方式进行校验:

* 需要提供对应属性的get方法才可以!!!

* 针对Action中的所有的方法校验

* Action所在的包下创建一个与Action类名相同-validation.xml.

* 引入DTD:

* xwork-core-2.3.7.jar有一个xwork-validator-1.0.3.dtd

* 进行配置:

<validators>

<!-- name:要校验的字段名 -->

<field name="username">

<field-validator type="requiredstring">

<message>用户名不能为空!(XML)</message>

</field-validator>

</field>

<field name="password">

<field-validator type="requiredstring">

<message>密码不能为空!(XML)</message>

</field-validator>

</field>

</validators>

 

* requiredstring就是校验规则:com.opensymphony.xwork2.validator.validators.default.xml中可以查看校验规则

 

* 针对Action中的某一个方法校验:

 

* Action所在的包下创建一个文件与Action类名-要访问的方法对应的action的名称-validation.xml

* <action name=login2 class=cn.itcast.action.demo4.LoginAction2 method=execute/>

* 创建校验execute的文件:

* LoginAction2-login2-validation.xml

 

 

* 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指定最大值)

conversion(转换校验器,指定在类型转换失败时,提示的错误信息)

visitor(用于校验action中复合类型的属性,它指定一个校验文件用于校验复合类型属性中的属性)

expression(OGNL表达式校验器,它是一个非字段校验器, expression参数指定ognl表达式,该逻辑表达式基于ValueStack进行求值,返回true时校验通过,否则不通过,该校验器不可用在字段校验器风格的配置中)

 

1.3.2 自定义校验器:(了解)

* 若需要普通的验证程序, 可以继承 ValidatorSupport ---校验的时候不是针对一个字段的(密码和确认密码)

* 若需要字段验证程序, 可以继承 FieldValidatorSupport ---针对一个字段的校验(用户名的校验)

 

* 编写一个类继承FieldValidatorSupport :

public class MyAgeValidator extends FieldValidatorSupport {

 

public void validate(Object obj) throws ValidationException {

// 获得字段名称:

String name = this.getFieldName();

// 获得字段的值:

Object value =  this.getFieldValue(name, obj);

if(value instanceof Integer){

int age = (Integer) value;

if(age < 0){

this.addFieldError(name, obj);

}

}

}

 

}

 

* 注册校验规则:

* src下创建一个validators.xml

* 引入一个DTD:

* xwork-core-2.3.7.jar下的xwork-validator-config-1.0.dtd

* 配置:

<validators>

<validator name="aaa" class="cn.itcast.action.demo6.MyAgeValidator"></validator>

</validators>

 

* 使用校验规则:

<validators>

<field name="age">

<field-validator type="aaa">

<message>年龄不能为负数!</message>

</field-validator>

</field>

</validators>

 

1.4 Struts2中的国际化:

1.4.1 国际化:

软件的国际化:软件根据来访者的不同,自动切换语言进行显示.

 

提供一组资源包:

* 资源包需要有相同的基本名称.

* 命名规则.基本名称_语言_国家.properties

* ResourceBundle读取资源包.

 

1.4.2 Struts2中的国际化:

全局的国际化:(*****)

提供一组资源包:

* 放在src

* message_zh_CN.properties

* message_en_US.properties

 

* 需要在struts.xml中开启一个常量:

<constant name="struts.custom.i18n.resources" value="message"/>

如何在其他地方引用國際化文件中配置好的文本信息

Action类中

* String name = getText("name");

JSP

* <s:text name="name"/>

在国际化配置文件中

* <message key="login.username"/>

Action范围的国际化:

Action类中使用

* Action所在的包下创建一个属性文件.---名字与Action的类名一致!!!

包范围的国际化:

在当前包以及当前包的子包下使用.

* 在某个包下创建属性文件.----package_语言_国家.properties

临时的国际化:

在页面JSP中的使用

<s:i18n name="cn/itcast/action/demo7/package">

<s:text name="package"></s:text>

</s:i18n>

 

1.5 Struts2中拦截器:

1.5.1 拦截器的原理:

拦截器和过滤器区别?

拦截器:Interceptor

* 拦截器拦截对Action的访问.(拦截器能拦截HTML/JSP 不能拦截.)---拦截可以拦截细粒度的Action访问.比如拦截add方法.

* AOP思想实现,是可以插拔的.

* AOP:面向切面编程.

 

过滤器:Filter

* 过滤器过滤的是客服端向服务器发送的请求.

 

Struts2核心就是拦截器:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值