Could not write JSON: No serializer found for 的坑


記一次 Could not write JSON: No serializer found for 的坑


今天在返回一個 DTO 實體的時候報錯如下:

"message": "Could not write JSON: No serializer found for class com.entity.Question and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS); nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class com.entity.Question and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: com.common.component.RspDTO[\"data\"]->com.dto.common.PageDTO[\"records\"]->java.util.ArrayList[0])",

  • 在看到上述問題的時候 首先看到的是 No serializer ,因此首先查看 我們的 PageDTO 類,如下類
public class PageDTO implements Serializable {

    private static final long serialVersionUID = -7254888630210798460L;

    /**
     * 每頁顯示條數,默認 10
     */
    private Integer size;

    /**
     * 當前頁
     */
    private Integer current;

    private Long total;

    /**
     * 是否為升序 ASC( 默認: true )
     */
    private Boolean isAsc;

    private Map<String, String> condition;

    private List records = Collections.emptyList();

    /**
     *  get set 方法忽略
     */
}

可以看到 已經實現了 Serializable 接口,並且有正常的 serialVersionUID 字段 ,所以類沒有問題

接着繼續查看:

com.common.component.RspDTO["data"]->com.dto.common.PageDTO["records"]->java.util.ArrayList[0])",

發現了如下關鍵字,所以懷疑是 List 中的 entity 的問題,如下:

public class Question extends BaseEntity {

    private static final long serialVersionUID = 1L;

    private Long id;
    
    private Integer grade;

    private Integer subject;
   
    @Version
    private Date modifiedAt;

    @Override
    public Date getModifiedAt() {
        return modifiedAt;
    }

    @Override
    public void setModifiedAt(Date modifiedAt) {
        this.modifiedAt = modifiedAt;
    }

    // 忽略 get  set 方法

BaseEntity 代碼如下:

public class BaseEntity implements Serializable {

    private static final long serialVersionUID = 1L;
    
    private Integer isDel;
    
    private Long creatorId;
    
    private Date createdAt;
    
    private Long modifierId;
   
    private Date modifiedAt;

Question 類繼承了 BaseEntity 並且實現了 Serializable 接口,查完也沒有問題。

那么只能一步步看代碼了:

 Page page = this.selectPage(new Page(pageDTO.getCurrent(), pageDTO.getSize()), wrapper);

        pageDTO.setRecords(page.getRecords());

經查明發現出錯的 就是 pageDTO.setRecords(page.getRecords());

然后我們手動獲取 page.getRecords(),是沒有問題的,那么就剩下了 pageDTO.setRecords() 這個方法,執行后發現果然是這里的問題。

問題來了,為什么一個 setList 的方法會出問題呢?

看了下 page.getRecords() 的內容,發現在 Question 中有一個重寫了父類的 modifiedAt 字段,在數據庫返回的時候給該值賦值成功,但是他還有個 BaseEntity.modifiedAt 的字段,這個值是 null,就是這里引起的問題

最暴力的方法就是 for 循環 然后給該值賦值,這樣就序列化成功了,但是這不是我們想要的效果,之后發現是因為在 setList 的時候,沒有使用泛型限定值的類型,所以在set的時候就要全部set進去了。所以一個很小的改動就好:

public class PageDTO <T> implements Serializable{

    private List<T> records = Collections.emptyList();

        .
        .
        
}

加入限定修飾,然后在使用的時候

Page<Question> page = this.selectPage(new Page(pageDTO.getCurrent(), pageDTO.getSize()), wrapper);

完美解決


遇到坑不怕,怕的是你不深入就跳過去了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM