JAXB: Interception during disassembly?

I have a typical web service using JAX-RS and JAXB, and after disassembling, I would like to know which setters were explicitly called by JAXB. This effectively lets me know which elements were included in the document provided by the caller.

I know that maybe I can solve this with XmlAdapter, but I have many classes in several different packages, and I do not want to create adapters for each of them. I also do not want to put hooks in each setter. If possible, I would like a general solution. Please note that all my classes are configured to use getters and setters; none of them use fields for access type.

My service uses Jersey 2.4, Spring 3.2, and MOXy 2.5.1, so if there is something that can be used from any of them, it's all better. Our initial thought was that we could dynamically create a factory class (similar to what it supports @XmlType) that returns a proxy object that intercepts setters. We thought that this could happen using the concept MetadataSourcein MOXy, but this is not possible.

Does anyone have any idea?

+4
source share
1 answer

My service uses Jersey 2.4, Spring 3.2, and MOXy 2.5.1, so if there is anything you can use from any of them to make things better.

Create your own EclipseLink AttributeAccessor

MOXy ( EclipseLink) AttributeAccessor . , .

import org.eclipse.persistence.exceptions.DescriptorException;
import org.eclipse.persistence.mappings.AttributeAccessor;

public class MyAttributeAccessor extends AttributeAccessor {

    private AttributeAccessor attributeAccessor;

    public MyAttributeAccessor(AttributeAccessor attributeAccessor) {
        this.attributeAccessor = attributeAccessor;
    }

    @Override
    public Object getAttributeValueFromObject(Object domainObject)
            throws DescriptorException {
        return attributeAccessor.getAttributeValueFromObject(domainObject);
    }

    @Override
    public void setAttributeValueInObject(Object domainObject, Object value)
            throws DescriptorException {
        System.out.println("Thread: " + Thread.currentThread().getId() + " - Set value:  " + value + " on property: " + attributeAccessor.getAttributeName() + " for object: " + domainObject);
        attributeAccessor.setAttributeValueInObject(domainObject, value);
    }

}

MOXy, AttributeAccessor

SessionEventListener , AttributeAccessor. JAXBContext.

    Map<String, Object> properties = new HashMap<String, Object>(1);
    properties.put(JAXBContextProperties.SESSION_EVENT_LISTENER, new SessionEventAdapter() {

        @Override
        public void postLogin(SessionEvent event) {
            Project project = event.getSession().getProject();
            for(ClassDescriptor descriptor : project.getOrderedDescriptors()) {
                for(DatabaseMapping mapping : descriptor.getMappings()) {
                    mapping.setAttributeAccessor(new MyAttributeAccessor(mapping.getAttributeAccessor()));
                }
            }
            super.preLogin(event);
        }

    });

    JAXBContext jc = JAXBContext.newInstance(new Class[] {Foo.class}, properties);

JAX-RS ContextResolver JAXBContext

JAX-RS, ContextResolver JAXBContext.


Java- (Foo)

, ( ).

import javax.xml.bind.annotation.*;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Foo {

    private String bar;
    private String baz;

}

import java.io.StringReader;
import java.util.*;
import javax.xml.bind.*;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.jaxb.JAXBContextProperties;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.sessions.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        Map<String, Object> properties = new HashMap<String, Object>(1);
        properties.put(JAXBContextProperties.SESSION_EVENT_LISTENER, new SessionEventAdapter() {

            @Override
            public void postLogin(SessionEvent event) {
                Project project = event.getSession().getProject();
                for(ClassDescriptor descriptor : project.getOrderedDescriptors()) {
                    for(DatabaseMapping mapping : descriptor.getMappings()) {
                        mapping.setAttributeAccessor(new MyAttributeAccessor(mapping.getAttributeAccessor()));
                    }
                }
                super.preLogin(event);
            }

        });

        JAXBContext jc = JAXBContext.newInstance(new Class[] {Foo.class}, properties);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        StringReader xml = new StringReader("<foo><bar>Hello World</bar></foo>");
        Foo foo = (Foo) unmarshaller.unmarshal(xml);
    }

}

Thread: 1 - Set value:  Hello World on property: bar for object: forum21044956.Foo@37e47e38

UPDATE

, , . -, domainObject 0 . , .

, , toString() , .

-, , , . .

. , .

-, JAXBContext, , . ?

JAXBContext, .

+2

All Articles