1

我正在尝试使用 JSON 将表单从 Ext JS 4 提交到 Spring 3 控制器。我正在使用 Jackson 1.9.8 进行序列化/反序列化,使用 Spring 的内置 Jackson JSON 支持。

我在新记录的域对象中有一个状态字段最初为空。提交表单时,它会生成以下 json(缩小到几个字段)

{"id":0,"name":"someName","status":""}

提交后在服务器日志中看到以下内容

"nested exception is org.codehaus.jackson.map.JsonMappingException: Can not construct instance of com.blah.domain.StatusEnum from String value '': value not one of the declared Enum instance names"

因此,杰克逊似乎期望一个有效的枚举值或根本没有值,包括一个空字符串。无论是在 Ext JS、Jackson 还是 Spring 中,我该如何解决这个问题?

我试图创建自己的 ObjectMapper,例如

public class MyObjectMapper extends Object Mapper {
    public MyObjectMapper() {
        configure(DeserializationConfig.Feature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
    }
}

并将其作为属性发送给 MappingJacksonMappingView 但这不起作用。我也尝试将它发送到 MappingJacksonHttpMessageConverter 但这没有用。附带问题:我应该在自己的 ObjectMapper 中发送哪个?

建议?

4

4 回答 4

2

您可以做的另一件事是org.codehaus.jackson.map.JsonDeserializer为您的特定枚举创建一个专门的反序列化器(extends),它对不匹配的事物具有默认值。我所做的是为枚举创建一个抽象的反序列化器,它采用它反序列化的类,当我遇到问题时它会加快这个过程。

public abstract class EnumDeserializer<T extends Enum<T>> extends JsonDeserializer<T> {
    private Class<T> enumClass;

    public EnumDeserializer(final Class<T> iEnumClass) {
        super();
        enumClass = iEnumClass;
    }

    @Override
    public T deserialize(final JsonParser jp,
                         final DeserializationContext ctxt) throws IOException, JsonProcessingException {
        final String value = jp.getText();
        for (final T enumValue : enumClass.getEnumConstants()) {
            if (enumValue.name().equals(value)) {
                return enumValue;
            }
        }
        return null;
    }
}

那是通用类,基本上只需要一个枚举类,迭代枚举的值并检查下一个标记以匹配任何名称。如果他们这样做,则返回它,否则返回 null;

然后如果你有一个枚举 MyEnum 你会创建一个EnumDeserializer像这样的子类:

public class MyEnumDeserializer extends EnumDeserializer<MyEnum> {
    public MyEnumDeserializer() {
        super(MyEnum.class);
    }
}

然后无论您在哪里声明MyEnum

@JsonDeserialize(using = MyEnumDeserializer.class)
public enum MyEnum {
    ...
}
于 2014-09-26T18:23:27.737 回答
1

我不熟悉 Spring,但以防万一,在客户端处理它可能更容易:

Ext.define('My.form.Field', {
    extend: 'Ext.form.field.Text',

    getSubmitValue: function() {
        var me = this,
            value;

        value = me.getRawValue();

        if ( value === '' ) {
            return ...;
        }
    }
});

您还可以通过将其allowBlank属性设置为 来禁止提交空字段false

于 2012-08-15T16:03:52.473 回答
1

最终在 EXT JS 模型中添加了默认值,因此总是有一个值。希望我不必这样做,但这没什么大不了的。

于 2012-08-28T13:48:51.923 回答
1

我有同样的问题。我正在读取带有一些空字符串的 JSON 流。我无法控制 JSON 流,因为它来自外部服务。而且我总是收到相同的错误消息。我在这里试过这个:

mapper.getDeserializationConfig().with(DeserializationConfig.Feature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);

但是没有任何效果。看起来像个虫子。

于 2012-10-17T08:01:22.007 回答