Transfer huge data from servlet to android application
I am developing an android application in which i have to store a bitmap in a remote server. Steps are:
Step 1: Convert the bitmap into byte array 开发者_运维技巧and send it from android application to server.I am sending the bitmap as MultipartEntity.In server side, i am receiving it in doPost() method.
Step 2: Store the byte array in mysql database.Bitmap is stored as blob data type.I am able to store the received byte array into mysql database.
Step 3: Retrieve the bitmap stored as blob and send it back to the android application.I am able to retrieve the blob and convert into byte array and send it.
My Issue
The problem is the data sent from server is received in small batches.The image length was 1380 but it is received in variable lengths of 10's,50's,100's.When i add up the total i am getting only 1345,missing few bytes of data.I am posting the code in receiving end.
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
sending end:
OutputStreamWriter writer = new OutputStreamWriter(response.getOutputStream());
writer.write(senddata);
How to receive it in full stretch?
Don't use readLine(). You are working with raw data. Raw data does not have lines only text has.
Some of your bytes are probably converted into 2 byte unicode characters which explains your perceived loss of data.
I would avoid using the character-oriented Reader and Writer to send and receive image data (which is presumably in binary [if you are base64 encoding or something, which you don't mention, disregard this]). The bytes are being interpreted as characters, converted back to bytes, then interpreted as characters again, and finally back to bytes; in the process the image data is being corrupted. Use the InputStream/OutputStream interfaces supplied by the Http objects instead of putting Readers and Writers on them.
You are using readLine() for reading byte data, which is at least odd, if not the issue. In your sample code, you are not closing your Readers (which should InputStreams). Buffered input may have some bytes left in the buffer which will not be read until flushed or closed.
Hope this helps.
You can use 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);
}
This will build and return the List
in the following JSON format:
["item1","item2","item3"]
This is in turn parseable by org.json
API in Android as follows:
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`.
If your database resides locally and not in the internet cloud, you can access it directly via JDBC API with JDBC connector mysql-connector-java-3.0.17-ga-bin.jar. Is not that you can't access your database remotely but is very unwise and risky to expose your database directly in the cloud.
For reading a blob to a bmp in Android, you can use BitmapFactory, like this:
// 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();
}
You'll need to implement a pool of connections to speed up query response times cause JDBC put a little overhead to Android when building a connection to server, it takes 2 to 3 seconds to start but once connected works very fast.
精彩评论