为每个 REST API 响应美化或返回漂亮的 JSON 响应

问题描述

我的 REST API 响应如下所示:

{"business_id": "vcNAWiLM4dR7D2nwwJ7nCA","full_address": "4840 E Indian School Rd\nSte 101\nPhoenix,AZ 85018","hours": {"Tuesday": {"close": "17:00","open": "08:00"},"Friday": {"close": "17:00","Monday": {"close": "17:00","Wednesday": {"close": "17:00","Thursday": {"close": "17:00","open": "08:00"}},"open": true,"categories": ["Doctors","Health & Medical"],"city": "Phoenix","review_count": 7,"name": "Eric Goldberg,MD","neighborhoods": [],"longitude": -111.98375799999999,"state": "AZ","stars": 3.5,"latitude": 33.499313000000001,"attributes": {"By Appointment Only": true},"type": "business"}

是否有任何 HTTP 标头或类似的东西可以美化这个 JSON 响应?

这是一个现有项目,所以我不能真正使用任何 3rd 方库在每个服务或控制器层中更改它。我需要一些可以适用于每个回复内容

预期回复

{
  "business_id": "vcNAWiLM4dR7D2nwwJ7nCA","hours": {
    "Tuesday": {
      "close": "17:00","open": "08:00"
    },"Friday": {
      "close": "17:00","Monday": {
      "close": "17:00","Wednesday": {
      "close": "17:00","Thursday": {
      "close": "17:00","open": "08:00"
    }
  },"categories": [
    "Doctors","Health & Medical"
  ],"longitude": -111.983758,"latitude": 33.499313,"attributes": {
    "By Appointment Only": true
  },"type": "business"
}

我正在寻找类似“Content-type”的标题来决定响应的格式。

解决方法

Spring 使用 ObjectMapper 类来序列化/反序列化 json 对象。您可以通过提供自定义配置来覆盖它:

@Configuration
public class ObjectMapperConfig {
    @Bean
    public ObjectMapper objectMapper() {
        return new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT);
    }
}

这样,您的应用程序中的任何序列化 json(不仅是 http 响应)都将是“漂亮的”。

但是,如果您只想美化 http 响应。您可以通过以下方式覆盖 AbstractHttpMessageConverter 类:

@Component
public class PrettyJsonMessageConverter extends AbstractHttpMessageConverter<Object> {

    @Autowired
    private ObjectMapper objectMapper;

    public PrettyJsonMessageConverter() {
        super(MediaType.APPLICATION_JSON);
    }

    @Override
    protected boolean supports(Class<?> clazz) {
        return true;
    }

    @Override
    protected Object readInternal(Class<? extends Object> clazz,HttpInputMessage inputMessage) throws HttpMessageNotReadableException,IOException {
        return objectMapper.readValue(inputMessage.getBody(),clazz);
    }

    @Override
    protected void writeInternal(Object o,HttpOutputMessage outputMessage) throws IOException,HttpMessageNotWritableException {
        outputMessage.getBody().write(objectMapper.writerWithDefaultPrettyPrinter().writeValueAsBytes(o));
    }
}