Reputation: 112
I am trying to send a response from spring mvc controller to jsp page and I got an exception
Firstly, I tried to return a list to jsp page
code for list:
@RequestMapping(value = "/Users", method = RequestMethod.POST)
@ResponseBody
public List<Users> getUsers(@RequestParam(value = "intermediate" ,required = false) String intermediate)throws java.text.ParseException{
List<Users> list = null;
int intermediateSelection = Integer.parseInt(intermediate);
list = getUsersBySelection(IntermediateSelection) //This will return list of users
return list;
}
Then I tried to return a JSONObject to the JSP Page
Code for JSONObject :
@RequestMapping(value = "/Users", method = RequestMethod.POST)
@ResponseBody
public JSONObject getUsers(@RequestParam(value = "intermediate" ,required = false) String intermediate) throws java.text.ParseException{
List<Users> list = null;
int IntermediateSelection = Integer.parseInt(intermediate);
list = getUsersBySelection(IntermediateSelection); //This will return list of users
Iterator<Users> iterator=list.iterator();
JSONObject UsersJSON = new JSONObject();
JSONArray usersArray = new JSONArray();
while (iterator.hasNext()) {
Users users = iterator.next();
JSONObject object = new JSONObject();
object.put("Id", users.getUserId());
object.put("Name", users.getUserName());
object.put("Group", users.getGroup());
usersArray.add(object);
}
UsersJSON.put("users", usersArray);
//System.out.println(UsersJSON.toString());
return UsersJSON;
}
Either of them didn't work for me. I got an exception like this.
org.apache.catalina.core.StandardWrapperValve invoke
java.lang.StackOverflowError
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLoader.java:2918)
at org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:1174)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1669)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1547)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:682)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:156)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:132)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:94)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:24)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:575)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:666)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:156)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:575)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:666)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:156)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:132)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:94)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:24)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:575)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:666)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:156)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:575)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:666)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:156)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:132)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:94)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:24)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:575)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:666)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:156)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:575)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:666)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:156)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:132)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:94)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:24)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:575)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:666)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:156)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:575)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:666)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:156)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:132)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:94)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:24)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:575)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:666)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:156)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:575)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:666)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:156)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:132)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:94)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:24)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:575)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:666)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:156)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:575)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:666)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:156)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:132)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:94)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:24)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:575)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:666)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:156)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:575)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:666)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:156)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:132)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:94)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:24)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:575)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:666)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:156)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:575)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:666)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:156)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:132)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:94)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:24)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:575)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:666)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:156)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:575)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:666)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:156)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:132)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:94)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:24)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:575)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:666)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:156)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:575)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:666)
Users Pojo:
@Entity
@Table(name = "Users")
public class Users implements java.io.Serializable {
private int userId;
private Role role;
private Groups groupId;
private UserType userType;
private String userName;
private String password;
private Boolean isActive;
public Users() {
}
public Users(int userId, Role role, Groups groupId ,UserType userType, String userName, String password, boolean isActive) {
this.userId = userId;
this.role = role;
this.groupId = groupId;
this.userType = userType;
this.userName = userName;
this.password = password;
this.isActive = isActive;
}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "UserID", unique = true, nullable = false)
public int getUserId() {
return this.userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "RoleID", nullable = false)
public Role getRole() {
return this.role;
}
public void setRole(Role role) {
this.role = role;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "GroupId", nullable = false)
public Groups getGroup() {
return this.groupId;
}
public void setGroup(Groups group) {
this.groupId = group;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "UserTypeID", nullable = false)
public UserType getUserType() {
return this.userType;
}
public void setUserType(UserType userType) {
this.userType = userType;
}
@Column(name = "UserName", nullable = false)
public String getUserName() {
return this.userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
@Column(name = "Password", nullable = false)
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
@Column(name = "IsActive", nullable = false, columnDefinition = "BIT")
public Boolean isIsActive() {
return this.isActive;
}
public void setIsActive(Boolean isActive) {
this.isActive = isActive;
}
}
Upvotes: 1
Views: 2154
Reputation: 17345
From this blog post,
For Jackson to work well, one of the two sides of the relationship should not be serialized, in order to avoid the annoying infinite recursive loop that causes our StackOverflow error.
So, Jackson takes the forward part of the reference, for example an attribute of a java class (i.e.
List<Role>
roles in User class), and converts it in a json-like storage format; this is the so-called marshalling process. Then, Jackson looks for the back part of the reference (i.e.List<User>
users inRole
class) and leaves it as it is, not serializing it. This part of the relationship will be re-constructed during the deserialization (unmarshalling) of the forward reference.
Solution:
Add the @JsonManagedReference
In the forward part of the relationship (i.e. Users.java
class):
Add the @JsonBackReference
In the back part of the relationship (i.e. Role.java
and Groups.java
class):
Users.java
(example code):
@Entity
public class Users implements java.io.Serializable{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "UserID", unique = true, nullable = false)
@Column(name="name")
private String name;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "RoleID", nullable = false)
@JsonManagedReference
public Role getRole() {
return this.role;
}
...
Role.java(example code)
:
@Entity
public class Role implements java.io.Serializable {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
@OneToMany
@JsonBackReference
private Set<User> users = new HashSet<User>();
...
and the same way goes for
Groups.java
@Entity
public class Groups implements java.io.Serializable {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
@ManyToMany(mappedBy="groups")
@JsonBackReference
private Set<User> users = new HashSet<User>();
...
Another useful annotation you could check is
@JsonIdentityInfo
: using it, everytime Jackson serializes your object, it will add anID
(or another attribute of your choose) to it, so that it won't entirely "scan" it again everytime. This can be useful when you've got a chain loop between more interrelated objects (for example:Order -> OrderLine -> User -> Order
and over again).In this case you've got to be careful, since you could need to read your object's attributes more than once (for example in a products list with more products that share the same seller), and this annotation prevents you to do so. I suggest to always take a look at firebug logs to check the JSON response and see what's going on in your code.
Hope this helps.
Upvotes: 5