【问题标题】:jersey 2.6 jackson 2.3 and complex keys in mapsjersey 2.6 jackson 2.3 和地图中的复杂键
【发布时间】:2014-04-06 03:24:24
【问题描述】:

我有一个包含 id 的简单对象。我正在寻找一种将其用作哈希图中的键的方法。

Jersey 在我的 web.xml 中注册为 servlet

<servlet>
        <servlet-name>Jersey Web Application</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>javax.ws.rs.Application</param-name>
            <param-value>org.ambientlight.RestConfig</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
</servlet>

杰克逊在这里注册。

public class RestConfig extends ResourceConfig {

    public RestConfig() {
        packages("org.ambientlight.webservice");
        register(JacksonFeatures.class);
    }
}

这是我的关键对象:

@JsonSerialize(using = SwitchableIdSerializer.class)
public class SwitchableId {

    public String id;

    public SwitchType type;


    public SwitchableId(String id, SwitchType type) {
        super();
        this.id = id;
        this.type = type;
    }
}

这是我的序列化器

public class SwitchableIdSerializer extends JsonSerializer<SwitchableId> {

    @Override
    public void serialize(SwitchableId data, JsonGenerator json, SerializerProvider provider) throws IOException,
    JsonGenerationException {
        json.writeString(data.id + "|" + data.type);
    }
}

如果我直接返回 SwitchableId,一切都会像方面一样工作。但如果我返回一个带有 hasmap 的结构,则不使用序列化程序,只应用简单的 SwitchableId.toString()。

那里有很多例子。对于较旧的版本,或者如果杰克逊是独立使用的。但我找不到任何提示如何处理球衣 servlet。请帮忙!

我试图注释包含的类:

public class PowerstateHandlerConfiguration extends AbstractActionHandlerConfiguration {

    @JsonSerialize(keyUsing = SwitchableIdSerializer.class)
    public Map<SwitchableId, Boolean> powerStateConfiguration = new HashMap<SwitchableId, Boolean>();
}

但没有成功。缺少什么?

【问题讨论】:

    标签: java json rest servlets jackson


    【解决方案1】:

    用于Map 键的序列化器(和反序列化器)与常规值(反)序列化器不同,因此要使用的注释是:

    class MapBean {
      @JsonSerialize(keyUsing=SwitchableIdSerializer.class)
      public Map<SwitchableId, String> values;
    }
    

    原因是与@JsonGenerator 一起使用的写入方法不同(writeFieldName() 而不是writeString())。 如果使用注释,则需要在有问题的 Map 属性上使用它。或者,您可以使用SimpleModule 注册密钥序列化程序;但为此,您需要访问 Jersey 使用的ObjectMapper(这是一个应该通过谷歌搜索找到答案的问题)。

    【讨论】:

    • 我试图注释包含的类。但没有成功。如果我调试我的 tomcat 7,则不会调用序列化程序。是否缺少配置?
    • 要注释的类必须是Map,所以通常你会注释属性(使用Map 值),而不是类。
    • 抱歉这个愚蠢的问题。但你能发布一个简单的例子吗?我不知道我是否理解你的权利
    【解决方案2】:

    感谢您的帮助,

    一个非常烦人的事情是。我在服务器端的地图之前使用了该注释,但没有成功。相反,在我的 android 客户端上,spring rest 模板的模块注册不起作用。在那里,我使用了您在回答中向我展示的注释-它在那里起作用。

    无论如何,为了回答我的问题,以及所有试图在球衣使用的对象映射器上注册模块的人 - 这是我的解决方案,因为它现在适用于我。一个特点是序列化程序始终可用,而不是注释每个映射。

    资源配置如下:

    public class RestConfig extends ResourceConfig {
    
        public RestConfig() {
            packages("org.ambientlight.webservice");
    
            register(new ContextResolver<ObjectMapper>() {
    
                @Override
                public ObjectMapper getContext(Class<?> type) {
                    ObjectMapper objectMapper = new ObjectMapper();
                    objectMapper.registerModule(new SwitchableIdModule());
                    return objectMapper;
                }
            });
        }
    }
    

    序列化程序已更改为读取映射键:

    public class SwitchableIdSerializer extends JsonSerializer<SwitchableId> {
    
        @Override
        public void serialize(SwitchableId data, JsonGenerator json, SerializerProvider provider) throws IOException,
        JsonGenerationException {
            json.writeFieldName(data.id + "|" + data.type);
        }
    }
    

    序列化程序在一个简单的模块中注册 - 在 ResourceConfig 中注册:

    public class SwitchableIdModule extends SimpleModule {
    
        private static final long serialVersionUID = 1L;
    
    
        public SwitchableIdModule() {
            addKeySerializer(SwitchableId.class, new SwitchableIdSerializer());
            addKeyDeserializer(SwitchableId.class, new SwitchableIdDeserializer());
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-07-30
      • 1970-01-01
      • 2013-05-28
      • 2012-01-23
      • 2023-03-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多