對於實際開發中,我們的統一返回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();
}
//綜上所述使用法二
}
}