简体   繁体   中英

Simple XML deserialization

I am trying out the Simple XML serializer . I am more interested in deserialization from XML->Java. Here is my code as a unit test:

import java.io.StringReader;
import java.io.StringWriter;

import junit.framework.TestCase;

import org.simpleframework.xml.Attribute;
import org.simpleframework.xml.Root;
import org.simpleframework.xml.Serializer;
import org.simpleframework.xml.core.Persister;

public class SimpleTest extends TestCase {
    public void testWriting() throws Exception {
        StringWriter writer = new StringWriter();
        Address address = new Address("1234 Main Street", "San Francisco", "CA");
        Serializer serializer = new Persister();

        serializer.write(address, writer);
        System.out.println("Wrote: " + writer.getBuffer());
    }

    public void testReading() throws Exception {
        String input = "<address street='1234 Main Street' city='San Francisco' state='CA'/>";
        Serializer serializer = new Persister();
        System.out.println("Read back: " + serializer.read(Address.class, new StringReader(input)));
    }
}

@Root
class Address {
    @Attribute(name="street")
    private final String street;

    @Attribute(name="city")
    private final String city;

    @Attribute(name="state")
    private final String state;

    public Address(@Attribute(name="street") String street, @Attribute(name="city") String city, @Attribute(name="state") String state) {
        super();
        this.street = street;
        this.city = city;
        this.state = state;
    }

    @Override
    public String toString() {
        return "Address [city=" + city + ", state=" + state + ", street=" + street + "]";
    }   
}

This works, but the repeated @Attribute annotations (at the field and at the constructor argument) in the Address class look ugly. Is there some way to:

  • have simple figure out the attribute name from the field name?
  • have simple ignore serialization, so that I can get away with annotating either the fields or the constructor argument?

I don't think you need all that repetition and the extra annotations' attribute. If the name is the same as the object attribute, it will be used by default.

so you can just declare it as:

@Root
class Address {
    @Attribute
    private final String street;

    @Attribute
    private final String city;

    @Attribute
    private final String state;

    public Address(String street, String city, String state) {
        super();
        this.street = street;
        this.city = city;
       this.state = state;
   }

   @Override
   public String toString() {
      return "Address [city=" + city + ", state=" + state + ", street=" + street + "]";
   }   
}

如果Java实现Serializable并遵循JavaBean语法,Java将默认序列化所有类成员。

I had similar concern but with pretty complicated objects structures. I solved it by using JAXB library for marshaling and de-marshaling which is a pretty common one. You can consider also totally separating the marshaling logic from your java class by using aspects - you can treat all the annotations in a separate aspect what will make your java class fully clean from marshaling annotations.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM