DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Because the DevOps movement has redefined engineering responsibilities, SREs now have to become stewards of observability strategy.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Related

  • Dependency Injection in Spring
  • Deploying a Scala Play Application to Heroku: A Step-by-Step Guide
  • Dynamic Pricing Implementation: Price Rules and QCP in Salesforce CPQ
  • How To Create a Homescreen Widget in Android

Trending

  • MCP Servers: The Technical Debt That Is Coming
  • The Future of Java and AI: Coding in 2025
  • Tired of Spring Overhead? Try Dropwizard for Your Next Java Microservice
  • Scaling Microservices With Docker and Kubernetes on Production
  1. DZone
  2. Coding
  3. Languages
  4. JAXB and Namespace Prefixes

JAXB and Namespace Prefixes

By 
Blaise Doughan user avatar
Blaise Doughan
·
Dec. 03, 11 · Tutorial
Likes (8)
Comment
Save
Tweet
Share
244.0K Views

Join the DZone community and get the full member experience.

Join For Free

In a previous post I covered how to use namespace qualification with JAXB.  In this post I will cover how to control the prefixes that are used.  This is not covered in the JAXB (JSR-222) specification but I will demonstrate the extensions available in both the reference and EclipseLink MOXy implementations for handling this use case

Java Model

The following domain model will be used for this post.  The @XmlRootElement and @XmlElement annotation are used to specify the appropriate namespace qualification.

package blog.prefix;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(namespace="http://www.example.com/FOO")
public class Root {

    private String a;
    private String b;
    private String c;

    @XmlElement(namespace="http://www.example.com/BAR")
    public String getA() {
        return a;
    }

    public void setA(String a) {
        this.a = a;
    }

    @XmlElement(namespace="http://www.example.com/FOO")
    public String getB() {
        return b;
    }

    public void setB(String b) {
        this.b = b;
    }

    @XmlElement(namespace="http://www.example.com/OTHER")
    public String getC() {
        return c;
    }

    public void setC(String c) {
        this.c = c;
    }

}

Demo Code

We will use the following code to populate the domain model and produce the XML.

package blog.prefix;

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

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext ctx = JAXBContext.newInstance(Root.class);

        Root root = new Root();
        root.setA("A");
        root.setB("B");
        root.setC("OTHER");

        Marshaller m = ctx.createMarshaller();
        m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        m.marshal(root, System.out);
    }

}

 

Output

XML like the following is produced by default.  The JAXB implementation has arbitrarily assigned prefixes to the namespace URIs specified in the domain model:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:root
    xmlns="http://www.example.com/BAR"
    xmlns:ns2="http://www.example.com/FOO"
    xmlns:ns3="http://www.example.com/OTHER">
    <a>A</a>
    <ns2:b>B</ns2:b>
    <ns3:c>OTHER</ns3:c>
</ns2:root>

Specify Prefix Mappings with JAXB RI & Metro JAXB

The reference and Metro implementations of JAXB provide a mechanism called NamespacePrefixMapper to control the prefixes that will be assigned to namespaces.

NamespacePrefixMapper

package blog.prefix;

import com.sun.xml.internal.bind.marshaller.NamespacePrefixMapper;
//import com.sun.xml.bind.marshaller.NamespacePrefixMapper;

public class MyNamespaceMapper extends NamespacePrefixMapper {

    private static final String FOO_PREFIX = ""; // DEFAULT NAMESPACE
    private static final String FOO_URI = "http://www.example.com/FOO";

    private static final String BAR_PREFIX = "bar";
    private static final String BAR_URI = "http://www.example.com/BAR";

    @Override
    public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) {
        if(FOO_URI.equals(namespaceUri)) {
            return FOO_PREFIX;
        } else if(BAR_URI.equals(namespaceUri)) {
            return BAR_PREFIX;
        }
        return suggestion;
    }

    @Override
    public String[] getPreDeclaredNamespaceUris() {
        return new String[] { FOO_URI, BAR_URI };
    }

}

Demo Code

The NamespacePrefixMapper is set on an instance of Marshaller. I would recommend wrapping the setPropery call in a try/catch block so that your application does not fail if you change JAXB implementations.

package blog.prefix;

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

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext ctx = JAXBContext.newInstance(Root.class);

        Root root = new Root();
        root.setA("A");
        root.setB("B");
        root.setC("OTHER");

        Marshaller m = ctx.createMarshaller();
        m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        try {
            m.setProperty("com.sun.xml.internal.bind.namespacePrefixMapper", new MyNamespaceMapper());
            //m.setProperty("com.sun.xml.bind.namespacePrefixMapper", new MyNamespaceMapper());
        } catch(PropertyException e) {
            // In case another JAXB implementation is used
        }
        m.marshal(root, System.out);
    }
 }

Output

The resulting document now uses the NamespacePrefixMapper to determine the prefixes that should be used in the resulting document.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root
    xmlns:bar="http://www.example.com/BAR"
    xmlns="http://www.example.com/FOO"
    xmlns:ns3="http://www.example.com/OTHER">
    <bar:a>A</bar:a>
    <b>B</b>
    <ns3:c>OTHER</ns3:c>
</root>

 

Specify Prefix Mappings with EclipseLink JAXB (MOXy)

MOXy will use the namespace prefixes as they are defined on the @XmlSchema annotation.  In order for MOXy to be able to use the default namespace the elementFormDefault property on the @XmlSchema annotation must be set to XmlNsForm.QUALIFIED.

package-info

XmlSchema(
    elementFormDefault=XmlNsForm.QUALIFIED,
    namespace="http://www.example.com/FOO",
    xmlns={@XmlNs(prefix="bar",
                  namespaceURI="http://www.example.com/BAR")}
)
package blog.prefix;

import javax.xml.bind.annotation.XmlNs;
import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;

Output

The resulting document now uses the xmlns setting from the @XmlSchema annotation to determine the prefixes that should be used in the resulting document.

<?xml version="1.0" encoding="UTF-8"?>
<root
   xmlns="http://www.example.com/FOO"
   xmlns:ns0="http://www.example.com/OTHER"
   xmlns:bar="http://www.example.com/BAR">
   <bar:a>A</bar:a>
   <b>B</b>
   <ns0:c>OTHER</ns0:c>
</root>

Further Reading

If you enjoyed this post then you may also be interested in:

  • JAXB & Namespaces
  • Specifying EclipseLink MOXy as Your JAXB Provider

 

 

From http://blog.bdoughan.com/2011/11/jaxb-and-namespace-prefixes.html

Domain model Document Annotation Implementation POST (HTTP) Use case EclipseLink XML application

Opinions expressed by DZone contributors are their own.

Related

  • Dependency Injection in Spring
  • Deploying a Scala Play Application to Heroku: A Step-by-Step Guide
  • Dynamic Pricing Implementation: Price Rules and QCP in Salesforce CPQ
  • How To Create a Homescreen Widget in Android

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!