Question

I'm working on a project with JAXB but I run into a small problem with JAXB and the char datatype.

char gender = 'M';

Translates after marshalling into:

<gender>77</gender>

So I think that char is mapped to integer, but I simply want to map it to a String. How can I do this? Is it even possible?

Was it helpful?

Solution

After some experimentation, there appears to be no way to configure JAXB to handle primitive chars properly. I'm having a hard time accepting it, though.

I've tried defining an XmlAdaptor to try and coerce it into a String, but the runtime seems to only accept adapters annotated on Object types, not primitives.

The only workaround I can think of is to mark the char field with @XmlTransient, and then write getters and setters which get and set the value as a String:

   @XmlTransient
   char gender = 'M';

   @XmlElement(name="gender")
   public void setGenderAsString(String gender) {
      this.gender = gender.charAt(0);
   }

   public String getGenderAsString() {
      return String.valueOf(gender);
   }

Not very nice, I'll grant you, but short of actually changing your char field tobe a String, that's all I have.

OTHER TIPS

@XmlJavaTypeAdapter(value=MyAdapter.class, type=int.class)

Thats the trick specify type to make it work with primitives

In your adapter

using the same in package-info will mean you do it globally for that package

Found this after experimenting.

public class MyAdapter extends XmlAdapter<String, Integer> {

First thing i got in my mind :)

String gender = "M";

This still appears to be a problem in Metro JAXB (the RI), atleast the version of Metro shipped with JDK 1.6.0_20.

EclipseLink JAXB (MOXy) marshals char correctly:

To use EclipseLink JAXB simply add eclipselink.jar to your classpath and add a jaxb.properties file in with your model classes with the following entry:

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

create a specialized XmlAdapter:

package br.com.maritima.util;

import javax.xml.bind.annotation.adapters.XmlAdapter;

public class CharAdapter extends XmlAdapter<String,Character>{

 @Override
 public String marshal(Character v) throws Exception {
  return new String(new char[]{v});
 }

 @Override
 public Character unmarshal(String v) throws Exception {
   if(v.length()>0)
   return v.charAt(0);
  else return ' ';
 }

}

then you can register it to entire package with package-info.java (avoid to forgot it inside some other class) or use it specifically for a certain field.

see http://blogs.oracle.com/CoreJavaTechTips/entry/exchanging_data_with_xml_and for more info.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top