How to use spring to marshal and unmarshal xml?

后端 未结 4 1457
渐次进展
渐次进展 2020-12-07 23:44

I have a spring boot project. I have a few xsds in my project. I have generated the classes using maven-jaxb2-plugin. I have used this tutorial to get a sample spring boot a

相关标签:
4条回答
  • 2020-12-07 23:54

    If you just want serializing/deserializing bean with XML. I think jackson fasterxml is one good choice:

    ObjectMapper xmlMapper = new XmlMapper();
    String xml = xmlMapper.writeValueAsString(new Simple());  // serializing
    
    Simple value = xmlMapper.readValue("<Simple><x>1</x><y>2</y></Simple>",
         Simple.class); // deserializing
    

    maven:

    <dependency>
        <groupId>com.fasterxml.jackson.dataformat</groupId>
        <artifactId>jackson-dataformat-xml</artifactId>
    </dependency>
    

    Refer: https://github.com/FasterXML/jackson-dataformat-xml

    0 讨论(0)
  • 2020-12-08 00:01

    OXM is definitely the right for you!

    A simple java configuration of a Jaxb2Marshaller would look like:

    //...
    import java.util.HashMap;
    import org.springframework.oxm.jaxb.Jaxb2Marshaller;
    //...
    
    @Configuration
    public class MyConfigClass {
        @Bean
        public Jaxb2Marshaller jaxb2Marshaller() {
            Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
            marshaller.setClassesToBeBound(new Class[]{
               //all the classes the context needs to know about
               org.kaushik.xsds.All.class,
               org.kaushik.xsds.Of.class,
               org.kaushik.xsds.Your.class,
               org.kaushik.xsds.Classes.class
            });
            // "alternative/additiona - ly":
              // marshaller.setContextPath(<jaxb.context-file>)
              // marshaller.setPackagesToScan({"com.foo", "com.baz", "com.bar"});
    
            marshaller.setMarshallerProperties(new HashMap<String, Object>() {{
              put(javax.xml.bind.Marshaller.JAXB_FORMATTED_OUTPUT, true);
              // set more properties here...
            }});
    
            return marshaller;
        }
    }
    

    In your Application/Service class you could approach like this:

    import java.io.InputStream;
    import java.io.StringWriter;
    import javax.xml.bind.JAXBException;
    import javax.xml.transform.Result;
    import javax.xml.transform.stream.StreamResult;
    import javax.xml.transform.stream.StreamSource;
    import org.springframework.oxm.jaxb.Jaxb2Marshaller;  
    
    @Component
    public class MyMarshallerWrapper {
       // you would rather:
       @Autowired
       private Jaxb2Marshaller  marshaller;
       // than:
       // JAXBContext jc = JAXBContext.newInstance(User.class);
       // Marshaller marshaller = jc.createMarshaller();
    
       // marshalls one object (of your bound classes) into a String.
       public <T> String marshallXml(final T obj) throws JAXBException {
          StringWriter sw = new StringWriter();
          Result result = new StreamResult(sw);
          marshaller.marshal(obj, result);
          return sw.toString();
       }
    
       // (tries to) unmarshall(s) an InputStream to the desired object.
       @SuppressWarnings("unchecked")
       public <T> T unmarshallXml(final InputStream xml) throws JAXBException {
          return (T) marshaller.unmarshal(new StreamSource(xml));
       }
    }
    

    See Jaxb2Marshaller-javadoc, and a related Answer

    0 讨论(0)
  • 2020-12-08 00:07

    Spring BOOT is very smart and it can understand what you need with a little help.

    To make XML marshalling/unmarshalling work you simply need to add annotations @XmlRootElement to class and @XmlElement to fields without getter and target class will be serialized/deserialized automatically.

    Here is the DTO example

    package com.exmaple;
    
    import lombok.AllArgsConstructor;
    import lombok.Getter;
    import lombok.NoArgsConstructor;
    import lombok.Setter;
    import lombok.ToString;
    
    import javax.xml.bind.annotation.XmlElement;
    import javax.xml.bind.annotation.XmlRootElement;
    import java.io.Serializable;
    import java.util.Date;
    import java.util.Random;
    
    @AllArgsConstructor
    @NoArgsConstructor
    @ToString
    @Setter
    @XmlRootElement
    public class Contact implements Serializable {
        @XmlElement
        private Long id;
    
        @XmlElement
        private int version;
    
        @Getter private String firstName;
    
        @XmlElement
        private String lastName;
    
        @XmlElement
        private Date birthDate;
    
        public static Contact randomContact() {
            Random random = new Random();
            return new Contact(random.nextLong(), random.nextInt(), "name-" + random.nextLong(), "surname-" + random.nextLong(), new Date());
        }
    }
    

    And the Controller:

    package com.exmaple;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    @Controller
    @RequestMapping(value="/contact")
    public class ContactController {
        final Logger logger = LoggerFactory.getLogger(ContactController.class);
    
        @RequestMapping("/random")
        @ResponseBody
        public Contact randomContact() {
            return Contact.randomContact();
        }
    
        @RequestMapping(value = "/edit", method = RequestMethod.POST)
        @ResponseBody
        public Contact editContact(@RequestBody Contact contact) {
            logger.info("Received contact: {}", contact);
            contact.setFirstName(contact.getFirstName() + "-EDITED");
            return contact;
        }
    }
    

    You can check-out full code example here: https://github.com/sergpank/spring-boot-xml

    Any questions are welcome.

    0 讨论(0)
  • 2020-12-08 00:14

    You can use StringSource / StringResult to read / read xml source with spring

     @Autowired
        Jaxb2Marshaller jaxb2Marshaller;
    
        @Override
        public Service parseXmlRequest(@NonNull String xmlRequest) {
            return (Service) jaxb2Marshaller.unmarshal(new StringSource(xmlRequest));
        }
    
        @Override
        public String prepareXmlResponse(@NonNull Service xmlResponse) {
            StringResult stringResult = new StringResult();
            jaxb2Marshaller.marshal(xmlResponse, stringResult);
            return stringResult.toString();
        }
    
    0 讨论(0)
提交回复
热议问题