这是我第一次改装,但我正在尝试向我的服务器发送一组Gps数据点
来自我的设备
这是我的POJO课程
script_function
这是我的Request类,它包含列表
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;
}
这是我提出请求的方式
public interface GpsApiInterface {
@Headers( "Content-Type: application/json" )
@POST("/api/v2/GPS")
Call<ResponseBody> sendGpsData(@Body GpsRequest gpsData);
}
这是我用来测试的服务器代码
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) {
}
});
这是服务器上的GPS数据类
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);
}
}
}
当我发出请求时,服务器被命中但没有数据(gpsData为null)。如果我从public class GPSData
{
public string mduid;
public double latitude;
public double longitude;
public int speed;
public string time;
public string status;
}
拨打同一个电话,它会被调用,数据就在那里,所以我错过了什么?
更新
添加了对okhttp的记录,这是日志
postman
比较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
}
]
似乎服务器上的{
"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
}
]
}
是一个数组,但应用程序正在发送带有数组的对象可能是问题?如果是这样,我如何发送不在对象中的数组?
答案 0 :(得分: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);
答案 1 :(得分:0)
Digression到POJO模型。如果使用@Expose
创建Gson实例,则POJO中的GsonConverterFactory.create()
注释无效(因为后台的Gson
实例是使用new Gson()
创建的),因此来自{{GpsData
的所有属性无论注释如何,都将序列化类。
如果您希望注释生效,则必须将Gson
实例创建为new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create()
并将其传递给GsonConverterFactory.create()
。也许它影响服务器不要正确地序列化数据,但不确定..
其次,使用OkHttp
日志记录非常有用,这样您就可以在android studio console中看到HTTP请求详细信息。
以下是OkHttpClient
为所有端点设置Content-Type
的示例,您可以从@Headers
中删除GpsApiInterface
。
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();
}
然后修改Retrofit实例化,如下所示:
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")
答案 2 :(得分:0)
问题是我发送了一个带有数组的对象,服务器只期待一个数组,所以我将请求更改为
@POST("/api/v2/GPS")
Call<ResponseBody> sendGpsData(@Body List<GpsData> gpsData);
现在它正常工作