簡體   English   中英

如何有條件地從 json 響應中排除屬性

[英]How to conditionally exclude property from a json response

我有一個類 pojo 用於返回對其余控制器中 API 調用的響應

EmployeeResponse response = validationService.validate(request);
return new ResponseEntity<>(response, HttpStatus.OK);

但是,現在我們要對控制器類進行功能標記,以便如果未設置配置屬性,則響應將不包含屬性。 我們怎么能做到這一點?

public class EmployeeResponse {
    private String firstName;
    private String lastName
    private String address;   // don't want to include this if boolean flag is not set
}

編輯:在此處添加控制器代碼以顯示對象在沒有被序列化的情況下返回,所以我看不到如何將 objectMapper 放入其中

@RestController
public class EmployeeController {

    @PostMapping(value = "/validate", produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<EmployeeResponse> get(final @RequestBody EmployeeRequest employeeRequest) {

        MasterSubResponse response = validationService.validate(employeeRequest);
        return new ResponseEntity<>(response, HttpStatus.OK);
    }

}

您可以使用 Jackson Filter 來控制序列化過程。 當使用 JSON 格式時,Spring Boot 將使用 ObjectMapper 實例來序列化響應和反序列化請求。 這個想法是創建自定義過濾器,您將在其中放置業務邏輯,以便有條件地從 DTO 呈現所需的字段。 然后你應該將該過濾器添加到對象映射器。

總而言之,以下是您需要遵循的步驟:

  1. 使用@JsonFilter("myFilter")注釋您的 DTO 類
  2. 為您的自定義過濾器創建實現類
  3. ObjectMapper創建配置類,您將在其中設置在步驟 1 中創建的過濾器。
  4. application.properties文件中創建布爾標志

步驟1:

import com.fasterxml.jackson.annotation.JsonFilter;

@JsonFilter("myFilter")
public class EmployeeResponse {
    private String firstName;
    private String lastName;
    private String address;

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}

第2步:

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
import com.fasterxml.jackson.databind.ser.PropertyFilter;
import com.fasterxml.jackson.databind.ser.PropertyWriter;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;


public class CustomFilter extends SimpleBeanPropertyFilter implements PropertyFilter {

    private boolean isSerializable;



    @Override
    public void serializeAsField
            (Object pojo, JsonGenerator jgen, SerializerProvider provider, PropertyWriter writer)
            throws Exception {
        if (include(writer)) {
            if (!writer.getName().equals("address")) {
                writer.serializeAsField(pojo, jgen, provider);
                return;
            }
            System.out.println(isSerializable);
            if (isSerializable) {
                writer.serializeAsField(pojo, jgen, provider);
            }
        } else if (!jgen.canOmitFields()) { // since 2.3
            writer.serializeAsOmittedField(pojo, jgen, provider);
        }
    }

    @Override
    protected boolean include(BeanPropertyWriter writer) {
        return true;
    }

    @Override
    protected boolean include(PropertyWriter writer) {
        return true;
    }

    public boolean isSerializable() {
        return isSerializable;
    }

    public void setSerializable(boolean serializable) {
        isSerializable = serializable;
    }
}

第 3 步:

import com.example.demo.filter.CustomFilter;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ObjectMapperCofiguration {

    @Value("${isSerializable}")
    public boolean isSerializable;

    @Configuration
    public class FilterConfiguration {
        public FilterConfiguration(ObjectMapper objectMapper) {
            SimpleFilterProvider simpleFilterProvider = new SimpleFilterProvider().setFailOnUnknownId(true);
            CustomFilter customFilter = new CustomFilter();
            customFilter.setSerializable(isSerializable);
            simpleFilterProvider.addFilter("myFilter", customFilter);
            objectMapper.setFilterProvider(simpleFilterProvider);
        }
    }

}

第 4 步:在 application.properties 文件中添加以下屬性:

isSerializable= false

第 5 步:

創建 Controller 類來測試它:

@RestController
public class RestSpringBootController {

   
    @GetMapping(path = "/test")
    public ResponseEntity<EmployeeResponse> test() throws JsonProcessingException {
        EmployeeResponse employeeResponse = new EmployeeResponse();
        employeeResponse.setAddress("addres");
        employeeResponse.setFirstName("first");
        employeeResponse.setLastName("last");
        ResponseEntity<EmployeeResponse> responseEntity = ResponseEntity.ok(employeeResponse);
        return responseEntity;
    }
}

最后,當您啟動 SpringBoot 應用程序時,將布爾標志isSerializable設置為false ,您應該得到以下響應: 在此處輸入圖像描述

如果您將isSerializable標志設置為true並重新啟動應用程序,您應該會看到以下響應:

在此處輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM