在Jersey生成的JSON

时间:2015-10-09 14:26:44

标签: json jersey jackson

我有基于Jersey(1.x)的REST服务。它使用Jackson 2.4.4生成JSON响应。我需要在响应结束时添加换行符(cURL用户抱怨响应中没有新行)。我正在使用Jersey漂亮的打印功能(SerializationFeature.INDENT_OUTPUT)。

当前: {\n "prop" : "value"\n}

想要: {\n "prop" : "value"\n}\n

  1. 我尝试使用自定义序列化程序。我只需要在根对象的末尾添加\n。 Serializer是按数据类型定义的,这意味着,如果这样的类的实例嵌套在响应中,我将在我的JSON中间得到\n

  2. 我想到了com.fasterxml.jackson.core.JsonGenerator.java的子类化,覆盖close()我添加writeRaw('\n')的地方,但这感觉非常黑客。

  3. 另一个想法是添加Servlet过滤器,它会重写Jersey过滤器的响应,添加\n并将contentLenght递增1.看来不仅 hacky ,但也效率低下。

  4. 我也可以放弃Jersey负责序列化内容并执行ObjectMapper.writeValue() + "\n",但这对我的代码非常有用(需要更改很多地方)。

  5. 该问题的 clean 解决方案是什么?

    我发现这些线程存在同样的问题,但没有一个提供解决方案:

    更新

    最后,我使用NewlineAddingPrettyPrinter(也是杰克逊版本为2.6.2)获得@ arachnid的解决方案。可悲的是,它与Jaskson一样不能成为JAX-RS Json提供者。 PrettyPrinter中更改的ObjectMapper未传播到JsonGenerator(请参阅here原因)。为了使其工作,我不得不添加ResponseFilter添加ObjectWriterModifier(现在我可以根据输入参数轻松切换漂亮和最小):

    @Provider
    public class PrettyPrintFilter extends BaseResponseFilter {
    
        public ContainerResponse filter(ContainerRequest request, ContainerResponse response) {
            ObjectWriterInjector.set(new PrettyPrintToggler(true));
            return response;
        }
    
        final class PrettyPrintToggler extends ObjectWriterModifier {
    
            private static final PrettyPrinter NO_PRETTY_PRINT = new MinimalPrettyPrinter();
    
            private final boolean usePrettyPrint;
    
            public PrettyPrintToggler(boolean usePrettyPrint) {
                this.usePrettyPrint = usePrettyPrint;
            }
    
            @Override
            public ObjectWriter modify(EndpointConfigBase<?> endpoint, MultivaluedMap<String, Object> responseHeaders,
                                       Object valueToWrite, ObjectWriter w, JsonGenerator g) throws IOException {
                if (usePrettyPrint) g.setPrettyPrinter(new NewlineAddingPrettyPrinter());
                else g.setPrettyPrinter(NO_PRETTY_PRINT);
                return w;
            }
    
        }
    }
    

1 个答案:

答案 0 :(得分:0)

尚未测试,但以下情况应该有效:

public class MyObjectMapper extends ObjectMapper {

       _defaultPrettyPrinter = com.fasterxml.jackson.core.util.MinimalPrettyPrinter("\n");

    // AND/OR

       @Override
       protected PrettyPrinter _defaultPrettyPrinter() {
            return new com.fasterxml.jackson.core.util.MinimalPrettyPrinter("\n");
       }

}


public class JerseyConfiguration extends ResourceConfig {
    ...
    MyObjectMapper mapper = new MyObjectMapper();
    mapper.enable(SerializationFeature.INDENT_OUTPUT); //enables pretty printing

    // create JsonProvider to provide custom ObjectMapper
    JacksonJaxbJsonProvider provider = new JacksonJaxbJsonProvider();
    provider.setMapper(mapper);
    register(provider); //register so that jersey use it
}

不知道这是否是最干净的&#34;解决方案但它比其他人感觉更少hacky。

应该产生类似

的东西

{\ n&#34; root&#34; :&#34; 1&#34; \ n} \ n {\ n&#34; root2&#34; :&#34; 2&#34; \ n}

但是,如果只有一个根元素,它似乎不起作用。

想法来自https://gist.github.com/deverton/7743979