描述:
在使用spring boot 对xml进行解析并返回xml格式是系列化数据没有DOCTYPE,除了实现自定义序列化程序之外,可以对XmlSerializerProvider
在 XML 生成器初始化后重写以写入 DTD 字符串;
请求数据:
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE cXML SYSTEM "http://xmlsss.org/schemas/cXML/1.2.014/cXML.dtd">
<cXML payloadID="111" version="1.2.021" timestamp="2012-11-27T22:54:58+00:00">
<Header>
...
</Header>
<Request deploymentMode="production">
...
</Request>
</cXML>
正常系列化得到数据:
<?xml version='1.0' encoding='UTF-8'?>
<cXML payloadID="asdas" version="1.2.021" timestamp="2012-11-27T22:54:58+00:00">
...
</cXML>
实际想要数据:
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE cXML SYSTEM "http://xml.cxml.org/schemas/cXML/1.2.014/cXML.dtd">
<cXML payloadID="1qweq" version="1.2.021" timestamp="2012-11-27T22:54:58+00:00">
...
</cXML>
关键追加代码:
//add DTD
final String dtd = "<!DOCTYPE cXML SYSTEM \"http://xml.cxml.org/schemas/cXML/1.2.014/cXML.dtd\">";
DtdXmlSerializerProvider serializerProvider = new DtdXmlSerializerProvider(
(XmlSerializerProvider) xmlMapper.getSerializerProvider(),
xmlMapper.getSerializationConfig(),
xmlMapper.getSerializerFactory(),
dtd);
详细使用方式:
方法一:重写MappingJackson2XmlHttpMessageConverter,在对xmlmapper追加DTO,代码如下:
@Bean
public MappingJackson2XmlHttpMessageConverter mappingJackson2XmlHttpMessageConverter(Jackson2ObjectMapperBuilder builder) {
XmlMapper xmlMapper = builder.createXmlMapper(true).build();
xmlMapper.enable(ToXmlGenerator.Feature.WRITE_XML_DECLARATION);
//add DTD
final String dtd = "<!DOCTYPE cXML SYSTEM \"http://xml.cxml.org/schemas/cXML/1.2.014/cXML.dtd\">";
DtdXmlSerializerProvider serializerProvider = new DtdXmlSerializerProvider(
(XmlSerializerProvider) xmlMapper.getSerializerProvider(),
xmlMapper.getSerializationConfig(),
xmlMapper.getSerializerFactory(),
dtd);
xmlMapper.setSerializerProvider(serializerProvider);
return new MappingJackson2XmlHttpMessageConverter(xmlMapper);
}
方法二:外部封装方法进行重写返回:(代码如下):
@Operation(
summary = "Submit an order request for approval",
security = @SecurityRequirement(name = "bearerAuth"))
@PostMapping(
value = "/request2",
consumes = MediaType.APPLICATION_XML_VALUE,
produces = MediaType.APPLICATION_XML_VALUE)
public ResponseEntity<CXML> request2(@RequestBody CXML cxmlRequest) throws JsonProcessingException {
log.debug("cxmlRequest {} ", JSON.toJSONString(cxmlRequest));
HttpStatus status = HttpStatus.OK;
XmlMapper xmlMapper = new XmlMapper();
//如果没有xml头也可以加入如下注释行
// .configure(ToXmlGenerator.Feature.WRITE_XML_DECLARATION, true);
xmlMapper.enable(ToXmlGenerator.Feature.WRITE_XML_DECLARATION);
final String dtd = "<!DOCTYPE cXML SYSTEM \"http://xml.cxml.org/schemas/cXML/1.2.014/cXML.dtd\">";
DtdXmlSerializerProvider serializerProvider = new DtdXmlSerializerProvider(
(XmlSerializerProvider) xmlMapper.getSerializerProvider(),
xmlMapper.getSerializationConfig(),
xmlMapper.getSerializerFactory(),
dtd);
xmlMapper.setSerializerProvider(serializerProvider);
log.debug("mapper.writeValueAsString,cxmlRequest {} ",xmlMapper.writeValueAsString(cxmlRequest));
return new ResponseEntity(cxmlRequest, status);
}
DtdXmlSerializerProvider 类见链接DtdXmlSerializerProvider
CXML为自己定义的xml结构体数据,简单举例内容如下:
package com.XXX.XXX.XXX.model.DTO;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonRootName;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@JsonRootName(value="cXML")
public class CXML {
//@JacksonXmlProperty(isAttribute=true, localName = "xml:lang")
//private String xmlLang;
@JsonProperty
@JacksonXmlProperty(isAttribute=true,localName="payloadID")
private String payloadID;
@JsonProperty
@JacksonXmlProperty(isAttribute=true,localName="version")
private String version;
@JsonProperty
@JacksonXmlProperty(isAttribute=true,localName="timestamp")
private String timestamp;
// private Date timestamp;
@JacksonXmlProperty(localName="Header")
private Header Header;
@JacksonXmlProperty(localName="Request")
private Request Request;
}
请求示例如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE cXML SYSTEM "http://xml.cxml.org/schemas/cXML/1.2.021/cXML.dtd">
<cXML xml:lang="en-US" payloadID="asdasd" timestamp="2012-11-27T22:54:58+00:00" version="1.2.021">
<Header>
...
</Header>
<Request deploymentMode="production">
...
</Request>
</cXML>
返回示例;最终结果跟请求示例一致 ;