Перенос огромных данных из сервлета в приложение для Android - PullRequest
3 голосов
/ 13 июля 2011

Я занимаюсь разработкой приложения для Android, в котором мне нужно сохранить растровое изображение на удаленном сервере.Шаги:

Шаг 1: Преобразование растрового изображения в байтовый массив и отправка его из приложения Android на сервер. Я отправляю растровое изображение как MultipartEntity. На стороне сервера я получаю его вметод doPost ().

Шаг 2: Сохранить байтовый массив в базе данных mysql. Битовая карта хранится как тип данных BLOB-объектов. Я могу сохранить полученный байтовый массив в базе данных mysql.

Шаг 3: Получить растровое изображение, хранящееся в виде BLOB-объекта, и отправить его обратно в приложение Android. Я могу получить BLOB-объект, преобразовать его в байтовый массив и отправить его.

MyПроблема

Проблема в том, что данные, отправленные с сервера, принимаются небольшими партиями. Длина изображения была 1380, но она получена с переменной длиной 10, 50 и 100. Когда я складываю общее количествоЯ получаю только 1345, пропуская несколько байтов данных. Я отправляю код в конец приема.

URL url = new URL( "http://10.0.2.2:8080/ServerPartProject/BlobGetter");
 URLConnection yc = url.openConnection();              
 BufferedReader in = new BufferedReader(new       InputStreamReader(yc.getInputStream()));                                                      String data;
 int val=0; 
 while((data=in.readLine())!=null){
    val=val+data.length();  //The data.length is like 10,20..
 }
 System.out.println("Total value obtained is "+val);//val was 1345 where it should be 1380

конец отправки:

OutputStreamWriter writer = new OutputStreamWriter(response.getOutputStream());
writer.write(senddata);

Как получить его в полном объеме?

Ответы [ 5 ]

1 голос
/ 03 января 2013

Вы можете использовать JSON.

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    List<String> list = new ArrayList<String>();
    list.add("item1");
    list.add("item2");
    list.add("item3");
    String json = new Gson().toJson(list);

    response.setContentType("application/json");
    response.setCharacterEncoding("UTF-8");
    response.getWriter().write(json);
}

Это создаст и вернет List в следующем формате JSON:

["item1","item2","item3"]

Это, в свою очередь, разбирается на org.jsonAPI в Android выглядит следующим образом:

String jsonString = getServletResponseAsStringSomehow(); // HttpClient?
JSONArray jsonArray = new JSONArray(jsonString);
List<String> list = new ArrayList<String>();

for (int i = 0; i < jsonArray.length(); i++) {
    list.add(jsonArray.getString(i));
}

// Now you can use `list`.
1 голос
/ 13 июля 2011

Я бы не стал использовать символьно-ориентированные программы чтения и записи для отправки и получения данных изображения (которые предположительно в двоичном формате (если вы используете кодировку base64 или что-то, что вы не упоминаете, не обращайте на это внимания)).Байты интерпретируются как символы, преобразуются обратно в байты, затем снова интерпретируются как символы и, наконец, обратно в байты;в процессе данные изображения повреждены.Используйте интерфейсы InputStream / OutputStream, предоставляемые объектами Http, вместо того, чтобы помещать в них средства чтения и записи.

1 голос
/ 13 июля 2011

Вы используете readLine () для чтения байтовых данных, что, по крайней мере, странно, если не проблема. В вашем примере кода вы не закрываете свои читатели (которые должны использовать InputStreams). В буферизованном вводе могут остаться некоторые байты в буфере, которые не будут считываться, пока не будут сброшены или закрыты.

Надеюсь, это поможет.

1 голос
/ 13 июля 2011

Не используйте readLine () .Вы работаете с необработанными данными.Необработанные данные не имеют строк, содержащих только текст.

Некоторые из ваших байтов, вероятно, преобразованы в 2-байтовые символы Юникода, что объясняет вашу предполагаемую потерю данных.

0 голосов
/ 15 июля 2011

Если ваша база данных находится локально, а не в облаке Интернета, вы можете получить к ней доступ напрямую через API JDBC с помощью коннектора JDBC mysql-connector-java-3.0.17-ga-bin.jar.Это не значит, что вы не можете получить доступ к вашей базе данных удаленно, но очень неразумно и рискованно выставлять вашу базу данных непосредственно в облаке.

Для чтения большого двоичного объекта в bmp в Android вы можете использовать BitmapFactory, например так:

// this is a snippet of course..

try
{
  Class.forName("com.mysql.jdbc.Driver");
  String astring = "jdbc:mysql://localhost:3306/mydb?user=root&password=pass"; 
  Connection ac = DriverManager. getConnection(astring);
  Statement st = ac.GetStatement();
  astring = "SELECT MYBLOB FROM MYTABLE";  // create your query here
  ResultSet rs = st.executeQuery(astring)

  if(rs.next())
  {
     java.sql.Blob ablob = rs.getBlob("MYBLOB");
     Bitmap bmp = BitmapFactory.decodeStream(ablob.getBinaryStream());

     // here you have your bmp, do whatever you want
     UseBmp(bmp);
  }

}
catch(Exception e)
{
  e.printStackTrace();
}

Вам потребуется реализовать пул соединений для ускорения времени отклика на запросы, поскольку JDBC накладывает небольшие издержки на Android при создании соединения с сервером, для запуска требуется от 2 до 3 секунд, но один разподключено работает очень быстро.

...