HttpMethod.Delete not working with RestTemplate of Spring-Android - android

I am trying to use DELETE method of HttpMethod. The code that I am using for that is
response = restTemplate.exchange(url, HttpMethod.DELETE, requestEntity, Response.class);
I am also using JacksonJson for mapping json. The delete functionality returns the json which should be mapped to Response class. But calling the above line doesn't works and gives internal server error with 500 as response code. But, the same API does work with RESTClient in the browser so I guess there is something that I am not doing correctly.

After doing some more research it seems that DELETE method doesn't supports request body. As we had the control over REST API we have changed the request body to be added as parameters. After doing this change the request is working properly.
Hope it helps someone.

A little late to the party I'd like to chime in here as well (document my solution for posterity)
I'm too using spring's rest template, also trying to perform a delete request with a payload AND i'd also like to be able to get the response code from the server side
Disclaimer: I'm on Java 7
My solution is also based on a post here on SO, basically you initially declare a POST request and add a http header to override the request method:
RestTemplate tpl = new RestTemplate();
/*
* http://bugs.java.com/view_bug.do?bug_id=7157360
* As long as we are using java 7 we cannot expect output for delete
* */
HttpHeaders headers = new HttpHeaders();
headers.add("X-HTTP-Method-Override", "DELETE");
HttpEntity<Collection<String>> request = new HttpEntity<Collection<String>>(payload, headers);
ResponseEntity<String> exchange = tpl.exchange(uri, HttpMethod.POST, request, String.class);

Related

Can't PUT from Android to DJANGO REST

I have a DJANGO REST server on my personal network that is set up to get and receive JSON strings to update "statuses" for a project I'm working on. I can GET the information down into my Android application just fine but when I try to PUT information up to the server, I get the error:
Bad Request: /api/users/1/
[28/Oct/2019 21:23:23] "PUT /api/users/1/ HTTP/1.1" 400 107
I think it's the app because I can successfully do a PUT request via Windows Powershell, but it doesn't work on the Android app. Here is the code using the OKHTTP class:
MediaType JSON = MediaType.parse("application/json; charset=utf-8");
String content = String.format("{'status':%s}", selectedStatus);
RequestBody body = RequestBody.create(JSON, content);
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(IPAddress + "api/users/" + currentUserID + "/")
.addHeader("Content-Type", "application/json")
.put(body) //PUT
.build();
client.newCall(request).execute();
I have tried using the standard HttpURLConnection class, which is what I did for the GET method, but I don't even get a response from the server when I do that. I've tried about a dozen ways to PUT something to the server, but nothing has worked. Any help achieving this goal would be appreciated. Thanks.
For anyone looking at this later, I found the issue. It turns out that in the Windows Powershell, you can use single quotes in the JSON string, but you NEED to use double quotes with the OKHTTP methods. Thus, I changed:
String content = String.format("{'status':%s}", selectedStatus);
to:
String content = String.format("{\"status\":%s}", selectedStatus);
and everything went through perfectly. Hope this helps someone.

Getting Request body content using Retrofit 2.0 POST method

I have a requirement to get a request body and to perform some logic operations with Retrofit 2.0 before doing enque operation. But unfortunately I am not able to get the post body content from my service call. At present after searching a lot I found only one solution like logging the request that I am posting using Retrofit 2.0 from this method by using HttpLoggingInterceptor with OkHttpClient. I am using the following code to log the request body in the Android Logcat:
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(Level.BODY);
OkHttpClient httpClient = new OkHttpClient();
httpClient.interceptors().add(logging);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseURL)
.addConverterFactory(GsonConverterFactory.create())
.build();
return retrofit.create(apiClass);
Problem I am facing with the above method:
Request body are seen only on the default Android Logcat like
02-04 01:35:59.235 5007-5035/com.example.retrofitdemo D/OkHttp:{"nameValuePairs":{"id":"1","name":"chandru","type":"user"}}
But the above method returns only response body in the logcat, I am not able to get it as either String or JSONObject. Eventhough if I could able to get the response body using HttpLoggingInterceptor, my request body will be shown in the Logcat with the tag "OkHttp" all the time even after the application goes into the production (So primarily this leads like a kind of relieving the post data in the logcat).
My Requirement:
I need to get the request body as String or JSONObject or whatever method without reviling the post data in the Logcat.
What I tried:
I tried to fetch the request body even after onResponse from Response<T> response, but though I couldn't able to get it done possible. Please find the code that I am using for this purpose as follows:
Gson gson = new Gson();
String responseString = gson.toJson(response.raw().request().body());
Note: The above converted request body using gson.toJson method returns only the meta data not the request post data.
Kindly help me with this by providing your valuable tips and solutions. I have no idea how to do this. I am completely stuck up with this for the past two days. Please forgive if my question is too lengthy. Your comments are always welcome. Do let me know if my requirement is not clear. Thanks in advance.
I have got it working from this link
Retrofit2: Modifying request body in OkHttp Interceptor
private String bodyToString(final RequestBody request) {
try {
final RequestBody copy = request;
final Buffer buffer = new Buffer();
if (copy != null)
copy.writeTo(buffer);
else
return "";
return buffer.readUtf8();
} catch (final IOException e) {
return "did not work";
}
}
Retrofit dependencies i am using are
compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta3'
compile 'com.squareup.okhttp3:okhttp:3.0.0-RC1'
compile 'com.squareup.okhttp3:logging-interceptor:3.0.0-RC1'
compile 'com.squareup.retrofit2:retrofit:2.0.0-beta3'
I too had the similar issue, I had set JSON as #Body type in retrofit, so the namevaluepair appears in front of the raw body, and it can be seen inside the interceptor.
Even though if we log/debug the jsonObject.toString we see the request as correct without the namevaluepair presented.
What i had done was by setting
Call<ResponseBody> getResults(#Body JsonObject variable);
and in the calling of the method i converted the JSONObject to JsonObject by
new JsonParser().parse(model).getAsJsonObject();

Missing parameter access_token on OAuth2 request

I'm using the Apache Amber libraries to try to retrieve an OAuth2 access token from a Web site under my control. My client code is running under Android.
My code is patterned on the example at:
https://cwiki.apache.org/confluence/display/AMBER/OAuth+2.0+Client+Quickstart
In the first step, I'm able to retrieve a "code" by submitting a GET request using a WebView browser:
OAuthClientRequest request = OAuthClientRequest
.authorizationLocation(AUTHORIZE_URL)
.setClientId(CLIENT_ID)
.setRedirectURI(REDIR_URL)
.setResponseType(CODE_RESPONSE)
.buildQueryMessage();
webview.loadUrl(request.getLocationUri());
I use a WebViewClient callback to capture the redirect URL with the "code" parameter. So far, so good.
Using that code, I try to retrieve my access token:
OAuthClient oAuthClient = new OAuthClient(new URLConnectionClient());
OAuthClientRequest request = OAuthClientRequest
.tokenLocation(ACCESS_TOKEN_URL)
.setGrantType(GrantType.AUTHORIZATION_CODE)
.setClientId(CLIENT_ID)
.setClientSecret(CLIENT_SECRET)
.setRedirectURI(REDIR_URL)
.setCode(code)
.buildBodyMessage();
GitHubTokenResponse oAuthResponse =
oAuthClient.accessToken(request, GitHubTokenResponse.class);
Each time I run my code, I get an OAuthProblemException, where the message is that I have an invalid request due to a missing parameter, access_token.
Another StackOverflow post mentions this exception from a similar OAuth2 request, which in that case was caused by having different redirect URIs across OAuth requests. But I've made sure my redirect URIs are the same by using a named constant. Here's the link to that post:
OAuthProblem, missing parameter access_token
Now, I can print out the code returned by the first request, and paste it into a curl command run from my desktop machine:
curl -d "code=...&client_id=...&client_secret=...&grant_type=...&redirect_uri=..." http://my_website.com
and I get a nice JSON response from my site with an access_token.
Why does the call from Java fail, where my hand-rolled command line succeeds?
I had the same problem implementing the client and the server, the problem is about one mistake in the Client Example in the Apache Amber (Oltu) project:
First you have the Auth code request (which work):
OAuthClientRequest request = OAuthClientRequest
.authorizationLocation(AUTHORIZE_URL)
.setClientId(CLIENT_ID)
.setRedirectURI(REDIR_URL)
.setResponseType(CODE_RESPONSE)
.**buildQueryMessage**();
And second the request about the Access Token (which don't work):
OAuthClientRequest request = OAuthClientRequest
.tokenLocation(ACCESS_TOKEN_URL)
.setGrantType(GrantType.AUTHORIZATION_CODE)
.setClientId(CLIENT_ID)
.setClientSecret(CLIENT_SECRET)
.setRedirectURI(REDIR_URL)
.setCode(code)
.**buildBodyMessage**();
The mistake is about the buildBodyMessage() in the second request. Change it by buildQueryMessage().
Solved in my case.
Amber/Oltu "Missing parameter access_token" error may mean that GitHubTokenResponse or OAuthJSONAccessTokenResponse are unabled to translate response body for any reason. In my case (with Google+ oAuth2 authentication), the response body, is not parsed properly to the inner parameters map.
For example:
GitHubTokenResponse
parameters = OAuthUtils.decodeForm(body);
Parse a form-urlencoded result body
... and OAuthJSONAccessTokenResponse has the next parse function
parameters = JSONUtils.parseJSON(body);
This JSONUtils.parseJSON is a custom JSON parser that not allow for me JSON response body from GOOGLE+ and throws an JSONError (console not logged),
Each error throwed parsing this parameters, are not console visible, and then always is throwed doomed "Missing parameter: access_token" or another "missing parameter" error.
If you write your Custom OAuthAccessTokenResponse, you can see response body, and write a parser that works with your response.
This is what I encountered and what I did to get it working:
I quickly put together a similar example described in:
https://cwiki.apache.org/confluence/display/OLTU/OAuth+2.0+Client+Quickstart
and:
svn.apache.org/repos/asf/oltu/trunk/oauth-2.0/client/src/test/java/org/apache/oltu/oauth2/client/OAuthClientTest.java
This was my command to execute it:
java -cp .:./org.apache.oltu.oauth2.client-1.0.1-20150221.171248-36.jar OAuthClientTest
I also ended up with the above mentioned error where the access_token was expected. I ended up debugging in intellij and traced an anomaly with the if condition which checks that the string begins with the "{" character.
In doing so, I also added the following jar to my classpath so that I may debug the trace a little deeper.
./java-json.jar
(downloaded from http://www.java2s.com/Code/Jar/j/Downloadjavajsonjar.htm)
During the next debug session, the code actually started working. My mate and I eventually found the root cause was due to the JSON jar not being included.
This is the command which works:
java -cp .:./java-json.jar:./org.apache.oltu.oauth2.client-1.0.1-20150221.171248-36.jar OAuthClientTest
I was having the same problem when trying to get the access token from fitbit OAuth2. buildBodyMessage() and buildQueryMessage() were both giving me missing parameter, access_token.
I believe this is something to do with the apache oauth2 client library. I ended up making simple post requests using spring's RestTemplate and it's working fine.
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.set("Authorization", "Basic " + "MjI5TkRZOjAwNDBhNDBkMjRmZTA0OTJhNTE5NzU5NmQ1N2ZmZGEw");
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("client_id", FITBIT_CLIENT_ID);
map.add("grant_type", "authorization_code");
map.add("redirect_uri", Constants.RESTFUL_PATH + "/fitbit/fitbitredirect");
map.add("code", code);
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.postForEntity(FITBIT_TOKEN_URI, request, String.class);
log.debug("response.body: " + response.getBody());

Asynchronous HTTP post with JSON parsing the result with Android 4?

I'm quite new to Android. I've been looking for a good example on how to perform a HTTP post request over the web, but I'm hesitating on which to use since I'm only developing for Android 4. I want something asynchronous, fast and simple. An example with JSON result parsing would be much appreciated. Any ideas? Should I use Apache HTTP Client or HttpURLConnection?
For me RestTemplate is one of the easiest ways to consume REST services on Android.
Example for JSON:
RestTemplate template = new RestTemplate();
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
//setting timeout
requestFactory.getHttpClient().getParams().setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT,
HTTP_TIMEOUT);
requestFactory.getHttpClient().getParams().setIntParameter(CoreConnectionPNames.SO_TIMEOUT,
HTTP_TIMEOUT);
template.setRequestFactory(requestFactory);
//setting converter for JSON
List<HttpMessageConverter<?>> converters = template.getMessageConverters();
converters.add(new MappingJacksonHttpMessageConverter());
template.setMessageConverters(converters);
ResponseEntity<ResponseObject> response = template.postForEntity(URL, requestObject, ResponseObject.class);
ResponseObject result = response.getBody();
To make this works You need RestTemplate and jackson(I think it should be jackson-all) jars in your project. You can find links to those jars in RestTemplate documentation(link above).
To make this asynchronous use AsyncTask from Android SDK.

Android : 400 Error code when accessing a RESTful webservice

I want to access a Restful web service. I want the request should be in the following format.
GET /API/Contacts/username HTTP/1.1
HOST: $baseuri:port
Accept: text/xml
Authorization: Basic ZmF0aWdhYmxlIGdlbmVyYXR=
And also I am calling the web service though HTTPS protocol.
The folowing is the code I am using :
HttpGet get = new HttpGet("https://secure.myapp.com/MyApp/API/Contacts/myname");
get.addHeader("Accept","text/xml");
get.addHeader("Authorization","Basic ZmF0aWdhYmxlIGdlbmVyYXR=");
get.addHeader("Host","https://secure.myapp.com");
get.addHeader("Connection Use","HTTP 1.1");
DefaultHttpClient client = new DefaultHttpClient();
ResponseHandler objHandler = new BasicResponseHandler();
String getResponse = client.execute(get,objHandler);
But I am getting an Error : 400 Bad request.
I am not sure whether my code is correct. Is it necessary to specify the method (GET, POST or PUT) explicitly in the header?
Please help me...
Thnking You....
Shouldn't you put 'Basic ZmF0aWdhYmxlIGdlbmVyYXR=' in double quotes?
Also check web service example request and response and make sure that everything is specified.
Ohh...
That was my mistake.
I did not keep the order of adding headers.
When I changed its order according to the Request it is working fine.
In the request the HOST should be the first parameter.
The following is the corrected code.
get.addHeader("Host","secure.myapp.com");
get.addHeader("Accept","text/xml");
get.addHeader("Authorization","Basic ZmF0aWdhYmxlIGdlbmVyYXR=");
get.addHeader("Connection Use","HTTP 1.1");
Sorry to disturb you all...

Categories

Resources