RestTemplate - Put - Wrong Accept Header - Workaround needed - android

I've been using RestTemplate for a while and have always been satisfied !
But now It sucks.
I used to make my put like this :
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new GsonHttpMessageConverter());
restTemplate.put(URI, object);
Usually my server was accepting format in the URL in a Ruby way : resource.json
But now I'm consuming a server who is not doing so anymore. I need to use Header to deal with format.
Everything is ok, restTemplate set content-type to application/json but don't set the Accept header. So my server is issuing a 406 error because default format is HTML, and he don't render html.
So, does anybody has a workaround for putting both content and accept header to json and adding a json formatted body ?

You can get the headers from the RestTemplate object and add what you need to it (since the headers are nothing more than a map).
Here is the sample code provided by Dam after he got it working:
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new GsonHttpMessageConverter());
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setContentType(MediaType.APPLICATION_JSON);
requestHeaders.setAccept(Arrays.asList(new MediaType[] {MediaType.APPLICATION_JSON}));
HttpEntity<T> requestEntity = new HttpEntity<T>((T) parameter, requestHeaders);
restTemplate.exchange(URI , HttpMethod.PUT, requestEntity, null );

Related

HttpMethod.Delete not working with RestTemplate of Spring-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);

RestTemplate Post UTF-8 data with setContentType(MediaType.MULTIPART_FORM_DATA)

I'm using spring for android. I want to create registration form in my android app. The users maybe fill out the form with utf-8 format but when data send to server and store in MySQL database I find ?????? in my database field.table's column type set to utf8_general_ci. My question is:
Do I need to set something for content type in php page OR I need set UTF-8 in my android code? What should I do for both of them?
Here is my code that I'm using: I did same as here
File cacheDirectory = context.getFilesDir();
tmpFile = new File(cacheDirectory.getPath() + "/" + "avatar.png");
Resource file = new FileSystemResource(tmpFile);
MultiValueMap<String, Object> formData = new LinkedMultiValueMap<String, Object>();
formData.add("firstName", registerFields[0]);
formData.add("lastName", registerFields[1]);
formData.add("userName", registerFields[2]);
formData.add("file", file);
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setContentType(MediaType.MULTIPART_ FORM_DATA);
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<MultiValueMap<String, Object>>(formData, requestHeaders);
RestTemplate restTemplate = new RestTemplate(true);
restTemplate.getMessageConverters().add(
new GsonHttpMessageConverter());
restTemplate.getMessageConverters().add(
new StringHttpMessageConverter());
ResponseEntity<Success[]> response = restTemplate.exchange(url, HttpMethod.POST, requestEntity,Success[].class);
return response.getBody();
Edit: Solved problem with UTF-8 I just added this line into my config.php file and problem solved
mysql_query("SET character_set_results=utf8 , character_set_client=utf8 , character_set_connection=utf8 , character_set_database=utf8 , character_set_server=utf8",$con);
Edit: Not solved the problem
Debugging here will be your friend. Some things to be aware of:
Check that whatever you are using to view the data isn't the issue. Does MySQL store ????? or it your app just showing you ????
Check content formatting on your connection to MySQL, this is a likely culprit. (You could test this by simply writing an app to push data into your database without going over the net)
Check your web application is handling the reading in UTF-8. For example in an older version of JBoss I worked with the embedded apache container read strings from the connection in the default character set of the machine the server was running on (which wasn't utf-8)

android resttemplate +httpclient header encoding problems

Android client, using Springs resttemplace and the Apache common HTTP client to make requests.
I'm working against a server, that sometimes returns a 401 error, with a http header string, "ERROR" that contains a user-info string. The string is language dependent, so it might contain, for example, Scandinavian characters.
The string looks fine in my IOS app, aswell as when i examine it in the Firefox RESTclient plugin.
However, in my Android app, i cannot for the life of me get the chars to come out right. I'd very much appreciate it if someone could think of a way i can make the data come out right.
The server sends content-type UTF-8, and its a regular .setHeader() on the httpservletresponse that sets the parameter i try to retrieve.
Here's the creation of my resttemplate in my Android client (ive tried most methods as you can see):
HttpClient httpClient = new HttpClient();
Credentials defaultcreds = new UsernamePasswordCredentials(msisdn, password);
httpClient.getState().setCredentials(new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM), defaultcreds);
httpClient.getParams().setSoTimeout(prefs.getServerTimeout());
httpClient.getParams().setConnectionManagerTimeout(3000);
httpClient.getParams().setContentCharset("utf-8");
httpClient.getParams().setCredentialCharset(prefs.getCredentialsEncoding());
httpClient.getParams().setHttpElementCharset("utf-8");
httpClient.getParams().setUriCharset("utf-8");
CommonsClientHttpRequestFactory requestFactory = new CommonsClientHttpRequestFactory(httpClient);
requestFactory.setReadTimeout(prefs.getServerTimeout());
RestTemplate restTemplate = new RestTemplate(requestFactory);
// Add message converters
List<HttpMessageConverter<?>> mc = restTemplate.getMessageConverters();
MappingJacksonHttpMessageConverter json = new MappingJacksonHttpMessageConverter();
List<MediaType> supportedMediaTypes = new ArrayList<MediaType>();
supportedMediaTypes.add(MediaType.APPLICATION_JSON);
json.setSupportedMediaTypes(supportedMediaTypes);
mc.add(json);
restTemplate.setMessageConverters(mc);
// Set our specific error handler
restTemplate.setErrorHandler(new MyErrorHandler());
this is my http response, copied from restclient in Firefox if i run the same request there:
Status Code: 401 Unauthorized
Content-Length: 954
Content-Type: text/html;charset=utf-8
Date: Sat, 19 Jan 2013 23:53:10 GMT
ERROR: För att <contents cut out but as you see Scandinavian char looks fine here >
Server: Apache-Coyote/1.1
WWW-Authenticate: Basic realm="rest"
HTTP headers use ASCII (or, in the older specs, Latin-1). Putting other encodings into headers might or might not work.
Your Response Content-Type appears to be text/html. Did you try setting Content-Type and charset in the request header like below? As per documentation here
Documents transmitted with HTTP that are of type text, such as text/html, text/plain, etc., can send a charset parameter in the HTTP header to specify the character encoding of the document.
LinkedMultiValueMap<String, String> headers = new LinkedMultiValueMap<String, String>();
headers.set("Content-Type", "text/html;charset=utf-8");
HttpEntity request = new HttpEntity(null, headers);
ResponseEntity<Person> response = template.exchange(url,
HttpMethod.GET, request, Person.class);

How can I set the charset=UTF-8 in Spring for Android?

I have the following code:
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setAccept(Collections.singletonList(new MediaType("text","plain;charset=UTF-8")));
However this throw me an IllegalArgumentException. The problem is that I want to set the charset as UTF-8 without change it from the config file. Is this possible?
According to the API doc IllegalArgumentException is thrown if MediaType fails to convert itself to String.
Try the following:
requestHeaders.setAccept(
Arrays.asList(new MediaType("text", "plain", Charset.forName("UTF-8")))
);

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.

Categories

Resources