WireMock 中请求头匹配与响应配置的一些实践
记录用 WireMock 挡服务时,通过 JSON 映射文件和 Java API 做请求头匹配、响应头与响应体配置的两种方式及细节。
支持通配符SSL证书、多域名证书、IP证书。适配ACME接口, 支持Zerossl、Let's Encrypt和Google等渠道。登录已有账号
2026-06-17 17:15:37 Java XML解析 DOM DOM4J
解析XML字符串这活儿,Java开发里挺常见的。配置、接口返回、老系统对接,时不时就得撸一段。工具没有好坏,看场景——JDK自带的DOM能用,第三方DOM4J也能用,两套都写一下,顺便聊聊什么时候用哪个。
DOM是JDK自带的,不用加任何Maven依赖,拿出来就能跑。
核心步骤就是:拿到DocumentBuilderFactory,创建DocumentBuilder,然后把XML字符串包成InputSource丢进去parse。
贴一段完整的例子,直接读一个books的XML,把书名、作者、价格打出来。
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import java.io.StringReader;
public class DomXmlParser {
public static void main(String[] args) {
String xmlString = """
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book id="1">
<title>Java Programming</title>
<author>James Gosling</author>
<price>59.99</price>
</book>
<book id="2">
<title>Effective Java</title>
<author>Joshua Bloch</author>
<price>49.99</price>
</book>
</books>
""";
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new InputSource(new StringReader(xmlString)));
NodeList bookNodes = document.getElementsByTagName("book");
for (int i = 0; i < bookNodes.getLength(); i++) {
Element book = (Element) bookNodes.item(i);
System.out.println("ID: " + book.getAttribute("id"));
System.out.println("Title: " + book.getElementsByTagName("title").item(0).getTextContent());
System.out.println("Author: " + book.getElementsByTagName("author").item(0).getTextContent());
System.out.println("Price: " + book.getElementsByTagName("price").item(0).getTextContent());
System.out.println("----------------------");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
API用起来略啰嗦,取个文本得先getElementsByTagName再.item(0).getTextContent(),属性倒是直接getAttribute就行。
如果XML结构简单,这点代码还能忍,字段一多就开始肉眼可见的繁。好处就是零依赖,什么环境都能跑,也不用担心版本冲突。
DOM4J需要额外引个包,Maven里加一下:
<dependency>
<groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>2.1.3</version>
</dependency>
代码就清爽多了。
SAXReader.read()直接扔一个StringReader进去,拿回来的Document可以链式取根元素,然后elements("book")返回一个List,遍历的时候attributeValue、elementText一把梭。
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.StringReader;
import java.util.List;
public class Dom4jXmlParser {
public static void main(String[] args) {
String xmlString = """
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book id="1">
<title>Java Programming</title>
<author>James Gosling</author>
<price>59.99</price>
</book>
<book id="2">
<title>Effective Java</title>
<author>Joshua Bloch</author>
<price>49.99</price>
</book>
</books>
""";
try {
SAXReader reader = new SAXReader();
Document document = reader.read(new StringReader(xmlString));
List<Element> books = document.getRootElement().elements("book");
for (Element book : books) {
System.out.println("ID: " + book.attributeValue("id"));
System.out.println("Title: " + book.elementText("title"));
System.out.println("Author: " + book.elementText("author"));
System.out.println("Price: " + book.elementText("price"));
System.out.println("----------------------");
}
} catch (DocumentException e) {
e.printStackTrace();
}
}
}
elementText这个方法内部帮你处理了空值,不会直接抛NullPointerException,这点比DOM裸调item(0)要安全一些。另外DOM4J还支持XPath,做复杂条件筛选的时候很方便,这是标准DOM不具备的。
把两个放一起看,差别很明显。
标准DOM不需要任何第三方jar,打一个可执行jar就能跑,在受限环境或者对依赖敏感的项目里这是硬优势。API虽然丑陋但也不是不能用,XML节点少、结构固定的时候完全够。我之前有个小工具解析几十行的配置文件,就用的DOM,写完一两年没动过,也没出过问题。
DOM4J带来的便利主要是API设计,代码量少、可读性高。真要解析一个几百K的XML,或者需要按条件提取节点,elementText和XPath能省不少事。
而且它的性能通常比DOM好,处理大文件内存占用更小——这个结论是社区公认的,具体细节可以去看DOM4J的文档。
所以选型上基本是:如果你不想引入额外依赖,XML又简单,直接用标准DOM。
如果XML比较复杂,或者你已经在用DOM4J(很多老项目比如Hibernate配置解析就用的它),那没什么好纠结,用它就行。需要XPath的时候,DOM4J也是更自然的选择。
两种方式没有绝对的好坏,主要看当前场景对“零依赖”和“开发效率”的侧重。
记录用 WireMock 挡服务时,通过 JSON 映射文件和 Java API 做请求头匹配、响应头与响应体配置的两种方式及细节。
记录在 Aspose.PDF 里加载本地 TTF 字体,以及绕过 TTC 格式不支持问题的两种可行方案。
记录一次排序 NPE 的排查和解决,顺便说下 IDEA 调试集合时 null 元素不显示的问题怎么调整。
记录一次排序 NPE 的排查和解决,顺便说下 IDEA 调试集合时 null 元素不显示的问题怎么调整。
还在为Java程序阻塞而烦恼?本文将带你轻松掌握CompletableFuture.runAsync,告别传统阻塞模式。通过直观的错误与正确代码对比,你将学会如何用简单的lambda表达式在新线程中运行无返回值任务。快速理解Thread.currentThread().getName()的验证机制,立即解锁高性能并发编程,让你的应用响应更快!