java Jax-rs json 漂亮的输出

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10532217/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 01:27:23  来源:igfitidea点击:

Jax-rs json pretty output

javajax-rsHymansonpretty-print

提问by niklas

in Java when i use the

在 Java 中,当我使用

@Produces("application/json")

annotation the output is not formated into human readable form. How do i achive that?

注释输出未格式化为人类可读的形式。我如何做到这一点?

回答by Alexey Gavrilov

Just for the record, if you want to enable the pretty output only for some resources you can use the @HymansonFeatures annotationon a resource method.

只是为了记录,如果您只想为某些资源启用漂亮的输出,您可以在资源方法上使用@HymansonFeatures 注释

Here is example:

这是示例:

@Produces(MediaType.APPLICATION_JSON)
@HymansonFeatures(serializationEnable =  { SerializationFeature.INDENT_OUTPUT })
public Bean resource() {
    return new Bean();
}

回答by DaTroop

Create this class anywhere in your project. It will be loaded on deployment. Notice the .configure(SerializationConfig.Feature.INDENT_OUTPUT, true);which configures the mapper to format the output.

在项目中的任何位置创建此类。它将在部署时加载。请注意.configure(SerializationConfig.Feature.INDENT_OUTPUT, true);配置映射器以格式化输出的 。

For Hymanson 2.0 and later, replace the two .configure()lines with these: .configure(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES, false).configure(SerializationFeature.INDENT_OUTPUT, true);

对于 Hymanson 2.0 及更高版本,将这两.configure()行替换为以下内容: .configure(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES, false).configure(SerializationFeature.INDENT_OUTPUT, true);

And change your imports accordingly.

并相应地更改您的导入。

package com.secret;

import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;
import org.codehaus.Hymanson.map.DeserializationConfig;
import org.codehaus.Hymanson.map.ObjectMapper;
import org.codehaus.Hymanson.map.SerializationConfig;

/**
 *
 * @author secret
 */
@Provider
@Produces(MediaType.APPLICATION_JSON)
public class HymansonContextResolver implements ContextResolver<ObjectMapper> {
    private ObjectMapper objectMapper;

    public HymansonContextResolver() throws Exception {
        this.objectMapper = new ObjectMapper();
    this.objectMapper
        .configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false)
        .configure(SerializationConfig.Feature.INDENT_OUTPUT, true);
    }

    @Override
    public ObjectMapper getContext(Class<?> objectType) {
        return objectMapper;
    }
}

Bear in mind that formatting has a negative effect on performance.

请记住,格式化对性能有负面影响。

回答by Kirill Groshkov

This is how you can properly do conditional pretty/non-pretty json output based on presence of "pretty" in query string.

这是根据查询字符串中“漂亮”的存在正确执行条件漂亮/非漂亮json输出的方法。

Create a PrettyFilterthat implements ContainerResponseFilter, that will be executed on every request:

创建一个PrettyFilter实现ContainerResponseFilter,它将在每个请求上执行:

@Provider
public class PrettyFilter implements ContainerResponseFilter {

    @Override
    public void filter(ContainerRequestContext reqCtx, ContainerResponseContext respCtx) throws IOException {

        UriInfo uriInfo = reqCtx.getUriInfo();
        //log.info("prettyFilter: "+uriInfo.getPath());

        MultivaluedMap<String, String> queryParameters = uriInfo.getQueryParameters();
        if(queryParameters.containsKey("pretty")) {
            ObjectWriterInjector.set(new IndentingModifier(true));
        }

    }

    public static class IndentingModifier extends ObjectWriterModifier {

        private final boolean indent;

        public IndentingModifier(boolean indent) {
            this.indent = indent;
        }


        @Override
        public ObjectWriter modify(EndpointConfigBase<?> endpointConfigBase, MultivaluedMap<String, Object> multivaluedMap, Object o, ObjectWriter objectWriter, JsonGenerator jsonGenerator) throws IOException {
            if(indent) jsonGenerator.useDefaultPrettyPrinter();
            return objectWriter;
        }
    }
}

And pretty much that's it!

差不多就是这样!

You will need to ensure that this class gets used by Jersey by either automated package scanning or registered manually.

您需要通过自动包扫描或手动注册来确保 Jersey 使用该类。

Spent few hours trying to achieve that and found that no-one has published a ready-to-use solution before.

花了几个小时试图实现这一目标,发现之前没有人发布过现成的解决方案。

回答by Fabien Arrault

Building on helpful DaTroop's answer, here is another version which allows choosing between optimized json and formatted json based on the absence or presence of a "pretty" parameter :

基于有用的 DaTroop 的答案,这是另一个版本,它允许根据“漂亮”参数的缺失或存在在优化的 json 和格式化的 json 之间进行选择:

package test;


import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;

import org.codehaus.Hymanson.map.ObjectMapper;
import org.codehaus.Hymanson.map.SerializationConfig;

@Provider
@Produces(MediaType.APPLICATION_JSON)
public class HymansonContextResolver implements ContextResolver<ObjectMapper> {

    private ObjectMapper prettyPrintObjectMapper;
    private UriInfo uriInfoContext;

    public HymansonContextResolver(@Context UriInfo uriInfoContext) throws Exception {
        this.uriInfoContext = uriInfoContext;

        this.prettyPrintObjectMapper = new ObjectMapper();
        this.prettyPrintObjectMapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, true);
    }

    @Override
    public ObjectMapper getContext(Class<?> objectType) {

        try {
            MultivaluedMap<String, String> queryParameters = uriInfoContext.getQueryParameters();
            if(queryParameters.containsKey("pretty")) {
                return prettyPrintObjectMapper;
            }

        } catch(Exception e) {
            // protect from invalid access to uriInfoContext.getQueryParameters()
        }

        return null; // use default mapper
    }
}

回答by ATorras

If you are using Spring, then you can globally set the property

如果您使用的是 Spring,那么您可以全局设置该属性

spring.Hymanson.serialization.INDENT_OUTPUT=true

More info at https://docs.spring.io/spring-boot/docs/current/reference/html/howto-properties-and-configuration.html

更多信息见https://docs.spring.io/spring-boot/docs/current/reference/html/howto-properties-and-configuration.html

回答by Tristan Perry

If you are using the jersey-media-json-bindingdependency, which uses Yasson (the official RI of JSR-367) and JAVAX-JSON, you can introduce pretty printing as follows:

如果你使用jersey-media-json-binding依赖,它使用 Yasson(JSR-367 的官方 RI)和 JAVAX-JSON,你可以引入漂亮的打印如下:

import javax.json.bind.Jsonb;
import javax.json.bind.JsonbBuilder;
import javax.json.bind.JsonbConfig;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;

@Provider
public class RandomConfig implements ContextResolver<Jsonb> {
    private final Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withFormatting(true));

    public RandomConfig() { }

    @Override
    public Jsonb getContext(Class<?> objectType) {
        return jsonb;
    }
}