Sunteți pe pagina 1din 6

Java XML and JSON Binding: JAXB and Marshal...

Ms

http://blog.bdoughan.com/2010/12/jaxb-and-mars...

Siguiente blog

Crear blog

Acceder

Java XML and JSON Binding


Object-to-XML and object-to-JSON mapping using JAXB and EclipseLink MOXy.
Home

Contact Me

DECEMBER 20, 2010

JAXB and Marshal/Unmarshal Schema Validation

TRANSLATE

Select Language
Powered by

Translate

In a previous post I described how to validate an object model (mapped with JAXB annotations) against an XML schema using the
javax.xml.validation APIs. In this post I'll describe how to leverage those APIs during unmarshal and marshal operations.

TOTAL PAGEVIEWS

3292832
Java Model
ABOUT ME
The following object model will be used for this example. Notice how the model classes do not contain any validation specific
information.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

package blog.jaxb.validation;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Customer {

Blaise Doughan
Follow

Team lead for the


TopLink/EclipseLink JAXB & SDO
implementations, and the Oracle
representative on those
specifications.
View my complete profile

private String name;


private List<PhoneNumber> phoneNumbers =
new ArrayList<PhoneNumber>();
public String getName() {
return name;
}

GOOGLE+ FOLLOWERS

Blaise Doughan
Add to circles

public void setName(String name) {


this.name = name;
}
@XmlElement(name="phone-number")
public List<PhoneNumber> getPhoneNumbers() {
return phoneNumbers;
}
public void setPhoneNumbers(List<PhoneNumber> phoneNumbers) {
this.phoneNumbers = phoneNumbers;
}
}

797 have me in circles

View all

SEARCH THIS BLOG

Search
1
2
3
4
5

package blog.jaxb.validation;
public class PhoneNumber {

BLOG ARCHIVE

2013 (19)

2012 (26)

XML Schema (customer.xsd)


The following is our XML schema. The following are the interesting constraints:
The customer's name cannot be longer than 5 characters.
The customer cannot have more than 2 phone numbers.
1
2
3

1 de 6

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="customer">

2011 (41)
2010 (34)
December (5)
Represent String Values as
Element Names with
JAXB...
JAXB and
Marshal/Unmarshal
Schema Validation

26/01/16 15:13

Java XML and JSON Binding: JAXB and Marshal...


4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

http://blog.bdoughan.com/2010/12/jaxb-and-mars...

<xs:complexType>
<xs:sequence>
<xs:element name="name" type="stringMaxSize5"/>
<xs:element ref="phone-number" maxOccurs="2"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="phone-number">
<xs:complexType>
<xs:sequence/>
</xs:complexType>
</xs:element>
<xs:simpleType name="stringMaxSize5">
<xs:restriction base="xs:string">
<xs:maxLength value="5"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>

Extending JAXB Representing Metadata


as XML
Case Insensitive
Unmarshalling with JAXB
JAXB and Immutable
Objects
November (4)
October (4)
September (5)
August (10)
July (6)

LABELS

Atom (2)
Attachment (1)

ValidationEventHandler

Binder (1)
Bindings File (7)

JAXB reports validation events through the ValidationEventHandler. The event is represented as an instance of ValidationEvent, and

Case Insensitivity (1)

provides many details about the issue. The data is quite similar to what is available from a SAXParseException. Returning false from

CDATA (1)

the handleEvent method will cause the JAXB operation to stop, returning true will allow it to continue (if possible).

Choice (2)
Collection Property (5)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

package blog.jaxb.validation;
import javax.xml.bind.ValidationEvent;
import javax.xml.bind.ValidationEventHandler;
public class MyValidationEventHandler implements ValidationEventHandler {
public boolean handleEvent(ValidationEvent event) {
System.out.println("\nEVENT");
System.out.println("SEVERITY: " + event.getSeverity());
System.out.println("MESSAGE: " + event.getMessage());
System.out.println("LINKED EXCEPTION: " + event.getLinkedException());
System.out.println("LOCATOR");
System.out.println("
LINE NUMBER: " + event.getLocator().getLineNumber());
System.out.println("
COLUMN NUMBER: " + event.getLocator().getColumnNumber());
System.out.println("
OFFSET: " + event.getLocator().getOffset());
System.out.println("
OBJECT: " + event.getLocator().getObject());
System.out.println("
NODE: " + event.getLocator().getNode());
System.out.println("
URL: " + event.getLocator().getURL());
return true;
}
}

Comparison (3)
Database (1)
Date/Time (2)
DOM (2)
DTD (1)
Dynamic JAXB (1)
EclipseLink (52)
EclipseLink 2.3 (8)
EclipseLink 2.4 (8)
EclipseLink 2.5 (11)
EclipseLink 2.6 (4)
EJB (1)
Enum (1)
Extension (33)
Geocode (2)
GlassFish (2)
Inheritance (7)

Unmarshal Demo

Interface (2)

To enable validation an instance of Schema must be set on the Unmarshaller. To handle the events an
implementation of ValidationEventHandler must also be set.

JavaOne (1)

Java API for JSON Processing (2)


JAX-RS (15)
JAX-WS (4)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

2 de 6

package blog.jaxb.validation;
import
import
import
import
import
import

java.io.File;
javax.xml.XMLConstants;
javax.xml.bind.JAXBContext;
javax.xml.bind.Unmarshaller;
javax.xml.validation.Schema;
javax.xml.validation.SchemaFactory;

public class UnmarshalDemo {


public static void main(String[] args) throws Exception {
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = sf.newSchema(new File("customer.xsd"));
JAXBContext jc = JAXBContext.newInstance(Customer.class);

JAXB (89)
jaxb.properties (2)
JAXBElement (4)
JAXBIntrospector (1)
JAXBResult (1)
JAXBSource (4)
Jettison (2)
JPA (5)
JPA-RS (2)
JSON (21)
Map (2)
Mapping Bad XML (1)

Unmarshaller unmarshaller = jc.createUnmarshaller();


unmarshaller.setSchema(schema);
unmarshaller.setEventHandler(new MyValidationEventHandler());
Customer customer = (Customer) unmarshaller.unmarshal(new File("input.xml"));
}

Mapping File (10)


Marshaller (3)
MetadataSource (1)
MOXy (54)

26/01/16 15:13

Java XML and JSON Binding: JAXB and Marshal...

http://blog.bdoughan.com/2010/12/jaxb-and-mars...

Multi-Tenant (1)

Input (input.xml)

Namespaces (5)
Object Graphs (4)

1
2
3
4
5
6

<customer>
<name>Jane Doe</name>
<phone-number/>
<phone-number/>
<phone-number/>
</customer>

Predicate (1)
Release (4)
REST (15)
SAX (3)
SDO (2)
Specification (1)
StAX (3)

Output

TopLink (1)

The validation performed during the unmarshal raised 3 events. The first 2 events are related to the text value of the
"name" element being too long. The 3rd event is related to the extra "phone-number" element.

Twitter (1)
Unmarshaller (4)
Unmarshaller.Listener (1)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

UnmarshallerHandler (1)
EVENT
SEVERITY: 1
Validation (2)
MESSAGE: cvc-maxLength-valid: Value 'Jane Doe' with length = '8' is not facet-valid with respect to maxLen
WebLogic
LINKED EXCEPTION: org.xml.sax.SAXParseException: cvc-maxLength-valid: Value 'Jane Doe' with length
= (3)
LOCATOR
XJC (3)
LINE NUMBER: 3
XML Infoset (1)
COLUMN NUMBER: 25
OFFSET: -1
XML Schema (4)
OBJECT: null
XmlAccessorType (3)
NODE: null
URL: null
XmlAccessType (3)
XmlAdapter (13)
EVENT
SEVERITY: 1
XmlAnyElement (5)
MESSAGE: cvc-type.3.1.3: The value 'Jane Doe' of element 'name' is not valid.
XmlClassExtractor (1)
LINKED EXCEPTION: org.xml.sax.SAXParseException: cvc-type.3.1.3: The value 'Jane Doe' of element
LOCATOR
XmlElement (3)
LINE NUMBER: 3
XmlElementDecl (2)
COLUMN NUMBER: 25
OFFSET: -1
XmlElementRef (3)
OBJECT: null
XmlElements (2)
NODE: null
URL: null
XmlElementWrapper (3)

EVENT
SEVERITY: 1
MESSAGE: cvc-complex-type.2.4.d: Invalid content was found starting with element 'customer'
LINKED EXCEPTION: org.xml.sax.SAXParseException: cvc-complex-type.2.4.d: Invalid content was
LOCATOR
LINE NUMBER: 7
COLUMN NUMBER: 12
OFFSET: -1
OBJECT: null
NODE: null
URL: null

XmlEnum (1)
XmlEnumValue (1)
XmlID (1)

found startin
XmlIDREF (1)

XmlInlineBinaryData (2)
XmlInverseReference (2)
XmlList (1)
XmlMimeType (2)
XmlNamedObjectGraph (2)
XmlNamedSubgraph (2)
XmlNs (1)

Marshal Demo

XmlPath (5)
XmlRootElement (6)

To enable validation an instance of Schema must be set on the Marshaller. To handle the events an implementation
of ValidationEventHandler must also be set.

XmlSchema (2)
XmlSchemaType (1)
XmlTransformation (1)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

3 de 6

package blog.jaxb.validation;
import
import
import
import
import
import

java.io.File;
javax.xml.XMLConstants;
javax.xml.bind.JAXBContext;
javax.xml.bind.Marshaller;
javax.xml.validation.Schema;
javax.xml.validation.SchemaFactory;

public class MarshalDemo {


public static void main(String[] args) throws Exception {
Customer customer = new Customer();
customer.setName("Jane Doe");
customer.getPhoneNumbers().add(new PhoneNumber());
customer.getPhoneNumbers().add(new PhoneNumber());
customer.getPhoneNumbers().add(new PhoneNumber());

XmlTransient (3)
XmlType (4)
XmlValue (2)
XmlVariableNode (3)
XmlVirtualAccessMethods (4)

RELATED LINKS

My Website
EclipseLink MOXy
JAXB 2.2 (JSR-222)
SDO 2.1.1 (JSR-235)

SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = sf.newSchema(new File("customer.xsd"));

26/01/16 15:13

Java XML and JSON Binding: JAXB and Marshal...


22
23
24
25
26
27
28
29
30
31

http://blog.bdoughan.com/2010/12/jaxb-and-mars...

JAXBContext jc = JAXBContext.newInstance(Customer.class);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setSchema(schema);
marshaller.setEventHandler(new MyValidationEventHandler());
marshaller.marshal(customer, System.out);

FOLLOWERS
Join this site
with Google Friend Connect

Members (112) More

}
}

Output
The validation performed during the marshal raised 3 events. The first 2 events are related to the text value of the
"name" element being too long. The 3rd event is related to the extra "phone-number" element.

Already a member? Sign in

DZONE MVB

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
1
2
3
4
5
6

EVENT
SEVERITY: 1
MESSAGE: cvc-maxLength-valid: Value 'Jane Doe' with length = '8' is not facet-valid with respect to maxLen
LINKED EXCEPTION: org.eclipse.persistence.oxm.record.ValidatingMarshalRecord$MarshalSAXParseException: cvc
LOCATOR
LINE NUMBER: -1
COLUMN NUMBER: -1
JCG - RENOWNED GEEK
OFFSET: -1
OBJECT: blog.jaxb.validation.Customer@10045eb
NODE: null
URL: null
EVENT
SEVERITY: 1
MESSAGE: cvc-type.3.1.3: The value 'Jane Doe' of element 'name' is not valid.
LINKED EXCEPTION: org.eclipse.persistence.oxm.record.ValidatingMarshalRecord$MarshalSAXParseException: cvc
LOCATOR
LINE NUMBER: -1
STACK OVERFLOW
COLUMN NUMBER: -1
OFFSET: -1
OBJECT: blog.jaxb.validation.Customer@10045eb
NODE: null
URL: null
EVENT
JAVA AFFINITY MARK
SEVERITY: 1
MESSAGE: cvc-complex-type.2.4.d: Invalid content was found starting with element 'customer'
LINKED EXCEPTION: org.eclipse.persistence.oxm.record.ValidatingMarshalRecord$MarshalSAXParseException: cvc
LOCATOR
LINE NUMBER: -1
COLUMN NUMBER: -1
OFFSET: -1
OBJECT: blog.jaxb.validation.Customer@10045eb
NODE: null
URL: null
<customer>
<name>Jane Doe</name>
<phone-number/>
<phone-number/>
<phone-number/>
</customer>

CODERWALL

Further Reading
If you enjoyed this post, then you may also be interested in:
Validate a JAXB Object Model With an XML Schema

Posted by Blaise Doughan at 4:25 PM

+1 Recommend this on Google

Labels: JAXB, Marshaller, Unmarshaller, Validation, XML Schema

10 comments:
Macs March 31, 2011 at 2:03 PM
Hi,
why the Node field of Locator is always null?
How can I get it valorized?
Reply

4 de 6

26/01/16 15:13

Java XML and JSON Binding: JAXB and Marshal...

http://blog.bdoughan.com/2010/12/jaxb-and-mars...

chesteric31 May 19, 2011 at 7:12 AM


Hi, I've too needed these values... that are always null, why?
Reply

Blaise Doughan

May 19, 2011 at 4:57 PM

Hi Macs & chesteric31,


The node and url properties are not always available to be set on the locator. That being said, I believe there are currently
use cases where they are available and are not being returned. I have entered the following EclipseLink bug for this issue:
- https://bugs.eclipse.org/346542
-Blaise
Reply

Randall Kwiatkowski August 17, 2011 at 9:33 AM


Hi, very interesting article. I was wondering if this type of validation could also be done for Unmarshalling using a
streamReader. (StAX and JAXB)
Reply

Blaise Doughan

August 17, 2011 at 10:21 AM

Hi Randall,
Schema validation for marshalling and unmarshalling is available for streams, DOM, SAX, and StAX.
-Blaise
Reply

Brad June 1, 2012 at 1:29 PM


I am developing web service using JAX WS,
my coursework is to utilise web services to compose a travel agency. The travel agency consists of three independent
services: flight booking, hotel reservation, and currency conversion. i will build the first two application services by myself
but i should consume a publically available service for currency conversion.
My issue is getting the flight information from java objects to xml document,
would you please hlp me in this issue,
Thanks for your time.
Chao Fan,
@WebMethod(operationName = Flightfile)
public Boolean CreateItinerary() {
Flights ss = new Flights();
List newSegments = (List) setSegments.getFlightSegments();
ss toflights;
toflights = new ss();
toflights.setAirline(American Airlines);
toflights.setOriginCity(long beach); toflights.setDestinationCity(aus islands);
try {
javax.xml.bind.JAXBContext jaxbCtx =
javax.xml.bind.JAXBContext.newInstance(ss.getClass().getPackage().getName());
javax.xml.bind.Marshaller marshaller = jaxbCtx.createMarshaller();
marshaller.setProperty(javax.xml.bind.Marshaller.JAXB_ENCODING, UTF-8); //NOI18N
marshaller.setProperty(javax.xml.bind.Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
File flightstore = new File(file.xml);
marshaller.marshal(ss, flightstore);
Reply

Anonymous December 4, 2012 at 2:16 AM


I have one doubt that if I had actually used JAXB and gotmy classes\stubs from a schema (e.g. abc.xsd).. then those
classes are tightly linked to that schema.
So, is there any need to again do a schema validation, because anyway now my classes\beans are already tightly linked
to the schema using which they were generated.
Reply

5 de 6

26/01/16 15:13

Java XML and JSON Binding: JAXB and Marshal...

http://blog.bdoughan.com/2010/12/jaxb-and-mars...

Replies
Blaise Doughan

December 4, 2012 at 3:22 PM

Agreed that an object model generated from an XML schema ensures that most of the structure will be valid
against the XML schema. There are a few items that you may still wish to validate:
- Collections with a maxOccurs other that unbounded aren't exceeded.
- The values that correspond to simple types with facets are valid.
- Non-nillable required elements are present in the document.
- etc.
Reply

Chris L. July 29, 2013 at 3:01 PM


Thanks for all the great code! Please add a variation that shows how to use an XML catalog, which allows mapping of
URIs to local files for convenience when coping with un-hosted schemas and disconnected computers.
Reply
Replies
Blaise Doughan

July 29, 2013 at 3:28 PM

Hi Chris,
I will try to add a post on this. In the mean time you can leverage the setResourceResolver method on
SchemaFactory for this.
http://docs.oracle.com/javase/7/docs/api/javax/xml/validation
/SchemaFactory.html#setResourceResolver%28org.w3c.dom.ls.LSResourceResolver%29
You will need to implement an LSResourceResolver to pull in the local schemas:
- http://docs.oracle.com/javase/7/docs/api/org/w3c/dom/ls/LSResourceResolver.html
-Blaise
Reply

Comment as:

Publish

Google Account

Preview

Note: Only a member of this blog may post a comment.

Links to this post


Create a Link

Newer Post

Home

Older Post

Subscribe to: Post Comments (Atom)

DISCLAIMER

The views expressed here are my own and do not necessarily reflect those of my employer.

Picture Window template. Powered by Blogger.

6 de 6

26/01/16 15:13

S-ar putea să vă placă și