将巨大的数据从servlet传输到android应用程序

时间:2011-07-13 12:57:41

标签: java android mysql servlets blob

我正在开发一个Android应用程序,我必须在远程服务器中存储位图。 步骤是:

第1步:将位图转换为字节数组并将其从android应用程序发送到server.I我将位图发送为MultipartEntity。在服务器端,我在doPost()方法中接收它。

第2步:将字节数组存储在mysql数据库中.Bitmap存储为blob数据类型。我能够将收到的字节数组存储到mysql数据库中。

第3步:检索存储为blob的位图并将其发送回android应用程序。我能够检索blob并转换为字节数组并发送它。

我的问题

问题是从服务器发送的数据是小批量接收的。图像长度是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 个答案:

答案 0 :(得分:1)

请勿使用readLine()。 您正在使用原始数据。原始数据没有只有文本的行。

您的一些字节可能会转换为2字节的unicode字符,这可以解释您感知到的数据丢失。

答案 1 :(得分:1)

我会避免使用面向字符的Reader and Writer来发送和接收图像数据(可能是二进制的[如果你是base64编码或其他东西,你没有提及,请忽略这一点])。字节被解释为字符,转换回字节,然后再次解释为字符,最后返回字节;在此过程中图像数据被破坏。使用Http对象提供的InputStream / OutputStream接口,而不是将Readers和Writers放在它们上。

答案 2 :(得分:1)

您正在使用readLine()来读取字节数据,如果不是问题,则至少是奇数。在示例代码中,您没有关闭读者(应该是InputStreams)。缓冲输入可能在缓冲区中留下一些字节,直到刷新或关闭才会被读取。

希望这有帮助。

答案 3 :(得分:1)

您可以使用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);
}

这将以以下JSON格式构建并返回List

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

这可以通过Android中的org.json API解析,如下所示:

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`.

答案 4 :(得分:0)

如果您的数据库位于本地而不是Internet云中,则可以使用JDBC连接器mysql-connector-java-3.0.17-ga-bin.jar直接通过JDBC API访问它。并不是说您无法远程访问数据库,但直接在云中公开您的数据库是非常不明智和冒险的。

要在Android中读取blob到bmp,可以使用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秒,但一旦连接工作速度非常快。 / p>