JAXB giving an exception when trying to Marshall with given order - java

i have a code similar to this
#XmlRootElement(name = "root")
#XmlType(propOrder={"param1", "param2""})
public class Demo{
public Demo() {
}
private int param1;
private String param2;
private String param3;
public int getparam1() {
return param1;
}
#XmlElement
public void setparam1(int param1) {
this.param1= param1;
}
//other setters and getters here except for param3
}
but it gives me
n4 counts of IllegalAnnotationExceptions
exception when i try to run the program (i have 6 parameters in total in original code and only 4 is use for Marshall )
What would be the reason for this?

There is an error in the #XmlType anntation:
#XmlType(propOrder={"param1", "param2","param3"})
If this not fix the problem, try to check the name of the properties in the propOrder OR directly use field accessor type:
#XmlRootElement(name = "root")
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(propOrder={"param1", "param2", "param3"})
public class Demo{
public Demo() {
}
private int param1;
private String param2;
private String param3;
//getter & setters without annotations
}

Related

How to initialize builder class members with dummy values while calling cls.builder.param().build()

I need to initialize my builder class members with some Dummy values while calling .param()
#Builder
public class MyQuery {
private String param1;
private String param1;
private String param1;
private String param1;
...
private String param100;
}
When I call the builder class like below, I want them to be initialized with some dummy value(or empty string) and the rest should be null. If I use the LOMBOK builder, it has to be initialized with some value as .param1("some string"). Is there any library which can help me here.
MyQuery query = MyQuery.builder()
.param1()
.param2()
.param3()
.build();
whichever parameter I call, should have some dummy value(non-null, could be empty as well).
After going through the lombok builder doc, I realized that I could do something as follows. Lombok will not generate the resources if a resource with the same name already exists. This approach will still reduce some of the boiler plate codes.
import lombok.Builder;
#Builder
public class MyQuery {
private static final String SOME_STRING = "This is needed";
private String paramWithNoSpecialCase // This is any other parameter, lombok will generate the builder for this.
private String param1;
private String param2;
private String param3;
public static class MyQueryBuilder {
public MyQuery.MyQueryBuilder param1() {
this.param1 = SOME_STRING;
return this;
}
public MyQuery.MyQueryBuilder param2() {
this.param1 = SOME_STRING;
return this;
}
public MyQuery.MyQueryBuilder param3() {
this.param1 = SOME_STRING;
return this;
}
}
}

jaxb delete list tag

I need to marshall a java class to get a xml, but i don't know how to delete a tag inside the one generated.
I have a class with an object list with this form
#XmlRootElement(name = "Element")
public class Element {
private List<Foo> foos;
#XmlElementWrapper("fooList")
public List<Foo> getfoos() {
return foos;
}
public void setFoos(List<Foo> foos) {
this.foos = foos;
}
}
And the class Foo of the list is lie this:
#XmlRootElement
public class Foo {
private String id;
private String code;
#XmlElement
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
#XmlElement
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
}
When marshalling to get xml I get this:
<Element>
<fooList>
<foos>
<string1>asd</string1>
<string2>qwe</string2>
</foos>
<foos>
<string1>poi</string1>
<string2>lkj</string2>
</foos>
</fooList>
</Element>
But I want to get it without the tag foos, like this:
<Element>
<fooList>
<string1>asd</string1>
<string2>qwe</string2>
<string1>poi</string1>
<string2>lkj</string2>
</fooList>
</Element>
Can anyone help me?
Thanks a lot!!
You could do something like this:
#XmlRootElement(name = "Element")
#XmlAccessorType(XmlAccessType.FIELD)
public class Element {
#XmlElementWrapper(name = "fooList")
#XmlElements({
#XmlElement(name = "id", type = Id.class),
#XmlElement(name = "code", type = Code.class),
})
private List<FooItem> foos;
public List<FooItem> getfoos() {
return foos;
}
public void setFoos(List<FooItem> foos) {
this.foos = foos;
}
}
and then Id and Code classes look similar:
public class Id implements FooItem {
#XmlValue
private String id;
public Id() {}
public Id(String id) {
this.id = id;
}
}
They are bounded by an interface that doesn't do much:
public interface FooItem { }
This structure will allow you to marshal into xml as the one you specified you need.
The challenge with the class structure you had is that class Foo had 2 fields and #XmlValue can be applied only to one field per class. So having 2 fields "forces" them to stand for #XmlElement and they in turn have to be children of an xml element. This is why you had the "intermediate" foo elements in your xml for each Foo instance in your List.

How to name properties of compex #RequestParams in #RestController?

Is it possible to rename the parameters used inside a GET webservice in spring? Like search.limitResults in the following example:
localhost:8080/firstname=test&search.limitResults=10
You get the idea. Can this be achieved?
#RestController
public class MyServlet {
#RequestMapping(value = "/", method = RequestMethod.GET)
private String test(RestParams p) {
}
}
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class RestParams {
private String firstname;
private String lastname;
//is that possible to nest?
#XmlElement(name = "search")
private MyComplexSearch search;
public MyComplexSearch getSearch() {return search;}
public void setSearch(MyComplexSearch) {this.search = search;}
#XmlRootElement(name = "search")
#XmlAccessorType(XmlAccessType.FIELD)
public class MyComplexSearch {
private int limitResults;
//some more
}
}
The request will not work with the code above. Instead one would have to use myComplexSearch as the objects name.
localhost:8080/firstname=test&myComplexSearch.limitResults=10
How can I redefine the name of the input property, without having to rename the java class itself?
Nested classes have to be static.
public static class MyComplexSearch

JAXB - How to specify xml attributes in binding Java Class

I know to create a JAXB Class to marshal/unmarshall an xml like this
<outertag>
<innerelement>
<innerElementDetail1>some value</inner-element-detail1>
</innerelement>
</outertag>
here is the class I created
#XmlRootElement(name ="outertag")
#XmlAccessorType(XmlAccessType.FIELD)
public class OuterTag {
#XmlElement(name = "innerelement")
private List<InnerElement> innerElemements
public static InnerElement{
private String innerElementDetail;
// getters and setters
}
}
If I have to have an attribute on one of the inner elements like this
<outertag>
<innerelement attribute1="attribute1value">
<innerElementDetail1>some value</inner-element-detail1>
</innerelement>
</outertag>
how do I do that ?
This should do it :
#XmlRootElement(name ="outertag")
#XmlAccessorType(XmlAccessType.FIELD)
public class OuterTag {
#XmlElement(name = "innerelement")
private List<InnerElement> innerElemements
public static InnerElement{
#XmlAttribute(name = "attribute1")
protected String attribute1;
private String innerElementDetail;
// getters and setters
}
}

issues while Unmarshalling using JaxB

I have the following XML file to unmarshall
<root>
<emp>Google</emp>
<emp>Yahoo</emp>
<xyz>random</xyz>
</root>
And i have used annotations in the following way,
#XmlRootElement(name = "root")
#XmlAccessorType(XmlAccessType.FIELD)
public class abc {
#XmlElement(name = "emp")
private String emp1;
#XmlElement(name = "emp")
private String emp2;
#XmlElement(name = "xyz")
private String xyz;
// added getters and setters for these fields
}
My problem is while i'm trying to get
obj.getEmp1(); // result is Yahoo instead of Google
obj.getEmp2(); // result is null.
Kindly clarify me, what am i doing wrong?
Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB (JSR-222) expert group.
The standard JAXB (JSR-222) annotations do not support mapping 2 different properties to the same XML element.
You could use EclipseLink JAXB (MOXy)'s #XmlPath extension for this use case.
import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.XmlPath;
#XmlRootElement(name = "root")
#XmlAccessorType(XmlAccessType.FIELD)
public class abc {
#XmlPath("emp[1]/text()")
private String emp1;
#XmlPath("emp[2]/text()")
private String emp2;
#XmlElement(name = "xyz")
private String xyz;
// added getters and setters for these fields
}
For More Information
http://blog.bdoughan.com/2010/07/xpath-based-mapping.html
http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html
If for whatever reason you cannot use MOXy, another solution would be to map the emp element as a list
#XmlRootElement(name = "root")
#XmlAccessorType(XmlAccessType.FIELD)
public class abc {
#XmlElement(name = "emp")
private List<String> emp;
#XmlElement(name = "xyz")
private String xyz;
// added getters and setters for these fields
}
And then use the following code to get the values:
obj.getEmp().get(0);
obj.getEmp().get(1);
But Blaise's solution is more elegant
You could have a String[] field and have your current accessor methods access the String[].
import javax.xml.bind.annotation.*;
#XmlRootElement(name = "root")
#XmlAccessorType(XmlAccessType.FIELD)
public class abc {
private String[] emp = new String[2];
private String xyz;
public String getEmp1() {
return emp[0];
}
public void setEmp1(String emp1) {
this.emp[0] = emp1;
}
public String getEmp2() {
return emp[1];
}
public void setEmp2(String emp2) {
this.emp[1] = emp2;
}
public String getXyz() {
return xyz;
}
public void setXyz(String xyz) {
this.xyz = xyz;
}
}
This might work.
<root>
<emp1>Google</emp1>
<emp2>Yahoo</emp2>
<xyz>random</xyz>
</root>
#XmlRootElement(name = "root")
#XmlAccessorType(XmlAccessType.FIELD)
public class abc {
#XmlElement(name = "emp1")
private String emp1;
#XmlElement(name = "emp2")
private String emp2;
#XmlElement(name = "xyz")
private String xyz;
}

Categories

Resources