2012-08-15 111 views
0

我想從Ext JS 4提交表單到使用JSON的Spring 3控制器。我使用的是Jackson 1.9.8的序列化/反序列化,使用Spring內置的Jackson JSON支持。如何處理將空字符串反序列化爲Enum?

我有一個狀態字段,最初爲空記錄在一個新記錄的域對象。當提交表單時它會生成以下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中發送哪一個?

對此提出建議?

回答

1

結束了在EXT JS模型中添加默認值,所以總是有一個值。希望我不必這樣做,但這不是什麼大問題。

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提交空字段。

2

我有同樣的問題。我正在閱讀帶有一些空字符串的JSON流。我無法控制JSON流,因爲它來自外部服務。我總是收到相同的錯誤信息。我試過這裏:

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

但沒有任何影響。看起來像一個Bug。

+1

我在JIRA開罰單爲: http://jira.codehaus.org/browse/JACKSON-873?focusedCommentId=311657 – 2012-10-17 08:44:32

1

你可以做的另一件事是爲你的特定枚舉創建一個專用的反序列化器(擴展爲org.codehaus.jackson.map.JsonDeserializer),它具有不匹配的事物的默認值。我所做的就是爲枚舉創建一個抽象反序列化器,它接受它反序列化的類,並在遇到問題時加速這個過程。

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 { 
    ... 
} 
相關問題