2014-03-04 33 views
1

我有一个简单的对象包含一个id。我正在寻找一种将它用作hashmap中的关键字的方法。球衣2.6杰克逊2.3和地图中的复杂键

球衣在我的web.xml

<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> 

杰克逊在这里登记注册为一个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一切就像aspeceted。但是如果我用hasmap返回一个结构体,那么序列化程序不会被使用,只是简单的SwitchableId.toString()被应用。

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

我试图注释包含类:

public class PowerstateHandlerConfiguration extends AbstractActionHandlerConfiguration { 

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

但没有成功。什么不见​​了?

回答

0

感谢您的帮助,

一个很烦人的事情是。我在服务器端的地图之前使用了该注释,但没有成功。相反,在我的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()); 
    } 
} 
1

用于Map键串行器(和串并转换器)是从常规值不同(反)序列,所以注释使用是:

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

和的原因是因为写方法与@JsonGenerator使用是不同的( writeFieldName()而不是writeString())。 如果使用注释,则需要在Map属性中使用此注释。或者,您可以使用SimpleModule注册关键序列化器;但为此你需要访问泽西岛使用的ObjectMapper(这是一个问题,应该通过谷歌搜索找到答案)。

+0

我试图注释包含class.but没有成功。如果我调试我的tomcat 7,序列化程序不会被调用。有没有配置丢失? – furefix

+0

注解的类必须是'Map',所以通常你会注解属性(使用Map值)而不是类。 – StaxMan

+0

对那个愚蠢的问题感到抱歉。但你可以发表一个简单的例子。我不知道我是否理解你的权利 – furefix