我将一个JAXB对象发布到REST服务。生成的类没有XMLRootElement,因此我使用Object Factory createXMl方法创建它。当我手动添加XMLRootElement时,它可以工作,但这只是一种解决方法,因为JAXB类总是在没有XMLRootElement的情况下生成。在发布请求时编组的XMl似乎存在一些问题。
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_XML);
String userAndPass = "Test:Test123";
headers.add("Authorization", "Basic " + Base64Utility.encode(userAndPass.getBytes()));
JAXBElement<DocumentDef> documentDef = PrintFactory.createPrintObjects();
HttpEntity<JAXBElement<DocumentDef>> request = new HttpEntity<>(documentDef, headers);
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
map.add("lang", "2");
ResponseEntity<String> result = restTemplate.exchange(url, HttpMethod.POST, request, String.class, map);
PrintFactory.java
public JAXBElement<DocumentDef> createPrintObjects() {
DocumentDef documentDef = new DocumentDef();
JAXBElement<DocumentDef> documentDefJAXBElement = factory.createXml(documentDef);
return documentDefJAXBElement;
}
ObjectFactory.java
/**
* Create an instance of {@link JAXBElement }{@code <}{@link DocumentDef }{@code >}}
*
*/
@XmlElementDecl(namespace = "http://www.example.com/testservice", name = "xml")
public JAXBElement<DocumentDef> createXml(DocumentDef value) {
return new JAXBElement<DocumentDef>(_Xml_QNAME, DocumentDef.class, null, value);
}
错误:
org.springframework.web.client.RestClientException: Could not write request: no suitable HttpMessageConverter found for request type [javax.xml.bind.JAXBElement] and content type [application/xml]
at org.springframework.web.client.RestTemplate$HttpEntityRequestCallback.doWithRequest(RestTemplate.java:859)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:617)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:588)
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:507)
以下HttpMessageConverters已经注册:
org.springframework.http.converter.ByteArrayHttpMessageConverter@68022358, org.springframework.http.converter.StringHttpMessageConverter@7b3a8b9f, org.springframework.http.converter.StringHttpMessageConverter@645e9bc0, org.springframework.http.converter.ResourceHttpMessageConverter@7f438dba, org.springframework.http.converter.xml.SourceHttpMessageConverter@2c0def9c, org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter@46ee015c, org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@2c833e50, org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@339b6365, org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter@1e9a965b
答案 0 :(得分:0)
嗯,因为以下原因,它不适合你,
JAXBElement<DocumentDef> documentDef = PrintFactory.createPrintObjects();
HttpEntity<JAXBElement<DocumentDef>> request = new HttpEntity<>(documentDef, headers);
同时Jaxb2RootElementHttpMessageConverter
就是这样:
* <p>This converter can read classes annotated with {@link XmlRootElement} and
* {@link XmlType}, and write classes annotated with {@link XmlRootElement},
* or subclasses thereof.
和
public boolean canWrite(Class<?> clazz, MediaType mediaType) {
return (AnnotationUtils.findAnnotation(clazz, XmlRootElement.class) != null && canWrite(mediaType));
}
当您的JAXBElement
完全没有@XmlRootElement
时。
尝试找出没有JAXBElement
包装器的解决方案。
答案 1 :(得分:0)
我已经通过创建.xjb文件解决了这个问题,该文件自动将XMLRootElement注释附加到父java类,同时生成如下:
<?xml version="1.0" encoding="UTF-8"?>
<jxb:bindings xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
jxb:extensionBindingPrefixes="xjc" version="1.0">
<jxb:bindings schemaLocation="mySchema.xsd" node="/xs:schema">
<jxb:globalBindings>
<xjc:simple/>
</jxb:globalBindings>
</jxb:bindings>
答案 2 :(得分:0)
如果您需要使用XMLRootElement
发布一个没有{1>}注释的jaxb对象,则解决方案是使用自定义RestTemplate
:
HttpMessageConverter
请注意,此转换器将尝试转换包装为// jaxb context specific to your xml elements
JAXBContext jaxbContext =
JAXBContext.newInstance(ObjectFactory.class.getPackage().getName());
// custom converter (see declaration below)
JaxbElementHttpMessageConverter converter = new JaxbElementHttpMessageConverter();
converter.setJaxbContext(jaxbContext);
RestTemplate template = new RestTemplate();
template.getMessageConverters().add(converter); // <--- here
// your object needs to be wrapped around a JAXBElement
YourRequestObject yourObject = ...;
JAXBElement<YourRequestObject> element =
new ObjectFactory().createYourRequestObject(request);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_XML);
ResponseEntity<YourResponseObject> response =
template.postForEntity("/your/url",
HttpEntity<>(element, headers),
YourResponseObject.class,
params);
的所有对象,因此您需要:
JAXBElement
的定义如下:
JaxbElementHttpMessageConverter
答案 3 :(得分:0)
该问题与 canWrite
类中的 canRead
和 MarshallingHttpMessageConverter
方法有关。这些方法检查编组器和解组器是否支持一个类。就我而言,启用 jaxb 元素支持有所帮助。
MarshallingHttpMessageConverter converter = new MarshallingHttpMessageConverter();
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setSupportJaxbElementClass(true);
marshaller.setContextPath(ObjectFactory.class.getPackage().getName());
converter.setMarshaller(marshaller);
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(converter);