Jax-rs json相当不错

nik*_*las 13 java jax-rs pretty-print jackson

在Java中我使用的时候

@Produces("application/json")
Run Code Online (Sandbox Code Playgroud)

注释输出不会形成人类可读的形式.我怎么做到这一点?

Ale*_*lov 21

仅为记录,如果您只想为某些资源启用pretty输出,则可以在资源方法上使用@JacksonFeatures批注.

这是一个例子:

@Produces(MediaType.APPLICATION_JSON)
@JacksonFeatures(serializationEnable =  { SerializationFeature.INDENT_OUTPUT })
public Bean resource() {
    return new Bean();
}
Run Code Online (Sandbox Code Playgroud)

  • `@JacksonFeatures` 仅适用于方法,而不适用于类。 (2认同)

DaT*_*oop 15

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

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

并相应地更改您的导入.

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.jackson.map.DeserializationConfig;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;

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

    public JacksonContextResolver() 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

请记住格式化会对性能产生负面影响.

  • Jersey如何知道使用这个上下文解析器,而不是内置于Jackson的JAXRS提供程序? (2认同)

Kir*_*kov 15

这就是你如何根据查询字符串中"漂亮"的存在来正确地执行条件漂亮/非漂亮的json输出.

创建一个将在每个请求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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

而且几乎就是这样!

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

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

  • 这是迄今为止最好的解决方案,我希望我能投票两次。不要忘记在“ResourceConfig”中使用“register(PrettyFilter.class)”。 (2认同)