同一個接口,聲明、返回多個視圖

對於實際開發中,我們的統一返回dto,也有可能要求不同情況返回不同的字段,比如下面的返回dto:

package com.walletServer.dto;

import java.io.Serializable;

import com.fasterxml.jackson.annotation.JsonView;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * Description: BaseResponseDto
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class BaseResponseDto implements Serializable {
    private static final long serialVersionUID = 2120869894112984147L;

    public interface SuccessView {
    };

    public interface ErrorView extends SuccessView {
    };

    @JsonView(BaseResponseDto.SuccessView.class)
    private long id;
    @JsonView(BaseResponseDto.SuccessView.class)
    private Object data;
    @JsonView(BaseResponseDto.ErrorView.class)
    private String error;

    public static BaseResponseDto Ok(Object data) {
        return BaseResponseDto.builder().data(data).build();
    }

    public static BaseResponseDto Error(String error) {
        return BaseResponseDto.builder().error(error).build();
    }
}

分別有id,data,error字段,接口處理成功,返回數據到data,處理異常返回error信息到error字段。

具體實現思路兩種:

1️⃣通過Jackson json解析器的@JsonFilter註解,結合代碼實現,在轉換json的時候過濾掉不必要的字段;

2️⃣通過Jackson的@JsonView註解,定義不同的返回視圖,動態的指定不同的返回視圖。

返回Dto還是上面的dto。可以看到dto裏面已經定義了兩個返回視圖,具體測試代碼如下:

package jsonFilter;

import org.junit.Test;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ser.FilterProvider;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
import com.walletServer.dto.BaseResponseDto;

public class JsonFilterTest {
    
    private ObjectMapper setupJsonFilter(String filterId,String[] filters){
        if(filters==null) {
            filters = new String[] {};
        }
        ObjectMapper mapper = new ObjectMapper();
        String nonPasswordFilterName = "non-error";//需要跟對應實體類上的註解@JsonFilter("non-error")裏面的一致
        FilterProvider filterProvider = new SimpleFilterProvider()
                .addFilter(nonPasswordFilterName, SimpleBeanPropertyFilter.serializeAllExcept(filters));
                //serializeAllExcept 表示序列化全部,除了指定字段
                //filterOutAllExcept 表示過濾掉全部,除了指定的字段
        mapper.setFilterProvider(filterProvider);
        return mapper;
    }
    
    @Test
    public void testJsonFilter() throws JsonProcessingException {
        
        BaseResponseDto dto = BaseResponseDto.builder().id(123456).data("dataMsg").error("errorMsg").build();
        
        //法一    需在dto頭添加@JsonFilter("non-error")註解,不然filter不生效
        System.out.println(setupJsonFilter("non-error",new String[] {"error"}).writeValueAsString(dto));
        System.out.println(setupJsonFilter("non-error",null).writeValueAsString(dto));
        
        //法二    使用法一dto添加@JsonFilter("non-error"), 會提示Can not resolve PropertyFilter with id 'non-error'; no FilterProvider configured異常
        //          故使用法二需去掉dto的@JsonFilter("non-error")註解
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            System.out.println(objectMapper.writerWithView(BaseResponseDto.SuccessView.class).writeValueAsString(dto));
            System.out.println(objectMapper.writerWithView(BaseResponseDto.ErrorView.class).writeValueAsString(dto));
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        
        //綜上所述使用法二
    }

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章