如何防止杰克逊输出漂亮的打印JSON?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何防止杰克逊输出漂亮的打印JSON?相关的知识,希望对你有一定的参考价值。

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

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

答案

根据您使用的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方法

另一答案

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

/**
 * 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;
    }
  }
}
另一答案

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

以上是关于如何防止杰克逊输出漂亮的打印JSON?的主要内容,如果未能解决你的问题,请参考以下文章

JSON 使用杰克逊库相同对象的字段,但在必要时打印不同的值

如何使用 Go 漂亮地打印 JSON?

如何以 json 格式(双引号)漂亮地打印(人类可读的打印)Python dict? [复制]

在 Swift 中编写一个带有排序键的漂亮打印 JSON 对象

使用 Jackson 将 JSON 字符串转换为漂亮的打印 JSON 输出

使用 JavaScript 漂亮地打印 JSON