Search code examples
xmljaxbjaxb2xmladapter

Confused as how to use JAXB XML Adapter for my requirement


I am Using JAXB for unmarshalling process , for which the request comes from the UI to our service class . The below is the format of XML request .

<SampleRequest  user="testUser"  account="testAccount"    Specifier=  "value1a,value1b,value1c : name2a,value2b,value2c"/>

My requirement is that , the Specifier attribute has got Multiple series of values (: colon separated) i need to map each series of values to my custom java class

I tried this way

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class SampleRequest {

    @XmlAttribute
    private String user;

    @XmlAttribute
    private String account;


    @XmlAttribute(name="Specifier")
    private List<Specifier> specifier;


}

Specifier.java

@XmlJavaTypeAdapter(SpecifierAdapter.class)
public class Specifier {



}

SpecifierAdapter.java

public class SpecifierAdapter  extends XmlAdapter{

    @Override
    public Object marshal(Object arg0) throws Exception {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Object unmarshal(Object arg0) throws Exception {
        // TODO Auto-generated method stub
        return null;
    }

}

Edited part

The class Specifier has got 3 String properties .

class Specifier
{
String value1;
String value2;
String value3;
}

And i need each series of Specifier for example (value1a,value1b,value1c) should be mapped to value1 , value2 , value3 respectively

Edited Part 3

Hi , Thanks for the response , i tried to unmarshall this example , what i found is that , i am getting null

This is the request i passed

<sampleRequest user="user" account="account" Specifier="v1,v2,v3 : a1,a2,a3"/>

Just want to make sure that , is my Specifier class is correct or not ?? (As i did not use any Annotations here )

package com;

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

@XmlJavaTypeAdapter(SpecifierAdapter.class)
public class Specifier {


    Specifier(String v1 , String v2 , String v3)
    {

    }

    String value1;

    public String getValue1() {
        return value1;
    }

    public void setValue1(String value1) {
        this.value1 = value1;
    }

    public String getValue2() {
        return value2;
    }

    public void setValue2(String value2) {
        this.value2 = value2;
    }

    public String getValue3() {
        return value3;
    }

    public void setValue3(String value3) {
        this.value3 = value3;
    }

    String value2;
    String value3;

}

Solution

  • NOTE: The adapter code could be made simpler by using guava-library's Joiner and Splitter.

    SampleRequest

    public class SampleRequest
    {
        @XmlAttribute
        private String user;
    
        @XmlAttribute
        private String account;
    
        @XmlAttribute(name = "Specifier")
        @XmlJavaTypeAdapter(SpecifierAdapter.class)
        private List<Specifier> specifier;
    }
    

    Adapter

    public class SpecifierAdapter extends XmlAdapter<String, List<Specifier>>
    {
        @Override
        public List<Specifier> unmarshal(final String v) throws Exception
        {
            String[] values = v.split(":");
            List<Specifier> l = new ArrayList<Specifier>();
            for (String s : values)
            {
                String[] vs = s.split(",");
                l.add(new Specifier(vs[0], vs[1], vs[2]));
            }
            return l;
        }
    
        @Override
        public String marshal(final List<Specifier> v) throws Exception
        {
            String values = "";
            for (Specifier s : v)
            {
                values += s.getValue1() + "," + s.getValue2() + "," + s.getValue3() + " : ";
            }
            return values.length() > 0 ? values.substring(0, values.length() - 3) : values;
        }
    }
    

    Usage

    public static void main(final String a[]) throws JAXBException
    {
            SampleRequest r = new SampleRequest();
            r.setAccount("account");
            r.setUser("user");
            List<Specifier> sps = new ArrayList<Specifier>();
            sps.add(new Specifier("v1", "v2", "v3"));
            sps.add(new Specifier("a1", "a2", "a3"));
            r.setSpecifier(sps);
    
            JAXBContext jc = JAXBContext.newInstance(SampleRequest.class);
            Marshaller marshaller = jc.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.marshal(r, System.out);
    }
    

    Output

    <?xml version="1.0" encoding="UTF-8"?>
    <sampleRequest user="user" account="account" Specifier="v1,v2,v3 : a1,a2,a3"/>