Я отправляю массив изображений в REST API, который возвращает поля формы после оцифровки. Мое приложение имеет минимальный уровень API 21. Я использую Android Volley
для отправки и получения данных в / из REST API.
Код отлично работает для одного изображения, но затем не работает, когда отправлено более одного изображения. Несколько ответов здесь предложили очистить кеш в очереди , но он уже присутствует в коде, и это не решает проблему.
Кроме того, в фоновом коде нет проблем, потому что он хорошо работает в Postman, но ответ не получается в Android. Прямо сейчас я пробую это на Зефире. Это работает редко. Похоже, проблема не в API.
JSON-запрос:
{
"imageFormat": "jpeg",
"formType": "dummyForm",
"images":
[
"//base64 of image1",
"//base64 of image2", //as many as required
]
}
JSON-ответ:
{
"dummyLines": // Response from all images' form fields is in this array
[
{
"confidence": "high",
"key": "FIRST NAME :",
"value": "ABC"
},
...
// The above set is repeated for all form fields
],
"dummyStatus": "Succeeded",
"message": "none"
}
EDIT:
Это классы, которые обрабатывают запрос и ответ:
DummyRequest
класс
public class DummyRequest
{
String imageFormat;
String formType;
String images[];
}
DummyImageResponse
класс
public class DummyImageResponse implements Serializable
{
ArrayList<FieldsJson> dummyLines = new ArrayList<>();
String dummyStatus;
}
FieldsJson
класс
public class FieldsJson implements Serializable
{
String key;
String value;
String confidence;
}
EDIT
Этот код кодирует Bitmap
изображения в Base64
:
for(int i=0; i<cameraImageAdapter.getCount(); i++)
{
Bitmap bitmap = BitmapFactory.decodeFile(capturedImagePathList.get(i));
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream);
byte[] imageByteArray = byteArrayOutputStream.toByteArray();
cameraEncodedImages[i] = Base64.encodeToString(imageByteArray, Base64.DEFAULT);
}
EDIT
Я включил некоторый дополнительный код в метод onErrorResponse и получил следующую трассировку стека.
Это код, который вызывает API:
ResponseHandler responseHandler = new ResponseHandler(
API_URL,
DummyImageResponse.class,
request,
new HashMap<String, String>(),
new Response.Listener<DummyImageResponse>() {
@Override
public void onResponse(DummyImageResponse response) {
Log.e("Success response", response.toString());
// Call new activity to display the result
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e("Error response", error.toString());
NetworkResponse errorResponse = error.networkResponse;
if(error instanceof ServerError && errorResponse != null)
{
try {
Log.e("In error response", "Response not null");
String response = new String(errorResponse.data,
HttpHeaderParser.parseCharset(errorResponse.headers, "UTF-8"));
Log.e("Parsed response", response);
}
catch (UnsupportedEncodingException e)
{
Log.e("In error response", e.getMessage());
}
}
else
Log.e("In error response", "Response is null");
// Call new activity to display error message
}
}
);
RequestQueue queue = Volley.newRequestQueue(context);
responseHandler.setRetryPolicy(new DefaultRetryPolicy(
50000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
queue.getCache().clear(); // Clear the queue
queue.add(responseHandler); // Request is sent to the REST API
Ожидаемый вывод должен содержать все поля в форме. Однако, когда задействовано несколько изображений, ответ JSON, скорее всего, по какой-то причине искажается, и это может привести к генерации ServerError
из-за некоторой библиотеки glassfish
, которая анализирует JSON, я читал так. Я не уверен.
Возможно, это может быть потому, что Android и Почтальон обрабатывают данные JSON немного по-разному.
Это точное сообщение об ошибке, которое я получаю:
<code>E/Volley: [18942] BasicNetwork.performRequest: Unexpected response code 500 for **URL goes here**
E/Error response: com.android.volley.ServerError
E/In error response: Response not null
E/Parsed response: <!doctype html><html lang="en"><head><title>HTTP Status 500 – Internal Server Error</title><style type="text/css">h1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} h2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} h3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} body {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} b {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} p {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;} a {color:black;} a.name {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTP Status 500 – Internal Server Error</h1><hr class="line" /><p><b>Type</b> Exception Report</p><p><b>Message</b> java.lang.StringIndexOutOfBoundsException: String index out of range: -2</p><p><b>Description</b> The server encountered an unexpected condition that prevented it from fulfilling the request.</p><p><b>Exception</b></p><pre>javax.servlet.ServletException: java.lang.StringIndexOutOfBoundsException: String index out of range: -2
org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:408)
org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:346)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:365)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:318)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:205)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
Основная причина
java.lang.StringIndexOutOfBoundsException: String index out of range: -2
java.lang.String.substring(String.java:1967)
com.example.ICRAPI.GetGender.main(GetGender.java:21)
com.example.ICRAPI.dummyForm.main(dummyForm.java:178)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:498)
org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory.lambda$static$0(ResourceMethodInvocationHandlerFactory.java:52)
org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:124)
org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:167)
org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$TypeOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:219)
org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:79)
org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:469)
org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:391)
org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:80)
org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:253)
org.glassfish.jersey.internal.Errors$1.call(Errors.java:248)
org.glassfish.jersey.internal.Errors$1.call(Errors.java:244)
org.glassfish.jersey.internal.Errors.process(Errors.java:292)
org.glassfish.jersey.internal.Errors.process(Errors.java:274)
org.glassfish.jersey.internal.Errors.process(Errors.java:244)
org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:265)
org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:232)
org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:679)
org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:392)
org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:346)
org.glassfish.jersey.servlet.ServletConta
</code>