2012-12-07 104 views
-1

我只是想解析一個json輸入,這是一個包含自定義對象的AbstractList的實現。但是,由於某種原因,當它碰到CustomerDealerRecord的反序列化器時,它永遠不會通過第一個節點,然後最終拋出一個StackOverflowException。我一直在爲這樣的4個小時敲響,而且我做了大量不同的谷歌搜索無濟於事。所以,我最後的努力就來到這裏。任何你可以擺脫這一點的光將非常感激。謝謝。代碼如下。json反序列化 - StackOverflowException

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 
} 
] 
+0

你可以添加一個示例JSON字符串,你試圖解析的問題? –

+0

添加了JSON字符串。 –

+1

看起來像你的手機解串器呼叫你的手機解串器。 – bmargulies

回答

0

是的,最初我沒有使用反序列化器,而@pgelinas說,這是不需要的。那是我玩過東西后得到的地方。它沒有工作。根本問題是我不得不回到使用mapper.convertValue並給Phone類一個公共的無參數構造函數。基本上,我是一個白癡,只是過分分析簡單。

+0

您也可以保留當前的構造函數並使用'@ JsonProperty'註釋參數。您需要在註釋中指定屬性名稱。傑克遜將正確解析構造函數並使用它來代替使用setter。額外的獎勵:由於你不再需要Jackson的二傳手,所以這個類可以變得不可變;) –

1

作爲@bmargulies評論的,所述PhoneDeserializer調用(間接地)PhoneDeserializer。行mapper.readValue(jp, Phone.class);將讓傑克遜解決Phone類的解串器,這恰好是PhoneDeserializer。您根本不需要Phonedeserializer類,Jackson會正確處理您的電話類。

+0

是的,最初我沒有使用解串器。它沒有工作。根本問題是我不得不回到使用convertValue並給Phone類一個公共的無參數構造函數。基本上,我是一個白癡,只是過分分析簡單。 –