Java Jax-rs-json输出

Java Jax-rs-json输出,java,jax-rs,jackson,pretty-print,Java,Jax Rs,Jackson,Pretty Print,在Java中,当我使用 @Produces("application/json") 注释输出未格式化为人类可读的形式。如何实现这一点?在项目中的任何位置创建此类。它将在部署时加载。注意.configure(SerializationConfig.Feature.INDENT\u输出,true)将映射器配置为格式化输出 对于Jackson 2.0及更高版本,将两行.configure()替换为以下内容: .configure(属性上的反序列化功能.FAIL\u被忽略\u,false) .conf

在Java中,当我使用

@Produces("application/json")

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

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

对于Jackson 2.0及更高版本,将两行
.configure()
替换为以下内容:
.configure(属性上的反序列化功能.FAIL\u被忽略\u,false)
.configure(SerializationFeature.INDENT\u输出,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;
    }
}
package.com.secret;
导入javax.ws.rs.products;
导入javax.ws.rs.core.MediaType;
导入javax.ws.rs.ext.ContextResolver;
导入javax.ws.rs.ext.Provider;
导入org.codehaus.jackson.map.DeserializationConfig;
导入org.codehaus.jackson.map.ObjectMapper;
导入org.codehaus.jackson.map.SerializationConfig;
/**
*
*@作者秘密
*/
@提供者
@产生(MediaType.APPLICATION_JSON)
公共类JacksonContextResolver实现ContextResolver{
私有对象映射器对象映射器;
公共JacksonContextResolver()引发异常{
this.objectMapper=新的objectMapper();
这个是.objectMapper
.configure(属性未知时反序列化config.Feature.FAIL,false)
.configure(SerializationConfig.Feature.INDENT_输出,true);
}
@凌驾
公共对象映射器getContext(类objectType){
返回对象映射器;
}
}

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

如果您只想为资源方法上可以使用的某些资源启用漂亮的输出,请仅针对记录

下面是一个例子:

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

基于DaTroop的回答,这里是另一个版本,它允许根据是否存在“pretty”参数在优化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.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;

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

    private ObjectMapper prettyPrintObjectMapper;
    private UriInfo uriInfoContext;

    public JacksonContextResolver(@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
    }
}
封装测试;
导入javax.ws.rs.products;
导入javax.ws.rs.core.Context;
导入javax.ws.rs.core.MediaType;
导入javax.ws.rs.core.MultivaluedMap;
导入javax.ws.rs.core.UriInfo;
导入javax.ws.rs.ext.ContextResolver;
导入javax.ws.rs.ext.Provider;
导入org.codehaus.jackson.map.ObjectMapper;
导入org.codehaus.jackson.map.SerializationConfig;
@提供者
@产生(MediaType.APPLICATION_JSON)
公共类JacksonContextResolver实现ContextResolver{
私有对象映射器prettyPrintObjectMapper;
私有UriInfo-uriInfoContext;
公共JacksonContextResolver(@Context-UriInfo-uriInfoContext)引发异常{
this.uriInfoContext=uriInfoContext;
this.prettyPrintObjectMapper=新的ObjectMapper();
这个.prettyPrintObjectMapper.configure(SerializationConfig.Feature.INDENT_输出,true);
}
@凌驾
公共对象映射器getContext(类objectType){
试一试{
多值Map queryParameters=uriInfoContext.getQueryParameters();
if(queryParameters.containsKey(“pretty”)){
返回prettyPrintObjectMapper;
}
}捕获(例外e){
//防止对uriInfoContext.getQueryParameters()的无效访问
}
返回null;//使用默认映射器
}
}

这就是如何根据查询字符串中是否存在“pretty”来正确地执行条件pretty/non-pretty json输出

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

@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;
        }
    }
}
@Provider
公共类PrettyFilter实现ContainerResponseFilter{
@凌驾
公共无效筛选器(ContainerRequestContext reqCtx、ContainerResponseContext respCtx)引发IOException{
UriInfo UriInfo=reqCtx.getUriInfo();
//log.info(“prettyFilter:+uriInfo.getPath());
多值Map queryParameters=uriInfo.getQueryParameters();
if(queryParameters.containsKey(“pretty”)){
set(新的缩进修饰符(true));
}
}
公共静态类IndentingModifier扩展ObjectWriterModifier{
私有最终布尔缩进;
公共缩进修饰符(布尔缩进){
this.indent=缩进;
}
@凌驾
公共ObjectWriter修改(EndpointConfigBase EndpointConfigBase、MultivaluedMap MultivaluedMap、Object o、ObjectWriter ObjectWriter、JsonGenerator JsonGenerator)引发IOException{
if(indent)jsonggenerator.useDefaultPrettyPrinter();
返回objectWriter;
}
}
}
差不多就是这样

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


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

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

spring.jackson.serialization.INDENT_OUTPUT=true

更多信息请访问

如果您使用的是使用Yasson(JSR-367的官方RI)和JAVAX-json的泽西媒体json绑定
依赖项,您可以按如下方式引入漂亮的打印:

import javax.json.bind.Jsonb;
导入javax.json.bind.JsonbBuilder;
导入javax.json.bind.JsonbConfig;
导入javax.ws.rs.ext.ContextResolver;
导入javax.ws.rs.ext.Provider;
@提供者
公共类RandomConfig实现ContextResolver{
private final Jsonb Jsonb=JsonbBuilder.create(new JsonbConfig().withFormatting(true));
公共随机配置(){}
@凌驾
公共Jsonb getContext(类objectType){
返回jsonb;
}
}

您使用的json序列化程序是什么?仅使用netbeans标准。使用向导“从实体类创建新的RESTfulWebservices”创建,我对它不熟悉,但我认为它是jackson?所以问题是在哪里可以更改netbeans中的输出格式。我在谷歌上找到了一些信息。但它只是关于ObjectMapper的。Netbeans隐藏了所有这些。Whi