2014-04-26 44 views
0

我在控制器上有一個Spring Rest Controller和一個用於POST方法的「命令」/ DTO對象。我還爲字段「due」之一寫了一個序列化器/反序列化器 - 這是一個Calendar對象。Json解串器沒有被Spring檢測到

由於Jackson2的依賴關係是在pom.xml中定義的,我希望Spring能夠檢測到我的反序列化器並使用它將字符串輸入轉換爲java.util.Calendar。但是,我收到了「沒有匹配的編輯器或轉換策略」異常。我的串行器正在工作...只有解串器不能工作!

休息控制器(TaskController.java)

@Controller 
public class TasksController { 

    ... 

    @RequestMapping(value = "/tasks", method = RequestMethod.POST) 
    public @ResponseBody Task createTask(@Valid TasksCommand tasksCommand){ 

     Task task = new Task(); 
     task.setName(tasksCommand.getName()); 
     task.setDue(tasksCommand.getDue()); 
     task.setCategory(tasksCommand.getCategory()); 

     return task; 
    } 
} 

命令/ DTO對象:

public class TasksCommand { 

    @NotBlank 
    @NotNull 
    private String name; 

    @JsonDeserialize(using = CalendarDeserializer.class) 
    @JsonSerialize(using = CalendarSerializer.class) 
    private Calendar due; 

    private String category; 

    ... getters & setters ... 
} 

串行日曆 - 用於我的自訂日期格式

public class CalendarSerializer extends JsonSerializer<Calendar>{ 

     @Override 
     public void serialize(Calendar calendar, JsonGenerator jgen, SerializerProvider provider) 
       throws IOException, JsonProcessingException { 
      SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss Z"); // Z - RFC 822 time zone 

      jgen.writeString(simpleDateFormat.format(calendar.getTime())); 

     } 

} 

解串器對日曆

public class CalendarDeserializer extends JsonDeserializer<Calendar> { 

    private static Logger logger = Logger.getLogger(CalendarDeserializer.class); 

    @Override 
    public Calendar deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) 
      throws IOException, JsonProcessingException { 

     String dateStr = jsonParser.getText(); 
     logger.info("deserializing date:" + dateStr); 

     return Calendar.getInstance(); 

    } 
} 

我有在Maven中指定的Jackson2依賴關係。在執行GET(代碼未在此處顯示)時,序列化程序正確調用,並看到「Task」對象的JSON輸出。

然而,當我提出一個HTTP POST如下

curl -X POST -d name=task1 -d category=weekly -d due=01/01/2013 http://localhost:8080/tasks 

檢測不到,解串器和我既然是越來越檢測串行異常

Failed to convert property value of type java.lang.String to required type java.util.Calendar for property due; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [java.util.Calendar] for property due: no matching editors or conversion strategy found 

,我不明白爲什麼解串器沒有被檢測到並調用正確。從我讀過的內容來看,在classpath上有Jackson2庫會被Spring檢測到,它會自動將MappingJackson2HttpMessageConverter添加到消息轉換器列表中。因此,此代碼應該檢測HTTP POST中的字符串,並使用Deserializer將其轉換爲java.util.Calendar。我錯過了什麼?

回答

0

想通了這一點。

當使用描述中所示的Curl(帶-d標誌)進行HTTP POST時,POST自帶內容類型「application/x-www-form-urlencoded」(事後明瞭,因爲它被處理作爲網頁表單數據)。這會觸發Spring FormHttpMessageConverter消息轉換器,並且MappingJackson2HttpMessageConverter轉換器永遠不會被觸發。

但是,序列化程序和反序列化程序使用Jackson註釋進行註釋,並且只有MappingJackson2HttpMessageConverter知道如何處理該註釋。這是導致問題中所述異常的原因。

的解決方案是在JSON數據傳遞在捲曲命令:

curl -X POST -H "Content-Type: application/json" -d '{"name":"test1","due":"1/1/2013","category":"weekly"}' http://localhost:8080/tasks 

另外,由於JSON輸入進來的HTTP POST呼叫的主體中,我們需要使用在該@RequestBody註釋控制器方法簽名。

@RequestMapping(value = "/tasks", method = RequestMethod.POST) 
    public @ResponseBody Task createTask(@RequestBody @Valid TasksCommand tasksCommand){ 

     Task task = new Task(); 
     task.setName(tasksCommand.getName()); 
     task.setDue(tasksCommand.getDue()); 
     task.setCategory(tasksCommand.getCategory()); 

     return task; 
    } 

現在反序列化器被觸發並且輸入到期日從字符串正確轉換爲日曆對象。