I want to make a request to a web services http://www.w3schools.com/webservices/tempconvert.asmx and I cannot get a OK respond and got 400 bad request instead.
Here is my AsyncTask doInBackground
protected String doInBackground(Void... params) {
String s=null;
try {
restclient client1 = new restclient("http://www.w3schools.com/webservices/tempconvert.asmx");
client1.AddParam("Celsius", "12");
client1.AddHeader("Content-Type", "text/xml; charset=utf-8" );
client1.AddHeader("SOAPAction", "http://tempuri.org/CelsiusToFahrenheit");
client1.Execute(RequestMethod.POST);
s = client1.getResponse();
return s;
} catch (Exception e) {
e.printStackTrace();
}
return s;
}
I have a class for client1 that I got from a post (cant find the link for that now)
public class restclient {
public enum RequestMethod {
GET, POST
}
private ArrayList<NameValuePair> params;
private ArrayList<NameValuePair> headers;
private String url;
private int responseCode;
private String message;
private String response;
public String getResponse() {
return response;
}
public String getErrorMessage() {
return message;
}
public int getResponseCode() {
return responseCode;
}
public restclient(String url) {
this.url = url;
params = new ArrayList<NameValuePair>();
headers = new ArrayList<NameValuePair>();
}
public void AddParam(String name, String value) {
params.add(new BasicNameValuePair(name, value));
}
public void AddHeader(String name, String value) {
headers.add(new BasicNameValuePair(name, value));
}
public void Execute(RequestMethod method) throws Exception {
switch (method) {
case GET: {
// add parameters
String combinedParams = "";
if (!params.isEmpty()) {
combinedParams += "?";
for (NameValuePair p : params) {
String paramString = p.getName() + "="
+ URLEncoder.encode(p.getValue(), "UTF-8");
if (combinedParams.length() > 1) {
combinedParams += "&" + paramString;
} else {
combinedParams += paramString;
}
}
}
HttpGet request = new HttpGet(url + combinedParams);
// add headers
for (NameValuePair h : headers) {
request.addHeader(h.getName(), h.getValue());
}
executeRequest(request, url);
break;
}
case POST: {
HttpPost request = new HttpPost(url);
// add headers
for (NameValuePair h : headers) {
request.addHeader(h.getName(), h.getValue());
}
if (!params.isEmpty()) {
request.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
}
executeRequest(request, url);
break;
}
}
}
private void executeRequest(HttpUriRequest request, String url) {
HttpClient client = new DefaultHttpClient();
HttpResponse httpResponse;
try {
httpResponse = client.execute(request);
responseCode = httpResponse.getStatusLine().getStatusCode();
message = httpResponse.getStatusLine().getReasonPhrase();
HttpEntity entity = httpResponse.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
response = convertStreamToString(instream);
// Closing the input stream will trigger connection release
instream.close();
}
} catch (ClientProtocolException e) {
client.getConnectionManager().shutdown();
e.printStackTrace();
} catch (IOException e) {
client.getConnectionManager().shutdown();
e.printStackTrace();
}
}
private static String convertStreamToString(InputStream is) {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}
}
I’ve also included access for Internet
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.test"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="7" />
<uses-permission android:name="android.permission.INTERNET" />
<application android:icon="@drawable/icon" android:label="@string/app_name">
.....
</application>
I only get a bad request response when I tried to post. Do I need to use more parameters? I feel that the body is wrong, but I can’t find a solution.
EDIT: I just saw your content-type header, have you tried “application/soap+xml”? Also, SOAP required POST I believe, GET will not work, so you’re right to do POST.
EDIT2: That client class your using isn’t going to work. You need to send a XML in the body of your POST request, wrapped in a SOAP XML wrapper. The XML needs to follow the structure of the WSDL for your endpoint. I would recommend using SOAP UI (link below) to figure out what the XML should look like. If you wanted to get fancy, you should create a class that will serialize to look exactly like the request the SOAP UI creates.
For SOAP services you can almost always access the WSDL by adding ?WSDL to the endpoint url:
http://www.w3schools.com/webservices/tempconvert.asmx?wsdl
If that doesn’t work…
How to troubleshoot web services:
I’ve done exactly this a million times, it’s a guaranteed method to find the difference between two requests. Good luck!