如何在Apache Camel中将XML转为Java对象?遇jaxb格式找不到问题
Hey there, let's work through this issue you're facing with unmarshalling that currency XML into your Currency Java object. That error usually boils down to missing dependencies or misconfiguration with JAXB. Here's how to fix it step by step:
1. Make Sure JAXB Dependencies Are Added to Your pom.xml
First off, JAXB isn't included in JDK versions 9 and above, and even in Java 8, sometimes explicit dependencies help avoid classpath issues. Add these to your Maven pom based on your Java version:
For Java 8 or Older
<dependencies> <!-- JAXB API --> <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>2.3.1</version> </dependency> <!-- JAXB Implementation --> <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-impl</artifactId> <version>2.3.1</version> <scope>runtime</scope> </dependency> <!-- JAXB Core --> <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-core</artifactId> <version>2.3.0.1</version> </dependency> <!-- Activation API (required for JAXB) --> <dependency> <groupId>javax.activation</groupId> <artifactId>activation</artifactId> <version>1.1.1</version> </dependency> </dependencies>
For Java 9+ (Modular JDK)
Java 9 moved JAXB to external modules, so use these Jakarta EE dependencies instead:
<dependencies> <dependency> <groupId>jakarta.xml.bind</groupId> <artifactId>jakarta.xml.bind-api</artifactId> <version>3.0.2</version> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-impl</artifactId> <version>3.0.2</version> <scope>runtime</scope> </dependency> <dependency> <groupId>jakarta.activation</groupId> <artifactId>jakarta.activation-api</artifactId> <version>2.0.1</version> </dependency> </dependencies>
2. If You're Using Apache Camel's jaxbUnmarshal Component
If you're working with Apache Camel, just adding dependencies might not be enough—you need to make sure the JAXB data format is registered properly:
Spring Boot Projects
Use the Camel JAXB starter to auto-configure everything:
<dependency> <groupId>org.apache.camel.springboot</groupId> <artifactId>camel-jaxb-starter</artifactId> <version><!-- Match your Camel version --></version> </dependency>
Non-Spring Boot Projects
Manually register the JAXB data format in your Camel context:
import org.apache.camel.model.dataformat.JaxbDataFormat; // Create and configure the JAXB data format JaxbDataFormat jaxbFormat = new JaxbDataFormat(); jaxbFormat.setContextPath("your.package.name"); // Replace with the package containing your Currency class // Register it with your Camel context camelContext.getDataFormats().put("jaxb", jaxbFormat);
3. Double-Check Your Currency Class Annotations
Make sure your Currency class has the correct JAXB annotations mapped to your XML structure. For example:
import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlElement; @XmlRootElement(name = "currency") // Match the root element name in your XML public class Currency { private String code; private String name; private double exchangeRate; @XmlElement(name = "code") // Match the XML element name for this field public String getCode() { return code; } public void setCode(String code) { this.code = code; } // Add getters/setters with @XmlElement annotations for other fields, matching your XML structure }
4. Alternative: Use Jackson XML Binding
If JAXB is giving you too much trouble, Jackson's XML module is a great alternative for converting XML to Java objects. Here's how to set it up:
Add Jackson XML Dependency
<dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-xml</artifactId> <version>2.15.2</version> </dependency>
Sample Conversion Code
import com.fasterxml.jackson.dataformat.xml.XmlMapper; import java.io.InputStream; import java.net.URL; import java.util.List; public class CurrencyParser { public static void main(String[] args) throws Exception { // Fetch the XML from the URL URL xmlUrl = new URL("http://dnb.no/portalfront/datafiles/miscellaneous/csv/kursliste_ws.xml"); try (InputStream inputStream = xmlUrl.openStream()) { XmlMapper xmlMapper = new XmlMapper(); // Use a wrapper class if your XML has a root element containing multiple <currency> entries CurrencyList currencyList = xmlMapper.readValue(inputStream, CurrencyList.class); List<Currency> currencies = currencyList.getCurrencies(); // Do your后续操作 here } } } // Wrapper class for the XML root element import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; import java.util.List; @JacksonXmlRootElement(localName = "your-root-element-name") // Replace with your XML's root element public class CurrencyList { private List<Currency> currency; public List<Currency> getCurrencies() { return currency; } public void setCurrencies(List<Currency> currency) { this.currency = currency; } } // Updated Currency class for Jackson import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; public class Currency { @JacksonXmlProperty(localName = "code") private String code; @JacksonXmlProperty(localName = "name") private String name; @JacksonXmlProperty(localName = "rate") private double rate; // Getters and setters here }
If none of these steps fix your issue, share your full pom.xml code and a snippet of your XML structure, and I'll help you dig deeper.
内容的提问来源于stack exchange,提问作者user9126208

