【问题标题】:How to prevent Jackson from outputting pretty print JSON?如何防止杰克逊输出漂亮的打印 JSON?
【发布时间】:2012-08-07 18:35:05
【问题描述】:

我想确保 Jackson 生成的 JSON 文件永远不会被打印出来。我是一个正在从事现有项目的初级人员,因此我需要向后工作以找出可以将 JSON 配置为输出为漂亮打印的所有方式。我可以确认项目中有 0 个对 .defaultPrettyPrintingWriter() 的引用,以及对 .setSerializationConfig 的 0 个引用,我相信它们也可以用来启用漂亮的打印。

那么这怎么可能呢?或者,是否有一种可靠的方法来确保 JSON 文件不是打印出来的?

【问题讨论】:

  • 您是否使用任何 bean 或应用程序服务器?您可能需要检查配置文件中的 prettyPrint 属性。
  • 更新:我在我正在处理的项目中发现了几个 ObjectMapper 实例。如果我写了类似 OutputMapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, false);然后我会得到我正在寻找的非漂亮打印 JSON,对吧?
  • "OutputMapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, false); 然后我会得到我正在寻找的非漂亮打印 JSON,对吧?"*从理论上讲,是的,这应该使 ObjectMapper 的那个实例打印得不好。不过,仍然可以通过其他方式创建 ObjectMappers。
  • 编辑:详细地说,我在项目中搜索了所有新的 ObjectMapper 对象,但我想是否有一种方法可以创建 ObjectMapper 而不是简单的“私有静态最终 ObjectMapper objectMapper;”那么可能还有未受影响的 ObjectMapper 对象。
  • 就像它是通过工厂创建并透明地使用一样。类似于:getMapperFactory().getMapper().getJsonFactory().createJsonGenerator(message); 你不能用 grep 表示,因为ObjectMapper 没有明确的实例变量。但我不知道这段代码是什么样子的,所以这可能没有实际意义

标签: java json jackson


【解决方案1】:

根据您使用的 Spring 版本,MappingJacksonHttpMessageConverte‌​r 应该有一个名为 prettyPrint 的布尔属性,用于在序列化 JSON 时配置打印机。

所以这个 XML 配置应该可以解决问题(如果您使用的是 Spring 3 的最新版本)

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAda‌​pter">
  <property name="messageConverters">
    <list>
      <ref bean="jsonConverter" />
    </list>
  </property>
</bean>

<bean id="jsonConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverte‌​r">
  <property name="supportedMediaTypes" value="application/json" />
  <property name="objectMapper" ref="jacksonObjectMapper" />
  <property name="prettyPrint" value="false" />
</bean>

你可以在github上看到related commit介绍这个属性。类的trunk version 也包含此属性。最后这是 Spring Jira 问题SPR-7201 与上一次提交相关。

或者您可以尝试将您的 Jackson 版本更新到更新的版本,包括 Alexander Ryzhov 提到的 useDefaultPrettyPrintersetPrettyPrinter 方法

【讨论】:

    【解决方案2】:

    最优雅的解决方案是将漂亮/非漂亮的开关放入过滤器中,并重用静态配置对象。这可以防止无用的垃圾回收。

    /**
     * Evaluate the "pretty" query parameter. If given without any value, or with "true": pretty JSON output.
     * E.g. /test?pretty or /test?pretty=true
     * Otherwise output without any formatting.
     *
     * @see https://stackoverflow.com/questions/10532217/jax-rs-json-pretty-output
     */
    @Provider
    @Produces(MediaType.APPLICATION_JSON)
    public class RestPrettyJsonFilter implements ContainerResponseFilter {
    
      public static final String QUERYPARAM_PRETTY = "pretty";
    
      private static final IndentingModifier INDENTING_MODIFIER_PRETTY = new IndentingModifier(true);
      private static final IndentingModifier INDENTING_MODIFIER_NOT_PRETTY = new IndentingModifier(false);
    
      @Override
      public void filter(ContainerRequestContext reqCtx, ContainerResponseContext respCtx) throws IOException {
    
        boolean pretty = false;
    
        UriInfo uriInfo = reqCtx.getUriInfo();
        //log.info("prettyFilter: "+uriInfo.getPath());
    
        MultivaluedMap<String, String> queryParameters = uriInfo.getQueryParameters();
        if(queryParameters.containsKey(QUERYPARAM_PRETTY)) {
          // Pretty query parameter is present
          String prettyParam = queryParameters.getFirst(QUERYPARAM_PRETTY);
    
          // Pretty is present without any value, or value is set to "true"?
          if (prettyParam == null || "".equals(prettyParam) || "true".equals(prettyParam)) {
            pretty = true;
          }
        }
    
        // Prevent recreation of objects over and over again
        //ObjectWriterInjector.set(new IndentingModifier(pretty));
        if (pretty) {
          ObjectWriterInjector.set(INDENTING_MODIFIER_PRETTY);
        } else {
          ObjectWriterInjector.set(INDENTING_MODIFIER_NOT_PRETTY);
        }
      }
    
      /**
       * Used to switch on / off pretty output for each response.
       */
      public static class IndentingModifier extends ObjectWriterModifier {
    
        private final boolean indent;
    
        /** Minimal pretty printer is not printing pretty. */
        private final static PrettyPrinter NOT_PRETTY_PRINTER = new com.fasterxml.jackson.core.util.MinimalPrettyPrinter();
    
        public IndentingModifier(boolean indent) {
          this.indent = indent;
        }
    
        /* (non-Javadoc)
         * @see com.fasterxml.jackson.jaxrs.cfg.ObjectWriterModifier#modify(com.fasterxml.jackson.jaxrs.cfg.EndpointConfigBase, javax.ws.rs.core.MultivaluedMap, java.lang.Object, com.fasterxml.jackson.databind.ObjectWriter, com.fasterxml.jackson.core.JsonGenerator)
         */
        @Override
        public ObjectWriter modify(EndpointConfigBase<?> endpointConfigBase, MultivaluedMap<String, Object> multivaluedMap, Object o, ObjectWriter objectWriter, JsonGenerator jsonGenerator) throws IOException {
          if(indent) {
            // Pretty
            jsonGenerator.useDefaultPrettyPrinter();
          } else {
            // Not pretty
            jsonGenerator.setPrettyPrinter(NOT_PRETTY_PRINTER);
          }
          return objectWriter;
        }
      }
    }
    

    【讨论】:

      【解决方案3】:

      不确定您使用的是哪个版本的 Jackson,但在最新版本 (1.9.10) 中,JsonGenerator 的默认行为不是漂亮的打印。打开它的最简单方法是调用generator.useDefaultPrettyPrinter()generator.setPrettyPrinter(new DefaultPrettyPrinter())。尝试搜索 useDefaultPrettyPrintersetPrettyPrinter 并删除这些语句。

      【讨论】:

      • 本项目使用的版本是1.3。我在项目中搜索了 useDefaultPrettyPrinter 和 setPrettyPrinter,但无济于事
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-19
      • 1970-01-01
      相关资源
      最近更新 更多