[英]Accept SOAP message in RestController using JAXB
我們創建了一個Spring Boot @RestController,它將使用SOAP接受XML請求,但是我無法使其正常工作。
樣本消息:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<PostPayload xmlns="http://mynamespace/">
<Message>
<Header type="Main" version="1.0" desc="Some header description...">
<Title content="The quick brown fox." />
</Header>
<Content />
<Footer type="Copyright" name="Footer01">Some random content...</Footer>
</Message>
</PostPayload>
</soap:Body>
</soap:Envelope>
休息控制器:
@RestController
@RequestMapping("rest-service")
public class MessageController {
@PostMapping(consumes = MediaType.APPLICATION_XML_VALUE)
public String handler(@RequestBody Message message) {
System.out.println(message);
System.out.println("\n\n\n");
try {
JAXBContext jaxbContext = JAXBContext.newInstance(Message.class);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(message, System.out);
} catch(JAXBException ex) {
System.out.println(ex.toString());
}
return "Done!";
}
}
訊息類別
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "Message")
public class Message {
@XmlElement(name = "Header", required = true)
private Header header;
@XmlElement(name = "Content", required = true)
private Content content;
@XmlElement(name = "Footer", required = true)
private Footer footer;
// Getters and setters here...
@Override
public String toString() {
// In here, I outputted the values of the header and footer.
}
}
標頭類
@XmlRootElement(name = "Header")
@XmlAccessorType(XmlAccessType.FIELD)
public class Header {
@XmlAttribute(name = "type", required = true)
private String type;
@XmlAttribute(name = "version", required = true)
private String version;
@XmlAttribute(name = "desc", required = true)
private String description;
// Getters and setters here...
}
內容類別
@XmlRootElement(name = "Content")
@XmlAccessorType(XmlAccessType.FIELD)
public class Content {
}
頁腳類
@XmlRootElement(name = "Footer")
@XmlAccessorType(XmlAccessType.FIELD)
public class Footer {
@XmlValue
private String value;
@XmlAttribute(name = "name")
private String name;
@XmlAttribute(name = "type")
private String type;
//Getter and setters here...
}
因此,如果我將該肥皂消息發送到我的休息服務,它將返回null。 rest控制器中的編組器只是檢查輸出是否與請求相同,這意味着我正在正確讀取XML。 不幸的是,它返回空值。 有什么想法為什么呢?
您不需要使用Jaxb序列化請求,因為spring rest控制器會自動執行該請求。 您的Message類(在函數中作為參數)必須包含PostPayload,並且具有xml中的名稱空間( http:// mynamespace / )。 restcontroller檢查標頭中的內容類型並自動進行轉換。
這篇文章包括更多信息: 具有XML支持的Spring Boot REST
工作示例:
package com.mkysoft.restxml.contoller;
import com.mkysoft.restxml.domain.*;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
@RestController
@RequestMapping("rest-service")
public class MessageController {
@PostMapping(consumes = MediaType.APPLICATION_XML_VALUE)
public String handler(@RequestBody Envelope envelope) {
System.out.println(envelope);
System.out.println("\n\n\n");
try {
JAXBContext jaxbContext = JAXBContext.newInstance(Envelope.class);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(envelope, System.out);
} catch (JAXBException ex) {
System.out.println(ex.toString());
}
return "Done!";
}
@GetMapping()
public Envelope gethandler() {
final Envelope envelope = new Envelope();
final Message message = new Message();
final Header header = new Header();
header.setType("type");
header.setDescription("description");
header.setVersion("version");
message.setHeader(header);
message.setContent(new Content());
message.setFooter(new Footer());
final Body body = new Body();
final PostPayload postPayload = new PostPayload();
postPayload.setMessage(message);
//body.setPostPayload(postPayload);
envelope.setBody(body);
return envelope;
}
}
Envelope.java
package com.mkysoft.restxml.domain;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "Envelope", namespace = "http://schemas.xmlsoap.org/soap/envelope/")
public class Envelope {
@XmlElement(name = "Body", required = true, namespace = "http://schemas.xmlsoap.org/soap/envelope/")
private Body body;
public Body getBody() {
return body;
}
public void setBody(Body body) {
this.body = body;
}
}
Body.java
package com.mkysoft.restxml.domain;
import com.sun.xml.internal.txw2.annotation.XmlNamespace;
import org.apache.cxf.jaxrs.ext.xml.XMLName;
import javax.xml.bind.annotation.*;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "Body", namespace = "http://schemas.xmlsoap.org/soap/envelope/")
public class Body {
@XmlElement(name = "PostPayload", required = true, namespace = "http://mynamespace/")
private PostPayload postPayload;
public PostPayload getPostPayload() {
return postPayload;
}
public void setPostPayload(PostPayload postPayload) {
this.postPayload = postPayload;
}
}
PostPayload.java
package com.mkysoft.restxml.domain;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "PostPayload", namespace = "http://mynamespace/")
public class PostPayload {
@XmlElement(name = "Message", required = true, namespace = "http://mynamespace/")
private Message message;
public Message getMessage() {
return message;
}
public void setMessage(Message message) {
this.message = message;
}
}
Message.java
package com.mkysoft.restxml.domain;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "Message", namespace = "http://mynamespace/")
public class Message {
@XmlElement(name = "Header", required = true, namespace = "http://mynamespace/")
private Header header;
@XmlElement(name = "Content", required = true, namespace = "http://mynamespace/")
private Content content;
@XmlElement(name = "Footer", required = true, namespace = "http://mynamespace/")
private Footer footer;
public Header getHeader() {
return header;
}
public void setHeader(Header header) {
this.header = header;
}
public Content getContent() {
return content;
}
public void setContent(Content content) {
this.content = content;
}
public Footer getFooter() {
return footer;
}
public void setFooter(Footer footer) {
this.footer = footer;
}
@Override
public String toString() {
// In here, I outputted the values of the header and footer.
return null;
}
}
Header.java
package com.mkysoft.restxml.domain;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "Header", namespace = "http://mynamespace/")
@XmlAccessorType(XmlAccessType.FIELD)
public class Header {
@XmlAttribute(name = "type", required = true)
private String type;
@XmlAttribute(name = "version", required = true)
private String version;
@XmlAttribute(name = "desc", required = true)
private String description;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
Footer.java
package com.mkysoft.restxml.domain;
import javax.xml.bind.annotation.*;
@XmlRootElement(name = "Footer", namespace = "http://mynamespace/")
@XmlAccessorType(XmlAccessType.FIELD)
public class Footer {
@XmlValue
private String value;
@XmlAttribute(name = "name")
private String name;
@XmlAttribute(name = "type")
private String type;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
Content.java
package com.mkysoft.restxml.domain;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "Content", namespace = "http://mynamespace/")
@XmlAccessorType(XmlAccessType.FIELD)
public class Content {
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.