Struts2.0 中支持的基本数据类的转换的类XWorkBasicConverter的分析
? 项目中Struts2.1.6不支持基本数据类型的自动转换,项目继而采用Struts2.1.8支持数据类型的基本原始数据类型的自动转换。主要原因在:XWork的版本原来xwork2.1.3 提供为xwork2.16 版本:
?
下面代码为xwork2.16版本的源码:
?
?
* <p/>
?* XWork will automatically handle the most common type conversion for you. This includes support for converting to
?* and from Strings for each of the following:
?* <p/>
?* <ul>
?* <li>String</li>
?* <li>boolean / Boolean</li>
?* <li>char / Character</li>
?* <li>int / Integer, float / Float, long / Long, double / Double</li>
?* <li>dates - uses the SHORT format for the Locale associated with the current request</li>
?* <li>arrays - assuming the individual strings can be coverted to the individual items</li>
?* <li>collections - if not object type can be determined, it is assumed to be a String and a new ArrayList is
?* created</li>
?* </ul>
?* <p/> Note that with arrays the type conversion will defer to the type of the array elements and try to convert each
?* item individually. As with any other type conversion, if the conversion can't be performed the standard type
?* conversion error reporting is used to indicate a problem occured while processing the type conversion.
?* <p/>
?
?
public class XWorkBasicConverter extends DefaultTypeConverter :
?
?
?
//转换器的重点转换的方面如下:
?@Override
??? public Object convertValue(Map<String, Object> context, Object o, Member member, String s, Object value, Class toType) {
??????? Object result = null;
??????? if (value == null || toType.isAssignableFrom(value.getClass())) {
??????????? // no need to convert at all, right?
??????????? return value;
??????? }
??????? if (toType == String.class) {
??????????? /* the code below has been disabled as it causes sideffects in Struts2 (XW-512)
??????????? // if input (value) is a number then use special conversion method (XW-490)
??????????? Class inputType = value.getClass();
??????????? if (Number.class.isAssignableFrom(inputType)) {
??????????????? result = doConvertFromNumberToString(context, value, inputType);
??????????????? if (result != null) {
??????????????????? return result;
??????????????? }
??????????? }*/
??????????? // okay use default string conversion
??????????? result = doConvertToString(context, value);
??????? } else if (toType == boolean.class) {
??????????? result = doConvertToBoolean(value);
??????? } else if (toType == Boolean.class) {
??????????? result = doConvertToBoolean(value);
??????? } else if (toType.isArray()) {
??????????? result = doConvertToArray(context, o, member, s, value, toType);
??????? } else if (Date.class.isAssignableFrom(toType)) {
??????????? result = doConvertToDate(context, value, toType);
??????? } else if (Calendar.class.isAssignableFrom(toType)) {
??????????? Date dateResult = (Date) doConvertToDate(context, value, Date.class);
??????????? if (dateResult != null) {
??????????????? Calendar calendar = Calendar.getInstance();
??????????????? calendar.setTime(dateResult);
??????????????? result = calendar;
??????????? }
??????? } else if (Collection.class.isAssignableFrom(toType)) {
??????????? result = doConvertToCollection(context, o, member, s, value, toType);
??????? } else if (toType == Character.class) {
??????????? result = doConvertToCharacter(value);
??????? } else if (toType == char.class) {
??????????? result = doConvertToCharacter(value);
??????? } else if (Number.class.isAssignableFrom(toType) || toType.isPrimitive()) {
??????????? result = doConvertToNumber(context, value, toType);
??????? } else if (toType == Class.class) {
??????????? result = doConvertToClass(value);
??????? }
??????? if (result == null) {
??????????? if (value instanceof Object[]) {
??????????????? Object[] array = (Object[]) value;
??????????????? if (array.length >= 1) {
??????????????????? value = array[0];
??????????????? } else {
??????????????????? value = null;
??????????????? }
??????????????? // let's try to convert the first element only
??????????????? result = convertValue(context, o, member, s, value, toType);
??????????? } else if (!"".equals(value)) { // we've already tried the types we know
??????????????? result = super.convertValue(context, value, toType);
??????????? }
??????????? if (result == null && value != null && !"".equals(value)) {
??????????????? throw new XWorkException("Cannot create type " + toType + " from value " + value);
??????????? }
??????? }
??????? return result;
??? }
// 其中的一个数字类型的转换:有此可以看出支持红色的部分的哦:^_^
??? private Object doConvertToNumber(Map<String, Object> context, Object value, Class toType) {
??????? if (value instanceof String) {
??????????? if (toType == BigDecimal.class) {
??????????????? return new BigDecimal((String) value);
??????????? } else if (toType == BigInteger.class) {
??????????????? return new BigInteger((String) value);
??????????? } else if (toType.isPrimitive()) {
??????????????? Object convertedValue = super.convertValue(context, value, toType);
??????????????? String stringValue = (String) value;
??????????????? if (!isInRange((Number)convertedValue, stringValue,? toType))
??????????????????????? throw new XWorkException("Overflow or underflow casting: \"" + stringValue + "\" into class " + convertedValue.getClass().getName());
??????????????? return convertedValue;
??????????? } else {
??????????????? String stringValue = (String) value;
??????????????? if (!toType.isPrimitive() && (stringValue == null || stringValue.length() == 0)) {
??????????????????? return null;
??????????????? }
??????????????? NumberFormat numFormat = NumberFormat.getInstance(getLocale(context));
??????????????? ParsePosition parsePos = new ParsePosition(0);
??????????????? if (isIntegerType(toType)) {
??????????????????? numFormat.setParseIntegerOnly(true);
??????????????? }
??????????????? numFormat.setGroupingUsed(true);
??????????????? Number number = numFormat.parse(stringValue, parsePos);
??????????????? if (parsePos.getIndex() != stringValue.length()) {
??????????????????? throw new XWorkException("Unparseable number: \"" + stringValue + "\" at position "
??????????????????????????? + parsePos.getIndex());
??????????????? } else {
??????????????????? if (!isInRange(number, stringValue,? toType))
??????????????????????? throw new XWorkException("Overflow or underflow casting: \"" + stringValue + "\" into class " + number.getClass().getName());
???????????????????
??????????????????? value = super.convertValue(context, number, toType);
??????????????? }
??????????? }
??????? } else if (value instanceof Object[]) {
??????????? Object[] objArray = (Object[]) value;
??????????? if (objArray.length == 1) {
??????????????? return doConvertToNumber(context, objArray[0], toType);
??????????? }
??????? }
??????? // pass it through DefaultTypeConverter
??????? return super.convertValue(context, value, toType);
??? }
?
?
//时间类型的转换:
?private Object doConvertToDate(Map<String, Object> context, Object value, Class toType) {
??????? Date result = null;
??????? if (value instanceof String && value != null && ((String) value).length() > 0) {
??????????? String sa = (String) value;
??????????? Locale locale = getLocale(context);
??????????? DateFormat df = null;
??????????? if (java.sql.Time.class == toType) {
??????????????? df = DateFormat.getTimeInstance(DateFormat.MEDIUM, locale);
??????????? } else if (java.sql.Timestamp.class == toType) {
??????????????? Date check = null;
??????????????? //支持的格式
??????????????? SimpleDateFormat dtfmt = (SimpleDateFormat) DateFormat.getDateTimeInstance(DateFormat.SHORT,
??????????????????????? DateFormat.MEDIUM,
??????????????????????? locale);
??????????????? SimpleDateFormat fullfmt = new SimpleDateFormat(dtfmt.toPattern() + MILLISECOND_FORMAT,
??????????????????????? locale);
??????????????? SimpleDateFormat dfmt = (SimpleDateFormat) DateFormat.getDateInstance(DateFormat.SHORT,
??????????????????????? locale);
??????????????? SimpleDateFormat[] fmts = {fullfmt, dtfmt, dfmt};
??????????????? for (SimpleDateFormat fmt : fmts) {
??????????????????? try {
??????????????????????? check = fmt.parse(sa);
??????????????????????? df = fmt;
??????????????????????? if (check != null) {
??????????????????????????? break;
??????????????????????? }
??????????????????? } catch (ParseException ignore) {
??????????????????? }
??????????????? }
??????????? } else if (java.util.Date.class == toType) {
??????????????? Date check = null;
??????????????? DateFormat[] dfs = getDateFormats(locale);
??????????????? for (DateFormat df1 : dfs) {
??????????????????? try {
??????????????????????? check = df1.parse(sa);
??????????????????????? df = df1;
??????????????????????? if (check != null) {
??????????????????????????? break;
??????????????????????? }
??????????????????? }
??????????????????? catch (ParseException ignore) {
??????????????????? }
??????????????? }
??????????? }
??????????? //final fallback for dates without time
??????????? if (df == null) {
??????????????? df = DateFormat.getDateInstance(DateFormat.SHORT, locale);
??????????? }
??????????? try {
??????????????? df.setLenient(false); // let's use strict parsing (XW-341)
??????????????? result = df.parse(sa);
??????????????? if (!(Date.class == toType)) {
??????????????????? try {
??????????????????????? Constructor constructor = toType.getConstructor(new Class[]{long.class});
??????????????????????? return constructor.newInstance(new Object[]{Long.valueOf(result.getTime())});
??????????????????? } catch (Exception e) {
??????????????????????? throw new XWorkException("Couldn't create class " + toType + " using default (long) constructor", e);
??????????????????? }
??????????????? }
??????????? } catch (ParseException e) {
??????????????? throw new XWorkException("Could not parse date", e);
??????????? }
??????? } else if (Date.class.isAssignableFrom(value.getClass())) {
??????????? result = (Date) value;
??????? }
??????? return result;
??? }
?
//Struts2.0可以格式化的几种类型:
??? private DateFormat[] getDateFormats(Locale locale) {
??????? DateFormat dt1 = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.LONG, locale);
??????? DateFormat dt2 = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM, locale);
??????? DateFormat dt3 = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, locale);
??????? DateFormat d1 = DateFormat.getDateInstance(DateFormat.SHORT, locale);
??????? DateFormat d2 = DateFormat.getDateInstance(DateFormat.MEDIUM, locale);
??????? DateFormat d3 = DateFormat.getDateInstance(DateFormat.LONG, locale);
??????? DateFormat rfc3399 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
??????? DateFormat[] dfs = {dt1, dt2, dt3, rfc3399, d1, d2, d3}; //added RFC 3339 date format (XW-473)
??????? return dfs;
??? }
<constant name="struts.custom.i18n.resources" value="applicationResource"></constant>
三:jsp页面取值:
数字和时间一样
页面格式化输出数据时候,只需要:
<s:text name="format.number">
<s:param name="value" value="a.somefield"/>
</s:text>
3 楼 longgangbai 2010-05-27 wgx198302 写道请问struts2中的Date格式怎么修改?
默认是“yyyy-MM-dd'T'HH:mm:ss”,我想改成“yyyy-MM-dd'T'HH:mm”?
第二种方式就是
一。采用自定义转换器继承自DefaultTypeConverter ,实现相应的转换方法即可。备注此处你需要实现的是将时间Date转换为自定义的格式的字符串。
二.在全巨额的xwork-conversion.properties文件配置。
数据类型=转换器类(包含包名)
例如:
java.util.Date=com.easyway.dev.common.DataTypeConverter