Parsing XML from a site protected with Basic HTTP Auth

Problems with WiFi, SQLite ,Bluetooth, WiMax, Proxies, etc...

Parsing XML from a site protected with Basic HTTP Auth

Postby Croccy22 » Sat Oct 24, 2009 12:02 pm

Hi All,

I have an application which as part of it needs to retrieve some XML from a website. I have followed the tutorials on here and it all works fine when I test it within my network.

However once I go to use 3G/GPRS the website is designed to ask for HTTP Basic Authentication.

If I try to use my application it doesn't work as it cannot retrieve the XML.

How can I pass my Username/Password to SAXParser/XMLReader so it can authenticate before trying to retrive the XML?

Thanks, Matt.
Croccy22
Developer
Developer
 
Posts: 31
Joined: Wed Dec 03, 2008 3:15 pm

Top

Postby RS » Sat Oct 24, 2009 3:25 pm

Code hard, go pro! Don't wait for someone to do your own project.
User avatar
RS
Junior Developer
Junior Developer
 
Posts: 11
Joined: Tue Oct 20, 2009 10:49 pm

Postby Croccy22 » Sat Oct 24, 2009 6:03 pm

Hi,

I have now changed my SAXParser to use httpclient to get the XML Document which works fine, but I am still unable to Authentication working.

the setAuthenticationPreemptive doesn't seem to exist on Android unless I'm looking in completely the wrong place (More than Likely)

Any chance of some sample code? This is what I have so far:

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2. ResponseHandler<String> responseHandler = new BasicResponseHandler();
  3.  
  4.  
  5.  
  6. HttpClient client = new DefaultHttpClient();
  7.  
  8. HttpGet request = new HttpGet(URL);
  9.  
  10.  
  11.  
  12. response = client.execute(request,responseHandler);
  13.  
  14.  
Parsed in 0.031 seconds, using GeSHi 1.0.8.4


This returns my XML as a string ready to Parsed. How would I change this to send a Username and Password to the requested server?

Thanks in advance,

Matt.
Croccy22
Developer
Developer
 
Posts: 31
Joined: Wed Dec 03, 2008 3:15 pm

Postby Croccy22 » Sat Oct 24, 2009 8:06 pm

Ok, looks like I've stumbled across one of Androids problems here.

I now have this code:

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2. //Setup Response Handler to convert our XML into a String
  3.  
  4. ResponseHandler<String> responseHandler = new BasicResponseHandler();
  5.  
  6.  
  7.  
  8. //Create a HTTP Client to fetch the XML File
  9.  
  10. DefaultHttpClient client = new DefaultHttpClient();
  11.  
  12.                
  13.  
  14. //Set the User name and Password to access HomeSeer
  15.  
  16. client.getCredentialsProvider().setCredentials(new AuthScope(AuthScope.ANY_HOST,AuthScope.ANY_PORT,AuthScope.ANY_REALM), new UsernamePasswordCredentials(Username, Password));
  17.  
  18.                        
  19.  
  20. //Get the XML File
  21.  
  22. HttpGet request = new HttpGet(StatusURL);
  23.  
  24. response = client.execute(request,responseHandler);
  25.  
  26.  
Parsed in 0.032 seconds, using GeSHi 1.0.8.4


However, when I run it I get a Force Close and the Log shows 10-24 19:45:58.708: WARN/System.err(14322): org.apache.http.client.HttpResponseException: Authorization Required.

I think I need to enable Preemptive authentication but apparently the httpclient in Android 1.5 doesn't support this method.

So back to the drawing board! Anyone else know how I can etrieve an XML File from a site protected with Basic Authentication and store it in a string ready to be parsed?

Thanks, Matt.
Croccy22
Developer
Developer
 
Posts: 31
Joined: Wed Dec 03, 2008 3:15 pm

Postby padde » Sat Oct 24, 2009 10:16 pm

Try this....

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2.         // first create default http client
  3.  
  4.         DefaultHttpClient http = new DefaultHttpClient();
  5.  
  6.  
  7.  
  8.         // create credentials for basic auth
  9.  
  10.         UsernamePasswordCredentials c = new UsernamePasswordCredentials("user","pass");
  11.  
  12.  
  13.  
  14.         // create a basic credentials provider and pass the credentials
  15.  
  16.         BasicCredentialsProvider cP = new BasicCredentialsProvider();
  17.  
  18.         cP.setCredentials(AuthScope.ANY, c);
  19.  
  20.  
  21.  
  22.         // set credentials provider for our default http client so it will use those
  23.  
  24.         // credentials
  25.  
  26.         http.setCredentialsProvider(cP);
  27.  
  28.  
  29.  
  30.         // get what we want from the target site
  31.  
  32.         HttpResponse res = http.execute(new HttpGet("http://www.mysite.com/my.xml"));
  33.  
  34.         InputStream is = res.getEntity().getContent();
  35.  
  36.  
  37.  
  38.         // from here you should know how to parse the xml...
  39.  
  40.  
Parsed in 0.036 seconds, using GeSHi 1.0.8.4
padde
Master Developer
Master Developer
 
Posts: 443
Joined: Wed Apr 08, 2009 4:52 pm

Postby Croccy22 » Sun Oct 25, 2009 11:46 am

Thankyou, thankyou, thankyou!! :D

I was having a couple of problems last night with it not authenticating sometimes but I think that was down to me being tired and my webserver being hammered by ivalid login attempts by me!

Anyway I deleted everything I tried last night and tried again this morning at it all seems to work fine!

Just out of interest though I guess this isn't using preemptive login? So it will fail on it's first request but then go through?

Thanks again for the help.

Matt.
Croccy22
Developer
Developer
 
Posts: 31
Joined: Wed Dec 03, 2008 3:15 pm

Top

Postby padde » Sun Oct 25, 2009 12:50 pm

If you need preemptive auth try the code example from apache.. it is android compatibel
.. well at least its compiling without errors ;)

https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/httpclient/src/examples/org/apache/http/examples/client/ClientPreemptiveBasicAuthentication.java
padde
Master Developer
Master Developer
 
Posts: 443
Joined: Wed Apr 08, 2009 4:52 pm

Postby nRikeDiaz » Thu Dec 31, 2009 12:26 pm

Hi to all!! :)

Croccy22 wrote:Hi,

I have now changed my SAXParser to use httpclient to get the XML Document which works fine, but I am still unable to Authentication working.

the setAuthenticationPreemptive doesn't seem to exist on Android unless I'm looking in completely the wrong place (More than Likely)

Any chance of some sample code? This is what I have so far:

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. ResponseHandler<String> responseHandler = new BasicResponseHandler();
  2.  
  3. HttpClient client = new DefaultHttpClient();
  4. HttpGet request = new HttpGet(URL);
  5.  
  6. response = client.execute(request,responseHandler);
  7.  
Parsed in 0.035 seconds, using GeSHi 1.0.8.4


This returns my XML as a string ready to Parsed. How would I change this to send a Username and Password to the requested server?

Thanks in advance,

Matt.


I have the same problem, but i don't know which i need to change, do i only implement httpclient to my SAXParser? can you please post your code as example ??

Thanks in advance,
Enrique Díaz.
nRikeDiaz
Freshman
Freshman
 
Posts: 3
Joined: Fri Dec 18, 2009 1:10 am

Postby nRikeDiaz » Sat Jan 02, 2010 11:23 am

Ok, i contacted with Croccy22 and sent me a snippet which worked for me, so i send my code:

This class is called ParsingXML
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2.  
  3.  
  4. import java.io.InputStream;
  5.  
  6. import java.net.URI;
  7.  
  8. import java.net.URL;
  9.  
  10.  
  11.  
  12. import javax.xml.parsers.SAXParser;
  13.  
  14. import javax.xml.parsers.SAXParserFactory;
  15.  
  16.  
  17.  
  18. import org.apache.http.HttpResponse;
  19.  
  20. import org.apache.http.auth.AuthScope;
  21.  
  22. import org.apache.http.auth.UsernamePasswordCredentials;
  23.  
  24. import org.apache.http.client.methods.HttpGet;
  25.  
  26. import org.apache.http.impl.client.BasicCredentialsProvider;
  27.  
  28. import org.apache.http.impl.client.DefaultHttpClient;
  29.  
  30. import org.xml.sax.InputSource;
  31.  
  32. import org.xml.sax.XMLReader;
  33.  
  34.  
  35.  
  36. import android.app.Activity;
  37.  
  38. import android.os.Bundle;
  39.  
  40. import android.util.Log;
  41.  
  42. import android.widget.TextView;
  43.  
  44.  
  45.  
  46.  
  47.  
  48. public class ParsingXML extends Activity {
  49.  
  50.      
  51.  
  52.      private static final String Username = "yourusername";
  53.  
  54.         private static final String Password = "yourpassword";
  55.  
  56.         private final String MY_DEBUG_TAG = "Enter";
  57.  
  58.  
  59.  
  60.      /** Called when the activity is first created. */
  61.  
  62.      @Override
  63.  
  64.      public void onCreate(Bundle icicle) {
  65.  
  66.           super.onCreate(icicle);
  67.  
  68.  
  69.  
  70.           /* Create a new TextView to display the parsingresult later. */
  71.  
  72.           TextView tv = new TextView(this);
  73.  
  74.          
  75.  
  76.                 //Start the XML Parsing
  77.  
  78.                         try {
  79.  
  80.                                 //First create defaulthttpclient
  81.  
  82.                                 DefaultHttpClient http = new DefaultHttpClient();
  83.  
  84.                                 //Create credentials for basic auth
  85.  
  86.                                 UsernamePasswordCredentials c = new UsernamePasswordCredentials(Username,Password);
  87.  
  88.                                 //create a basic credentials provider and pass the credentials
  89.  
  90.                                 BasicCredentialsProvider cP = new BasicCredentialsProvider();
  91.  
  92.                                 cP.setCredentials(AuthScope.ANY, c );
  93.  
  94.                                 //Set credentials provider for our default http client so it will use those credentials
  95.  
  96.                                 http.setCredentialsProvider(cP);
  97.  
  98.                                 //get what we want from the target site
  99.  
  100.                                 HttpResponse res = http.execute(new HttpGet("http://your_target_site.com/1.xml"));
  101.  
  102.                                 InputStream is =res.getEntity().getContent();
  103.  
  104.                                 //Create a SAXParser to parse the XML file
  105.  
  106.                                 SAXParserFactory spf =SAXParserFactory.newInstance();
  107.  
  108.                                 SAXParser sp = spf.newSAXParser();
  109.  
  110.                                 XMLReader xr = sp.getXMLReader();
  111.  
  112.                                 //Set a handler to parse the XML
  113.  
  114.                                 ExampleHandler myExampleHandler = new ExampleHandler();
  115.  
  116.                                 xr.setContentHandler(myExampleHandler);
  117.  
  118.                                 xr.parse(new InputSource(is));
  119.  
  120.                                 //Retrieve result from the parser
  121.  
  122.                                 ParsedExampleDataSet parsedExampleDataSet = myExampleHandler.getParsedData();
  123.  
  124.                                
  125.  
  126.                                 // Set the result to be displayed in our GUI. */
  127.  
  128.                                 tv.setText(parsedExampleDataSet.toString());
  129.  
  130.                
  131.  
  132.           }
  133.  
  134.                         catch (Exception e) {
  135.  
  136.                /* Display any Error to the GUI. */
  137.  
  138.                tv.setText("Error: " + e.getMessage());
  139.  
  140.                Log.e(MY_DEBUG_TAG, "WeatherQueryError", e);
  141.  
  142.           }
  143.  
  144.           /* Display the TextView. */
  145.  
  146.           this.setContentView(tv);
  147.  
  148.      }
  149.  
  150. }
  151.  
  152.  
Parsed in 0.047 seconds, using GeSHi 1.0.8.4


Here's another class called ExampleHandler

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2. import org.xml.sax.Attributes;
  3.  
  4. import org.xml.sax.SAXException;
  5.  
  6. import org.xml.sax.helpers.DefaultHandler;
  7.  
  8.  
  9.  
  10.  
  11.  
  12. public class ExampleHandler extends DefaultHandler{
  13.  
  14.  
  15.  
  16.      // ===========================================================
  17.  
  18.      // Fields
  19.  
  20.      // ===========================================================
  21.  
  22.      
  23.  
  24.      private boolean in_outertag = false;
  25.  
  26.      private boolean in_innertag = false;
  27.  
  28.      private boolean in_first_name = false;
  29.  
  30.      private boolean in_last_name = false;
  31.  
  32.      private boolean in_bio = false;
  33.  
  34.  
  35.  
  36.      
  37.  
  38.      private ParsedExampleDataSet myParsedExampleDataSet = new ParsedExampleDataSet();
  39.  
  40.  
  41.  
  42.      // ===========================================================
  43.  
  44.      // Getter & Setter
  45.  
  46.      // ===========================================================
  47.  
  48.  
  49.  
  50.      public ParsedExampleDataSet getParsedData() {
  51.  
  52.           return this.myParsedExampleDataSet;
  53.  
  54.      }
  55.  
  56.      
  57.  
  58.  
  59.  
  60.      // ===========================================================
  61.  
  62.      // Methods
  63.  
  64.      // ===========================================================
  65.  
  66.      @Override
  67.  
  68.      public void startDocument() throws SAXException {
  69.  
  70.           this.myParsedExampleDataSet = new ParsedExampleDataSet();
  71.  
  72.      }
  73.  
  74.  
  75.  
  76.      @Override
  77.  
  78.      public void endDocument() throws SAXException {
  79.  
  80.           // Nothing to do
  81.  
  82.      }
  83.  
  84.  
  85.  
  86.      /** Gets be called on opening tags like:
  87.  
  88.       * <tag>
  89.  
  90.       * Can provide attribute(s), when xml was like:
  91.  
  92.       * <tag attribute="attributeValue">*/
  93.  
  94.      @Override
  95.  
  96.      public void startElement(String namespaceURI, String localName,
  97.  
  98.                String qName, Attributes atts) throws SAXException {
  99.  
  100.           if (localName.equals("users")) {
  101.  
  102.                this.in_outertag = true;
  103.  
  104.           }else  if (localName.equals("user")) {
  105.  
  106.                this.in_innertag = true;
  107.  
  108.           }else if (localName.equals("first-name")) {
  109.  
  110.                this.in_first_name = true;
  111.  
  112.           }else if (localName.equals("last-name")) {
  113.  
  114.                    this.in_last_name = true;
  115.  
  116.           }else if (localName.equals("bio")) {
  117.  
  118.                        this.in_bio = true;  
  119.  
  120.  
  121.  
  122.           }
  123.  
  124.      }
  125.  
  126.      
  127.  
  128.      /** Gets be called on closing tags like:
  129.  
  130.       * </tag> */
  131.  
  132.      @Override
  133.  
  134.      public void endElement(String namespaceURI, String localName, String qName)
  135.  
  136.                throws SAXException {
  137.  
  138.          if (localName.equals("users")) {
  139.  
  140.                this.in_outertag = false;
  141.  
  142.           }else if (localName.equals("user")) {
  143.  
  144.                this.in_innertag = false;
  145.  
  146.           }else if (localName.equals("first-name")) {
  147.  
  148.                this.in_first_name = false;
  149.  
  150.           }else if (localName.equals("last-name")) {
  151.  
  152.               this.in_last_name = false;
  153.  
  154.           }else if (localName.equals("bio")) {
  155.  
  156.               this.in_bio = false;
  157.  
  158.                
  159.  
  160.           }  
  161.  
  162.      }
  163.  
  164.      
  165.  
  166.      /** Gets be called on the following structure:
  167.  
  168.       * <tag>characters</tag> */
  169.  
  170.      @Override
  171.  
  172.     public void characters(char ch[], int start, int length) {
  173.  
  174.           if(this.in_first_name){
  175.  
  176.                   myParsedExampleDataSet.setExtractedString(new String(ch, start, length));           }
  177.  
  178.    
  179.  
  180.      if(this.in_last_name){
  181.  
  182.           myParsedExampleDataSet.setExtractedString1(new String(ch, start, length));           }
  183.  
  184.  
  185.  
  186.      if(this.in_bio){
  187.  
  188.           myParsedExampleDataSet.setExtractedString2(new String(ch, start, length));           }
  189.  
  190. }
  191.  
  192.      
  193.  
  194. }
  195.  
  196.  
Parsed in 0.049 seconds, using GeSHi 1.0.8.4


And finally the class ParsedExampleDataSet

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2.  
  3.  
  4. public class ParsedExampleDataSet {
  5.  
  6.      private String extractedString = null;
  7.  
  8.      private String extractedString1 = null;
  9.  
  10.      private String extractedString2 = null;
  11.  
  12.  
  13.  
  14.      private int extractedInt = 0;
  15.  
  16.  
  17.  
  18.      public void setExtractedString(String extractedString) {
  19.  
  20.          this.extractedString = extractedString;
  21.  
  22.     }
  23.  
  24.      public String getExtractedString() {
  25.  
  26.           return extractedString;
  27.  
  28.      }
  29.  
  30.      
  31.  
  32.      public void setExtractedString1(String extractedString1) {
  33.  
  34.          this.extractedString1 = extractedString1;
  35.  
  36.     }
  37.  
  38.      
  39.  
  40.      public String getExtractedString1() {
  41.  
  42.          return extractedString1;
  43.  
  44.     }
  45.  
  46.      
  47.  
  48.      public void setExtractedString2(String extractedString2) {
  49.  
  50.          this.extractedString2 = extractedString2;
  51.  
  52.     }
  53.  
  54.  
  55.  
  56.      public String getExtractedString2() {
  57.  
  58.          return extractedString2;
  59.  
  60.     }
  61.  
  62.      
  63.  
  64.      public void setExtractedInt(int extractedInt) {
  65.  
  66.          this.extractedInt = extractedInt;
  67.  
  68.     }
  69.  
  70.      public int getExtractedInt() {
  71.  
  72.           return extractedInt;
  73.  
  74.      }
  75.  
  76.    
  77.  
  78.      
  79.  
  80.      public String toString(){
  81.  
  82.           //return "ExtractedString = " + this.extractedString
  83.  
  84.                 //    + "\nExtractedInt = " + this.extractedInt;
  85.  
  86.          
  87.  
  88.           return "Nombre : " + this.extractedString + "\n" + "Apellido : " + this.extractedString1 + "\n" + "Biografia : " + this.extractedString2;
  89.  
  90.          
  91.  
  92.      }
  93.  
  94. }
  95.  
  96.  
Parsed in 0.041 seconds, using GeSHi 1.0.8.4


Also i would like to thank you to padde, and plusminus, because they are so attentive with the community, that's why Anddev.org is the most important Android Community of the World.


Best Regards and happy new year,
Enrique Díaz.
nRikeDiaz
Freshman
Freshman
 
Posts: 3
Joined: Fri Dec 18, 2009 1:10 am

Top

Return to Networking & Database Problems

Who is online

Users browsing this forum: Exabot [Bot], Google Feedfetcher and 6 guests