2016-08-10 31 views
0

我具有時區POJO如下:處理空和默認值與傑克遜

@Entity 
public class TimeZoneDto implements Serializable { 
    private static final long serialVersionUID = 1L; 
    @Id 
    @Column(name = "id", nullable = false) 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "timezone_sequence") 
    @SequenceGenerator(name = "timezone_sequence", sequenceName = "t_timeZone_master_id_seq", initialValue = 1, allocationSize = 1) 
    private Long id; 
    @Column 
    private String timeZone; 
    @Column 
    private String name; 
    @Column 
    private double hourDifference; 
    /* all gettet/setter */ 
} 

我在彈簧控制器如下updateTimeZone方法:

@RequestMapping(value = "updateTimezone", consumes = "application/json", produces = "application/json", method = RequestMethod.POST) 

    public ResponseEntity<Object> updateTimezone(@RequestBody TimeZoneDto timeZoneDto){ 

} 

當我如下傳請求:

{"id":14,"name":"America/Los_Angeles -7:00 GMT"} 

然後它自動轉換其他值與默認值時映射與POJO a ND它變爲:

id=14, timeZone=null, name=America/Los_Angeles -7:00 GMT, hourDifference=0.0 

因爲如此,當我更新這POJO如下

getEntityManager().merge(timezoneDto); 

它覆蓋時區= null並且hourDifference = 0.0自動,

所以有任何方法,通過該我在@RequestBody中的TimeZoneDto只有那些在請求JSON中傳遞的列。

編輯

我在下面用在類,但它不能正常工作

@JsonInclude(value=Include.NON_EMPTY) 
       OR 
    @JsonInclude(value=Include.NON_DEFAULT) 
+0

你想要這些值默認爲?我的意思是,當Jackson反序列化JSON時,默認情況下它只是將DTO創建爲一個普通的java對象,而所有缺少的字段將採用它們的默認值。 –

+0

當傑克遜反序列化JSON –

+0

我不理解時,我想忽略DTO對象中所有缺少的字段,傑克遜已經忽略了那些字段,這就是爲什麼他們得到默認值。你需要JSOn中那些不存在的字段在DTO中? –

回答

0

這是經典模式,你首先需要從存儲庫中獲取TimeZone實體然後合併傳入的JSON數據與現有的記錄數據。

public ResponseEntity<Object> updateTimeZone(@RequestBody TimeZoneDto dto) { 
    final TimeZone timeZone = timeZoneRepository.findById(dto.getId()); 
    // use object mapper or whatever and merge dto onto timeZone 
    timeZoneRepository.saveOrUpdate(timeZone); 
    return timeZone; 
} 
+0

有沒有什麼方法可以讓我的@RequestBody中的TimeZoneDto只有那些在請求JSON中傳遞的列。 –

+0

您的DTO將由傑克遜填充JSON包含的字段。其他字段將簡單地爲空;那就是傑克遜將JSON流保存爲對象的方式。從這一點開始,您必須像上面描述的那樣處理屬性的邏輯合併。 – Naros

+0

如果所有這些字段都是NULL,這些字段不是JSON,我可以使用某些條件合併,但在我的情況下,某些Long,布爾變量採用默認值,所以有時可能是實際值,有時它們是默認值。所以它很難區分 –

1

我認爲問題出在您的設計上。您將實體與DTO混合使用。最常用的解決方案是分離這兩個層。你可以有一個共同的接口說TimeZoneInfo則有兩種實現

  • TimeZoneDto - 負責傳輸客戶端和服務器之間的數據,只聲明你在這個對象需要什麼。 (例如:無區字段)
  • TimeZoneEntity - 代表一個持久性實體(JPA /休眠)

然後你就可以有TimeZoneDto作爲請求主體和適應(即獲得所需的值,並設置爲實體)該對象作爲TimeZoneEntity。在適應這個DTO之前,您可能需要從DB獲取TimeZoneEntity。我最好在服務/代表類中說,不是在其他控制器中。