Bir*_*der 7 java rest android flask retrofit
我在android上使用RetroFit以便将图像发送到REST服务器(使用Python和Flask开发)。该应用程序将第一张图像发送到存储该图像的服务器,并将该图像的ID返回给客户端。然后,客户端拍摄另一张照片并将其发送到服务器,这次是在端点URL中使用先前的图像ID。然后,服务器应计算从图像A到图像B的旋转并返回结果。客户端发送完第二张图像后,它应重复轮询端点以获取结果,直到服务器端计算完成。
第一个图像正确发送,服务器将其存储。客户端然后正确地从服务器接收响应。当客户端发送第二个图像时,会出现问题。服务器正确接收了POST,但是客户端似乎从未收到响应。第三条消息(轮询结果的GET请求)也是如此,服务器已接收到该消息,但客户端从未看到响应。
我的REST服务器的代码在这里
class Image(Resource):
def post(self):
file = request.files['uploaded_file']
centerX = request.form['center_x']
centerY = request.form['center_y']
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], str(id(True)) + ".jpg"))
result = {'id' : id(), 'error' : True, 'result' : 5.5}
return jsonify(result)
else:
return {'id' : -1, 'error' : False}
class Find_Transform(Resource):
def post(self, first_id):
result = {'id' : 1, 'error' : True, 'result' : 1.2}
return jsonify(result)
class Find_Transform_Result(Resource):
def get(self, first_id, second_id):
print("Hello")
result = {'id' : 0, 'error' : True, 'result' : 1.1}
return jsonify(result)
api.add_resource(Image,'/image')
api.add_resource(Find_Transform,'/image/<first_id>/find-transform')
api.add_resource(Find_Transform_Result, '/image/<first_id>/find-transform/<second_id>')
if __name__ == '__main__':
app.run(host='0.0.0.0',port='5002')
Run Code Online (Sandbox Code Playgroud)
如您所见,某些端点仍然只是用于测试REST API的存根。
我的Java Respond.class在这里
public class Respond {
private int id;
private Boolean error;
private float result;
public int getMessage() {
return id;
}
public void setMessage(int id) {
this.id = id;
}
public Boolean getError() {
return error;
}
public void setError(Boolean error) {
this.error = error;
}
public void setResult(float result) {
System.out.println("Got Result");
this.result = result;
}
public float getResult() {
return result;
}
}
Run Code Online (Sandbox Code Playgroud)
我的改装界面在这里
public interface FileApi {
@Multipart
@POST("/image")
Call<Respond> uploadCropImage(@Part MultipartBody.Part file, @Part MultipartBody.Part x, @Part MultipartBody.Part y);
@Multipart
@POST("/image/{first_id}/find-transform")
Call<Respond> uploadCompareImage(@Path("first_id") int id, @Part MultipartBody.Part file);
@GET("/image/{first-id}/find-transform/{second-id}")
Call<Respond> getCompareResult(@Path("first-id") int firstId, @Path("second-id") int secondId);
}
Run Code Online (Sandbox Code Playgroud)
使用两个单独的文件上传功能的原因是,第一个图像需要与用户选择的中心点一起发送,而第二个只是图像。
最后,我建立请求的部分在这里:
private void uploadFirstImage(byte[] imageBytes) {
FileApi service = RetroClient.getApiService();
RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), imageBytes);
MultipartBody.Part fileBody =
MultipartBody.Part.createFormData("uploaded_file", "first_image.jpg", requestFile);
RequestBody image_center_x = RequestBody.create(MediaType.parse("multipart/form-data"), Float.toString(points[0].x));
MultipartBody.Part xBody = MultipartBody.Part.createFormData("center_x", null, image_center_x);
RequestBody image_center_y = RequestBody.create(MediaType.parse("multipart/form-data"), Float.toString(points[0].y));
MultipartBody.Part yBody = MultipartBody.Part.createFormData("center_y", null, image_center_y);
Call<Respond> resultCall = service.uploadCropImage(fileBody, xBody, yBody);
resultCall.enqueue(new Callback<Respond>() {
@Override
public void onResponse(Call<Respond> call, Response<Respond> response) {
// Response Success or Fail
if (response.isSuccessful()) {
if (response.body().getError()==true){
System.out.println(Double.toString(response.body().getResult()));
session_id = response.body().getMessage();
}
} else {
Toast.makeText(getApplicationContext(),"Failed to communicate with server",Toast.LENGTH_LONG).show();
}
}
@Override
public void onFailure(Call<Respond> call, Throwable t) {
}
});
}
Run Code Online (Sandbox Code Playgroud)
和这里:
private void uploadSecondImage(byte[] imageBytes) {
FileApi service = RetroClient.getApiService();
RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), imageBytes);
MultipartBody.Part fileBody =
MultipartBody.Part.createFormData("uploaded_file", "first_image.jpg", requestFile);
Call<Respond> resultCall = service.uploadCompareImage(session_id,fileBody);
resultCall.enqueue(new Callback<Respond>() {
@Override
public void onResponse(Call<Respond> call, Response<Respond> response) {
// Response Success or Fail
if (response.isSuccessful()) {
if (response.body().getError()==true){
System.out.println("Got Second Response");
resultID = response.body().getMessage();
}
} else {
Toast.makeText(getApplicationContext(),"Failed to communicate with server",Toast.LENGTH_LONG).show();
}
}
@Override
public void onFailure(Call<Respond> call, Throwable t) {
System.out.println("Failure");
}
});
}
Run Code Online (Sandbox Code Playgroud)
最后,对于GET请求
final boolean[] resultReady = {false};
while (!resultReady[0]) {
FileApi service = RetroClient.getApiService();
Call<Respond> resultCall = service.getCompareResult(session_id, resultID);
resultCall.enqueue(new Callback<Respond>() {
@Override
public void onResponse(Call<Respond> call, Response<Respond> response) {
// Response Success or Fail
if (response.isSuccessful()) {
if (response.body().getError()){
System.out.println("Got Response");
resultReady[0] = true;
theta[0] = response.body().getResult();
Toast.makeText(getApplicationContext(),"Measurement Recieved",Toast.LENGTH_LONG).show();
}
else {
Toast.makeText(getApplicationContext(),"Error Recieved",Toast.LENGTH_LONG).show();
}
} else {
Toast.makeText(getApplicationContext(),"Failed to communicate with server",Toast.LENGTH_LONG).show();
}
}
@Override
public void onFailure(Call<Respond> call, Throwable t) {
}
});
}
Run Code Online (Sandbox Code Playgroud)
我尝试将断点放在OnResponse函数中,并将调试语句放在OnResponse和OnFailure中,并且似乎该代码永远不会运行。这里可能出什么问题了?
编辑:好的,所以我有一些日志记录数据。我已经从python控制台测试了服务器
In [1]: import requests
In [2]: requests.get("http://localhost:5002/image/1/find-transform/2")
Out[2]: <Response [200]>
In [3]: _.text
Out[3]: '{"error": true, "id": 0, "result": 1.1}'
In [4]: requests.post("http://localhost:5002/image/find-transform")
Out[4]: <Response [404]>
In [5]: requests.post("http://localhost:5002/image/1/find-transform")
Out[5]: <Response [200]>
In [6]: _.text
Out[6]: '{"error": true, "id": 1, "result": 1.2}'
Run Code Online (Sandbox Code Playgroud)
我还根据注释的建议将http日志记录放在客户端,这给出了该日志记录的输出。
D/OkHttp: --> POST http://192.168.0.19:5002/image
Content-Type: multipart/form-data; boundary=bc4ae771-2762-4124-8f07-d00dc925d886
D/OkHttp: Content-Length: 2044497
D/OkHttp: --bc4ae771-2762-4124-8f07-d00dc925d886
Content-Disposition: form-data; name="uploaded_file"; filename="first_image.jpg"
Content-Type: multipart/form-data
Content-Length: 2043935
(Truncated raw image data)
V/RenderScript: 0x7f77b4c000 Launching thread(s), CPUs 8
D/OkHttp: <-- 200 OK http://192.168.0.19:5002/image (410ms)
Content-Type: application/json
Content-Length: 39
Server: Werkzeug/0.14.1 Python/3.6.8
Date: Wed, 24 Jul 2019 17:00:47 GMT
D/OkHttp: {"error": true, "id": 9, "result": 5.5}
<-- END HTTP (39-byte body)
I/System.out: 5.5
W/ImageReader_JNI: Unable to acquire a lockedBuffer, very likely client tries to lock more than maxImages buffers
I/System.out: Resultcall
D/OkHttp: --> POST http://192.168.0.19:5002/image/9/find-transform
Content-Type: multipart/form-data; boundary=63de36cb-0961-4802-a97f-57b98ebcd8cb
D/OkHttp: Content-Length: 1655614
D/OkHttp: --63de36cb-0961-4802-a97f-57b98ebcd8cb
Content-Disposition: form-data; name="uploaded_file"; filename="first_image.jpg"
Content-Type: multipart/form-data
Content-Length: 1655386
(Truncated raw image data)
D/OkHttp: <-- HTTP FAILED: java.net.SocketException: sendto failed: EPIPE (Broken pipe)
D/OkHttp: --> GET http://192.168.0.19:5002/image/9/find-transform/-1
--> END GET
D/OkHttp: <-- 200 OK http://192.168.0.19:5002/image/9/find-transform/-1 (90ms)
Run Code Online (Sandbox Code Playgroud)
看来服务器既正确地接收了请求,又发送了正确的响应。因此,客户端一定无法正确处理某些内容,但我不知道该怎么办。
| 归档时间: |
|
| 查看次数: |
266 次 |
| 最近记录: |