java, playframework, ajax, json - 将 Object 转换为 JSON 时发生无限递归
java, playframework, ajax, json - Infinite recursion occurs when converting Object to JSON
我需要将此对象列表转换为 JSON,以便我可以将其传递给我的 AJAX。
到目前为止我有(使用java playframework)
Application.java
@Transactional
public static Result fetchOptions(String strCategoryId, String strCategoryName) {
Main mainAppModel = new Main();
mainAppModel.populateOptions(strCategoryId, strCategoryName);
return ok(Json.toJson(mainAppModel));
}
Main.java
public void populateCountryOptions() {
Countries countriesDb = new Countries();
lstCountries = countriesDb.getCountriesByRegion(strRegionId);
}
public void populateLocationOptions() {
Locations locationsDb = new Locations();
lstLocations = locationsDb.getLocationByCountry(strCountryId);
}
public void populateDepartmentOptions() {
Departments departmentsDb = new Departments();
lstDepartments = departmentsDb.getDepartmentByLocationId(strLocationId);
}
public void populateOptions(String strCategoryId, String strCategoryName) {
switch (strCategoryName) {
case "region":
strRegionId = strCategoryId;
populateCountryOptions();
break;
case "country":
strCountryId = strCategoryId;
populateLocationOptions();
break;
case "location":
strLocationId = strCategoryId;
populateDepartmentOptions();
break;
default:
break;
}
}
conf/routes
POST /fetchOptions/:strCategoryId/:strCategoryName controllers.Application.fetchOptions(strCategoryId: String, strCategoryName: String)
Departments.java(删除了 getter 和 setter)
package models.db;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import play.db.jpa.JPA;
@Table(name = "DEPARTMENTS")
@Entity
public class Departments {
@Id
@Column(name = "DEPARTMENT_ID")
private String strDepartmentId;
@Column(name = "DEPARTMENT_NAME")
private String strDepartmentName;
@Column(name = "MANAGER_ID")
private String strManagerId;
@Column(name = "LOCATION_ID")
private String strLocationId;
@SuppressWarnings("unchecked")
public List<Departments> getDepartmentByLocationId(String strLocationId) {
StringBuilder sb = new StringBuilder();
sb.append(" SELECT ");
sb.append(" DEPARTMENT_ID ");
sb.append(" , DEPARTMENT_NAME ");
sb.append(" , MANAGER_ID ");
sb.append(" , LOCATION_ID ");
sb.append(" FROM ");
sb.append(" DEPARTMENTS ");
sb.append(" WHERE ");
sb.append(" LOCATION_ID = '" + strLocationId + "'");
sb.append(" ORDER BY ");
sb.append(" DEPARTMENT_NAME ASC ");
List<Departments> lstDepartments = new ArrayList<Departments>();
try {
lstDepartments = JPA.em().createNativeQuery(sb.toString(), Departments.class).getResultList();
} catch (Exception e) {
// TODO: handle exception
}
return lstDepartments;
}
}
Countries.java(对比)
package models.db;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import play.db.jpa.JPA;
@Table(name = "COUNTRIES")
@Entity
public class Countries {
@Id
@Column(name = "COUNTRY_ID")
private String strCountryId;
@Column(name = "COUNTRY_NAME")
private String strCountryName;
@Column(name = "REGION_ID")
private String strRegionId;
@SuppressWarnings("unchecked")
public List<Countries> getCountriesByRegion(String strRegionId) {
StringBuilder sb = new StringBuilder();
sb.append(" SELECT ");
sb.append(" COUNTRY_ID ");
sb.append(" , COUNTRY_NAME ");
sb.append(" , REGION_ID ");
sb.append(" FROM ");
sb.append(" COUNTRIES ");
sb.append(" WHERE ");
sb.append(" REGION_ID = '" + strRegionId + "'");
sb.append(" ORDER BY ");
sb.append(" COUNTRY_NAME ASC ");
List<Countries> lstCountries = new ArrayList<Countries>();
try {
lstCountries = JPA.em().createNativeQuery(sb.toString(), Countries.class).getResultList();
} catch (Exception e) {
// TODO: handle exception
}
return lstCountries;
}
}
我认为不再需要 javascript,因为错误发生在将 mainAppModel 对象返回为 Json 时。
所以我在 Main.java 上有 3 个方法,在 Application.java 上使用相同的方法。如果我使用 populateCountryOptions() 和 populateLocationOptions() Json 工作正常,但每当我使用 populateDepartmentOptions() 发生无限递归。该模型看起来彼此相似。我不知道是什么导致了这个错误。感谢您的帮助!
你需要在这里休息:
case "location":
strLocationId = strCategoryId;
populateDepartmentOptions();
break;
因为我无法修复错误。我通过覆盖 .toString() 手动创建自己的 JSON
虽然这不是我的问题的具体答案,但无论如何我都会 post 帮助其他可能遇到与 .toJson() 方法相同问题的人
这是我的代码:
Main.java
已添加
@Override
public String toString() {
return "{\"lstCountries\":" + lstCountries + ",\"lstLocations\":" + lstLocations
+ ",\"lstDepartments\":" + lstDepartments + "}";
}
Countries.java
@Override
public String toString() {
return "{\"strCountryId\":\"" + strCountryId + "\",\"strCountryName\":\"" + strCountryName
+ "\",\"strRegionId\":\"" + strRegionId + "\"}";
}
Locations.java
@Override
public String toString() {
return "{\"strLocationId\":\"" + strLocationId + "\",\"strStreetAddress\":\""
+ strStreetAddress + "\",\"strPostalCode\":\"" + strPostalCode + "\",\"strCity\":\""
+ strCity + "\",\"strStateProvince\":\"" + strStateProvince + "\",\"strCountryId\":\""
+ strCountryId + "\"}";
}
Departments.java
@Override
public String toString() {
return "{\"strDepartmentId\":\"" + strDepartmentId + "\",\"strDepartmentName\":\""
+ strDepartmentName + "\",\"strManagerId\":\"" + strManagerId + "\",\"strLocationId\":\""
+ strLocationId + "\"}";
}
Application.java
然后我将 return 更改为:
@Transactional
public static Result fetchOptions(String strCategoryId, String strCategoryName) {
Main mainAppModel = new Main();
mainAppModel.populateOptions(strCategoryId, strCategoryName);
return ok(Json.toJson(mainAppModel.toString()));
}
javascript
这是获取国家/地区列表的ajax
$.ajax({
type : 'POST',
url : "/fetchOptions/" + region + "/region",
dataType: "json",
success : function(data) {
data = JSON.parse(data);
//some codes here..
//use data.lstCountries for Countries List
},
error : function(error) {
alert("Error: " + error.status);
}
});
我需要将此对象列表转换为 JSON,以便我可以将其传递给我的 AJAX。
到目前为止我有(使用java playframework)
Application.java
@Transactional
public static Result fetchOptions(String strCategoryId, String strCategoryName) {
Main mainAppModel = new Main();
mainAppModel.populateOptions(strCategoryId, strCategoryName);
return ok(Json.toJson(mainAppModel));
}
Main.java
public void populateCountryOptions() {
Countries countriesDb = new Countries();
lstCountries = countriesDb.getCountriesByRegion(strRegionId);
}
public void populateLocationOptions() {
Locations locationsDb = new Locations();
lstLocations = locationsDb.getLocationByCountry(strCountryId);
}
public void populateDepartmentOptions() {
Departments departmentsDb = new Departments();
lstDepartments = departmentsDb.getDepartmentByLocationId(strLocationId);
}
public void populateOptions(String strCategoryId, String strCategoryName) {
switch (strCategoryName) {
case "region":
strRegionId = strCategoryId;
populateCountryOptions();
break;
case "country":
strCountryId = strCategoryId;
populateLocationOptions();
break;
case "location":
strLocationId = strCategoryId;
populateDepartmentOptions();
break;
default:
break;
}
}
conf/routes
POST /fetchOptions/:strCategoryId/:strCategoryName controllers.Application.fetchOptions(strCategoryId: String, strCategoryName: String)
Departments.java(删除了 getter 和 setter)
package models.db;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import play.db.jpa.JPA;
@Table(name = "DEPARTMENTS")
@Entity
public class Departments {
@Id
@Column(name = "DEPARTMENT_ID")
private String strDepartmentId;
@Column(name = "DEPARTMENT_NAME")
private String strDepartmentName;
@Column(name = "MANAGER_ID")
private String strManagerId;
@Column(name = "LOCATION_ID")
private String strLocationId;
@SuppressWarnings("unchecked")
public List<Departments> getDepartmentByLocationId(String strLocationId) {
StringBuilder sb = new StringBuilder();
sb.append(" SELECT ");
sb.append(" DEPARTMENT_ID ");
sb.append(" , DEPARTMENT_NAME ");
sb.append(" , MANAGER_ID ");
sb.append(" , LOCATION_ID ");
sb.append(" FROM ");
sb.append(" DEPARTMENTS ");
sb.append(" WHERE ");
sb.append(" LOCATION_ID = '" + strLocationId + "'");
sb.append(" ORDER BY ");
sb.append(" DEPARTMENT_NAME ASC ");
List<Departments> lstDepartments = new ArrayList<Departments>();
try {
lstDepartments = JPA.em().createNativeQuery(sb.toString(), Departments.class).getResultList();
} catch (Exception e) {
// TODO: handle exception
}
return lstDepartments;
}
}
Countries.java(对比)
package models.db;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import play.db.jpa.JPA;
@Table(name = "COUNTRIES")
@Entity
public class Countries {
@Id
@Column(name = "COUNTRY_ID")
private String strCountryId;
@Column(name = "COUNTRY_NAME")
private String strCountryName;
@Column(name = "REGION_ID")
private String strRegionId;
@SuppressWarnings("unchecked")
public List<Countries> getCountriesByRegion(String strRegionId) {
StringBuilder sb = new StringBuilder();
sb.append(" SELECT ");
sb.append(" COUNTRY_ID ");
sb.append(" , COUNTRY_NAME ");
sb.append(" , REGION_ID ");
sb.append(" FROM ");
sb.append(" COUNTRIES ");
sb.append(" WHERE ");
sb.append(" REGION_ID = '" + strRegionId + "'");
sb.append(" ORDER BY ");
sb.append(" COUNTRY_NAME ASC ");
List<Countries> lstCountries = new ArrayList<Countries>();
try {
lstCountries = JPA.em().createNativeQuery(sb.toString(), Countries.class).getResultList();
} catch (Exception e) {
// TODO: handle exception
}
return lstCountries;
}
}
我认为不再需要 javascript,因为错误发生在将 mainAppModel 对象返回为 Json 时。
所以我在 Main.java 上有 3 个方法,在 Application.java 上使用相同的方法。如果我使用 populateCountryOptions() 和 populateLocationOptions() Json 工作正常,但每当我使用 populateDepartmentOptions() 发生无限递归。该模型看起来彼此相似。我不知道是什么导致了这个错误。感谢您的帮助!
你需要在这里休息:
case "location":
strLocationId = strCategoryId;
populateDepartmentOptions();
break;
因为我无法修复错误。我通过覆盖 .toString() 手动创建自己的 JSON
虽然这不是我的问题的具体答案,但无论如何我都会 post 帮助其他可能遇到与 .toJson() 方法相同问题的人
这是我的代码:
Main.java
已添加
@Override
public String toString() {
return "{\"lstCountries\":" + lstCountries + ",\"lstLocations\":" + lstLocations
+ ",\"lstDepartments\":" + lstDepartments + "}";
}
Countries.java
@Override
public String toString() {
return "{\"strCountryId\":\"" + strCountryId + "\",\"strCountryName\":\"" + strCountryName
+ "\",\"strRegionId\":\"" + strRegionId + "\"}";
}
Locations.java
@Override
public String toString() {
return "{\"strLocationId\":\"" + strLocationId + "\",\"strStreetAddress\":\""
+ strStreetAddress + "\",\"strPostalCode\":\"" + strPostalCode + "\",\"strCity\":\""
+ strCity + "\",\"strStateProvince\":\"" + strStateProvince + "\",\"strCountryId\":\""
+ strCountryId + "\"}";
}
Departments.java
@Override
public String toString() {
return "{\"strDepartmentId\":\"" + strDepartmentId + "\",\"strDepartmentName\":\""
+ strDepartmentName + "\",\"strManagerId\":\"" + strManagerId + "\",\"strLocationId\":\""
+ strLocationId + "\"}";
}
Application.java
然后我将 return 更改为:
@Transactional
public static Result fetchOptions(String strCategoryId, String strCategoryName) {
Main mainAppModel = new Main();
mainAppModel.populateOptions(strCategoryId, strCategoryName);
return ok(Json.toJson(mainAppModel.toString()));
}
javascript
这是获取国家/地区列表的ajax
$.ajax({
type : 'POST',
url : "/fetchOptions/" + region + "/region",
dataType: "json",
success : function(data) {
data = JSON.parse(data);
//some codes here..
//use data.lstCountries for Countries List
},
error : function(error) {
alert("Error: " + error.status);
}
});