2014-03-04 38 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