JsonIgnore誤用引起的對象綁定問題

問題描述

Comment

開發通用評論功能時,創建評論實體。java

/**
 * @author zhangxishuo on 2018/8/19
 * 評論實體
 */
@Entity
@ApiModel(value = "Comment (評論)", description = "評論實體")
public class Comment extends YunZhiAbstractEntity {

    private static final Map<String, Class<?>> serviceMap = new HashMap<>();

    static {
        serviceMap.put("NonMandatoryInstrumentCheckApplyService", NonMandatoryInstrumentCheckApplyService.class);
    }

    @Column(length = 3000)
    private String content;

    @Transient    // 該字段不映射到數據庫
    @JsonIgnore   // 序列化時忽略屬性
    private String serviceName;

    @Transient    // 該字段不映射到數據庫
    @JsonIgnore   // 序列化時忽略屬性
    private Long relationId;
}

這裏由於考慮到須要將信息傳遞給相關聯該評論的實體,因此建了兩個額外的屬性serviceNamerelationId,可是這個僅在Service中使用,並不映射到數據庫,同時也不但願這個字段映射到前臺是也顯示。數據庫

測試代碼

@Test
public void saveTest() throws Exception {
    logger.debug("測試數據");
    NonMandatoryInstrumentCheckApply nonMandatoryInstrumentCheckApply = nonMandatoryInstrumentCheckApplyService.getOneSavedObject();
    Long relationId = nonMandatoryInstrumentCheckApply.getId();
    String content = "測試評論";
    String serviceName = "NonMandatoryInstrumentCheckApplyService";

    logger.debug("生成評論");
    Comment comment = new Comment();
    comment.setRelationId(relationId);
    comment.setContent(content);
    comment.setServiceName(serviceName);

    String json = JSONObject.toJSONString(comment);

    this.mockMvc
            .perform(MockMvcRequestBuilders.post("/Comment")
            .content(json)
            .contentType(MediaType.APPLICATION_JSON_UTF8))
            .andDo(document("Comment_save", preprocessResponse(prettyPrint())))
            .andExpect(MockMvcResultMatchers.status().isOk());
}

看着好像沒什麼問題,可是執行時發生了錯誤,Required type must not be nulljson

clipboard.png

logger.debug("獲取服務Bean");
String serviceName = comment.getServiceName();
Class<?> className = Comment.getServiceMap().get(serviceName);
Object service = ContextConfig.getContext().getBean(className);

在調用getBean(Class<T> requiredType)動態獲取Bean的時候,拋出了異常,requiredType不能爲空,也就是咱們調用getBean傳的參數className是空。post

調試

Debug

開啓找Bug模式,咱們看咱們測試請求的字符串json是沒問題,屬性齊全。測試

clipboard.png

走到控制器時,這兩個屬性就沒了。結論:Json反序列化時出錯。ui

clipboard.png

clipboard.png

JsonIgnore

緣由就在@JsonIgnore上,我只考慮了後臺的對象序列化到前臺時須要忽略該屬性,從而添加了這個註解。this

可是這個註解是在序列化與反序列化時都生效的,也就是說:序列化時,忽略該屬性;反序列化時,也忽略該屬性。因此形成了綁定時@JsonIgnore標註的屬性爲null的結果。spa

解決

去掉@JsonIgnore註解,一切正常。debug

總結

記得第一次見到@JsonIgnore註解時去網上查這個註解時幹什麼的。3d

clipboard.png

clipboard.png

谷歌第一條。而後,沒有認真看,一直覺得是JsonIgnore只在對象序列化爲json是才起做用。致使了誤用。

JsonIgnore在序列化與反序列化時都生效!

只知其一;不知其二,害己誤人。
相關文章
相關標籤/搜索