2012-02-07 45 views
2

我从下面的YAHOO网址获得了一个JSON对象,该对象将使用查询返回股票股票代码。网址是。使用Java读取/解析JSON

http://d.yimg.com/autoc.finance.yahoo.com/autoc?query=Siemens&callback=YAHOO.Finance.SymbolSuggest.ssCallback 

当我使用在线json验证程序看起来,YAHOO返回的JSON对象不是100%有效。

该网站

http://jsonformatter.curiousconcept.com/ 

告诉我,JSON对象是无效的。所以我决定使用YAHOO web服务的一个子字符串,这是一个有效的JSON对象。在这种情况下,我使用的输出

{"ResultSet":{"Query":"siemens","Result":[{"symbol":"SI", ... }]}} 

有了这个串我的所有验证告诉我,我有一个有效的JSON对象在这里。

我的Java代码,在这里我想反序列化JSON我物体看起来像这样:

import java.util.List; 

public class ResultSet { 
private String query; 
private List<Result> result; 

public String getQuery() { 
    return this.query; 
} 

public void setQuery(String query) { 
    this.query = query; 
} 

public List<Result> getResult() { 
    return this.result; 
} 

public void setResult(List<Result> result) { 
    this.result = result; 
} 
} 

public class Result { 
private String exch; 
private String exchDisp; 
private String name; 
private String symbol; 
private String type; 
private String typeDisp; 

public String getExch() { 
    return this.exch; 
} 

public void setExch(String exch) { 
    this.exch = exch; 
} 

public String getExchDisp() { 
    return this.exchDisp; 
} 

public void setExchDisp(String exchDisp) { 
    this.exchDisp = exchDisp; 
} 

public String getName() { 
    return this.name; 
} 

public void setName(String name) { 
    this.name = name; 
} 

public String getSymbol() { 
    return this.symbol; 
} 

public void setSymbol(String symbol) { 
    this.symbol = symbol; 
} 

public String getType() { 
    return this.type; 
} 

public void setType(String type) { 
    this.type = type; 
} 

public String getTypeDisp() { 
    return this.typeDisp; 
} 

public void setTypeDisp(String typeDisp) { 
    this.typeDisp = typeDisp; 
} 
} 

我的代码,在这里我想从谷歌与GSON反序列化对象看起来是这样的。

public String getTickerSymbol() { 
    String content = new URLContentLoader(url).getContent(); 
    content = content.substring(43, content.length()-1); 

    ResultSet data = new Gson().fromJson(content, ResultSet.class); 

    System.out.println(">>" + data.getResult()); 

    return null; 
} 

命名变量的内容 “内容” 是

{"ResultSet":{"Query":"siemens","Result":[{"symbol":"SI","name": "Siemens AG","exch": "NYQ","type": "S","exchDisp":"NYSE","typeDisp":"Equity"},{"symbol":"SIE.DE","name": "Siemens AG","exch": "GER","type": "S","exchDisp":"XETRA","typeDisp":"Equity"},{"symbol":"SIE.MU","name": "SIEMENS N","exch": "MUN","type": "S","exchDisp":"Munich","typeDisp":"Equity"},{"symbol":"SIEMENS.NS","name": "Siemens Ltd.","exch": "NSI","type": "S","exchDisp":"NSE","typeDisp":"Equity"},{"symbol":"SIE.MI","name": "Siemens AG","exch": "MIL","type": "S","exchDisp":"Milan","typeDisp":"Equity"},{"symbol":"SIE.F","name": "SIEMENS N","exch": "FRA","type": "S","exchDisp":"Frankfurt","typeDisp":"Equity"},{"symbol":"SIEMENS.BO","name": "Siemens Ltd.","exch": "BSE","type": "S","exchDisp":"Bombay","typeDisp":"Equity"},{"symbol":"SIEB.SG","name": "SIEMENS SP.ADR","exch": "STU","type": "S","exchDisp":"Stuttgart","typeDisp":"Equity"},{"symbol":"SIEB.DE","name": "Siemens AG","exch": "GER","type": "S","exchDisp":"XETRA","typeDisp":"Equity"},{"symbol":"SIE.L","name": "Siemens AG","exch": "LSE","type": "S","exchDisp":"London","typeDisp":"Equity"}]}} 

函数调用data.getResult()还给值 “空”。函数getTickerSymbol的输出将输出以下控制台输出。

>>null 

有人知道为什么对象没有以正确的方式反序列化吗?

我的目标是使用YAHOO webservice来检索公司的股票代码以获取他们的股票报价。

SOLUTION

的主要问题是资本化。 Q uery是用大写的Q编写的。在ResultSet类中它是用q写的。数据绑定机制无法处理这个开箱即用的问题。使用杰克森,您可以使用注释,以便您不必修改JSON对象和原始变量名称。在Java中,使用大写的变量名称不是一种统一的代码风格。通过杰克逊情怀,您可以手动进行映射。有用!

通过下面的代码,我得到了它的工作。感谢您的意见:-)

解决方案与杰克逊的lib

import java.util.List; 
import org.codehaus.jackson.annotate.JsonProperty; 

public class ResultSet { 
private String query; 
private List<Result> result; 

public String getQuery() { 
    return this.query; 
} 

@JsonProperty("Query") 
public void setQuery(String query) { 
    this.query = query; 
} 

public List<Result> getResult() { 
    return this.result; 
} 

@JsonProperty("Result") 
public void setResult(List<Result> result) { 
    this.result = result; 
} 
} 

代码Helper类

import org.codehaus.jackson.map.ObjectMapper; 

public class JsonUtils { 
public static <T> T parseJson(String json, Class<T> resultType) { 
    ObjectMapper objectMapper = new ObjectMapper(); 
    try { 
     return objectMapper.readValue(json, resultType); 
    } catch (Exception e) { 
     System.err.println(e.getMessage()); 
    } 
    return null; 
} 
} 

构建目标

ResultSet rs = JsonUtils.parseJson(content, ResultSet.class); 

for (Result result : rs.getResult()) { 
    System.out.println(result.getSymbol()); 
} 

回答

2

发生这种情况是因为ResultSet.class并不真正对应给定的JSON。不幸的是,你需要有另一个类,这将是对结果集的容器:

public class JsonContainer { 

    private ResultSet jsonContainer; 

    // getter/setter 
} 

那么你就需要做:

JsonContainer data = new Gson().fromJson(content, JsonContainer.class); 

如果这不工作比你有骆驼玩情况:将private ResultSet jsonContainer;更改为private ResultSet JsonContainer;或使用@SerializedName

+0

我读过这个提示在另一个stackoverflow线程。不幸的是,这并没有帮助我: - /任何其他建议? – Martin 2012-02-08 08:08:44

+0

这是由于大写问题。 – Martin 2012-02-09 14:24:40

2

问题是ResultSet类中没有名为ResultSet的属性。你应该反序列化这个子字符串:

{"Query":"siemens","Result":[{"symbol":"SI","name": "Siemens AG","exch": "NYQ","type": "S","exchDisp":"NYSE","typeDisp":"Equity"},{"symbol":"SIE.DE","name": "Siemens AG","exch": "GER","type": "S","exchDisp":"XETRA","typeDisp":"Equity"},{"symbol":"SIE.MU","name": "SIEMENS N","exch": "MUN","type": "S","exchDisp":"Munich","typeDisp":"Equity"},{"symbol":"SIEMENS.NS","name": "Siemens Ltd.","exch": "NSI","type": "S","exchDisp":"NSE","typeDisp":"Equity"},{"symbol":"SIE.MI","name": "Siemens AG","exch": "MIL","type": "S","exchDisp":"Milan","typeDisp":"Equity"},{"symbol":"SIE.F","name": "SIEMENS N","exch": "FRA","type": "S","exchDisp":"Frankfurt","typeDisp":"Equity"},{"symbol":"SIEMENS.BO","name": "Siemens Ltd.","exch": "BSE","type": "S","exchDisp":"Bombay","typeDisp":"Equity"},{"symbol":"SIEB.SG","name": "SIEMENS SP.ADR","exch": "STU","type": "S","exchDisp":"Stuttgart","typeDisp":"Equity"},{"symbol":"SIEB.DE","name": "Siemens AG","exch": "GER","type": "S","exchDisp":"XETRA","typeDisp":"Equity"},{"symbol":"SIE.L","name": "Siemens AG","exch": "LSE","type": "S","exchDisp":"London","typeDisp":"Equity"}]} 
+0

我不明白。有两个类ResultSet.class和Result.class - 我已经使用http://jsongen.byingtondesign.com/生成了这些类。无论如何,我也尝试过您的建议,只解析结果数组。为此,我缩短了JSON对象,就像你的例子。仍然没有运气。当我想使用get方法检索值时,我总是返回“null”。调试器也没有帮助我: -/ – Martin 2012-02-08 08:05:35

+0

@Marting:正如我所理解的答案,您需要更多层次的嵌套:您提供给'fromJson'的类必须“包含”一个ResultSet类。 – nikow 2012-02-08 16:21:23

+0

@nikow:感谢您的建议。我使用ResultSet类型的成员变量jsonContainer创建了一个名为JsonContainer的类,并添加了setters/getters。然后我调用JsonContainer data = new Gson()。fromJson(content,JsonContainer.class);不幸的是,data.getJsonContainer()仍然为空。我做错了什么?我也使用了由hakyer发布的JSON片段 – Martin 2012-02-08 16:37:37