android - httpsurlconnection 'get' 405 - method not allowed - java

I am using a 'get' method on HttpsUrlConnection. When i am testing my code on eclipse (Windows) it works fine. When i compress it to a jar file and use it on android studio it gives me '405 - method not allowed'. What's mean, I am running the method with bad verb (expected GET).
This is how i set the http method type:
conn.setRequestMethod("GET");
I am setting the http method to 'get' and when i debug it - conn.getRequestMethod = GET and conn.delegate.getRequestMethod = POST.
The error response is - {"Message":"The requested resource does not support http method 'POST'."}
EDITED - code added:
public static HttpsURLConnection getClient(URL url, LoginToken securityToken, RequestMethod methodType, String requestFormat, String responseFormat) throws IOException, SecurityTokenException {
HttpsURLConnection conn = (HttpsURLConnection)url.openConnection();
conn.addRequestProperty("Accept-Charset", "UTF-8");
conn.addRequestProperty("Content-Type", requestFormat);
conn.addRequestProperty("Accept", responseFormat);
conn.addRequestProperty("User-Agent", "***SDK/1.0");
conn.setRequestProperty("Cache-Control", "no-cache");
if(securityToken != null) {
LoginToken.ValidateToken(securityToken);
conn.addRequestProperty("Authorization", String.format("Bearer %1$s", new Object[]{securityToken.getTemporarySecurityCode()}));
}
conn.setRequestMethod(methodType.toString());
conn.setUseCaches(false);
conn.setDoOutput(true);
return conn;
}
public Boolean IsCompleted() throws SecurityTokenException, CommandFailedException {
LoginToken.ValidateToken(this.getSecurityToken());
HttpsURLConnection conn = null;
Gson gson = (new GsonBuilder()).create();
String json;
try {
URL url = new URL(String.format("https://api.***.com/%1$s/detector/%2$s/status", new Object[]{"v1", this.getPID()}));
conn = ***Client.getClient(url, this.getSecurityToken(), RequestMethod.GET, "application/json", "text/plain");
Throwable response1;
BufferedInputStream inputStream;
if(conn.getResponseCode() != 200) {
response1 = null;
inputStream = null;
String response2;
try {
BufferedInputStream inputStream1 = new BufferedInputStream(conn.getErrorStream());
try {
response2 = HttpURLConnectionHelper.convertStreamToString(inputStream1);
} finally {
if(inputStream1 != null) {
inputStream1.close();
}
}
} catch (Throwable var41) {
if(response1 == null) {
response1 = var41;
} else if(response1 != var41) {
response1.addSuppressed(var41);
}
throw response1;
}
BadLoginResponse response4 = (BadLoginResponse)gson.fromJson(response2, BadLoginResponse.class);
if(response4 == null) {
throw new RuntimeException("Unable to process server response.");
}
throw new CommandFailedException(response4.getMessage(), conn.getResponseCode());
}
Throwable response = null;
response1 = null;
try {
inputStream = new BufferedInputStream(conn.getInputStream());
try {
json = HttpURLConnectionHelper.convertStreamToString(inputStream);
} finally {
if(inputStream != null) {
inputStream.close();
}
}
} catch (Throwable var43) {
if(response == null) {
response = var43;
} else if(response != var43) {
response.addSuppressed(var43);
}
throw response;
}
} catch (IOException var44) {
throw new RuntimeException(var44.getMessage());
} finally {
if(conn != null) {
conn.disconnect();
}
}
How can i fix it?

Thanks BNK!
The solution was to remove conn.setDoOutput(true)

Related

Android HttpURLConnection: HTTP response always 403

public static class GetTitleTask extends AsyncTask<String, Void, String> {
protected String doInBackground(String... urls) {
try {
String youtubeUrl = urls[0];
if (youtubeUrl != null) {
URL url = new URL("http://www.youtube.com/oembed?url=" + youtubeUrl + "&format=json");
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
connection = (HttpURLConnection) url.openConnection();
connection.addRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:221.0) Gecko/20100101 Firefox/31.0");
connection.connect();
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
Log.d(TAG, "HTTP response code is " + connection.getResponseCode());
return null;
}
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null) {
buffer.append(line+"\n");
Log.d("Response: ", "> " + line);
}
return buffer.toString();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String title) {
Log.v(TAG, "onPostExecute: " + title);
super.onPostExecute(title);
// ...
}
}
Input for example: https://www.youtube.com/watch?v=hT_nvWreIhg
This always returns null. The HTTP response code is 403. That is why I tried adding a user agent, but it didn't help.
Is there any way to fix this? I would like to get the video title without using the YouTube API.
I tried fetching it with curl. Your URL uses http instead of https://..., change it to https://www.youtube.com/oembed?url=.
Trying to fetch the URL when it starts with just http resulted in a 403 status for me. But https was successful.
URL url = new URL("http://www.youtube.com/oembed?url=" + youtubeUrl + "&format=json");
Should be changed to:
URL url = new URL("https://www.youtube.com/oembed?url=" + youtubeUrl + "&format=json");
The server does not agree to fulfil the request (error code 403). This is probably due to the protocol. Try using HttpsURLConnection instead of HttpURLConnection.

Multiple HTTP request happening with single call on frequent network change in android

I am making a HTTP URLconnection for my JSON upload in android. The request is an Intent Service. I have a broadcast receiver which checks for Network change and calls the Intent Service to make the upload.
But in doing so when a user is frequently changing the network for Wifi to cellular or Vic-verse at times the same JSON is uploaded more than once.
BroadcastReciver.java
public void onReceive(Context context, Intent intent) {
if (ConnectivityManager.CONNECTIVITY_ACTION.equalsIgnoreCase(intent.getAction())) {
if (Utils.hasActiveInternet(context)) {
TripManager.uploadUnSubmittedTripsAsync(context, DataStore.getApplicationPath(context));
Logger.log("OSBroadcastReceiver","onReceive",new String[]{"Network available"});
}else
Logger.log("OSBroadcastReceiver","onReceive",new String[]{"Network unavailable"});
}
}
Upload.java
private ServiceResponse executeServiceRequestInternal() {
ServiceResponse serviceResponse = null;
HttpURLConnection connection = null;
boolean delay = false;
if (!Utils.hasActiveInternet(mContext)) {
pushError("error");
} else {
try {
if (jsonFile.exists()) {
do {
connection = (HttpURLConnection) getServiceUrl(mRequest.serviceUrl).openConnection();
setHttpRequestType(mRequest, connection);
setContentType(mRequest, connection);
setHeaders(mRequest, connection);
connection.setUseCaches(false);
connection.setDoInput(true);
if (mRequest.requestType != GET_REQUEST) {
connection.setDoOutput(true);
}
connection.setConnectTimeout(mRequest.requestTimeout);
connection.setReadTimeout(mRequest.requestTimeout);
connection.setRequestProperty("Connection", "close");
connection.setRequestProperty("Keep-Alive", "off");
if (mRequest.requestData != null && mRequest.requestData.length() > 0) {
sendRequestWithData(connection);
}
connection.connect();
int responseCode = connection.getResponseCode();
if (delay) {
Thread.sleep(TIME_BEFORE_RETRY);
}
if (responseCode != HttpURLConnection.HTTP_OK && responseCode != HttpURLConnection.HTTP_ACCEPTED && responseCode != HttpURLConnection.HTTP_CREATED) {
String serverResponse = connection.getResponseMessage();
if (null == serverResponse) serverResponse = serverError;
serviceResponse = getServiceResponse(responseCode,
serverResponse);
pushServerError(responseCode, serverResponse);
} else {
InputStream is = connection.getInputStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
String line;
StringBuffer response = new StringBuffer();
while ((line = rd.readLine()) != null) {
response.append(line);
response.append('\r');
}
rd.close();
String resultString = response.toString();
is.close();
if (TextUtils.isEmpty(resultString)) {
serviceResponse = getServiceResponse(
HttpURLConnection.HTTP_NO_CONTENT, "");
deleteTrip();
} else {
serviceResponse = getServiceResponse(
HttpURLConnection.HTTP_OK, resultString);
deleteTrip();
}
break;
}
// we did not succeed with connection (or we would have returned the connection).
connection.disconnect();
// retry
mRetryCounter++;
delay = true;
} while (mRetryCounter < MAX_RETRY_COUNT);
} else {
if (connection != null) {
connection.disconnect();
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
}
}
return serviceResponse;
}
Thank in advance.
I had the same issue and after adding connection.setChunkedStreamingMode(0) it was solved; this is the snippet you can refer,
HttpURLConnection request = (HttpURLConnection) url.openConnection();
request.setUseCaches(false);
request.setDoOutput(true);
request.setDoInput(true);
request.setConnectTimeout(CONNECTION_TIMEOUT);
request.setRequestMethod(HTTP_POST);
request.setReadTimeout(CONNECTION_TIMEOUT);
request.setChunkedStreamingMode(0);
DataOutputStream printout = new DataOutputStream(request.getOutputStream());
NameValuePair dataToSend = new NameValuePair(AppEnvironment.DATA, data);
// printout.write(getQuery(dataToSend));
printout.writeBytes(getQuery(dataToSend));
printout.flush();
printout.close();
private String getQuery(NameValuePair params) throws UnsupportedEncodingException {
StringBuilder result = new StringBuilder();
result.append(URLEncoder.encode(params.getKey(), "UTF-8"));
result.append("=");
result.append(URLEncoder.encode(params.getValue(), "UTF-8"));
// }
return result.toString();
}

Can not read request body from servlet

This is my controller code:
#RequestMapping(value = "/test", method = RequestMethod.POST)
public #ResponseBody String testPost(#RequestParam(value = "testParam") int testParam, HttpServletRequest request) {
try {
System.out.println("body is "+BufferUtil.getHttpRequestBody(request));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
BufferUtil.getHttpRequestBody(request) is
public static String getHttpRequestBody(HttpServletRequest request)
throws IOException {
Scanner s = null;
try {
s = new Scanner(request.getInputStream(), "UTF-8")
.useDelimiter("\\A");
} catch (IOException e) {
e.printStackTrace();
}
return s.hasNext() ? s.next() : "";
}
This is the code to use to test controller:
HTTPUtil.sendRequest("http://localhost:8081/es09android/test?testParam=1", "POST", "hello world");
sendRequest() implementation:
public static HttpResponse sendRequest(String url, String method,
String data) {
DataOutputStream wr = null;
BufferedReader in = null;
HttpResponse httpResponse = new HttpResponse();
try {
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod(method);
con.setRequestProperty("User-Agent", USER_AGENT);
con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
con.setDoOutput(true);
if (data != null) {
wr = new DataOutputStream(con.getOutputStream());
wr.write(data.getBytes(UTF8_CHARSET));
}
int responseCode = con.getResponseCode();
httpResponse.setResponseCode(responseCode);
if (httpResponse.isOk()) {
in = new BufferedReader(new InputStreamReader(
con.getInputStream(), "UTF8"));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
httpResponse.setData(response.toString());
}
return httpResponse;
} catch (IOException e) {
e.printStackTrace();
return null;
} finally {
if (wr != null) {
try {
wr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
If I run it and then send request, controller will not print body. But if remove #RequestParam(value = "testParam") from the controller, everything will be ok. What is wrong?
Edited after more information provided in comments below
I assume what's hapening is that s.hasNext() is returning false, because you're at the end of the request's InputStream. This is as designed, you can only read the InputStream once.
This question has a good example of a way you can cache the request to read it more than once.
This question describes a way you can use Spring to log the entire request, which seems to be what your aim is in your question.

Android : Web request helper class

I need to good class for sending and handling the all request such as get , post
I researched anywhere but i could not find the good helper class for it , i am beginner in java and android , please share a good connection helper class with me
public class RRequestHelper
{
DefaultHttpClient httpClient;
HttpContext localContext;
private String ret;
HttpResponse response = null;
HttpPost httpPost = null;
HttpGet httpGet = null;
public RRequestHelper()
{
this.setDefaultOptions();
}
public void setDefaultOptions()
{
HttpParams myParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(myParams, RGeneralSettings.getInstance().getSettingInt(RConstants.CONNECTION_TIMEOUT, false));
HttpConnectionParams.setSoTimeout(myParams, RGeneralSettings.getInstance().getSettingInt(RConstants.CONNECTION_TIMEOUT, false));
httpClient = new DefaultHttpClient(myParams);
localContext = new BasicHttpContext();
}
public void clearCookies()
{
httpClient.getCookieStore().clear();
}
public void abort()
{
try
{
if (httpClient != null)
{
System.out.println("Abort.");
httpPost.abort();
}
}
catch (Exception e)
{
System.out.println("Your App Name Here" + e);
}
}
public String sendPost(String url, String data)
{
return sendPost(url, data, null);
}
public String sendJSONPost(String url, JSONObject data)
{
return sendPost(url, data.toString(), "application/json");
}
public String sendPost(String url, String data, String contentType)
{
ret = null;
httpClient.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.RFC_2109);
httpPost = new HttpPost(url);
response = null;
StringEntity tmp = null;
Log.d("Your App Name Here", "Setting httpPost headers");
httpPost.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:32.0) Gecko/20100101 Firefox/32.0");
httpPost.setHeader("Accept", "text/html,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5");
if (contentType != null)
{
httpPost.setHeader("Content-Type", contentType);
}
else
{
httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");
}
try
{
tmp = new StringEntity(data,"UTF-8");
}
catch (UnsupportedEncodingException e)
{
Log.e("Your App Name Here", "HttpUtils : UnsupportedEncodingException : "+e);
}
httpPost.setEntity(tmp);
Log.d("Your App Name Here", url + "?" + data);
try
{
response = httpClient.execute(httpPost,localContext);
if (response != null)
{
ret = EntityUtils.toString(response.getEntity());
}
}
catch (Exception e)
{
Log.e("Your App Name Here", "HttpUtils: " + e);
}
Log.d("Your App Name Here", "Returning value:" + ret);
return ret;
}
public String sendGet(String url) {
httpGet = new HttpGet(url);
try {
response = httpClient.execute(httpGet);
} catch (Exception e) {
Log.e("Your App Name Here", e.getMessage());
}
//int status = response.getStatusLine().getStatusCode();
// we assume that the response body contains the error message
try {
ret = EntityUtils.toString(response.getEntity());
} catch (IOException e) {
Log.e("Your App Name Here", e.getMessage());
}
return ret;
}
public InputStream getHttpStream(String urlString) throws IOException
{
InputStream in = null;
int response = -1;
URL url = new URL(urlString);
URLConnection conn = url.openConnection();
if (!(conn instanceof HttpURLConnection))
{
throw new IOException("Not an HTTP connection");
}
try
{
HttpURLConnection httpConn = (HttpURLConnection) conn;
httpConn.setAllowUserInteraction(false);
httpConn.setInstanceFollowRedirects(true);
httpConn.setRequestMethod("GET");
httpConn.connect();
response = httpConn.getResponseCode();
if (response == HttpURLConnection.HTTP_OK) {
in = httpConn.getInputStream();
}
}
catch (Exception e)
{
throw new IOException("Error connecting");
} // end try-catch
return in;
}
}

my android application get connection time out while the browser still can use

code:
public static String openUrl(String url, String method,
RequestParam params) throws NuageException {
HttpURLConnection conn = null;
String response = "";
String decodParam = params.decod();
if (method.equals(GET))
{
url = url + "?" + decodParam;
// Log.v(LOG_TAG, "GET:" + url);
}
try {
Log.v("开始请求:", String.valueOf(System.currentTimeMillis()));
conn = (HttpURLConnection) new URL(url).openConnection();
conn.setReadTimeout(READTIMEOUT);
conn.setConnectTimeout(CONNECTTIMEOUT);
conn.setUseCaches(false);
conn.setRequestProperty("Connection", "Keep-Alive");
if (method.equals(POST)) {
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.getOutputStream().write(decodParam.getBytes("UTF-8"));
// Log.v(LOG_TAG, "POST:" + url + " " + decodParam);
}
InputStream is = null;
conn.connect();
int responseCode = conn.getResponseCode();
if (responseCode == 200 || responseCode == 201
|| responseCode == 202) {
is = conn.getInputStream();
} else {
is = conn.getErrorStream();
}
response = read(is);
Log.v("请求结束:", String.valueOf(System.currentTimeMillis()));
Log.v(LOG_TAG, "response:" + response);
checkResponse(response);
} catch (MalformedURLException e) {
throw new NuageException(e);
} catch (IOException e) {
if (e.getMessage() != null && e.getMessage().equals(
"Received authentication challenge is null"))
throw new NuageException(new NuageError(
NuageError.ERROR_SESSIONKEY_INVALID, "", "", ""));
e.printStackTrace();
throw new NuageException(e);
} catch (NuageException e) {
throw e;
} finally {
if (conn != null) {
conn.disconnect();
}
}
return response;
}
sometimes i get java.net.SocketTimeoutException: Connection timed out while the browser still work.
anyone can help to improve my code?

Categories