Android compresses POST request data

Source: Internet
Author: User
Tags http post

In Android development, the POST request is often used to send data to the server. In some cases, the post data is relatively large, such as obtaining local application information from the e-market, and then sending the application package name and version number to the server, if there are many applications, XML data will be huge, 10 KB ~ 30kb is possible. This is necessary to compress the post data.

Of course, we can use other message formats, such as protobuf and other highly efficient data formats, to reduce the amount of data sent, but this will increase the workload of server and client developers, it also takes some time to understand this data exchange format. Let's not talk about it. Let's take a look at the format of the following post message body (including a POST request Uploaded By a file ).

-------------------7d4a6d158c9Content-Disposition: form-data; name="myfile"; filename="test.txt"<this is file content>-------------------7d4a6d158c9Content-Disposition: form-data; name="text1" foo-------------------7d4a6d158c9Content-Disposition: form-data; name="text2" <this is gzipped post field> gzipped size:214 original:416-------------------7d4a6d158c9--

In this request body, the content of fields whose name is text2 adopts gzip compression to simulate large string fields. When the string is compressed by 10 KB, it can reduce the traffic by one to four times. For details about how to construct the message body, refer to here.

Content-Disposition: form-data; name="text2"

There are spaces between the colon and the semicolon. Otherwise, an error occurs during Server Parsing. Why? This is what RFC requires.

Next let's take a look at the server side's construction of the post Message Body (this is a feature added in the previous article on file upload)

 

Package COM. hoot. regx; import Java. io. file; import Java. io. fileinputstream; import Java. io. ioexception; import Java. io. inputstream; import Java. io. outputstream; import java.net. httpurlconnection; import java.net. URL; public class postdata {Private Static final string long_string = "require 'zlib 'equire 'stringio '" + "file.open('t1.gz', 'w') Do | f | Gz = zlib :: gzipwriter. new (f) "+" GZ. write 'Part one' gz.closeendfile.open('t2.gz ', 'w') Do | f | "+" Gz = zlib: gzipwriter. new (f) GZ. write 'Part 2' GZ. close "+" endcontents1 = file.open('t1.gz ', \ "RB \") {| Io. read} "+" contents2 = file.open('t2.gz ', \ "RB \") {| Io. read} "+" c = contents1 + contents2 "+" Gz = zlib: gzipreader. new (stringio. new (c) "+" GZ. each do | L | "+" puts l "+" end "; Private Static final string char_set =" UTF-8 "; Private Static final string boundary =" ----------------- 7d4a6d158c9 "; private Static final string two_hyphens = "--"; Private Static final string end = "\ r \ n "; /*** @ Param ARGs * @ throws ioexception */public static void main (string [] ARGs) throws ioexception {postdata Pd = new postdata (); PD. uploadfile (); // PD. uploadxml ();} public void uploadfile () throws ioexception {url = new URL ("http: // localhost: 4567/upload"); httpurlconnection conn = (httpurlconnection) URL. openconnection (); Conn. setdooutput (true); Conn. setdoinput (true); Conn. setrequestmethod ("Post"); Conn. setrequestproperty ("connection", "keep-alive"); Conn. setrequestproperty ("charset", char_set); Conn. setrequestproperty ("Content-Type", "multipart/form-data; boundary =" + boundary); stringbuffer sb = new stringbuffer (); // The decomposition operator sb. append (two_hyphens + boundary + end); // you can specify an empty line between the information of the last file and that of the uploaded file, otherwise, the subsequent data will be read as an attribute sb. append ("content-Disposition: Form-data; name = \" myfile \ "; filename = \" test.txt \ "" + end); system. out. print (sb. tostring (); byte [] DATA = sb. tostring (). getbytes (); outputstream OS = Conn. getoutputstream (); OS. write (data); // The following is the file data: fileinputstream FD = new fileinputstream (new file ("test.txt"); byte [] Buf = new byte [1024]; int Len = 0; while (LEN = Fi. read (BUF)> 0) {OS. write (BUF, 0, Len);} system. out. print ("<This is file content>");/*** pay attention to the Space following form-data ----------------------------- 7d33a816d302b6 ** content-Disposition: Form-data; name = "text1" ** Foo --------------------------- 7d33a816d302b6 */string split = end + two_hyphens + boundary + end + "content-Disposition: Form-data; "+" name = \ "text1 \" "+ end +" foo "/* + end */; system. out. print (split); OS. write (split. getbytes (); byte [] B = ziputil. compress (long_string.getbytes (); split = end + two_hyphens + boundary + end + "content-Disposition: Form-data; "+" name = \ "text2 \" "+ end/* + datastr + end */; system. out. print (split); OS. write (split. getbytes (); OS. write (B); OS. write (end. getbytes (); system. out. print ("<This is gzipped post field> gzipped size:" + B. length + "Original:" + long_string.getbytes (). length + end); string endstr = two_hyphens + boundary + two_hyphens + end; byte [] end_data = endstr. getbytes (); system. out. print (endstr); OS. write (end_data); OS. flush (); OS. close (); FCM. close (); inputstream is = Conn. getinputstream (); While (LEN = is. read (BUF)> 0) {system. out. write (BUF, 0, Len);} // is. close ();}}

The following is a tool class for compressing strings:

public static byte[] compress(byte[] data) throws IOException {if (data == null || data.length == 0) {return data;}ByteArrayOutputStream out = new ByteArrayOutputStream();GZIPOutputStream gzip = new GZIPOutputStream(out);gzip.write(data);gzip.close();return out.toByteArray();}

The server side is still the Sinatra framework, which is small and practical. If your servlet works well, it doesn't matter. You haven't started Java EE for a long time, and you forgot about it.

require 'rubygems'require 'sinatra'require 'haml'require 'zlib'get '/' do  'Hello world'end# Handle GET-request (Show the upload form)get "/upload" do  haml :uploadend# Handle POST-request (Receive and save the uploaded file)post "/upload" do  logger.info "#{params}"  unless   params[:myfile] &&  (tmpfile = params[:myfile][:tempfile]) &&  (name = params[:myfile][:filename])    @error = "No file selected"    logger.info "params #{@error} file: #{tmpfile} name: #{name} #{params}"    return haml(:error)  end  directory = 'uploads'  path = File.join(directory, name)  logger.info "name:#{params[:text1]}, #{params[:text2]}"  #gz = Zlib::GzipReader.new(params[:text2])  #print gz.read  #gz.close  logger.info inflate(params[:text2])  File.open(path, "wb") do |f|    f.write(tmpfile.read)  end  @msg = "file  #{name} was successfully uploaded!"enddef inflate(string)  gz = Zlib::GzipReader.new(StringIO.new(params[:text2].force_encoding("UTF-8")))  data = gz.readend

Blog source address here, PS: I didn't expect this reading volume to be so high... My poor blog on VPs ....

 

 

 

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.