Чтение / Разбор JSON с Java - PullRequest
       20

Чтение / Разбор JSON с Java

2 голосов
/ 08 февраля 2012

Я получил объект JSON из следующего URL YAHOO, который вернет мне символ биржевого тикера с помощью запроса.URL:

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

Когда я использую онлайн-валидатор json, кажется, что объект JSON, возвращаемый YAHOO, не на 100% действителен.

Сайт

http://jsonformatter.curiousconcept.com/

сказал мне, что объект JSON недействителен.Поэтому я решил использовать подстроку веб-службы YAHOO, которая является допустимым объектом 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 от Google, выглядит следующим образом.

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

Содержимое переменной с именем «content» равно

{"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 () возвращает значение «null».Выходные данные функции getTickerSymbol распечатывают следующий вывод консоли:

>>null

Кто-нибудь знает, почему объект не десериализован правильным образом?

Моя цель - использовать веб-сервис YAHOO дляполучить символ тикера для компании, чтобы получить их котировки акций.

РЕШЕНИЕ

Основной проблемой была капитализация. 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 ]

2 голосов
/ 08 февраля 2012

Проблема в том, что в классе 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"}]}
2 голосов
/ 08 февраля 2012

Это происходит потому, что ResultSet.class на самом деле не соответствует заданному JSON. К сожалению, вам нужен еще один класс, который будет контейнером для ResultSet:

public class JsonContainer {

  private ResultSet jsonContainer;

  // getter/setter
}

тогда вам нужно будет сделать это:

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

Если это не сработает, тогда вам придется поиграть с верблюжьим чехлом: измените private ResultSet jsonContainer; на private ResultSet JsonContainer; или используйте @SerializedName.

...