【问题标题】:Best way to make JSON pretty in Java在 Java 中使 JSON 漂亮的最佳方法
【发布时间】:2019-08-03 10:05:24
【问题描述】:

我有返回如下格式的对象列表(不漂亮)。

{"data":[{"id":1,"firstName":"Bill","lastName":"Johnson"}]

我希望它看起来像这样(漂亮)。

{
    "data":[{
        "id":1,"
        firstName":"Bill",
        "lastName":"Johnson"
        }]
}

这是我的方法签名,以及我对服务的调用以查询数据库以及将 json 打印到屏幕的返回。

public @ResponseBody ResponseEntity<ResponseData<List<NameSearchDTO>>> getInfo(@PathVariable String code, @PathVariable String idType)

ResponseData<List<NameSearchDTO>> response = new ResponseData<>();

List<NameSearchDTO> results = officeService.getByCode(code, idType); 
if (!results.isEmpty()) {
            response.setData(results);
            response.setStatus(Enum.SUCCESS.getDescription());
            response.setMessage(Enum.STATUS_SUCCESS.getDescription());
return new ResponseEntity<>(response, HttpStatus.OK);
}

ResponseData 类实现了可序列化。这是否使它成为“真正的”JSON,因为我没有使用 Jackson 或任何其他 JSON 库?

如何将响应传递给下面的 ObjectMapper 以使其美观?

ObjectMapper jacksonMapper = new ObjectMapper();
jacksonMapper.configure(SerializationFeature.INDENT_OUTPUT, true);

或者我需要创建某种 JSONHelper 类吗?

响应数据类

public class ResponseData <E> implements Serializable{


    private E data;
    private String status;
    private String message;
    private boolean hasValidationError = false;

    public E getData() {
        return data;
    }

    public void setData(E data) {
        this.data = data;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public boolean getHasValidationError(){
        return hasValidationError;
    }

    public void setHasValidationError(boolean hasValidationError){
        this.hasValidationError = hasValidationError;
    }
}

【问题讨论】:

标签: java json jackson spring-data-jpa gson


【解决方案1】:

我认为使用Jackson美化json字符串的最佳方法如下:

import com.fasterxml.jackson.databind.ObjectMapper;
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(yourObject)

【讨论】:

  • @Angular_Newbie 这不是 Spring 特定的,您每次都必须重复它。大量重复无用。
  • 我同意。我将尝试使用您的第三个和第四个选项。看起来像春天的魔法。
  • @Angular_Newbie 好吧,如果您需要帮助,请告诉我。作为一般规则,如果您使用 Spring,请坚持使用 Spring 方式。
  • @LppEdd 解决方案只是为了美化Json。您可以在上下文中创建一次 ObjectMapper 并在整个应用程序中使用它。我不知道你所说的白白复制是什么意思?
【解决方案2】:

你可以定义

  • MappingJacksonHttpMessageConverter(不需要 Spring Boot)
  • Jackson2ObjectMapperBuilder
  • 一个简单的ObjectMapper Bean 注解@Primary
  • 一个配置属性(Spring Boot - 最简单的跳到这个)。

对于第一个解决方案,您需要实现 WebMvcConfigurer 接口
(如果您使用的是 Spring Boot,请跳过此接口)

@Configuration
class CustomWebMvcConfigurer implements WebMvcConfigurer {
    @Override
    public void configureMessageConverters(final List<HttpMessageConverter<?>> converters) {
        final ObjectMapper mapper =
                new Jackson2ObjectMapperBuilder()
                        .indentOutput(true)
                        .build();

        // Or build ObjectMapper without the Spring builder, it's the same thing
        converters.add(new MappingJackson2HttpMessageConverter(mapper));
    }
}

关键是这一行

indentOutput(true)

实际操作底层ObjectMapper 配置

public Jackson2ObjectMapperBuilder indentOutput(boolean indentOutput) {
    this.features.put(SerializationFeature.INDENT_OUTPUT, indentOutput);
    return this;
}

第二个比较简单

@Bean
Jackson2ObjectMapperBuilder jackson() {
   return new Jackson2ObjectMapperBuilder().indentOutput(true);
}

第三个就更简单了,就

@Bean
@Primary
ObjectMapper objectMapper() {
   final ObjectMapper mapper = new ObjectMapper();
   mapper.enable(SerializationFeature.INDENT_OUTPUT);  
   return mapper;
}

第四种方式只包括使用配置属性

spring.jackson.serialization.indent_output=true

【讨论】:

    【解决方案3】:

    您标记了gson,因此您可以使用此库显示 .json 文件:

    import org.json.JSONObject

    val json = "{\"data\":[{\"id\":1,\"firstName\":\"Bill\",\"lastName\":\"Johnson\"}]\n"
    
    val jsonObject = JSONObject(json)
    
    println(jsonObject.toString(4))
    

    https://github.com/google/gson

    【讨论】:

      【解决方案4】:

      我相信您正在寻找 Gson 漂亮的打印功能。 既然您已经用 gson 标记了您的问题,我认为如果您使用该库就可以了。 Mkyong 有一个很棒的漂亮打印教程Here

      教程的基本内容是:

      Gson gson = new GsonBuilder().setPrettyPrinting().create();
      

      【讨论】:

        【解决方案5】:

        无需导入一堆新东西。只有系统可能会抱怨什么(如果有的话)。但是,如果您已经在使用 Jackson,并且想使用映射器 -> 只需使用“readValue”或“writeValue”对吗?

        这个链接解释了很多方法来做到这一点:Jackson Examples

        删除您的结果分配并使用 Mapper 直接转换

        ObjectMapper jacksonMapper = new ObjectMapper();
        jacksonMapper.configure(SerializationFeature.INDENT_OUTPUT, true);
        List<NameSearchDTO> mappedResults = mapper.readValue(officeService.getByCode(code, idType) ,new TypeReference<List<NameSearchDTO>>() {} );
        

        然后将其添加到您的结果返回中。 (添加容器类似乎有点笨拙,但我不会假装知道您的要求)。

        if (!mappedResults.isEmpty()) {
                    response.setData(mappedResults);
                    response.setStatus(Enum.SUCCESS.getDescription());
                    response.setMessage(Enum.STATUS_SUCCESS.getDescription());
        return new ResponseEntity<>(response, HttpStatus.OK);
        

        【讨论】:

          【解决方案6】:

          您可以使用 JSONObject 中的 toString(int indentFactor)

          【讨论】:

            猜你喜欢
            • 2012-02-09
            • 1970-01-01
            • 2011-05-05
            • 2010-10-25
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多