【问题标题】:Dropwizard Json pretty print query paramDropwizard Json 漂亮的打印查询参数
【发布时间】:2015-11-06 10:19:57
【问题描述】:

我知道如何在默认情况下漂亮地打印 JSON,但我想将选择权交给用户。这就是为什么我想通过 QueryParam 使其可配置。

这应该很漂亮地打印 json(如果没有给出默认为 false):

...test123/res123?pretty=T
...test123/res123?pretty=True
...test123/res123?pretty=t
...test123/res123?pretty=true

在不将相同的代码复制到数千个资源的情况下,有人有一个好主意吗?我应该与消息正文作者一起做吗?还是传出过滤器?

解决方案(感谢 Alexey Gavrilov 的提示):

import java.io.IOException;
import javax.ws.rs.core.MultivaluedMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.fasterxml.jackson.jaxrs.cfg.EndpointConfigBase;
import com.fasterxml.jackson.jaxrs.cfg.ObjectWriterModifier;

public class IndentingModifier extends ObjectWriterModifier {

    private static final Logger LOG = LoggerFactory.getLogger(IndentingModifier.class);

    public static boolean doIndent = false;

    public final Boolean _indent;

    public IndentingModifier() {
        this(null);
    }

    public IndentingModifier(
            Boolean indent) {
        _indent = indent;
    }

    @Override
    public ObjectWriter modify(
            EndpointConfigBase<?> endpoint,
            MultivaluedMap<String, Object> responseHeaders,
            Object valueToWrite,
            ObjectWriter w,
            JsonGenerator g) throws IOException {
        if (_indent != null) {
            if (_indent.booleanValue()) {
                LOG.debug("Using default pretty printer, because ident is null.");
                g.useDefaultPrettyPrinter();
            }
        } else {
            if (doIndent) {
                LOG.debug("Using default pretty printer, because ident is true.");
                g.useDefaultPrettyPrinter();
            }
        }
        return w;
    }
}

还有容器过滤器:

import java.io.IOException;
import java.util.List;
import java.util.Map.Entry;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.Provider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.jaxrs.cfg.ObjectWriterInjector;

@Provider
public class JsonPrettryPrintQueryParamContainerResponseFilter implements javax.ws.rs.container.ContainerResponseFilter {

    private static final Logger LOG = LoggerFactory.getLogger(JsonPrettryPrintQueryParamContainerResponseFilter.class);

    private static final String QUERY_PARAM_PRETTY = "pretty";
    private static final String QUERY_PARAM_T = "t";
    private static final String QUERY_PARAM_TRUE = "true";
    private static final String QUERY_PARAM_F = "f";
    private static final String QUERY_PARAM_False = "false";

    @Override
    public void filter(
            ContainerRequestContext requestContext,
            ContainerResponseContext responseContext) throws IOException {

        MultivaluedMap<String, String> queryParams = requestContext.getUriInfo().getQueryParameters();

        for (Entry<String, List<String>> queryEntry : queryParams.entrySet()) {

            if (queryEntry.getKey().equalsIgnoreCase(QUERY_PARAM_PRETTY)) {
                String valueOfLastQueryParamIndex = queryEntry.getValue().get(queryEntry.getValue().size() - 1);
                LOG.debug(String.format("Found queryPram '%s' with value '%s'.", queryEntry.getKey(),
                        valueOfLastQueryParamIndex));

                switch (valueOfLastQueryParamIndex.toLowerCase()) {
                case QUERY_PARAM_T:
                    ObjectWriterInjector.set(new IndentingModifier(true));
                    break;
                case QUERY_PARAM_TRUE:
                    ObjectWriterInjector.set(new IndentingModifier(true));
                    break;
                case QUERY_PARAM_F:
                    ObjectWriterInjector.set(new IndentingModifier(false));
                    break;
                case QUERY_PARAM_False:
                    ObjectWriterInjector.set(new IndentingModifier(false));
                    break;

                default:
                    break;
                }
                break;
            }
        }
    }
}

在扩展应用类run()中:

environment.jersey().register(JsonPrettryPrintQueryParamContainerResponseFilter.class);

【问题讨论】:

    标签: java json jersey jackson dropwizard


    【解决方案1】:

    您可以使用ObjectWriterInjector and ObjectWriterModifier根据查询参数自定义资源方法中的对象编写器。

    查看 Jackson JAX-RS 提供程序存储库中的 this code sample

    【讨论】:

    • 我更喜欢使用一般功能,即不会出现在任何资源中且仅在服务启动时出现的功能,例如在运行()。这就是为什么我问消息体作家是否是个好主意。在那里我只需要注入查询参数。
    • 我认为在过滤器中这样做是一个更好的主意。在那里您可以访问查询参数并可以使用 ObjectWriterInjector 自定义输出。
    • 感谢使用 ObjectWriterModifier 进行容器响应过滤对我有用。我在上面更新了我的解决方案。
    猜你喜欢
    • 2014-05-19
    • 2021-01-31
    • 2014-05-12
    • 2020-06-19
    • 1970-01-01
    • 2017-11-03
    • 2011-05-05
    • 2017-05-01
    相关资源
    最近更新 更多