chntgomez chntgomez - 3 months ago 9
Android Question

Why do I keep getting Error 400 after post in Android?

I'm building an app that logs with user credentials to Spotify. I follow this API call: https://developer.spotify.com/web-api/authorization-guide/#client_credentials_flow

And this is the implenentation code:

@Override
protected Session doInBackground(String... params) {

Session session = new Session();

try {
String response = "";
URL url = new URL(GET_TOKEN_URL);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();

String credentials = params[0]+":"+params[1];
String basicAuth ="Basic "+new String(android.util.Base64.encode(credentials.getBytes(), Base64.DEFAULT));

Uri.Builder builder = new Uri.Builder()
.appendQueryParameter(GRANT_TYPE, CLIENT_CREDENTIALS);

String query = builder.build().getEncodedQuery();

httpURLConnection.setRequestProperty("Authorization", basicAuth);
httpURLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
httpURLConnection.setRequestProperty("Content-Length", "" + query.getBytes().length);
httpURLConnection.setRequestProperty("Content-Language", "en-US");

httpURLConnection.setUseCaches(false);
httpURLConnection.setDoInput(true);
httpURLConnection.setDoOutput(true);
httpURLConnection.setRequestMethod(POST);


OutputStream os = httpURLConnection.getOutputStream();
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(os, "UTF-8"));


writer.write(query);
writer.flush();
writer.close();
os.close();

httpURLConnection.connect();

int responseCode=httpURLConnection.getResponseCode();

session.setResponseCode(responseCode);

if (responseCode == HttpsURLConnection.HTTP_OK) {
String line;
BufferedReader br=new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream()));
while ((line=br.readLine()) != null) {
response+=line;
}
}else;{
Log.e(getClass().getSimpleName(), "ERROR:" + responseCode);
response = "Something went wrong";
}
Log.d(getClass().getSimpleName(), response);

} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally{

}
return session;
}


But no matter what I change, I'm always getting an Error 400.

What am I doing wrong?

EJK EJK
Answer

Try correcting the following errors

1) Fix the typo in your else. There should be no semi-colon after the else.

2) Remove your code that calculates the content length and adds the header. The length should be that of the body, not the query string as you have coded. If you simply remove this code, the HttpUrlConnection class should generate this header for you.

3) Put the grant type parameter in the body. That is where the documentation says it belongs. You have it in the query string. You should be able to use the following code:

String body =  GRANT_TYPE + "=" + CLIENT_CREDENTIALS;
byte[] bodyBytes = body.getBytes("UTF-8");
OutputStream stream = httpURLConnection.getOutputStream();
stream.write(bodyBytes);    
stream.close();