2017-04-12 47 views
-1

發送POST消息這是我第一次與改造去,但我想的GPS數據點的數組從我的設備發送到我的服務器通過改造

這是我的POJO類

public class GpsData { 

    private long mId; 
    @SerializedName("mduid") 
    @Expose 
    private String mMduid; 
    @SerializedName("latitude") 
    @Expose 
    private double mLat; 
    @SerializedName("longitude") 
    @Expose 
    private double mLng; 
    @SerializedName("speed") 
    @Expose 
    private float mSpeed; 
    @SerializedName("time") 
    @Expose 
    private long mTime; 
    private boolean mSent; 
    @SerializedName("status") 
    @Expose 
    private String mStatus; 

,這是我的要求類,用於保存列表

public class GpsRequest { 
    @SerializedName("gpsData") 
    @Expose 
    public List<GpsData> data; 
} 

這是我的接口

這是我如何做

Retrofit retrofit = new Retrofit.Builder() 
       .baseUrl("http://"+ DEBUG_API) 
       .addConverterFactory(GsonConverterFactory.create()) 
       .build(); 

     GpsApiInterface apiInterface = retrofit.create(GpsApiInterface.class); 

     ArrayList<GpsData> list = new ArrayList<>(); 
     list.add(data); 
     list.add(data); 
     GpsRequest request = new GpsRequest(); 
     request.data = list; 

      Call<ResponseBody> call = apiInterface.sendGpsData(request); 
      call.enqueue(new Callback<ResponseBody>() { 
       @Override 
       public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) { 
        if(response.code() == HttpURLConnection.HTTP_OK){ 
         GpsDB db = new GpsDB(LocationService.this); 
         db.delete(GpsDB.ID+"=?",new String[]{String.valueOf(id)}); 
         db.close(); 
        } 
       } 

       @Override 
       public void onFailure(Call<ResponseBody> call, Throwable t) { 

       } 
      }); 

這是我使用測試

public class GPSController : ApiController 
    { 
     public GPSController() { } 

     public HttpResponseMessage Post([FromBody]GPSData[] gpsData) 
     { 
      if (gpsData != null) 
      { 
       for (int i = 0; i < gpsData.Length; i++) 
       { 

       } 
       return Request.CreateResponse(HttpStatusCode.OK); 
      } 
      else 
      { 
       return Request.CreateResponse(HttpStatusCode.BadRequest); 
      } 


     } 
    } 

這是服務器上的GPS數據類服務器代碼請求

public class GPSData 
    { 
     public string mduid; 
     public double latitude; 
     public double longitude; 
     public int speed; 
     public string time; 
     public string status; 
    } 

當我提出請求時服務器被擊中,但沒有數據(gpsData爲空)。如果我從postman撥打相同的電話,它會被調用,並且數據在那裏,所以我錯過了什麼?

更新

添加記錄到okhttp,這是日誌

D/OkHttp: --> POST http://192.168.202.170:9001/api/v2/GPS http/1.1 
D/OkHttp: Content-Type: application/json; charset=UTF-8 
D/OkHttp: Content-Length: 247 
D/OkHttp: Accept: application/json 
D/OkHttp: Host: 192.168.202.170:9001 
D/OkHttp: Connection: Keep-Alive 
D/OkHttp: Accept-Encoding: gzip 
D/OkHttp: User-Agent: okhttp/3.6.0 
D/OkHttp: {"gpsData":[{"mId":0,"latitude":43.0360532,"longitude":-78.8010079,"mSent":false,"speed":0.0,"status":"OK","time":1492088158526},{"mId":0,"latitude":43.0360532,"longitude":-78.8010079,"mSent":false,"speed":0.0,"status":"OK","time":1492088158526}]} 
D/OkHttp: --> END POST (247-byte body) 

Postman

[ 
    { 
     "latitude": 43.0360532, 
     "longitude": -78.8010079, 
     "speed": 0, 
     "time": 1492027407344 
    }, 
    { 
     "latitude": 43.0360532, 
     "longitude": -78.8010079, 
     "speed": 0, 
     "time": 1492027407344 
    } 
] 

的數據工作將JSON從應用

被送到比較
{ 
    "gpsData": [ 
     { 
      "mId": 0, 
      "latitude": 43.0360532, 
      "longitude": -78.8010079, 
      "mSent": false, 
      "speed": 0, 
      "status": "OK", 
      "time": 1492088158526 
     }, 
     { 
      "mId": 0, 
      "latitude": 43.0360532, 
      "longitude": -78.8010079, 
      "mSent": false, 
      "speed": 0, 
      "status": "OK", 
      "time": 1492088158526 
     } 
    ] 
} 

看來,因爲服務器上的gpsData是一個數組,但應用程序發送數組的對象可能是問題?如果是這樣,我怎麼發送一個數組不在一個對象?

回答

0

這個問題是我送的對象與陣列和服務器只期待一個數組,所以我改變了請求這個

@POST("/api/v2/GPS") 
Call<ResponseBody> sendGpsData(@Body List<GpsData> gpsData); 

,它工作正常現在

1

你需要一個構造函數爲您GPSRequest類:

public class GpsRequest { 
    @SerializedName("gpsData") 
    @Expose 
    public List<GpsData> data; 
    public GpsRequest(List<GpsData> data) { 
     this.data = data; 
    } 

然後在您的要求:

GpsRequest request = new GpsRequest(list); 
+0

添加一個構造函數沒有幫助,仍然在服務器上得到空 – tyczj

+0

你確定你的列表不是空的?另外,您可以通過添加loggingInterceptor [Retrofit 2 - Log Requests and Responses](https://futurestud.io/tutorials/retrofit-2-log-requests-and-responses)來調試您的請求。 – Bopmaster

+0

我剛更新了我的帖子日誌記錄和工作json和非工作區別之間的區別 – tyczj

0

題外話到POJO模型。 @Expose如果您使用GsonConverterFactory.create()創建Gson實例(因爲背景中的實例使用new Gson()創建),所以POJO中的註釋不起作用,因此GpsData類中的所有屬性都將被序列化,而與註釋無關。

如果您想註解有效,您必須創建Gson實例爲new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create()並將其傳遞給GsonConverterFactory.create()。也許它正在影響服務器不正確序列化數據,但不知道..

第二件事,使用OkHttp日誌記錄會很有用,以便您可以在android studio控制檯中看到HTTP請求詳細信息。

下面是OkHttpClient的示例,其中Content-Type設置爲所有端點,並且您可以從GpsApiInterface刪除@Headers

private OkHttpClient getClient() { 
    return new OkHttpClient.Builder() 
      .addNetworkInterceptor(new HttpLoggingInterceptor().setLevel(BuildConfig.DEBUG ? HttpLoggingInterceptor.Level.BODY : HttpLoggingInterceptor.Level.NONE)) 
      .addInterceptor(chain -> { 
       Request request = chain.request() 
         .newBuilder() 
         .addHeader("Content-Type", "application/json;charset=utf-8") 
         .addHeader("Accept", "application/json") 
         .build(); 

       return chain.proceed(request); 
      }).build(); 
} 

,然後修改改造實例是這樣的:

new Retrofit.Builder() 
      .baseUrl("http://"+ DEBUG_API) 
      .addConverterFactory(GsonConverterFactory.create(new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create())) 
      .client(getClient()) 
      .build(); 

在調試模式下運行時,你會看到在控制檯HTTP請求和響應,這將是更容易調試。 我知道這不是完整的答案,但它是解決方案的一步。 等待反饋。

更新:

另一件事是知道的。如果您使用的是Retrofit2,則baseUrl(在您的情況下爲DEBUG_API值)必須以/結尾,並且在這種情況下,在@POST("/api/v2/GPS")開始/可能導致問題,因爲生成的端點url可能看起來像這樣http://DEBUG_API//api/v2/GPS。 嘗試修改方法POST@POST("api/v2/GPS")

+0

我剛更新了我的帖子,請求日誌記錄以及工作json和非工作區別 – tyczj

+0

啊我看你已經想通了已經出來了。我沒有注意到你的服務器方法上有'[]'。很高興我能幫上忙。乾杯。 – bajicdusko