java使用 Jackson XmlMapper 序列化时添加 DTD(DOCTYPE)

描述: 
在使用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>

返回示例;最终结果跟请求示例一致 ;

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值