2012-02-07 20 views
2

次のYAHOO URLからJSONオブジェクトを取得しました。これにより、クエリを使用して株価記号が返されます。 URLはです。JSON with Javaの読み取り/解析

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

私はYAHOOから返されたJSONオブジェクトは100%有効ではないこと、それはそうオンラインJSONバリデータを使用しています。

サイト

http://jsonformatter.curiousconcept.com/ 

はJSONオブジェクトが無効であることを、私に言いました。そこで私は、有効なJSONオブジェクトであるYAHOO Webサービスの部分文字列を使用することに決めました。この場合、私はこの部分文字列で出力

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

を使用していますすべての私のバリデータは、私がここで有効なJSONオブジェクトを持っていることを、私に言いました。

私はこのようになりますと、私のJSONオブジェクトをデシリアライズしようとしている私のJavaコード、:

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; 
} 
} 

私はGoogleからの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ウェブサービスを使用して、株式相場を受け取る会社のティッカーシンボルを取得することです。

SOLUTION

主な問題は、大文字と小文字でした。 Q ueryは大文字のQで書かれました。ResultSetクラスにはqと書かれています。データバインディングメカニズムは、これをそのままの状態で処理することはできません。 jacksonではAnnotationsを使用できるので、JSON-Objectと元の変数名を変更する必要はありません。 Javaでは、大文字の変数名を使用するための標準的なコードスタイルではありません。 Jackson Annotionsでは、マッピングを手動で行うことができます。できます!

次のコードを使用して動作させました。ジャクソンのlibと

ソリューション:-)あなたのアドバイスのおかげで、オブジェクトを構築するヘルパークラス

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; 
} 
} 

ため

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; 
} 
} 

コード

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); 

が、これはあなたがラクダでプレイしているよりも、うまくいかない場合は残念ながら、あなたは、ResultSetのコンテナになり、別のクラスを持っている必要があります場合:private ResultSet jsonContainer;private ResultSet JsonContainer;に変更するか、@SerializedNameを使用してください。

+0

このヒントを別のstackoverflowスレッドで読みました。残念ながら、これは私を助けませんでした: - /他の提案? – Martin

+0

これは大文字の問題によるものです。 – Martin

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の2つのクラスがあります - 私はhttp://jsongen.byingtondesign.com/を使用してこれらのクラスを生成しました。とにかく、結果配列のみを解析するようにあなたの提案を試みました。このため、私はあなたの例のようにJSONオブジェクトを短縮しました。まだ運がありません。 get-methodsを使って値を取得したいとき、私はいつも "null"を返します。 -/ – Martin

+0

@Marting:私が答えを理解しているので、もう1つのレベルの入れ子が必要です。あなたが 'fromJson'に提供するクラスは' ResultSet'クラスを「含む」必要があります。 – nikow

+0

@nikow:アドバイスをいただきありがとうございます。私は、ResultSet型のメンバ変数jsonContainerを持つJsonContainerという名前のクラスを作成し、setters/gettersを追加しました。それでは、私はJsonContainerデータ=新しいGson()fromJson(content、JsonContainer.class)を呼び出しました。残念ながら、data.getJsonContainer()はまだnullです。私は間違っているの?また、hakyerによって投稿されたJSONフラグメントを使用しました – Martin