You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JAXB无法识别自定义CustomEscapeHandler的解决方案求助

Fixing JAXB CharacterEscapeHandler Internal Package Issue

Hey there, sorry to hear this has been plaguing you for a month—let's break down what's going on and fix it for good.

The Root Cause

The problem boils down to which JAXB implementation your project is using:

  • JDK-built-in JAXB (available in Java 6-8) relies on internal com.sun.xml.internal packages. This is why your custom handler keeps getting rejected unless it implements the internal CharacterEscapeHandler.
  • Standalone JAXB RI (the official reference implementation from GlassFish) uses public com.sun.xml.bind packages, which is what you want to use to avoid internal dependencies.

Most online examples you found are likely targeting the old JDK-built-in version, which is why they don't address your issue.

Step-by-Step Solution

1. Replace JDK-built-in JAXB with Standalone RI Dependencies

First, you need to exclude the JDK's internal JAXB and add the standalone implementation to your project. Here's how to do it with Maven (adjust for Gradle if needed):

<dependencies>
    <!-- JAXB API -->
    <dependency>
        <groupId>javax.xml.bind</groupId>
        <artifactId>jaxb-api</artifactId>
        <version>2.3.1</version>
    </dependency>
    <!-- JAXB Implementation (runtime) -->
    <dependency>
        <groupId>com.sun.xml.bind</groupId>
        <artifactId>jaxb-impl</artifactId>
        <version>2.3.1</version>
        <scope>runtime</scope>
    </dependency>
    <!-- JAXB Core Utilities -->
    <dependency>
        <groupId>com.sun.xml.bind</groupId>
        <artifactId>jaxb-core</artifactId>
        <version>2.3.0.1</version>
    </dependency>
    <!-- Activation API (required for JAXB 2.3+) -->
    <dependency>
        <groupId>javax.activation</groupId>
        <artifactId>activation</artifactId>
        <version>1.1.1</version>
    </dependency>
</dependencies>

For Java 9+, since JAXB was removed from the JDK, you'll also need to add module declarations in your module-info.java:

requires javax.xml.bind;
requires com.sun.xml.bind;

2. Update Your CustomEscapeHandler to Use the Public Package

Make sure your handler implements the public com.sun.xml.bind.marshaller.CharacterEscapeHandler (not the internal com.sun.xml.internal one):

import com.sun.xml.bind.marshaller.CharacterEscapeHandler;
import java.io.IOException;
import java.io.Writer;

public class CustomEscapeHandler implements CharacterEscapeHandler {
    private static final CustomEscapeHandler INSTANCE = new CustomEscapeHandler();

    public static CustomEscapeHandler getInstance() {
        return INSTANCE;
    }

    @Override
    public void escape(char[] ch, int start, int length, boolean isAttVal, Writer out) throws IOException {
        // Add your custom escape logic here
        for (int i = start; i < start + length; i++) {
            char c = ch[i];
            switch (c) {
                case '<': out.write("&lt;"); break;
                case '>': out.write("&gt;"); break;
                case '&': out.write("&amp;"); break;
                case '\"': if (isAttVal) out.write("&quot;"); else out.write(c); break;
                default: out.write(c); break;
            }
        }
    }
}

3. Configure Marshaller with the Correct Property Key

When setting your custom handler, use the public property key (matching the standalone RI):

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;

public class JaxbExample {
    public static void main(String[] args) throws Exception {
        JAXBContext jaxbContext = JAXBContext.newInstance(YourPojoClass.class);
        Marshaller jaxbMarshaller = jaxbContext.createMarshaller();

        // Set your custom escape handler using the public property key
        jaxbMarshaller.setProperty("com.sun.xml.bind.marshaller.CharacterEscapeHandler", CustomEscapeHandler.getInstance());
        
        // Optional: Format output for readability
        jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

        // Marshal your object
        jaxbMarshaller.marshal(yourPojoInstance, System.out);
    }
}

Key Notes to Avoid Pitfalls

  • Classpath Priority: Ensure the standalone JAXB dependencies are loaded before any JDK internal classes. Most build tools (Maven/Gradle) handle this automatically, but double-check if you have conflicting dependencies.
  • Framework Integration: If you're using a framework like Spring, make sure it's configured to use the standalone JAXB implementation. For example, Spring's Jaxb2Marshaller will pick up the standalone RI if it's on the classpath.

内容的提问来源于stack exchange,提问作者user4880619

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:32:27