我只是想解析一个 json 输入,它是 AbstractList 的一个实现,包含自定义对象。但是,由于某种原因,当它遇到 CustomerDealerRecord 的反序列化器时,它永远不会超过第一个节点,然后最终抛出 StackOverflowException。我已经为此苦苦挣扎了 4 个小时,并且我已经进行了许多不同的 Google 搜索,但均无济于事。所以,我最后的努力即将来到这里。你们所有人都可以对此有所了解,我们将不胜感激。谢谢你。代码如下。
public class PhoneDeserializer extends StdDeserializer<Phone>{
public PhoneDeserializer() {
super(Phone.class);
}
@SuppressWarnings("unchecked")
@Override
public Phone deserialize(JsonParser jp,
DeserializationContext ctx) throws IOException,
JsonProcessingException {
ObjectMapper mapper = (ObjectMapper) jp.getCodec();
return mapper.readValue(jp, Phone.class);
}
}
--
public class CustomerDealerRecordDeserializer extends StdDeserializer<CustomerDealerRecord>{
public CustomerDealerRecordDeserializer() {
super(CustomerDealerRecord.class);
}
@SuppressWarnings("unchecked")
@Override
public CustomerDealerRecord deserialize(JsonParser jp,
DeserializationContext ctx) throws IOException,
JsonProcessingException {
ObjectMapper mapper = (ObjectMapper) jp.getCodec();
return mapper.readValue(jp, CustomerDealerRecord.class);
}
}
-- 这是自定义列表
public class CustomerDealerRecordList extends AbstractList<CustomerDealerRecord> {
private List<CustomerDealerRecord> records = new ArrayList<CustomerDealerRecord>();
@Override
public CustomerDealerRecord get(int index) {
// TODO Auto-generated method stub
return records.get(index);
}
@Override
public int size() {
// TODO Auto-generated method stub
return records.size();
}
public boolean add(CustomerDealerRecord cdr){
return records.add(cdr);
}
}
-- 这是控制器方法
@SuppressWarnings("unchecked")
public String getCustomerDealerReportAsExcel(HttpServletRequest req, HttpServletResponse resp){
VelocityContext vc = new VelocityContext();
vc.put("response", resp);
// Jackson stuff
CustomerDealerRecordDeserializer deser = new CustomerDealerRecordDeserializer();
PhoneDeserializer phoneDeser = new PhoneDeserializer();
// We have to create a module for the alias'ed class
SimpleModule cdrModule = new SimpleModule("CustomerDealerRecord", new Version(1,0,0,null));
SimpleModule phoneModule = new SimpleModule("Phone", new Version(1,0,0,null));
// Add the deserializer to the module
cdrModule.addDeserializer(CustomerDealerRecord.class, deser);
phoneModule.addDeserializer(Phone.class, phoneDeser);
// Now, create our mapper and then register the module to it.
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(cdrModule);
mapper.registerModule(phoneModule);
CustomerDealerRecordList list = null;
try {
JsonParser jp = mapper.getJsonFactory().createJsonParser(req.getParameter("json"));
list = mapper.readValue(jp, CustomerDealerRecordList.class);
} catch (JsonParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JsonMappingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return format(req, vc, "reports/customer_dealer_report_excel");
}
-- 这是电话模型对象
public class Phone {
public Phone(String areaCode, String phone){
this.areaCode = areaCode;
this.phoneNumber = phone;
}
private String areaCode;
private String phoneNumber;
public String getAreaCode() {
return areaCode;
}
public void setAreaCode(String areaCode) {
this.areaCode = areaCode;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
}
-- 这是 CustomerDealerRecord 模型对象
public class CustomerDealerRecord {
private String fleetName;
private String fleetNumber;
private String dealerName;
private String dealerNumber;
private String territoryName;
private String territoryNumber;
private String city;
private String state;
private Date downTime;
private String failureDescription;
private String tireManufacturer;
private String tireSize;
private String tireType;
private String tirePosition;
private String category;
private String callerName;
private Phone callerPhone;
private String caseNumber;
private Date caseCloseDate;
private String poNumber;
private String truckNumber;
private String trailerNumber;
private String tractorNumber;
private String serviceDetailStatus;
private String refusalReason;
public String getFleetName() {
return fleetName;
}
public void setFleetName(String fleetName) {
this.fleetName = fleetName;
}
public String getFleetNumber() {
return fleetNumber;
}
public void setFleetNumber(String fleetNumber) {
this.fleetNumber = fleetNumber;
}
public String getDealerName() {
return dealerName;
}
public void setDealerName(String dealerName) {
this.dealerName = dealerName;
}
public String getDealerNumber() {
return dealerNumber;
}
public void setDealerNumber(String dealerNumber) {
this.dealerNumber = dealerNumber;
}
public String getTerritoryName() {
return territoryName;
}
public void setTerritoryName(String territoryName) {
this.territoryName = territoryName;
}
public String getTerritoryNumber() {
return territoryNumber;
}
public void setTerritoryNumber(String territoryNumber) {
this.territoryNumber = territoryNumber;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public Date getDownTime() {
return downTime;
}
public void setDownTime(Date downTime) {
this.downTime = downTime;
}
public String getFailureDescription() {
return failureDescription;
}
public void setFailureDescription(String failureDescription) {
this.failureDescription = failureDescription;
}
public String getTireManufacturer() {
return tireManufacturer;
}
public void setTireManufacturer(String tireManufacturer) {
this.tireManufacturer = tireManufacturer;
}
public String getTireSize() {
return tireSize;
}
public void setTireSize(String tireSize) {
this.tireSize = tireSize;
}
public String getTireType() {
return tireType;
}
public void setTireType(String tireType) {
this.tireType = tireType;
}
public String getTirePosition() {
return tirePosition;
}
public void setTirePosition(String tirePosition) {
this.tirePosition = tirePosition;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public String getCallerName() {
return callerName;
}
public void setCallerName(String callerName) {
this.callerName = callerName;
}
public Phone getCallerPhone() {
return callerPhone;
}
public void setCallerPhone(Phone callerPhone) {
this.callerPhone = callerPhone;
}
public String getCaseNumber() {
return caseNumber;
}
public void setCaseNumber(String caseNumber) {
this.caseNumber = caseNumber;
}
public Date getCaseCloseDate() {
return caseCloseDate;
}
public void setCaseCloseDate(Date caseCloseDate) {
this.caseCloseDate = caseCloseDate;
}
public String getPoNumber() {
return poNumber;
}
public void setPoNumber(String poNumber) {
this.poNumber = poNumber;
}
public String getTruckNumber() {
return truckNumber;
}
public void setTruckNumber(String truckNumber) {
this.truckNumber = truckNumber;
}
public String getTrailerNumber() {
return trailerNumber;
}
public void setTrailerNumber(String trailerNumber) {
this.trailerNumber = trailerNumber;
}
public String getTractorNumber() {
return tractorNumber;
}
public void setTractorNumber(String tractorNumber) {
this.tractorNumber = tractorNumber;
}
public String getServiceDetailStatus() {
return serviceDetailStatus;
}
public void setServiceDetailStatus(String serviceDetailStatus) {
this.serviceDetailStatus = serviceDetailStatus;
}
public String getRefusalReason() {
return refusalReason;
}
public void setRefusalReason(String refusalReason) {
this.refusalReason = refusalReason;
}
}
-- 示例 JSON
[
{
"fleetName":"sycamore specialzed carriers",
"fleetNumber":"CF00002760",
"dealerName":null,
"dealerNumber":null,
"territoryName":null,
"territoryNumber":null,
"city":null,
"state":null,
"downTime":"3000-01-01",
"failureDescription":null,
"tireManufacturer":"Continental Tire",
"tireSize":"10.00R15",
"tireType":"DRIVE",
"tirePosition":"LFO",
"category":"Dealer Location Information",
"callerName":"ANN RENNER",
"callerPhone":{
"areaCode":null,
"phoneNumber":null
},
"caseNumber":"189354",
"caseCloseDate":null,
"poNumber":null,
"truckNumber":null,
"trailerNumber":null,
"tractorNumber":null,
"serviceDetailStatus":"CAN",
"refusalReason":"Response time"
},
{
"fleetName":"sycamore specialzed carriers",
"fleetNumber":"CF00002760",
"dealerName":null,
"dealerNumber":null,
"territoryName":null,
"territoryNumber":null,
"city":null,
"state":null,
"downTime":"3000-01-01",
"failureDescription":null,
"tireManufacturer":null,
"tireSize":null,
"tireType":null,
"tirePosition":null,
"category":"Dealer Location Information",
"callerName":"ANN RENNER",
"callerPhone":{
"areaCode":null,
"phoneNumber":null
},
"caseNumber":"189354",
"caseCloseDate":null,
"poNumber":null,
"truckNumber":null,
"trailerNumber":null,
"tractorNumber":null,
"serviceDetailStatus":"ACT",
"refusalReason":null
},
{
"fleetName":"sycamore specialzed carriers",
"fleetNumber":"CF00002760",
"dealerName":null,
"dealerNumber":null,
"territoryName":null,
"territoryNumber":null,
"city":null,
"state":null,
"downTime":"3000-01-01",
"failureDescription":null,
"tireManufacturer":"Continental Tire",
"tireSize":"295/75R22.5",
"tireType":"BIAS",
"tirePosition":"LMI",
"category":"Service Call",
"callerName":" ",
"callerPhone":{
"areaCode":null,
"phoneNumber":null
},
"caseNumber":"189240",
"caseCloseDate":null,
"poNumber":null,
"truckNumber":null,
"trailerNumber":null,
"tractorNumber":null,
"serviceDetailStatus":"CAN",
"refusalReason":"Other"
},
{
"fleetName":"sycamore specialzed carriers",
"fleetNumber":"CF00002760",
"dealerName":null,
"dealerNumber":null,
"territoryName":null,
"territoryNumber":null,
"city":null,
"state":null,
"downTime":"3000-01-01",
"failureDescription":null,
"tireManufacturer":"Continental Tire",
"tireSize":"295/75R22.5",
"tireType":"DRIVE",
"tirePosition":"LMI",
"category":"Service Call",
"callerName":" ",
"callerPhone":{
"areaCode":null,
"phoneNumber":null
},
"caseNumber":"189240",
"caseCloseDate":null,
"poNumber":null,
"truckNumber":null,
"trailerNumber":null,
"tractorNumber":null,
"serviceDetailStatus":"ACT",
"refusalReason":null
},
{
"fleetName":"TEST CUSTOMER",
"fleetNumber":"123ee22a",
"dealerName":null,
"dealerNumber":null,
"territoryName":null,
"territoryNumber":null,
"city":null,
"state":null,
"downTime":"3000-01-01",
"failureDescription":null,
"tireManufacturer":null,
"tireSize":null,
"tireType":null,
"tirePosition":null,
"category":"Service Call",
"callerName":"JASON MA",
"callerPhone":{
"areaCode":"123",
"phoneNumber":"222"
},
"caseNumber":"189328",
"caseCloseDate":"2012-01-03",
"poNumber":null,
"truckNumber":null,
"trailerNumber":null,
"tractorNumber":null,
"serviceDetailStatus":"ACT",
"refusalReason":"Other"
},
{
"fleetName":"TEST CUSTOMER",
"fleetNumber":"123ee22a",
"dealerName":null,
"dealerNumber":null,
"territoryName":null,
"territoryNumber":null,
"city":"ST LOUIS",
"state":"MO",
"downTime":"3000-01-01",
"failureDescription":"REPAIR IF POSSIBLE",
"tireManufacturer":"Continental Tire",
"tireSize":"11R22.5",
"tireType":"RADIAL",
"tirePosition":"LRI",
"category":"Service Call",
"callerName":"BJ TEST",
"callerPhone":{
"areaCode":"314",
"phoneNumber":"592-3129"
},
"caseNumber":"189341",
"caseCloseDate":"2012-06-19",
"poNumber":null,
"truckNumber":null,
"trailerNumber":"34",
"tractorNumber":"12",
"serviceDetailStatus":"CAN",
"refusalReason":"Product not available"
},
{
"fleetName":"TEST CUSTOMER",
"fleetNumber":"123ee22a",
"dealerName":null,
"dealerNumber":null,
"territoryName":null,
"territoryNumber":null,
"city":"ST LOUIS",
"state":"MO",
"downTime":"3000-01-01",
"failureDescription":"REPAIR IF POSSIBLE",
"tireManufacturer":"Continental Tire",
"tireSize":"11R22.5",
"tireType":"RADIAL",
"tirePosition":"LRI",
"category":"Service Call",
"callerName":"BJ TEST",
"callerPhone":{
"areaCode":"314",
"phoneNumber":"592-3129"
},
"caseNumber":"189341",
"caseCloseDate":"2012-06-19",
"poNumber":null,
"truckNumber":null,
"trailerNumber":"34",
"tractorNumber":"12",
"serviceDetailStatus":"ACT",
"refusalReason":null
}
]