user1397770
user1397770

Reputation: 135

How to marshall and un marshall HashMap<String, ArrayList<String>>

I have a javabean which have HashMap (String, ArrayList(String) ) hashMap attribute. i have generated a jax ws client . But i am not able to access ArrayList from hashMap as it has converted to some default type arraylist.How can I solve this problem?

Upvotes: 1

Views: 617

Answers (1)

Ilya
Ilya

Reputation: 29693

using additional class Pair

@XmlAccessorType(XmlAccessType.FIELD)
public class Pair
{
   private String key;

   private String[] value;

   public Pair()
   {
   }

   public Pair(String key, String[] value)
   {
      this.key = key;
      this.value = value;
   }
}  

and XmlJavaAdaptor

public class PairAdaptor extends XmlAdapter<Pair[], HashMap<String, ArrayList<String>>>
{
   @Override
   public HashMap<String, ArrayList<String>> unmarshal(Pair[] v) throws Exception
   {
      final HashMap<String, ArrayList<String>> retVal = new HashMap<String, ArrayList<String>>();
      for (Pair pair : v)
      {
         retVal.put(pair.key, new ArrayList<String>(Arrays.asList(pair.value)));
      }

      return retVal;
   }

   @Override
   public Pair[] marshal(HashMap<String, ArrayList<String>> v) throws Exception
   {
      final Pair[] retVal = new Pair[v.size()];
      int counter = 0;
      for (String key : v.keySet())
      {
         retVal[counter] = new Pair(key, v.get(key).toArray(new String[]{}));
         counter++;
      }

      return retVal;
   }
}

usage

@XmlJavaTypeAdapter(PairAdaptor.class)
private HashMap<String, ArrayList<String>> value;  

UPDATE. Generic Instead Of String
Pair

@XmlAccessorType(XmlAccessType.FIELD)
public class Pair<T>
{
   private String key;

   private T[] value;

   public Pair()
   {
   }

   public Pair(String key, T[] value)
   {
      this.key = key;
      this.value = value;
   }

   public String getKey()
   {
      return key;
   }

   public T[] getValue()
   {
      return value;
   }
}  

GenericAdaptor

public class GenericAdaptor<T> extends XmlAdapter<Pair[], HashMap<String, ArrayList<T>>>
{
   @Override
   public HashMap<String, ArrayList<T>> unmarshal(Pair[] v) throws Exception
   {
      final HashMap<String, ArrayList<T>> retVal = new HashMap<String, ArrayList<T>>();
      for (Pair<T> pair : v)
      {
         retVal.put(pair.getKey(), new ArrayList<T>(Arrays.asList(pair.getValue())));
      }

      return retVal;
   }

   @Override
   public Pair[] marshal(HashMap<String, ArrayList<T>> v) throws Exception
   {
      final Pair[] retVal = new Pair[v.size()];
      int counter = 0;
      for (String key : v.keySet())
      {
         retVal[counter] = new Pair(key, v.get(key).toArray());
         counter++;
      }

      return retVal;
   }
}  

For each type you shoud have own adaptor.
For String

public class StringAdaptor extends GenericAdaptor<String>
{
}  

For Cat

public class CatAdaptor extends GenericAdaptor<Cat>
{
}

Usage

   @XmlJavaTypeAdapter(StringAdaptor.class)
   private HashMap<String, ArrayList<String>> value;   

   @XmlJavaTypeAdapter(CatAdaptor.class)
   private HashMap<String, ArrayList<Cat>> cats;

Upvotes: 1

Related Questions