Jaxb对xml报文头的小修小改

 

前言:
  也是在实际工作中, 借助jaxb来实现xml到java对象的映射转换. 在实际应用中, 也遇到了一些有趣好玩的东西, 权当记录下来.
  本文主要讲解jaxb如何生成约定的xml报文头的实现思路, 点比较小, 而且方法有点trick, 因此导致取博文标题的时候, 也有些小迷茫, ^_^.

 

现象:
  我们先来定义一个简单的java类, 并用于生成其对应的xml内容.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name="root")
public static class TNode {
 
    @XmlElement(name="key", required = true)
    private String key;
 
    @XmlElement(name="value", required = true)
    private String value;
 
}
 
 
public static void main(String[] args) {
    TNode obj = new TNode("key_1", "val_1");
    try {
        JAXBContext jc = JAXBContext.newInstance(TNode.class);
        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
 
        StringWriter writer = new StringWriter();
        marshaller.marshal(obj, writer);
 
        System.out.println(writer.toString());
    } catch (JAXBException e) {
        e.printStackTrace();
    }
}

  注: 这是简单的实体类, 以及对应的jaxb生成xml的代码
  具体的生成结果如下:

1
2
3
4
5
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
    <key>key_1</key>
    <value>val_1</value>
</root>

  在默认的xml报文头里, 比常见的多了一个standalone="yes" , 有没有办法去掉这个小尾巴呢?

 

尝试思路:
  Marshaller类定义了很多属性, 我们先来看一下有没有报文头相关的配置.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public interface Marshaller {
 
    // *) 指定编码模式
    public static final String JAXB_ENCODING = "jaxb.encoding";
 
    // *) 指定输出时, 是否支持缩进和换行
    public static final String JAXB_FORMATTED_OUTPUT = "jaxb.formatted.output";
 
    /**
     * The name of the property used to specify the xsi:schemaLocation
     * attribute value to place in the marshalled XML output.
     */
    public static final String JAXB_SCHEMA_LOCATION = "jaxb.schemaLocation";
 
    /**
     * The name of the property used to specify the
     * xsi:noNamespaceSchemaLocation attribute value to place in the marshalled
     * XML output.
     */
    public static final String JAXB_NO_NAMESPACE_SCHEMA_LOCATION
        = "jaxb.noNamespaceSchemaLocation";
 
    // *) 是否生成报文头
    public static final String JAXB_FRAGMENT = "jaxb.fragment";
 
}

  让人有点小失望, 里面涉及报文头的信息, 只有两个, JAXB_ENCODING控制编码, JAXB_FRAGMENT控制报文头的可见性, 对standalone的可见性没有配置项. 看来这条路是行不通的.

 

解决思路:
  本来觉得jaxb提供了一些listener是可以实现这个功能, 不过还没研究. 无意中, 看到网友写了一段输出xml的代码, 突然想到他或许也遇到了同样的问题, 只是没把为什么这样做的目的写出来.
  我们重新修改下生成xml的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public static void main(String[] args) {
    TNode obj = new TNode("key_1", "val_1");
    try {
        JAXBContext jc = JAXBContext.newInstance(TNode.class);
        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
        // 1) 隐去报文头的生成, Marshaller.JAXB_FRAGMENT默认为false
        marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
 
        StringWriter writer = new StringWriter();
        // 2) 自定义生成
        writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
        marshaller.marshal(obj, writer);
 
        System.out.println(writer.toString());
    } catch (JAXBException e) {
        e.printStackTrace();
    }
}

  注: 两个要点, 1. 激活JAXB_FRAGMENT为true, 隐去jaxb自动生成xml报文头. 2. 自定义输出报文头信息
  测试一下, 结果如下:

1
2
3
4
5
<?xml version="1.0" encoding="UTF-8" ?>
<root>
    <key>key_1</key>
    <value>val_1</value>
</root>

 

总结:
  这也算得上一篇博客水文, 这边就当学习笔记, 抛砖引玉. 后续想对jaxb的性能优化, 以及内部的实现机制多多深入研究一下.

 

posted on   mumuxinfei  阅读(1330)  评论(0编辑  收藏  举报

编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示