This is what I'm doing:
#XmlType(name = "foo")
#XmlAccessorType(XmlAccessType.NONE)
public final class Foo {
#XmlElement(name = "title")
public String title() {
return "hello, world!";
}
}
JAXB complains:
com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions
JAXB annotation is placed on a method that is not a JAXB property
this problem is related to the following location:
at #javax.xml.bind.annotation.XmlElement(nillable=false, name=title, required=false, defaultValue=, type=class javax.xml.bind.annotation.XmlElement$DEFAULT, namespace=##default)
at com.example.Foo
What to do? I don't want (and can't) rename the method.
There are a couple of different options:
Option #1 - Introduce a Field
If the value is constant as it is in your example, then you could introduce a field into your domain class and have JAXB map to that:
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
#XmlType(name = "foo")
#XmlAccessorType(XmlAccessType.NONE)
public final class Foo {
#XmlElement
private final String title = "hello, world!";
public String title() {
return title;
}
}
Option #2 - Introduce a Property
If the value is calculated then you will need to introduce a JavaBean accessor and have JAXB map to that:
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
#XmlType(name = "foo")
#XmlAccessorType(XmlAccessType.NONE)
public final class Foo {
public String title() {
return "hello, world!";
}
#XmlElement
public String getTitle() {
return title();
}
}
There might be a better way, but the first solution that comes to mind is:
#XmlElement(name = "title")
private String title;
public String getTitle() {
return title();
}
Why is it you can't name your method according to Java conventions anyway?
Related
I am trying to deserialize xml string into object but ran across strange problem. Everything is being serialized as intended, however when deserializing field which originates from parent class always returns null.
MyNffgDescriptor is a class which contain VNFTypeReader as attribute. All fields are deserialized correctly, VNFTypeReader ones as well except the name which is passed from parent class (NamedEntityReaderImpl) and it returns null.
Parent class
package it.polito.dp2.NFV.sol3.client1.implementations;
import java.io.Serializable;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import it.polito.dp2.NFV.NamedEntityReader;
#XmlAccessorType(XmlAccessType.NONE)
public class NamedEntityReaderImpl implements NamedEntityReader, Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private String entityName;
public NamedEntityReaderImpl() {
this.entityName = "";
}
public NamedEntityReaderImpl(String name) {
this.entityName = name;
}
#Override
public String getName() {
return this.entityName;
}
}
Child class
package it.polito.dp2.NFV.sol3.client1.implementations;
import java.io.Serializable;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import it.polito.dp2.NFV.VNFTypeReader;
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class VNFTypeReaderImpl extends NamedEntityReaderImpl implements Serializable,VNFTypeReader {
/**
*
*/
private static final long serialVersionUID = 1L;
#XmlElement
private int requiredMemory;
#XmlElement
private int requiredStorage;
#XmlElement
private it.polito.dp2.NFV.FunctionalType funcType;
public VNFTypeReaderImpl() {
super(null);
this.requiredMemory = 0;
this.requiredStorage = 0;
this.funcType = null;
}
public VNFTypeReaderImpl(VNFTypeReader reader) {
super(reader.getName());
this.requiredMemory = reader.getRequiredMemory();
this.requiredStorage = reader.getRequiredStorage();
this.funcType = reader.getFunctionalType();
}
#Override
public int getRequiredMemory() {
return this.requiredMemory;
}
#Override
public int getRequiredStorage() {
return this.requiredStorage;
}
#Override
public it.polito.dp2.NFV.FunctionalType getFunctionalType() {
return this.funcType;
}
#Override
#XmlElement(name="name", required=true)
public String getName() {
return super.getName();
}
}
This is the example of xml string I am trying to deserialize:
<?xml version="1.0" encoding="UTF-8"?>
<myNffgDescriptor>
<nodeList id="0">
<funcReader>
<requiredMemory>620</requiredMemory>
<requiredStorage>100</requiredStorage>
<funcType>WEB_SERVER</funcType>
<name>WEBSERVERt</name>
</funcReader>
<hostName>H3</hostName>
<linksList source="0" destination="10" />
<linksList source="0" destination="11" />
<linksList source="0" destination="8" />
</nodeList>
</myNffgDescriptor>
Place where unmarshalling occurs:
jaxbContext = JAXBContext.newInstance(MyNffgDescriptor.class);
unmarshaller = jaxbContext.createUnmarshaller();
StringReader reader = new StringReader(nffg);
MyNffgDescriptor nffgDesc = (MyNffgDescriptor) unmarshaller.unmarshal(reader);
Change XmlAccessType.NONE to XmlAccessType.FIELD on parent
class NamedEntityReaderImpl.
Also you could just add on class NamedEntityReaderImpl an annotation above the field:
#XmlElement(name= "name")
private String entityName;
Do either changes (or both) and it would work
I wants to make xml from javabean like below:
<tag2>message</tag2>
<tag3>message</tag3>
<tag4 id='UNIQUE MT ID 1'>MOBILE No.</tag4>
I tried below code in javabean:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "name", propOrder = {"tag2", "tag3", "tag4"})
public class newBean {
#XmlElement(required = true)
private List<String> tag2;
#XmlElement(required = true)
private List<String> tag3;
#XmlElement(required = true)
private List<String> tag4;
#XmlPath("tag4/#id")
private List<String> id;
public List<String> getTag2() {
return tag2;
}
public void setTag2(List<String> tag2) {
this.tag2 = tag2;
}
public List<String> gettag4() {
return tag4;
}
public void settag4(List<String> tag4) {
this.tag4 = tag4;
}
public List<String> getId() {
return id;
}
public void setId(List<String> identifier) {
this.id = identifier;
}
public List<String> gettag3() {
return tag3;
}
public void settag3(List<String> tag3) {
this.tag3 = tag3;
}
}
I am getting below error:
Errorcom.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
Property id is present but not specified in #XmlType.propOrder
this problem is related to the following location:
at private java.util.List model.newBean.id
at model.newBean
Please help me.I am using #XmlPath tag and generating error.I searched alot and found that #XmlPath usage is same as above i used but still getting error.
Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB (JSR-222) expert group.
About #XmlPath
#XmlPath is a EclipseLink JAXB (MOXy) extension and requires that you are using MOXy as your JAXB provider:
http://blog.bdoughan.com/2010/07/xpath-based-mapping.html
http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html
Valid Use Case #1
import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.XmlPath;
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "name", propOrder = { "tag4", "id" })
public class newBean {
#XmlElement(required=true)
String tag4;
#XmlPath("tag4/#id")
String id;
}
Valid Use Case #2
import java.util.List;
import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.XmlPath;
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "name", propOrder = { "tag4", "id" })
public class newBean {
#XmlPath("tag4/#id")
List<String> id;
}
Invalid Use Case
import java.util.List;
import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.XmlPath;
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "name", propOrder = { "tag4", "id" })
public class newBean {
#XmlElement(required=true)
List<String> tag4;
#XmlPath("tag4/#id")
List<String> id;
}
Mapping Your Use Case
You could introduce an object that corresponds to the tag4 element that has two properties corresponding to the id attribute and text. This would work with any JAXB (JSR-222) implementation.
newBean
import java.util.List;
import javax.xml.bind.annotation.*;
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "name", propOrder = { "tag4", "id" })
public class newBean {
List<Tag4> tag4;
}
Tag4
import javax.xml.bind.annotation.*;
#XmlAccessorType(XmlAccessType.FIELD)
public class Tag4 {
#XmlAttribute
private String id;
#XmlValue
private String value;
}
For More Information
http://blog.bdoughan.com/2011/06/jaxb-and-complex-types-with-simple.html
I have a Customer and CustomerFullAddress class and i am using JAXB to try to produce an XML file
<Customer CustomerID="GREAL">
<CompanyName>Great Lakes Food Market</CompanyName>
<ContactName>Howard Snyder</ContactName>
<ContactTitle>Marketing Manager</ContactTitle>
<Phone>(503) 555-7555</Phone>
<FullAddress>
<Address>2732 Baker Blvd.</Address>
<City>Eugene</City>
<Region>OR</Region>
<PostalCode>97403</PostalCode>
<Country>USA</Country>
</FullAddress>
</Customer>
The Customer Class looks like below (Its not a full implementation)
package org.abc.customers;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
#XmlRootElement(name = "customer")
#XmlType (propOrder = { "companyName", "contactName", "contactTitle", "phone" })
public class Customer {
*#XmlElement(name = "customerfulladdress")
private CustomerFullAddress custAdd;*
private String companyName;
private String contactName;
private String contactTitle;
private int phone;
public CustomerFullAddress getCustAddress() {
return custAdd;
}
public void setCustAddress(CustomerFullAddress custAdd) {
this.custAdd = custAdd;
}
...
While the CustomerFullAddress is
package org.abc.customers;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
#XmlRootElement(name = "customerfulladdress")
//If you want you can define the order in which the fields are written
//Optional
#XmlType(propOrder = { "address", "city", "region", "postalCode", "country" })
public class CustomerFullAddress {
private String address;
...
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
.....
}
and the error is
Exception in thread "main"
com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 2
counts of IllegalAnnotationExceptions Property custAdd is present but
not specified in #XmlType.propOrder this problem is related to the
following location: at private
org.abc.customers.CustomerFullAddress
org.abc.customers.Customer.custAdd at
org.abc.customers.Customer Property custAddress is present but not
specified in #XmlType.propOrder this problem is related to the
following location: at public
org.abc.customers.CustomerFullAddress
org.abc.customers.Customer.getCustAddress() at
org.abc.customers.Customer
Thanks for having a look!
From the JavaDoc for #XmlType:
propOrder
All of the JavaBean properties being mapped to XML Schema elements must be listed.
You need to add the CustomerFullAddress property to the propOrder for Customer.
Hello i have the following xml:
With the following code:
How can I get the attribute DispalyName of each element without creating new class for Down and Up and using #xmlAttribute.
I can solve it by adding new 2 classes UpElement and DownElement and for each class get the the #xmlAttribute but i want to it in once class.
Code Example:
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement(name = "StatusesList")
#XmlAccessorType(javax.xml.bind.annotation.XmlAccessType.FIELD)
public class StatusesListElement
{
#XmlElement(name = "Down")
private String down = "";
#XmlElement(name = "Up")
private String up = "";
public String getDown()
{
return down;
}
public void setDown(String down)
{
this.down = down;
}
public String getUp()
{
return up;
}
public void setUp(String up)
{
this.up = up;
}
}
Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB 2 (JSR-222) expert group.
Using EclipseLink JAXB (MOXy)
You could use the #XmlPath extension in MOXy to map this use case:
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement(name = "StatusesList")
#XmlAccessorType(javax.xml.bind.annotation.XmlAccessType.FIELD)
public class StatusesListElement
{
#XmlPath("Down/#DisplayName")
private String down = "";
#XmlElement(name = "Up/#DisplayName")
private String up = "";
}
Using any JAXB Implementation
You could use an XmlAdapter for this use case. Below is a link to an answer I gave that demonstrates how this can be done:
JAXB Element mapping
I'm switching from Castor to JAXB2 to perform marshaling/unmarshaling between XML and Java object. I'm having problem trying to configure a collection of polymorphic objects.
Sample XML
<project name="test project">
<orange name="fruit orange" orangeKey="100" />
<apple name="fruit apple" appleKey="200" />
<orange name="fruit orange again" orangeKey="500" />
</project>
Project class
The oranges list works fine, I'm seeing 2 oranges in the list. But, I'm not sure how to configure fruitList. The fruitList should have 3 fruit: 2 oranges and 1 apple.
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class Project {
#XmlAttribute
private String name;
#XmlElement(name = "orange")
private List<Orange> oranges = new ArrayList<Orange>();
// Not sure how to configure this... help!
private List<Fruit> fruitList = new ArrayList<Fruit>();
}
Fruit class
Fruit is an abstract class. For some reason, defining this class as an abstract seems to be causing a lot of problems.
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public abstract class Fruit {
#XmlAttribute
private String name;
}
Orange class
public class Orange extends Fruit {
#XmlAttribute
private String orangeKey;
}
Apple class
public class Apple extends Fruit {
#XmlAttribute
private String appleKey;
}
How do I configure my fruitList in Project to achieve what I want here?
Thanks much!
You want to leverage #XmlElementRef this is corresponds to the XML schema concept of substitution groups which corresponds to your question.
Step 1 - Using #XmlElementRef
The fruitList property is annotated with #XmlElementRef:
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElementRef;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class Project {
#XmlAttribute
private String name;
#XmlElementRef
private List<Fruit> fruitList = new ArrayList<Fruit>();
}
Step 2 - Annotate Apple and Orange with #XmlRootElement
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class Apple extends Fruit {
#XmlAttribute
private String appleKey;
}
and
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class Orange extends Fruit {
#XmlAttribute
private String orangeKey;
}
Demo Code
The following code can be used to demonstrate the solution:
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Project.class, Apple.class, Orange.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
Project project = (Project) unmarshaller.unmarshal(new File("input.xml"));
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(project, System.out);
}
}
For More Information:
http://bdoughan.blogspot.com/2010/11/jaxb-and-inheritance-using-substitution.html
After futzing around... I think I got it working now:-
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class Project {
#XmlAttribute
private String name;
// this has to be commented out, or else oranges won't show up in fruitList
// #XmlElement(name = "orange")
// private List<Orange> oranges = new ArrayList<Orange>();
#XmlElements({
#XmlElement(name = "orange", type = Orange.class),
#XmlElement(name = "apple", type = Apple.class)
})
private List<Fruit> fruitList = new ArrayList<Fruit>();
}
Put XmlAnyElement annotation:
#XmlAnyElement(lax = true)
private List<Fruit> fruitList = new ArrayList<Fruit>();