I have a sample rest
application that runs on tomcat
.
When replying - an object of type ActionError
is sent to client as a json
string.
ActionError
will pass to the client an
Array
ofStrings
2Array
ofFieldError
s- An arbitrary
Object
payload (defined as generic type).
In my test I pass as a payload
an object of type Employee
.
With the above arrangement - everything works fine. And I am getting results like:
{"actionErrors":["everything is ok"],"fieldErrors":null,"payload":{"empName":"Jony","empNo":"E3","position":"Manager"}}
However, if I remove the Array
of FieldError
(private ArrayList<FieldError> fieldErrors;
) part, so - that ActionError
now only contains:
1.Array
of Strings
2.Object
payload
then strangely the payload
is not serialised properly and I get:
{"actionErrors":["everything is ok"],"payload":"com.mycompany.mavenwebproject.model.Employee@41a8e0d9"}
What cant be causing this ? Any ideas on how could it be fixed?
Thanks.
Below are the class definitions:
ActionError.java
@XmlRootElement(name = "actionError")
@XmlAccessorType(XmlAccessType.FIELD)
public class ActionError<T> {
private ArrayList<String> actionErrors;
private ArrayList<FieldError> fieldErrors;
private T payload;
/**
* @return the actionErrors
*/
public ArrayList<String> getActionErrors() {
return actionErrors;
}
/**
* @param actionErrors the actionErrors to set
*/
public void setActionErrors(ArrayList<String> actionErrors) {
this.actionErrors = actionErrors;
}
/**
* @return the fieldErrors
*/
public ArrayList<FieldError> getFieldErrors() {
return fieldErrors;
}
/**
* @param fieldErrors the fieldErrors to set
*/
public void setFieldErrors(ArrayList<FieldError> fieldErrors) {
this.fieldErrors = fieldErrors;
}
public void addFieldError(String fieldName,String errorMessage){
if (this.fieldErrors==null)
this.fieldErrors = new ArrayList<>();
this.fieldErrors.add(new FieldError(fieldName, errorMessage));
}
public void addActionError(String errorMessage){
if (this.actionErrors==null)
this.actionErrors = new ArrayList<>();
this.actionErrors.add(errorMessage);
}
public boolean hasErrors(){
return (fieldErrors!=null && !fieldErrors.isEmpty()) || (actionErrors!=null && !actionErrors.isEmpty());
}
/**
* @return the payload
*/
public T getPayload() {
return payload;
}
/**
* @param payload the payload to set
* @return
*/
public ActionError setPayload(T payload) { //Class<T> payloadClass
this.payload = payload;
return this;
}
}
FieldError.java
@XmlRootElement(name = "fieldError")
@XmlAccessorType(XmlAccessType.FIELD)
public class FieldError {
private String fieldName;
private String fieldError;
/**
* @return the fieldName
*/
public String getFieldName() {
return fieldName;
}
/**
* @param fieldName the fieldName to set
*/
public void setFieldName(String fieldName) {
this.fieldName = fieldName;
}
/**
* @return the fieldError
*/
public String getFieldError() {
return fieldError;
}
/**
* @param fieldError the fieldError to set
*/
public void setFieldError(String fieldError) {
this.fieldError = fieldError;
}
public FieldError(String fieldName, String fieldError) {
this.fieldName = fieldName;
this.fieldError = fieldError;
}
}
Employee.java
@XmlRootElement(name = "employee")
@XmlAccessorType(XmlAccessType.FIELD)
public class Employee {
private String empNo;
private String empName;
private String position;
// This default constructor is required if there are other constructors.
public Employee() {
}
public Employee(String empNo, String empName, String position) {
this.empNo = empNo;
this.empName = empName;
this.position = position;
}
public String getEmpNo() {
return empNo;
}
public void setEmpNo(String empNo) {
this.empNo = empNo;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public String getPosition() {
return position;
}
public void setPosition(String position) {
this.position = position;
}
}
I managed to run the above both on Glassfish 4.1.1 and Tomcat 8 using following dependencies:
Tomcat 8
Glassfish 4.1.1
Also my web.xml has following entries:
Also To run on Glassfish 3.1.2 Jersey 1.x must be used, and there is no need for Genson.
So, the pom.xml dependencies look like this:
and the web.xml entry :
Edit 1
In order to forgo the use of
genson
onglassfish 4.1.1
a missing libraryjackson-module-jaxb-annotations-2.5.4.jar
should be added to Glassfish modules directory. Otherwisewill be thrown. But if the above jar is added then the pom for the Glassfish could be the following:
Glassfish 4.1.1 (missing library bug fixed)
Edit 2.
If one wants to use jackson 2 on Glassfish 3.1.2 with jersey 1 then the following configuration is in order
pom.xml
and the web.xml becomes