spring 如何使用spring来编组和解组xml?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/44676532/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use spring to marshal and unmarshal xml?
提问by Kaushik Chakraborty
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 thistutorial to get a sample spring boot application running.
我有一个弹簧启动项目。我的项目中有几个 xsd。我已经使用 maven-jaxb2-plugin 生成了这些类。我已经使用本教程来运行示例 Spring Boot 应用程序。
import org.kaushik.xsds.XOBJECT;
@SpringBootApplication
public class JaxbExample2Application {
public static void main(String[] args) {
//SpringApplication.run(JaxbExample2Application.class, args);
XOBJECT xObject = new XOBJECT('a',1,2);
try {
JAXBContext jc = JAXBContext.newInstance(User.class);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(xObject, System.out);
} catch (PropertyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JAXBException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
But my concern is that I need to have all the jaxb classes of the schema mapped. Also is there something in Spring that I can use to make my task easier. I have looked at the Spring OXMproject but it had application context configured in xml. Does spring boot have anything that I can use out of the box. Any examples will be helpful.
但我担心的是,我需要映射架构的所有 jaxb 类。在 Spring 中还有什么东西可以用来让我的任务更容易。我查看了 Spring OXM项目,但它在 xml 中配置了应用程序上下文。Spring Boot 是否有任何我可以开箱即用的东西。任何示例都会有所帮助。
Edit
编辑
I tried xerx593's answerand I ran a simple test using main method
我尝试了xerx593 的答案,并使用 main 方法进行了一个简单的测试
JaxbHelper jaxbHelper = new JaxbHelper();
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setClassesToBeBound(XOBJECT.class);
jaxbHelper.setMarshaller(marshaller);
XOBJECT xOBJECT= (PurchaseOrder)jaxbHelper.load(new StreamSource(new FileInputStream("src/main/resources/PurchaseOrder.xml")));
System.out.println(xOBJECT.getShipTo().getName());
It ran perfectly fine. Now I just need to plug it in using spring boot.
它运行得很好。现在我只需要使用 spring boot 将其插入即可。
回答by xerx593
OXM is definitely the right for you!
OXM 绝对适合您!
A simple java configuration of a Jaxb2Marshaller would look like:
Jaxb2Marshaller 的简单 java 配置如下所示:
//...
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
回答by bluearrow
If you just want serializing/deserializingbean with XML. I think Hymanson fasterxmlis one good choice:
如果您只想要serializing/deserializing带有 XML 的 bean。我认为Hymanson fasterxml是一个不错的选择:
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.Hymanson.dataformat</groupId>
<artifactId>Hymanson-dataformat-xml</artifactId>
</dependency>
回答by sergpank
Spring BOOT is very smart and it can understand what you need with a little help.
Spring BOOT 非常聪明,它可以在一点帮助下了解您的需求。
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.
要使 XML 编组/解组工作,您只需将注释 @XmlRootElement 添加到类并将 @XmlElement 添加到没有 getter 的字段,目标类将自动序列化/反序列化。
Here is the DTO example
这是 DTO 示例
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
您可以在此处查看完整的代码示例:https: //github.com/sergpank/spring-boot-xml
Any questions are welcome.
欢迎任何问题。
回答by Mohamed.Abdo
You can use StringSource/ StringResultto read / read xml source with spring
您可以使用StringSource/StringResult来读取/读取带有 spring 的 xml 源
@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();
}

