Use http service in Android

Source: Internet
Author: User

In Android, in addition to using APIs in the java.net package to access the HTTP service, we can also do the work in another way. The android SDK comes with the httpclient API of Apache. Apache httpclient is a complete HTTP client that provides comprehensive support for the HTTP protocol and can be accessed using http get and post. Next we will introduce how to use httpclient with examples.

Create an HTTP project and project structure

In this project, we do not need any activity, and all operations are completed in the unit test class httptest. java.

Because unit tests are used, we will first introduce how to configure unit tests in Android. All configuration information is completed in androidmanifest. xml:

<? XML version = "1.0" encoding = "UTF-8"?> <Br/> <manifest xmlns: Android = "http://schemas.android.com/apk/res/android" <br/> package = "com. scott. HTTP "<br/> Android: versioncode =" 1 "<br/> Android: versionname =" 1.0 "> <br/> <application Android: icon = "@ drawable/icon" Android: Label = "@ string/app_name"> <br/> <! -- Configure the class library to be used for testing --> <br/> <uses-library Android: Name = "android. test. runner "/> <br/> </Application> <br/> <! -- Configure the main class and target package of the test device --> <br/> <instrumentation Android: Name = "android. test. instrumentationtestrunner "<br/> Android: targetpackage =" com. scott. HTTP "/> <br/> <! -- Network permissions required to access the HTTP service --> <br/> <uses-Permission Android: Name = "android. permission. internet "/> <br/> <uses-SDK Android: minsdkversion =" 8 "/> <br/> </manifest>

Then, our unit test class needs to inherit android. test. androidtestcase class, which inherits from JUnit. framework. testcase and provides the getcontext () method to obtain the android context. This design is very useful because many Android APIs require context to complete.

Now let's take a look at our test cases. The httptest. Java code is as follows:

Package COM. scot. HTTP. test; </P> <p> Import Java. io. bytearrayoutputstream; <br/> Import Java. io. inputstream; <br/> Import Java. util. arraylist; <br/> Import Java. util. list; </P> <p> Import JUnit. framework. assert; </P> <p> Import Org. apache. HTTP. httpentity; <br/> Import Org. apache. HTTP. httpresponse; <br/> Import Org. apache. HTTP. httpstatus; <br/> Import Org. apache. HTTP. namevaluepair; <br/> Import Org. apache. HTTP. clie NT. httpclient; <br/> Import Org. apache. HTTP. client. entity. urlencodedformentity; <br/> Import Org. apache. HTTP. client. methods. httpget; <br/> Import Org. apache. HTTP. client. methods. httppost; <br/> Import Org. apache. HTTP. entity. mime. multipartentity; <br/> Import Org. apache. HTTP. entity. mime. content. inputstreambody; <br/> Import Org. apache. HTTP. entity. mime. content. stringbody; <br/> Import Org. apache. HTTP. impl. c Lient. defaulthttpclient; <br/> Import Org. apache. HTTP. message. basicnamevaluepair; </P> <p> Import android. test. androidtestcase; </P> <p> public class httptest extends androidtestcase {</P> <p> Private Static final string Path = "http: // 192.168.1.57: 8080/Web "; </P> <p> Public void testget () throws exception {<br/> httpclient client = new defaulthttpclient (); <br/> httpget get = new httpget (path + "/testservlet? Id = 1001 & name = John & age = 60 "); <br/> httpresponse response = client.exe cute (get); <br/> If (response. getstatusline (). getstatuscode () = httpstatus. SC _ OK) {<br/> inputstream is = response. getentity (). getcontent (); <br/> string result = instream2string (is); <br/> assert. assertequals (result, "get_success"); <br/>}</P> <p> Public void testpost () throws exception {<br/> httpclient client = new defau Lthttpclient (); <br/> httppost post = new httppost (path + "/testservlet"); <br/> List <namevaluepair> Params = new arraylist <namevaluepair> (); <br/> Params. add (New basicnamevaluepair ("ID", "1001"); <br/> Params. add (New basicnamevaluepair ("name", "John"); <br/> Params. add (New basicnamevaluepair ("Age", "60"); <br/> httpentity formentity = new urlencodedformentity (Params); <br/> post. setentity (formentity); <Br/> httpresponse response = client.exe cute (post); <br/> If (response. getstatusline (). getstatuscode () = httpstatus. SC _ OK) {<br/> inputstream is = response. getentity (). getcontent (); <br/> string result = instream2string (is); <br/> assert. assertequals (result, "post_success"); <br/>}</P> <p> Public void testupload () throws exception {<br/> inputstream is = getcontext (). getassets (). open ("book S. XML "); <br/> httpclient client = new defaulthttpclient (); <br/> httppost post = new httppost (path +"/uploadservlet "); <br/> inputstreambody ISB = new inputstreambody (is, "books. XML "); <br/> multipartentity = new multipartentity (); <br/> multipartentity. addpart ("file", ISB); <br/> multipartentity. addpart ("DESC", new stringbody ("this is description. "); <br/> post. setentity (multipartenti Ty); <br/> httpresponse response = client.exe cute (post); <br/> If (response. getstatusline (). getstatuscode () = httpstatus. SC _ OK) {<br/> is = response. getentity (). getcontent (); <br/> string result = instream2string (is); <br/> assert. assertequals (result, "upload_success "); <br/>}</P> <p> // convert the input stream to a string <br/> private string instream2string (inputstream is) throws exception {<br/> bytearrayoutputstre Am baos = new bytearrayoutputstream (); <br/> byte [] Buf = new byte [1024]; <br/> int Len =-1; <br/> while (LEN = is. read (BUF ))! =-1) {<br/> baos. write (BUF, 0, Len); <br/>}< br/> return new string (baos. tobytearray (); <br/>}< br/>

This file contains three test cases, so I will introduce them one by one.

First of all, we need to note that the IP address is used when locating the server address, because localhost cannot be used here, the server is running on Windows, and this unit test runs on the Android platform, if localhost is used, it means to access the service within Android, which may not be accessible. Therefore, IP addresses must be used to locate the service.

Let's analyze the testget test cases first. Httpget is used, and the request parameters are directly appended to the URL. Then, httpclient executes the GET request. If the response is successful, the system obtains the input stream in the response and converts it to a string, finally, determine whether it is get_success.

The servlet code for testget testing is as follows:

@ Override <br/> protected void doget (httpservletrequest request, httpservletresponse response) throws servletexception, ioexception {<br/> system. out. println ("doget method is called. "); <br/> string id = request. getparameter ("ID"); <br/> string name = request. getparameter ("name"); <br/> string age = request. getparameter ("Age"); <br/> system. out. println ("ID:" + ID + ", name:" + name + ", age:" + age); <br/> response. getwriter (). write ("get_success"); <br/>}

Then let's talk about the testpost test case. Httppost is used, and there is no parameter information after the URL. The parameter information is encapsulated into a set of namevaluepair types, after urlencodedformentity processing, call the setentity method of httppost to set the parameters, and then run the httpclient command.

The server code for testpost testing is as follows:

@ Override <br/> protected void dopost (httpservletrequest request, httpservletresponse response) throws servletexception, ioexception {<br/> system. out. println ("dopost method is called. "); <br/> string id = request. getparameter ("ID"); <br/> string name = request. getparameter ("name"); <br/> string age = request. getparameter ("Age"); <br/> system. out. println ("ID:" + ID + ", name:" + name + ", age:" + age); <br/> response. getwriter (). write ("post_success"); <br/>}

The above two are the most basic GET requests and post requests. The parameters are of the text data type and can meet common requirements. However, in some cases, when we need to upload files, we cannot use basic GET requests or POST requests. We need to use multipart POST requests. The following describes how to use multipart POST to upload a file to the server.

Because the httpclient version that comes with Android does not support multipart POST requests for the moment, we need to use an httpmime open-source project, which is specialized in processing mime-type operations. Httpmime is included in the httpcomponents project, so we need to download httpcomponents from the Apache official website and put the httpmime. jar package in the project,

Then, observe the testupload test case. We use the inputstreambody provided by httpmime to process file stream parameters, use stringbody to process common text parameters, and add all types of parameters to a multipartentity instance, set the multipartentity to the parameter entity of the POST request, and then execute the POST request. The server servlet code is as follows:

Package COM. scott. web. servlet; </P> <p> Import Java. io. fileoutputstream; <br/> Import Java. io. ioexception; <br/> Import Java. util. iterator; <br/> Import Java. util. list; </P> <p> Import javax. servlet. servletexception; <br/> Import javax. servlet. HTTP. httpservlet; <br/> Import javax. servlet. HTTP. httpservletrequest; <br/> Import javax. servlet. HTTP. httpservletresponse; </P> <p> Import Org. apache. commons. fileupload. fileitem; <br/> Import Org. apache. commons. fileupload. fileitemfactory; <br/> Import Org. apache. commons. fileupload. fileuploadexception; <br/> Import Org. apache. commons. fileupload. disk. diskfileitemfactory; <br/> Import Org. apache. commons. fileupload. servlet. servletfileupload; </P> <p> @ suppresswarnings ("serial ") <br/> public class uploadservlet extends httpservlet {</P> <p> @ override <br/> @ suppresswarnings ("rawtypes ") <br/> protected void dopost (httpservletrequest request, httpservletresponse response) throws servletexception, ioexception {<br/> Boolean ismultipart = servletfileupload. ismultipartcontent (request); <br/> If (ismultipart) {<br/> fileitemfactory factory = new diskfileitemfactory (); <br/> servletfileupload upload = new servletfileupload (factory ); <br/> try {<br/> list items = upload. parserequest (request); <br/> iterator iter = items. iterator (); <br/> while (ITER. hasnext () {<br/> fileitem item = (fileitem) ITER. next (); <br/> If (item. isformfield () {<br/> // common text information processing <br/> string paramname = item. getfieldname (); <br/> string paramvalue = item. getstring (); <br/> system. out. println (paramname + ":" + paramvalue); <br/>}else {<br/> // process uploaded file information <br/> string filename = item. getname (); <br/> byte [] DATA = item. get (); <br/> string filepath = getservletcontext (). getrealpath ("/Files") + "/" + filename; <br/> fileoutputstream Fos = new fileoutputstream (filepath); <br/> FOS. write (data); <br/> FOS. close (); <br/>}< br/>} catch (fileuploadexception e) {<br/> E. printstacktrace (); <br/>}< br/> response. getwriter (). write ("upload_success"); <br/>}< br/>

The server uses the Apache open-source project fileupload for processing. Therefore, we need the jar packages for the commons-fileupload and commons-io projects, if you are not familiar with server development, you can find related information on the Internet.

After introducing the three different situations above, we need to consider a problem. In actual applications, we cannot create httpclient every time, but should create only one httpclient for the entire application, and use it for all HTTP Communication. In addition, pay attention to the multithreading problems that may occur when multiple requests are sent simultaneously through an httpclient. To solve these two problems, we need to improve our project:

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

2. Use threadsafeclientmanager provided by the httpclient class library to create and manage httpclient.

Improved project structure

Myapplication extends the system application. The Code is as follows:

Package COM. scott. HTTP; </P> <p> Import Org. apache. HTTP. httpversion; <br/> Import Org. apache. HTTP. client. httpclient; <br/> Import Org. apache. HTTP. conn. clientconnectionmanager; <br/> Import Org. apache. HTTP. conn. scheme. plainsocketfactory; <br/> Import Org. apache. HTTP. conn. scheme. scheme; <br/> Import Org. apache. HTTP. conn. scheme. schemeregistry; <br/> Import Org. apache. HTTP. conn. SSL. sslsocketfactory; <br/> Import Org. apache. HTTP. impl. client. defaulthttpclient; <br/> Import Org. apache. HTTP. impl. conn. tsccm. threadsafeclientconnmanager; <br/> Import Org. apache. HTTP. params. basichttpparams; <br/> Import Org. apache. HTTP. params. httpparams; <br/> Import Org. apache. HTTP. params. httpprotocolparams; <br/> Import Org. apache. HTTP. protocol. HTTP; </P> <p> Import android. app. application; </P> <p> public class myapplication extends app Lication {</P> <p> private httpclient; </P> <p> @ override <br/> Public void oncreate () {<br/> super. oncreate (); <br/> httpclient = This. createhttpclient (); <br/>}</P> <p> @ override <br/> Public void onlowmemory () {<br/> super. onlowmemory (); <br/> This. shutdownhttpclient (); <br/>}</P> <p> @ override <br/> Public void onterminate () {<br/> super. onterminate (); <br/> This. shutdownhttpclient (); <br/>}</P> <p> // Create an httpclient instance <br/> private httpclient createhttpclient () {<br/> httpparams Params = new basichttpparams (); <br/> httpprotocolparams. setversion (Params, httpversion. http_1_1); <br/> httpprotocolparams. setcontentcharset (Params, HTTP. default_content_charset); <br/> httpprotocolparams. setuseexpectcontinue (Params, true); </P> <p> schemeregistry schreg = new schemeregistry (); <br/> schreg. register (New Schem E ("HTTP", plainsocketfactory. getsocketfactory (), 80); <br/> schreg. register (New Scheme ("HTTPS", sslsocketfactory. getsocketfactory (), 443); </P> <p> clientconnectionmanager connmgr = new threadsafeclientconnmanager (Params, schreg); </P> <p> return New defaulthttpclient (connmgr, params); <br/>}</P> <p> // close the Connection Manager and release resources <br/> private void shutdownhttpclient () {<br/> If (httpclient! = NULL & httpclient. getconnectionmanager ()! = NULL) {<br/> httpclient. getconnectionmanager (). shutdown (); <br/>}</P> <p> // provides an external httpclient instance <br/> Public httpclient gethttpclient () {<br/> return httpclient; <br/>}< br/>

We have rewritten the oncreate () method and created an httpclient when the system starts. We have rewritten the onlowmemory () and onterminate () Methods to close the connection when the memory is insufficient and the application ends, release resources. Note that when ulthttpclient is instantiated, A clientconnectionmanager instance created by threadsafeclientconnmanager is input to manage the HTTP Connection of httpclient.

Then, to make the enhanced version of "application" take effect, you need to make the following configuration in androidmanifest. xml:

<Application Android: Name = ". myapplication"...> <br/>... <br/> </Application>

If no configuration is available, the system uses Android by default. app. application, we have added the configuration, and the system will use our com. scott. HTTP. myapplication, and then you can call getapplication () in context to obtain the myapplication instance.

With the above configuration, we can apply it in the activity. The httpactivity. Java code is as follows:

Package COM. scott. HTTP; </P> <p> Import Java. io. bytearrayoutputstream; <br/> Import Java. io. inputstream; </P> <p> Import Org. apache. HTTP. httpresponse; <br/> Import Org. apache. HTTP. httpstatus; <br/> Import Org. apache. HTTP. client. httpclient; <br/> Import Org. apache. HTTP. client. methods. httpget; </P> <p> Import android. app. activity; <br/> Import android. OS. bundle; <br/> Import android. view. view; <br/> Import android. W Idget. button; <br/> Import android. widget. toast; </P> <p> public class httpactivity extends activity {<br/> @ override <br/> protected void oncreate (bundle savedinstancestate) {<br/> super. oncreate (savedinstancestate); <br/> setcontentview (R. layout. main); <br/> button BTN = (button) findviewbyid (R. id. BTN); <br/> BTN. setonclicklistener (new view. onclicklistener () {<br/> @ override <br/> Public void onclick (Vie W v) {<br/> execute (); <br/>}< br/> }); </P> <p >}</P> <p> private void execute () {<br/> try {<br/> myapplication APP = (myapplication) This. getapplication (); // obtain the myapplication instance <br/> httpclient client = app. gethttpclient (); // get httpclient instance <br/> httpget get = new httpget ("http: // 192.168.1.57: 8080/web/testservlet? Id = 1001 & name = John & age = 60 "); <br/> httpresponse response = client.exe cute (get); <br/> If (response. getstatusline (). getstatuscode () = httpstatus. SC _ OK) {<br/> inputstream is = response. getentity (). getcontent (); <br/> string result = instream2string (is); <br/> toast. maketext (this, result, toast. length_long ). show (); <br/>}< br/>} catch (exception e) {<br/> E. printstacktrace (); <br/>}</P> <p> // enter Convert the stream into a string <br/> private string instream2string (inputstream is) throws exception {<br/> bytearrayoutputstream baos = new bytearrayoutputstream (); <br/> byte [] Buf = new byte [1024]; <br/> int Len =-1; <br/> while (LEN = is. read (BUF ))! =-1) {<br/> baos. write (BUF, 0, Len); <br/>}< br/> return new string (baos. tobytearray (); <br/>}< br/>

Click execute. The execution result is as follows:

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.