如何有条件地从 json 响应中排除 属性

How to conditionally exclude property from a json response

我有一个 class pojo 用于 return 对其余控制器中的 API 调用的响应

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

但是现在我们想要对控制器 class 进行功能标记,以便在未设置配置 属性 时,响应将不包含 属性。我们该怎么做?

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

编辑:在此处添加控制器代码以显示一个对象是 returned 而没有被序列化,所以我不知道如何将 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")
  2. 注释你的 DTO class
  3. 为您的自定义过滤器创建实现 class
  4. ObjectMapper 创建配置 class,您将在其中设置在步骤 1 中创建的过滤器。
  5. 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 步:

创建控制器 class 进行测试:

@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;
    }
}

最后,当您启动 Spring 启动应用程序时,将布尔标志 isSerializable 设置为 false 您应该会得到以下响应:

如果您将 isSerializable 标志设置为 true 并重新启动应用程序,您应该看到以下响应: