A detailed explanation of HTTP service usage in Android programming _android

Source: Internet
Author: User
Tags assert

This example describes the HTTP service usage in Android programming. Share to everyone for your reference, specific as follows:

In Android, in addition to using the API under the Java.net package to access the HTTP service, we can do the job in a different way. The Android SDK comes with Apache's httpclient API. The Apache httpclient is a sophisticated HTTP client that provides full support for the HTTP protocol and can be accessed using HTTP GET and post. Below we combine the example, introduce the use method of HttpClient.

We create a new HTTP project, the project structure as shown:

In this project, we do not need any activity, and all operations are done in the Unit test class Httptest.java.

Because the unit tests are used, here's how to configure the unit tests in Android. All configuration information is completed in Androidmanifest.xml:

<?xml version= "1.0" encoding= "Utf-8"?> <manifest xmlns:android=
"http://schemas.android.com/apk/res/" Android "
   package=" com.scott.http "
   android:versioncode=" 1 "
   android:versionname=" 1.0 ">
  < Application android:icon= "@drawable/icon" android:label= "@string/app_name" >
    <!--Configure the class library to be used by the test-->
    <uses-library android:name= "Android.test.runner"/>
  </application>
  <!--Configure the main class and target package for the test device-- >
  <instrumentation android:name= "Android.test.InstrumentationTestRunner"
           android:targetpackage= "Com.scott.http"/>
  <!--network permissions required to access the HTTP service-->
  <uses-permission android:name= " Android.permission.INTERNET "/>
  <uses-sdk android:minsdkversion=" 8 "/>
</manifest>

Our unit test class then needs to inherit the Android.test.AndroidTestCase class, which itself is an inherited junit.framework.TestCase and provides the GetContext () method, Used to get the Android context, this design is very useful because many Android APIs require contexts to complete.

Now let's take a look at our test cases, Httptest.java code as follows:

Package com.scot.http.test;
Import Java.io.ByteArrayOutputStream;
Import Java.io.InputStream;
Import java.util.ArrayList;
Import java.util.List;
Import Junit.framework.Assert;
Import org.apache.http.HttpEntity;
Import Org.apache.http.HttpResponse;
Import Org.apache.http.HttpStatus;
Import Org.apache.http.NameValuePair;
Import org.apache.http.client.HttpClient;
Import org.apache.http.client.entity.UrlEncodedFormEntity;
Import Org.apache.http.client.methods.HttpGet;
Import Org.apache.http.client.methods.HttpPost;
Import org.apache.http.entity.mime.MultipartEntity;
Import Org.apache.http.entity.mime.content.InputStreamBody;
Import Org.apache.http.entity.mime.content.StringBody;
Import org.apache.http.impl.client.DefaultHttpClient;
Import Org.apache.http.message.BasicNameValuePair;
Import Android.test.AndroidTestCase;
  public class Httptest extends Androidtestcase {private static final String PATH = "Http://192.168.1.57:8080/web"; public void Testget () throws Exception {HttpclienT-client = new Defaulthttpclient ();
    HttpGet get = new HttpGet (PATH + "/testservlet?id=1001&name=john&age=60");
    HttpResponse response = Client.execute (get); if (Response.getstatusline (). Getstatuscode () = = HTTPSTATUS.SC_OK) {InputStream is = response.getentity (). getContent
      ();
      String result = Instream2string (IS);
    Assert.assertequals (Result, "get_success");
    } public void Testpost () throws Exception {httpclient client = new Defaulthttpclient ();
    HttpPost post = new HttpPost (PATH + "/testservlet");
    list<namevaluepair> params = new arraylist<namevaluepair> ();
    Params.add (New Basicnamevaluepair ("id", "1001"));
    Params.add (New Basicnamevaluepair ("name", "John"));
    Params.add (New Basicnamevaluepair ("Age", "60"));
    Httpentity formentity = new urlencodedformentity (params);
    Post.setentity (formentity);
    HttpResponse response = Client.execute (POST); if (Response.getstatusline (). Getstatuscode () = = HttpstatuS.SC_OK) {InputStream is = response.getentity (). getcontent ();
      String result = Instream2string (IS);
    Assert.assertequals (Result, "post_success");
    The public void Testupload () throws Exception {InputStream is = GetContext (). Getassets (). Open ("books.xml");
    HttpClient client = new Defaulthttpclient ();
    HttpPost post = new HttpPost (PATH + "/uploadservlet");
    Inputstreambody ISB = new Inputstreambody (IS, "books.xml");
    Multipartentity multipartentity = new multipartentity ();
    Multipartentity.addpart ("file", ISB);
    Multipartentity.addpart ("desc", New Stringbody ("This is description."));
    Post.setentity (multipartentity);
    HttpResponse response = Client.execute (POST);
      if (Response.getstatusline (). Getstatuscode () = = HTTPSTATUS.SC_OK) {is = Response.getentity (). getcontent ();
      String result = Instream2string (IS);
    Assert.assertequals (Result, "upload_success"); Replace the input stream with a string instream2string private string (inputStream is) throws Exception {Bytearrayoutputstream BAOs = new Bytearrayoutputstream ();
    byte[] buf = new byte[1024];
    int len =-1;
    while (len = Is.read (buf))!=-1) {baos.write (buf, 0, Len);
  Return to New String (Baos.tobytearray ());

 }
}

Because this file contains three test cases, I will introduce them one at a while.

First, we need to be aware that we are using IP when locating the server address, because we cannot use localhost, the service side is running on Windows, and this unit test runs on the Android platform. If using localhost means accessing the service within Android, it may not be accessible, so you must use IP to locate the service.

Let's analyze the Testget test case first. We use the HttpGet, the request parameter is appended directly to the URL, then executes the GET request by the HttpClient, if the response succeeds, obtains the response inside such as the input flow, and converts to the string, finally determines whether is get_success.

The Testget test corresponds to the service-side servlet code as follows:

@Override
  protected void doget (HttpServletRequest request, httpservletresponse response) throws Servletexception, IOException {
    System.out.println ("Doget method is called.");
    String id = request.getparameter ("id");
    String name = Request.getparameter ("name");
    String age = request.getparameter (' age ');
    SYSTEM.OUT.PRINTLN ("ID: + ID +", Name: "+ name +", Age: "+ age");
    Response.getwriter (). Write ("get_success");
  

Then say testpost test cases. We use the Httppost,url with no parameter information, and the parameter information is packaged into a collection of namevaluepair types, Then, after urlencodedformentity processing, the HttpPost setentity method is invoked to set the parameters, and finally the httpclient is executed.

The corresponding service-side code for the Testpost test is as follows:

@Override
  protected void DoPost (HttpServletRequest request, httpservletresponse response) throws Servletexception , IOException {
    System.out.println ("DoPost method is called.");
    String id = request.getparameter ("id");
    String name = Request.getparameter ("name");
    String age = request.getparameter (' age ');
    SYSTEM.OUT.PRINTLN ("ID: + ID +", Name: "+ name +", Age: "+ age");
    Response.getwriter (). Write ("post_success");
  

The above two are the most basic GET request and post requests, the parameters are text data types, to meet the common requirements, but in some cases, for example, we need to use the upload file, we can not use the basic GET request and POST request, we want to use a multiple-part post request. Here's how to upload a file to the server using a multi-part post operation.

Since the HttpClient version shipped with Android does not support multipart post requests, we need to use a Httpmime open source project that specializes in MIME type-related operations. Because Httpmime is included in the Httpcomponents project, we need to go to the Apache website to download the httpcomponents, and then put the Httpmime.jar package into the project, as shown in the figure:

We then looked at the testupload test case, and we used the Httpmime provided inputstreambody to process the file flow parameters and use Stringbody to process the normal text parameters. Finally, all the type parameters are added to a multipartentity instance, and the multipartentity is set as the parameter entity for this post request, and then the POST request is executed. The service-side servlet code is as follows:

Package com.scott.web.servlet;
Import Java.io.FileOutputStream;
Import java.io.IOException;
Import Java.util.Iterator;
Import java.util.List;
Import javax.servlet.ServletException;
Import Javax.servlet.http.HttpServlet;
Import Javax.servlet.http.HttpServletRequest;
Import Javax.servlet.http.HttpServletResponse;
Import Org.apache.commons.fileupload.FileItem;
Import Org.apache.commons.fileupload.FileItemFactory;
Import org.apache.commons.fileupload.FileUploadException;
Import Org.apache.commons.fileupload.disk.DiskFileItemFactory;
Import Org.apache.commons.fileupload.servlet.ServletFileUpload;
  @SuppressWarnings ("Serial") public class Uploadservlet extends HttpServlet {@Override @SuppressWarnings ("Rawtypes")
    protected void DoPost (HttpServletRequest request, httpservletresponse response) throws Servletexception, IOException {
    Boolean ismultipart = servletfileupload.ismultipartcontent (request);
   if (Ismultipart) {Fileitemfactory factory = new Diskfileitemfactory ();   Servletfileupload upload = new Servletfileupload (factory);
        try {List items = upload.parserequest (request);
        Iterator iter = Items.iterator ();
          while (Iter.hasnext ()) {Fileitem item = (Fileitem) iter.next ();
            if (Item.isformfield ()) {//General text information processing String paramname = Item.getfieldname ();
            String paramvalue = item.getstring ();
          System.out.println (paramname + ":" + paramvalue);
            else {//upload file information processing String fileName = Item.getname ();
            byte[] data = Item.get ();
            String FilePath = Getservletcontext (). Getrealpath ("/files") + "/" + fileName;
            FileOutputStream fos = new FileOutputStream (FilePath);
            Fos.write (data);
          Fos.close ();
      A catch (Fileuploadexception e) {e.printstacktrace ());
  } response.getwriter (). Write ("upload_success");

 }
}

The server uses the Apache open source project FileUpload to process, therefore we need the commons-fileupload and Commons-io these two projects the jar package, to the server development not very familiar friend may go to the Internet to look up the relevant information.

After introducing the above three different situations, we need to consider a problem, in the practical application, we cannot create a new httpclient each time, but should only for the entire application creates a httpclient, and uses it for all HTTP communication. Also, be aware of the multithreading problems that can occur when multiple requests are issued simultaneously through a httpclient. To address these two issues, we need to improve our project:

1. Extend the default application of the system and apply it to the project.

2. Use the Threadsafeclientmanager provided by the HttpClient class library to create and manage HttpClient.

The improved project structure is shown below:

Where MyApplication extends the application of the system, the code is as follows:

Package com.scott.http;
Import org.apache.http.HttpVersion;
Import org.apache.http.client.HttpClient;
Import Org.apache.http.conn.ClientConnectionManager;
Import Org.apache.http.conn.scheme.PlainSocketFactory;
Import Org.apache.http.conn.scheme.Scheme;
Import Org.apache.http.conn.scheme.SchemeRegistry;
Import Org.apache.http.conn.ssl.SSLSocketFactory;
Import org.apache.http.impl.client.DefaultHttpClient;
Import Org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
Import Org.apache.http.params.BasicHttpParams;
Import Org.apache.http.params.HttpParams;
Import Org.apache.http.params.HttpProtocolParams;
Import Org.apache.http.protocol.HTTP;
Import android.app.Application;
  public class MyApplication extends application {private httpclient httpclient;
    @Override public void OnCreate () {super.oncreate ();
  HttpClient = This.createhttpclient ();
    @Override public void Onlowmemory () {super.onlowmemory ();
  This.shutdownhttpclient (); @Override Public VOID onterminate () {super.onterminate ();
  This.shutdownhttpclient ();
    ///Create HttpClient instance private HttpClient createhttpclient () {httpparams params = new Basichttpparams ();
    Httpprotocolparams.setversion (params, httpversion.http_1_1); Httpprotocolparams.setcontentcharset (params, HTTP.
    Default_content_charset);
    Httpprotocolparams.setuseexpectcontinue (params, true);
    Schemeregistry Schreg = new Schemeregistry ();
    Schreg.register (New Scheme ("http", Plainsocketfactory.getsocketfactory (), 80));
    Schreg.register (New Scheme ("https", Sslsocketfactory.getsocketfactory (), 443));
    Clientconnectionmanager connmgr = new Threadsafeclientconnmanager (params, schreg);
  return new Defaulthttpclient (connmgr, params); //Close Connection Manager and release resource private void Shutdownhttpclient () {if (httpclient!= null && Httpclient.getconnectionman
    Ager ()!= null) {Httpclient.getconnectionmanager (). Shutdown (); }///External supply httpclient instance public httpclient GETHTTPCLient () {return httpclient;

 }
}

We rewrote the OnCreate () method, creating a httpclient at system startup, overriding the Onlowmemory () and Onterminate () methods, shutting down the connection at the end of memory, and releasing resources. It should be noted that when instantiating Defaulthttpclient, a Clientconnectionmanager instance created by Threadsafeclientconnmanager is passed in. Responsible for managing HTTP connections for HttpClient.

Then, to make our enhanced version of "Application" effective, you need to configure the following in Androidmanifest.xml:

<application android:name= ". MyApplication "...> ...
</application>

If we don't have a configuration, The system defaults to using Android.app.Application, we add the configuration, the system uses our com.scott.http.MyApplication, and then we can call Getapplication in the context () To get the MyApplication instance.

With the above configuration, we can apply it in the activity, Httpactivity.java code as follows:

Package com.scott.http;
Import Java.io.ByteArrayOutputStream;
Import Java.io.InputStream;
Import Org.apache.http.HttpResponse;
Import Org.apache.http.HttpStatus;
Import org.apache.http.client.HttpClient;
Import Org.apache.http.client.methods.HttpGet;
Import android.app.Activity;
Import Android.os.Bundle;
Import Android.view.View;
Import Android.widget.Button;
Import Android.widget.Toast; public class Httpactivity extends activity {@Override protected void onCreate (Bundle savedinstancestate) {super.
    OnCreate (savedinstancestate);
    Setcontentview (R.layout.main);
    Button btn = (button) Findviewbyid (R.ID.BTN); 
      Btn.setonclicklistener (New View.onclicklistener () {@Override public void OnClick (View v) {execute ();
  }
    }); private void Execute () {try {MyApplication app = (myapplication) this.getapplication ();//Get MyApplication Real  Example HttpClient client = App.gethttpclient (); Gets the httpclient instance httpget get = new HttpGet ("http://192.168.1.57:8080/web/testservlet?id=1001&name=john&age=60 ");
      HttpResponse response = Client.execute (get); if (Response.getstatusline (). Getstatuscode () = = HTTPSTATUS.SC_OK) {InputStream is = response.getentity (). GetConte
        NT ();
        String result = Instream2string (IS);
      Toast.maketext (this, result, Toast.length_long). Show ();
    } catch (Exception e) {e.printstacktrace (); }///Convert input flow to string private string instream2string (InputStream is) throws Exception {Bytearrayoutputstream BAOs =
    New Bytearrayoutputstream ();
    byte[] buf = new byte[1024];
    int len =-1;
    while (len = Is.read (buf))!=-1) {baos.write (buf, 0, Len);
  Return to New String (Baos.tobytearray ());

 }
}

Click on the "Execute" button to perform the following results:

I hope this article will help you with the Android program.

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.