使用Retrofit和GSON进行Android JSON解析会导致格式错误的JSON错误

时间:2016-08-04 20:18:08

标签: java android json gson retrofit

我正在尝试使用http://developer.forecast.io/ API制作天气应用。我收到错误 Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 1 path $我已经对此问题进行了足够的搜索并获得了一些答案,但我的应用上没有任何效果。这是我的代码:

build.gradle:dependencies

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:24.1.1'
    //Retrofit
    compile 'com.google.code.gson:gson:2.6.1'
    compile 'com.squareup.retrofit2:retrofit:2.1.0'
    compile 'com.squareup.retrofit2:converter-gson:2.1.0'
    //POJO Annotation
    compile 'org.glassfish:javax.annotation:10.0-b28'
}

Pojo模型类:Currently.java

package com.github.abdalimran.weatherforecaster.pojoModels;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

import javax.annotation.Generated;

@Generated("org.jsonschema2pojo")
public class Currently {

    @SerializedName("time")
    @Expose
    private int time;
    @SerializedName("summary")
    @Expose
    private String summary;
    @SerializedName("icon")
    @Expose
    private String icon;
    @SerializedName("precipIntensity")
    @Expose
    private double precipIntensity;
    @SerializedName("precipProbability")
    @Expose
    private double precipProbability;
    @SerializedName("precipType")
    @Expose
    private String precipType;
    @SerializedName("temperature")
    @Expose
    private double temperature;
    @SerializedName("apparentTemperature")
    @Expose
    private double apparentTemperature;
    @SerializedName("dewPoint")
    @Expose
    private double dewPoint;
    @SerializedName("humidity")
    @Expose
    private double humidity;
    @SerializedName("windSpeed")
    @Expose
    private double windSpeed;
    @SerializedName("windBearing")
    @Expose
    private int windBearing;
    @SerializedName("visibility")
    @Expose
    private double visibility;
    @SerializedName("cloudCover")
    @Expose
    private double cloudCover;
    @SerializedName("pressure")
    @Expose
    private double pressure;
    @SerializedName("ozone")
    @Expose
    private double ozone;

    /**
     * 
     * @return
     *     The time
     */
    public int getTime() {
        return time;
    }

    /**
     * 
     * @param time
     *     The time
     */
    public void setTime(int time) {
        this.time = time;
    }

    /**
     * 
     * @return
     *     The summary
     */
    public String getSummary() {
        return summary;
    }

    /**
     * 
     * @param summary
     *     The summary
     */
    public void setSummary(String summary) {
        this.summary = summary;
    }

    /**
     * 
     * @return
     *     The icon
     */
    public String getIcon() {
        return icon;
    }

    /**
     * 
     * @param icon
     *     The icon
     */
    public void setIcon(String icon) {
        this.icon = icon;
    }

    /**
     * 
     * @return
     *     The precipIntensity
     */
    public double getPrecipIntensity() {
        return precipIntensity;
    }

    /**
     * 
     * @param precipIntensity
     *     The precipIntensity
     */
    public void setPrecipIntensity(double precipIntensity) {
        this.precipIntensity = precipIntensity;
    }

    /**
     * 
     * @return
     *     The precipProbability
     */
    public double getPrecipProbability() {
        return precipProbability;
    }

    /**
     * 
     * @param precipProbability
     *     The precipProbability
     */
    public void setPrecipProbability(double precipProbability) {
        this.precipProbability = precipProbability;
    }

    /**
     * 
     * @return
     *     The precipType
     */
    public String getPrecipType() {
        return precipType;
    }

    /**
     * 
     * @param precipType
     *     The precipType
     */
    public void setPrecipType(String precipType) {
        this.precipType = precipType;
    }

    /**
     * 
     * @return
     *     The temperature
     */
    public double getTemperature() {
        return temperature;
    }

    /**
     * 
     * @param temperature
     *     The temperature
     */
    public void setTemperature(double temperature) {
        this.temperature = temperature;
    }

    /**
     * 
     * @return
     *     The apparentTemperature
     */
    public double getApparentTemperature() {
        return apparentTemperature;
    }

    /**
     * 
     * @param apparentTemperature
     *     The apparentTemperature
     */
    public void setApparentTemperature(double apparentTemperature) {
        this.apparentTemperature = apparentTemperature;
    }

    /**
     * 
     * @return
     *     The dewPoint
     */
    public double getDewPoint() {
        return dewPoint;
    }

    /**
     * 
     * @param dewPoint
     *     The dewPoint
     */
    public void setDewPoint(double dewPoint) {
        this.dewPoint = dewPoint;
    }

    /**
     * 
     * @return
     *     The humidity
     */
    public double getHumidity() {
        return humidity;
    }

    /**
     * 
     * @param humidity
     *     The humidity
     */
    public void setHumidity(double humidity) {
        this.humidity = humidity;
    }

    /**
     * 
     * @return
     *     The windSpeed
     */
    public double getWindSpeed() {
        return windSpeed;
    }

    /**
     * 
     * @param windSpeed
     *     The windSpeed
     */
    public void setWindSpeed(double windSpeed) {
        this.windSpeed = windSpeed;
    }

    /**
     * 
     * @return
     *     The windBearing
     */
    public int getWindBearing() {
        return windBearing;
    }

    /**
     * 
     * @param windBearing
     *     The windBearing
     */
    public void setWindBearing(int windBearing) {
        this.windBearing = windBearing;
    }

    /**
     * 
     * @return
     *     The visibility
     */
    public double getVisibility() {
        return visibility;
    }

    /**
     * 
     * @param visibility
     *     The visibility
     */
    public void setVisibility(double visibility) {
        this.visibility = visibility;
    }

    /**
     * 
     * @return
     *     The cloudCover
     */
    public double getCloudCover() {
        return cloudCover;
    }

    /**
     * 
     * @param cloudCover
     *     The cloudCover
     */
    public void setCloudCover(double cloudCover) {
        this.cloudCover = cloudCover;
    }

    /**
     * 
     * @return
     *     The pressure
     */
    public double getPressure() {
        return pressure;
    }

    /**
     * 
     * @param pressure
     *     The pressure
     */
    public void setPressure(double pressure) {
        this.pressure = pressure;
    }

    /**
     * 
     * @return
     *     The ozone
     */
    public double getOzone() {
        return ozone;
    }

    /**
     * 
     * @param ozone
     *     The ozone
     */
    public void setOzone(double ozone) {
        this.ozone = ozone;
    }

    @Override
    public String toString() {
        return "Weather Status: "+getSummary()+"\n"+
                "Precipitation: "+getPrecipType()+"\n"+
                "Pressure: "+getPressure()+"\n"+
                "Humidity: "+getHumidity()+"\n"+
                "Temperature: "+getTemperature();
    }
}

MainActivity.java

package com.github.abdalimran.weatherforecaster;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.TextView;

import com.github.abdalimran.weatherforecaster.pojoModels.Currently;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class MainActivity extends AppCompatActivity {

    private TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textView= (TextView) findViewById(R.id.textView);

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(Constants.BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        API_Interface weatherService = retrofit.create(API_Interface.class);
        Call<Currently> call = weatherService.getCurrentWeather(Constants.API_KEY,23.810514,90.3371889);

        call.enqueue(new Callback<Currently>() {
            @Override
            public void onResponse(Call<Currently> call, Response<Currently> response) {
                textView.setText(response.body().toString());
                Log.d("result",response.body().toString());
            }

            @Override
            public void onFailure(Call<Currently> call, Throwable t) {
                textView.setText("Something went wrong: " + t.getMessage());
                Log.e("error",t.getMessage());
            }
        });
    }
}

JSON响应: 链接:http://paste.ubuntu.com/22220252/

有人可以帮我解决这个问题吗?

1 个答案:

答案 0 :(得分:0)

据我所知,这里的问题是你提供给改装的对象与你在pastebin中提供的json不匹配。它们都需要以1:1的比例进行匹配。它适用于json中的一个字段 - currently,但json不仅仅是这个。

因此,如果你看一下你的java模型,你就有了一个适用于的模型:

 {
    "time": 1470336515,
    "summary": "Clear",
    "icon": "clear-night",
    "precipIntensity": 0.0021,
    "precipProbability": 0.05,
    "precipType": "rain",
    "temperature": 81.62,
    "apparentTemperature": 89.05,
    "dewPoint": 76.64,
    "humidity": 0.85,
    "windSpeed": 10.69,
    "windBearing": 138,
    "visibility": 2.49,
    "cloudCover": 0.22,
    "pressure": 999.91,
    "ozone": 269.33
}

这是您提供的json中的当前字段。如果要序列化和反序列化您提供的json,则需要更改改进调用以使用其中包含Currently对象的其他对象。像这样:

public class Prediction {
   @Expose
   @SerializedName("currently")
   private Currently currently;
   // ...
}

然后你的改装电话应该是这样的:

    Call<Prediction> call = weatherService.getCurrentWeather(Constants.API_KEY,23.810514,90.3371889);

    call.enqueue(new Callback<Prediction>() {
        @Override
        public void onResponse(Call<Prediction> call, Response<Prediction> response) {
            // ...
        }

        @Override
        public void onFailure(Call<Prediction> call, Throwable t) {
            // ...
        }
    });

您显然需要更改getCurrentWeather的声明。另请注意,我只是Prediction模型代表字段currently,但我认为您可以轻松了解如何在需要时添加其余字段。另外Prediction是我提出的名字,你可以使用你想要的任何东西。