Skip to content

OXM Jaxb2Unmarshaller to support non-root elements [SPR-10282] #14916

@spring-projects-issues

Description

@spring-projects-issues

David J. M. Karlsen opened SPR-10282 and commented

The JAXB2Unmarshaller should support JaxbElement/partial unmarshalling (e.g. classes not having a @RootElement).
#12586/SPR-9742 are analogue cases but for marshalling.
My usecase is using org.springframework.batch.item.xml.StaxEventItemReader in Spring Batch where I want to delegate unmarshalling of each event to the OXM unmarshaller.
This will fail if I cannot call the more specific unmarshalling method where the expected JAXB class can be provided.

This hack would make this possible by setting the expected class to return as a parameter to the Spring unmarshaller class:

public class ImprovedJaxb2Marshaller
    extends Jaxb2Marshaller
{
    private Class<?> partClass;

    public void setPartClass( Class<?> partClass )
    {
        this.partClass = partClass;
    }

    @Override
    public Object unmarshal( Source source, MimeContainer mimeContainer )
        throws XmlMappingException
    {
        if ( partClass == null )
        {
            return super.unmarshal( source, mimeContainer );
        }
        else
        {
            try
            {
                Unmarshaller jaxbUnmarshaller = createUnmarshaller();
                return source instanceof StAXSource ?
                                unmarshalStaxSource( jaxbUnmarshaller, source ) :
                                    jaxbUnmarshaller.unmarshal( source, partClass );
            }
            catch ( JAXBException e )
            {
                throw super.convertJaxbException( e );
            }
        }
    }

    private Object unmarshalStaxSource( Unmarshaller jaxbUnmarshaller, Source staxSource )
        throws JAXBException
    {
        XMLStreamReader streamReader = StaxUtils.getXMLStreamReader( staxSource );
        if ( streamReader != null )
        {
            return jaxbUnmarshaller.unmarshal( streamReader, partClass ).getValue();
        }
        else
        {
            XMLEventReader eventReader = StaxUtils.getXMLEventReader( staxSource );
            if ( eventReader != null )
            {
                return jaxbUnmarshaller.unmarshal( eventReader, partClass ).getValue();
            }
            else
            {
                throw new IllegalArgumentException( "StaxSource contains neither XMLStreamReader nor XMLEventReader" );
            }
        }
    }


Affects: 3.1.4

Referenced from: commits 283b3ee, de069d0, 23925ed

Metadata

Metadata

Assignees

Labels

in: dataIssues in data modules (jdbc, orm, oxm, tx)type: enhancementA general enhancement

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions