我有基于Jersey(1.x)的REST服务。它使用Jackson 2.4.4生成JSON响应。我需要在响应结束时添加换行符(cURL用户抱怨响应中没有新行)。我正在使用Jersey漂亮的打印功能(SerializationFeature.INDENT_OUTPUT
)。
当前: {\n "prop" : "value"\n}
想要: {\n "prop" : "value"\n}\n
我尝试使用自定义序列化程序。我只需要在根对象的末尾添加\n
。 Serializer是按数据类型定义的,这意味着,如果这样的类的实例嵌套在响应中,我将在我的JSON中间得到\n
。
我想到了com.fasterxml.jackson.core.JsonGenerator.java
的子类化,覆盖close()
我添加writeRaw('\n')
的地方,但这感觉非常黑客。
另一个想法是添加Servlet过滤器,它会重写Jersey过滤器的响应,添加\n
并将contentLenght递增1.看来不仅 hacky ,但也效率低下。
我也可以放弃Jersey负责序列化内容并执行ObjectMapper.writeValue() + "\n"
,但这对我的代码非常有用(需要更改很多地方)。
该问题的 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;
}
}
}
答案 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}
但是,如果只有一个根元素,它似乎不起作用。