使用从String到String格式化的Spring格式和spring:eval不起作用

时间:2013-12-12 11:28:29

标签: spring spring-mvc

我正在运行一个Spring 4.0 mvc webapp,并希望使用带有IbanFormatter的formater SPI:

    public class IbanFormatter implements Formatter<String>
    {
        @Override
        public String print ( String iban, Locale locale )
        {
            StringBuilder sb = new StringBuilder(iban);
            for (int i = 4; i < sb.length(); i += 5)
            {
                sb.insert(i, ' ');
            }
            return sb.toString();
        }

        @Override
        public String parse ( String iban, Locale locale ) throws ParseException
        {
            return iban.replaceAll("\\s+", "");
        }
    }

另外我有一个AnnotationFormaterFactory:

public final class IbanFormatAnnotationFormatterFactory implements AnnotationFormatterFactory<IbanFormat>
{
    @Override
    public Printer<?> getPrinter ( IbanFormat annotation, Class<?> fieldType )
    {
        return new IbanFormatter();
    }

    @Override
    public Parser<?> getParser ( IbanFormat annotation, Class<?> fieldType )
    {
        return new IbanFormatter();
    }

    @Override
    public Set<Class<?>> getFieldTypes ( )
    {
        HashSet<Class<?>> hashSet = new HashSet<Class<?>>();
        hashSet.add(String.class);
        return hashSet;
    }
}

当然是注释:

@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface IbanFormat
{}

使用这样的Object注释:

public class DirectDebitDTO 
{
    @IbanFormat
    private String  iban;
}

我注册了这样的格式化程序:

@Override
protected void addFormatters ( FormatterRegistry registry )
{
    registry.addFormatterForFieldAnnotation(new IsoFallbackJodaDateTimeFormatAnnotationFormatterFactory());
    registry.addFormatterForFieldAnnotation(new IbanFormatAnnotationFormatterFactory());
}

上面看到的我的DateFormatter就像一个魅力。

在我的jsp中我想显示格式化的iban:

IBAN: <spring:eval expression="directDebit.iban"  />

它不起作用。它只显示未格式化的iban。我调试了它,并在ExpressionUtils的第65行找到了原因

public static <T> T convertTypedValue(EvaluationContext context, TypedValue typedValue, Class<T> targetType) {
    Object value = typedValue.getValue();
    if ((targetType == null) || (value != null && ClassUtils.isAssignableValue(targetType, value))) {
        return (T) value;
    }
    if (context != null) {
        return (T) context.getTypeConverter().convertValue(value, typedValue.getTypeDescriptor(), TypeDescriptor.valueOf(targetType));
    }
    throw new EvaluationException("Cannot convert value '" + value + "' to type '" + targetType.getName() + "'");
}

触发第一个if语句,因为两个值都是字符串。没有转换,因此没有格式化。所以它甚至没有帮助添加转换器

当然我可以将iban的类型从String更改为Iban.class,只是为了获得类型转换。

对我来说,它看起来像一个Bug,但是没有发现任何关于此事的内容 这是预期的行为还是错误?

0 个答案:

没有答案