struts2中提供的类型转换

在web中我们使用beanutils直接将表单数据封装到javaBean中。---类型转换

struts2中action得到请求参数,也可以直接封装到javaBean.

struts2 内部提供大量类型转换器,用来完成数据类型转换问题

boolean 和 Boolean

char和 Character

int 和 Integer

long 和 Long

float 和 Float

double 和 Double

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

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

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

例如:日期类型,我们传递 yyyy-MM-dd yyyy年MM月dd日格式都可以,但是如果是yyyy/MM/dd

就会出现问题

HTTP Status 404 – Not Found


Type  Status Report

Message  No result defined for action com.demo.test2.action.RegistAction2 and result input

Description  The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.


Apache Tomcat/8.5.24

关于struts2中的类型转换器:

struts2中的类型转换器根接口是:com.opensymphony.xwork2.conversion.TypeConverter。

-------------------------------------------------------

自定义类型转换器:

步骤:

1.创建一个类实现TypeConverter接口.

2.重写接口中方法,实现类型转换操作.

3.注册类型转换器.

详解说明:

1.创建一个自定义类型转换器

1.实现TypeConverter需要重写

public Object convertValue(Map<String, Object> context, Object target, Member member, String propertyName, Object value, Class toType);

如果实现接口,这个方法参数太多(6个)

2.不推荐实现接口,可以继承 DefaultTypeConverter类

优点:重写的方法参数没有那么多

public Object convertValue(Map<String, Object> context, Object value, Class toType) {

return convertValue(value, toType);

}

3.个人推荐使用 继承DefaultTypeConverter类的一个子类StrutsTypeConverter.

原因:在这个类中将从页面传递的数据怎样封装,以及action中的数据怎样在页面上显示做了分离.

public abstract Object convert FromString(Map context, String[] values, Class toClass);

public abstract String convert ToString(Map context, Object o);





2.怎样注册一个自定义类型转换器.

1.局部--针对于action

注意:这时候的action必须被当作model,就是username是作为action的属性,并提供getset方法。

配置文件所在位置以及名称: 在Action类所在包 创建 Action类名-conversion.properties ,

例子:转换日期

Action:

public class RegistAction extends ActionSupport {

private String username;

private Date birthday;



public String getUsername() {

return username;

}



public void setUsername(String username) {

this.username = username;

}

public Date getBirthday() {

return birthday;

}



public void setBirthday(Date birthday) {

this.birthday = birthday;

}



public String regist(){

System.out.println(this.toString());

return null;

}

@Override

public String toString() {

return "RegistAction [username=" + username + , birthday=" + birthday + "]";

}



}

对应的配置文件:RegistAction-conversion.properties

birthday=com.demo.homework2.utils.MyTypeConverter

对应的转换器

public class MyTypeConverter extends StrutsTypeConverter {

// 接收页面传递的数据封装到javaBean.

@Override

public Object convertFromString(Map context, String[] values, Class toClass) {



// System.out.println(context); //ognl.OgnlContext@faae2497

// System.out.println(values[0]); //[Ljava.lang.String;@100c4d

// System.out.println(toClass); //class java.util.Date



String value = values[0];

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

Date date = null;



try {

date = sdf.parse(value);

} catch (ParseException e) {

// e.printStackTrace();

throw new RuntimeException();

}

return date;

}

@Override

public String convertToString(Map context, Object o) {

return null;

}

}



配置文件书写: 格式 : 属性名称=类型转换器的全类名

2.局部--针对于model

配置文件所在位置以及名称: 在model类所在包 创建 model类名-conversion.properties ,

配置文件书写: 格式 : 属性名称=类型转换器的全类名

例子:

Model:

注意:Action实现ModelDriver<User>接口,当用user封装数据时,转换器就起作用了

private User = new User();

public User getModel() {

return user;

}

public class User {



private String username;

private Date birthday;



return username;

}



public void setUsername(String username) {

this.username = username;

}

public Date getBirthday() {

return birthday;

}



public void setBirthday(Date birthday) {

this.birthday = birthday;

}



@Override

public String toString() {

return "User [username=" + username + ", birthday=" + birthday + ", hobby="]";

}

}



对应的配置文件:User-conversion.properties

birthday=com.demo.homework2.utils.MyTypeConverter

转换器也是上面那个



3.全局

配置文件所在位置以及名称:在src下创建一个 xwork-conversion.properties

配置文件书写: 格式: 要转换的类型全名=类型转换器的全类名

例子:所有date类型都会经过这个转换器

java.util.Date=com.demo.test2.utils.MyTypeConverter



-----------------------------------------------------------------------------

注意:

对于struts2中类型转换器,如果表单数据提交时,将数据向model封装,出现了问题,会报错:

No result defined for action cn.itcast.action.RegistAction and result input

上面的意思是说, 在RegistAction的配置中没有配置input结果视图.

<action name="regist" class="cn.itcast.action.RegistAction">

<result name="input">/success.jsp</result>

</action>

如果配置了,出现类型转换问题,就会跳转到input指定的视图。

问题:为什么会向input视图跳转?

是因为struts2中的拦截器(interceptor).

在struts2中的

<interceptor name="conversionError" class="org.apache.struts2.interceptor.StrutsConversionErrorInterceptor"/>

用于记录类型转换问题

在struts2中

<interceptor name="workflow" class="com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor"/>

用于得到问题,向input视图跳转。

关于错误信息展示:

通过分析拦截器作用,得知当类型转换出错时,自动跳转input视图 ,在input视图页面中 <s:fieldError/> 显示错误信息

* 在Action所在包中,创建 ActionName.properties,在局部资源文件中配置提示信息 : invalid.fieldvalue.属性名= 错误信息(国际化)

例子:RegistAction.properties RegistAction就是上面那个本身作为model的action类

invalid.fieldvalue.birthday=\u65E5\u671F\u683C\u5F0F\u4E0D\u80FD\u4E3A yyyy/MM/dd --》日期格式不能为 yyyy/MM/dd

如果是自定义类型转换器,出现类型转换问题,要跳转到input视图,在类型转换器中,必须抛出异常才可以