Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert jaxb xml message to base type in apache camel (java)

I'm trying to build a global error handler for all of my camel (v 2.13.1) routes. If an exception bubbles up to this error handler it will log it and send the team an email.

I'm having problems with polymorphism and my jaxb annotated messages, though. All of my messages look similar to this:

@XmlRootElement
@XmlAccessorType(value = XmlAccessType.PROPERTY)
@XmlType(propOrder = {})
static abstract class Request {

    @XmlElement(required = true)
    abstract String getThing();
    abstract void setThing(final String thing);
}

@XmlRootElement
@XmlAccessorType(value = XmlAccessType.PROPERTY)
@XmlType(propOrder = {})
static class MyRequest extends Request {

    private String name;
    @XmlElement(required = true)
    public String getName() {
        return name;
    }
    public void setName(final String name) {
        this.name = name;
    }

    private String thing;
    @Override
    @XmlElement(required = true)
    public String getThing() { 
        return thing;
    }
    public void setThing(final String thing) {
        this.thing = thing;
    }
}

My error route I'm playing around with looks like this:

from (errorQueue)
    .convertBodyTo(Request.class)
    .process(new Processor() {
        @Override
        public void process(Exchange exchange) throws Exception {
            final Request req = exchange.getIn().getBody(Request.class);
            log.info("name = {}, thing = {}", null, req.getThing());
        }
    });

Depending on the component that fails, the message could be a MyRequest, a MyOtherRequest, etc. All of the messages inherit from Request. Here is the particular message I am testing with:

<myRequest>
    <name>some_name</name>
    <thing>some_thing</thing>
</myRequest>

When I run this I get errors like:

Caused by: javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"myRequest"). Expected elements are <{}request>

How can I convert jaxb annotated messages from various types to some base type so that I can get to the information from the base class?

I would prefer using an interface instead of a base class, but I had similar results.

like image 679
grinch Avatar asked Jul 12 '26 10:07

grinch


1 Answers

Metadata may not be getting processed for the MyRequest class, as subclasses are not in. Try adding the @XmlSeeAlso annotation on the super class:

@XmlRootElement
@XmlAccessorType(value = XmlAccessType.PROPERTY)
@XmlType(propOrder = {})
@XmlSeeAlso({MyRequest.class})
static abstract class Request {
like image 140
bdoughan Avatar answered Jul 13 '26 23:07

bdoughan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!