10

EDIT completely re-working the question for better understanding

I have to query the given url http://api.bf3stats.com/pc/player/ with 2 POST parameters: 'player' (for player name) and 'opt' (for options). I've tested it on http://www.requestmaker.com/ with following data: player=Zer0conf&opt=all. I'm getting a correct JSON response (thought I don't know how their site performs the query, I guess it's php). Now I'm trying to do the same in Android:

  private StringBuilder inputStreamToString(InputStream is) {
       //this method converts an inputStream to String representation
    String line = "";
    StringBuilder total = new StringBuilder();

    BufferedReader rd = new BufferedReader(new InputStreamReader(is));

    try {
        while ((line = rd.readLine()) != null) {
            total.append(line);
        }
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    return total;
}

and that's how I make the request:

 public void postData(String url, String name) {

    HttpClient httpclient = new DefaultHttpClient();
    HttpPost httppost = new HttpPost(url);

    try {

        List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
                    //qname is a String containing a correct player name
        nameValuePairs.add(new BasicNameValuePair("player", qname));
        nameValuePairs.add(new BasicNameValuePair("opt", "all"));
        httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

        HttpResponse response = httpclient.execute(httppost);
        //test is just a string to check the result, which should be in JSON format
        test = inputStreamToString(response.getEntity().getContent())
                .toString();

    } catch (ClientProtocolException e) {

    } catch (IOException e) {

    }
}

What I'm getting in the 'test" String is not JSON, but the complete HTML-markup of some bf3stats page. What could be wrong with my request?

enter image description here

Cœur
  • 37,241
  • 25
  • 195
  • 267
Droidman
  • 11,485
  • 17
  • 93
  • 141
  • See if the answer [here](http://stackoverflow.com/questions/9805300/using-httpget-returning-complete-html-code/9813473#9813473) help. – yorkw Jul 18 '13 at 21:30

2 Answers2

14

you need to set content type "application/x-www-form-urlencoded" in your request headers for the type of data you want to send.

I tested your API for the above mentioned data, it is working fine and i received loads of data in response. You can find it here.

You can try the following code:

public  String postDataToServer(String url) throws Throwable
    {

    HttpPost request = new HttpPost(url);
    StringBuilder sb=new StringBuilder();

    String requestData = prepareRequest();
    StringEntity entity = new StringEntity(requestData);
                         entity.setContentType("application/x-www-form-urlencoded;charset=UTF-8");//text/plain;charset=UTF-8
                         request.getParams().setParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, Boolean.FALSE);

                         request.setHeader("Accept", "application/json");
                         request.setEntity(entity); 
                         // Send request to WCF service 
                         HttpResponse response =null;
                         DefaultHttpClient httpClient = new DefaultHttpClient();
                         //DefaultHttpClient httpClient = getNewHttpClient();
                         HttpConnectionParams.setSoTimeout(httpClient.getParams(), 10*1000); 
                         HttpConnectionParams.setConnectionTimeout(httpClient.getParams(),10*1000); 
                         try{

                         response = httpClient.execute(request); 
                         }
                         catch(SocketException se)
                         {
                             Log.e("SocketException", se+"");
                             throw se;
                         }
                         /* Patch to prevent user from hitting the request twice by clicking 
                          * the view [button, link etc] twice.
                          */
                         finally{
                         }



    InputStream in = response.getEntity().getContent();
    BufferedReader reader = new BufferedReader(new InputStreamReader(in));
    String line = null;
    while((line = reader.readLine()) != null){
        sb.append(line);

    }
    Log.d("response in Post method", sb.toString()+"");
    return sb.toString();
    }

    public String prepareRequest()
    {

        return "player=Zer0conf&opt=all";
    }

Edit: I was getting error Expectation Failed error- 417 for your Webservice. So we need to add one more param in our request. It is request.getParams().setParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, Boolean.FALSE); . I have updated above code with this. Now it works fine.

Response looks something like this.

Response looks something like this.

Hope this will help.

Cheers
N_JOY

N-JOY
  • 10,344
  • 7
  • 51
  • 69
  • I used your code (added player name as dynamic parameter) and still getting some HTML stuff in the "test" String... here is my complete class: http://pastebin.com/QBpTcjAG Maybe I'm going wrong at some point? – Droidman Jul 18 '13 at 01:10
  • really strange.. just executed the code I posted on pastebin, no errors but HTML instead of JSON.. – Droidman Jul 18 '13 at 11:24
  • We missed one param in our request. updated the same in the answer. – N-JOY Jul 18 '13 at 20:07
  • thanks a lot, finally I got the correct response in the "test" String! One more little issue: now my class looks like http://pastebin.com/icV8H5vj (please check the OnPostExecute method) For some reason, I can't pass the received data to another Activity, my application just exits after the Log message "starting activity". Did I miss something again? – Droidman Jul 19 '13 at 13:25
  • OnPostexecute() looks right. I guess there is not need of super.onPostExecute() so remove that. And also it is not recommended to pass your whole lot of data in form of string in intent. creates some javaBean class for that or find some alternative way for it. – N-JOY Jul 19 '13 at 13:43
  • yes I'm planning a class for data storage, just wanted to perform a quick test this way. BTW, can there be a limit of data which an Intent can transfer and my data exceeded this limit? Just trying to get an explanation for this behavior – Droidman Jul 19 '13 at 15:07
  • I just realized that I could add the parameters simple by using them directly in the request url.. like "http://api.bf3stats.com/pc/playerlist/?players=xC-Gektor,Zer0Conf&opt=clear,global" Does this have any disadvantages? – Droidman Jul 19 '13 at 18:30
0

Try to view the url in browser, I believe there is a !DOCTYPE declaration, which definitely cannot be parsed to a JSON object.

reTs
  • 1,808
  • 1
  • 13
  • 26
  • I'm redirected to the main page if I try to open the URL in the browser, are you sure that means url is incorrect? I used to get some JSON responses in the past but the system I worked with was completely different, you couldn't open the request url in the browser.. – Droidman Jul 15 '13 at 03:55
  • @Maver1ck If that url requires some kind of session variable (like login credentials) it is not possible to view it directly using the browser, but you can verify the String jsonResults by using eclipse debug tool or just logging it out to see the received response. A proper JSON response should not contain DOCTYPE declaration anyway. – reTs Jul 15 '13 at 04:19