I want my app to response with body utf-8 and iso-8859-1 encoded
per requests with Accept-Charset="utf-8" or Accept-Charset="iso-8859-1".
The response body is always JSON.
In my controller, when I doing this
render(json: data, status: :created)
It response with Content-Type="application/json; charset=utf-8" as well.
But how to make a response with body iso-8859-1 encoded when request Accept-Charset="iso-8859-1"?
In order to do this, you can use the method force_encoding and encoding for example
data = {'name'=>'raghav'}.to_json
data.encoding #This would return what encoding the value as #<Encoding:UTF-8>
new_data = data.force_encoding('ISO-8859-1') #This would force the encoding
new_data.encoding #<Encoding:ISO-8859-1>
Also to do this on the specific case you can always read the request.headers hash to determine the encoding.
There is also another method called encode the main difference between these are force_encoding changes the way string is being read from bytes, and encode changes the way string is written without changing the output (if possible)
Related
I already read the following: Send request to page with windows-1251 encoding from python
Yet I cannot print a correct string. I have tried nearly every combination of u''.join, encode and decode I could think about...
import requests
url = 'http://www.multitran.ru/c/m.exe'
payload = {'CL': '1', 's': 'foo', 'l1':'1'}
r = requests.post(url, data=payload)
# ????????? print(u''.join(r.text))
I'd be very glad to get a solution and an explanation, because I really do not get it!
I'm using HTTParty to send data to a remote API, however the API is complaining because the JSON being sent by HTTParty appears to be being escaped, and is thus deemed invalid.
Here's what I'm doing:
query = {"count"=>1,
"workspaces"=>
{123445=>
{"title"=>"Test Project",
"description"=>"",
"start_date"=>"2015-06-01T00:00:00.000Z",
"due_date"=>"2015-08-31T00:00:00.000Z",
"price_in_cents"=>8000,
"currency"=>"USD",
"status_key"=>130,
"custom_field_values_attributes"=>[],
"workspace_groups_attributes"=>
[{"created_at"=>"2015-07-13T11:06:36-07:00",
"updated_at"=>"2015-07-13T11:06:36-07:00",
"name"=>"Test Customer",
"company"=>true,
"contact_name"=>nil,
"email"=>nil,
"phone_number"=>nil,
"address"=>nil,
"website"=>nil,
"notes"=>nil,
"id"=>"530947",
"custom_field_values_attributes"=>[]}],
"id"=>123445}},
"results"=>[{"key"=>"workspaces", "id"=>123445}]}
Calling to_json on query escapes the JSON too:
"{\"count\":1,\"workspaces\":{\"123445\":{\"title\":\"Test Project\",\"description\":\"\",\"start_date\":\"2015-06-01T00:00:00.000Z\",\"due_date\":\"2015-08-31T00:00:00.000Z\",\"price_in_cents\":8000,\"currency\":\"USD\",\"status_key\":130,\"custom_field_values_attributes\":[],\"workspace_groups_attributes\":[{\"created_at\":\"2015-07-13T11:06:36-07:00\",\"updated_at\":\"2015-07-13T11:06:36-07:00\",\"name\":\"Test Customer\",\"company\":true,\"contact_name\":null,\"email\":null,\"phone_number\":null,\"address\":null,\"website\":null,\"notes\":null,\"id\":\"530947\",\"custom_field_values_attributes\":[]}],\"id\":123445}},\"results\":[{\"key\":\"workspaces\",\"id\":123445}]}"
Is this expected behavior to escape the JSON? Or I'm wondering if the hash I'm building for query is invalid for JSON purposes?
Any help would be greatly appreciated.
Calling to_json on query doesn't yield escaped JSON.
Try puts query.to_json to see that.
You see backslashes because #inspect method on String (and this method is called to display contents of variables to console) displays String enclosed in double quotes, and it has to escape quotes which are in the given string itself.
Your problem is probably not having proper Content-Type headers. You should do something like this:
result = HTTParty.post(url, body: query.to_json, headers: {'Content-Type' => 'application/json'})
I send a get request to a local (separate from app) jetty web server
RestClient.get("ip/command/core/get-version", {})
Then I do a JSON.parse() on the response.
As a result I get
{"revision"=>"r2407", "full_version"=>"2.5 [r2407]", "full_name"=>" [r2407]", "version"=>"2.5"}
What's wrong? How do I turn it into a hash, so I can extract the full_version property?
String returned by service is html encoded. Try decoding it first:
JSON.parse(CGI.unescape_html(response_body))
Your JSON response looks to be encoded into HTML entities.
If you are using Ruby, try decoding the response using CGI.unescape_html prior to running JSON.parse. Running the result of that method through JSON.parse should give you your hash.
I have a servlet which accepts HTML content as part of the request param. The HTML is a localized one which may be a french, spanish etc... content.
I'm also using apache HTTP client to make a request to this servlet for test purpose, which has the following header definition:
HttpClient client = new HttpClient();
PostMethod method = new PostMethod("<URL>");
String html = FileUtils.readFileToString(inputHTMLFile, "UTF-8");
method.addParameter("html", html);
method.addRequestHeader("Accept", "*/*");
method.setRequestHeader("accept-charset", "UTF-8");
Whatever HTML is read has the character encoding utf-8, sample text:
Télécharger un fichier
However when i get the html from the request param that texts becomes T?l?charger un fichier
I went through few links such as http://www.oracle.com/technetwork/articles/javase/httpcharset-142283.html which talks about charset and how normally a browser would encode the special characters. If i were to URLEncode the html with UTF-8 and then decode that with same charset in the servlet i get the HTML as expected.
Is this the only thing i can do to preserve the charsets? Am i missing something?
Thanks.
Now that the issue with the file itself is fixed, try modifying your code as follows:
HttpClient client = new HttpClient();
PostMethod postMethod = new PostMethod("<URL>");
postMethod.getParams().setContentCharset("utf-8"); //The line I added
...
Note that the client needs to decode the request as UTF-8 now. French and Spanish worked correctly because their characters are included in the default ISO-8859-1 charset. Chinese characters are not. If the French and Spanish were decoded correctly on client, the client is decoding the request as ISO-8859-1, and sending UTF-8 could fail.
So you could try also adding this:
postMethod.setRequestheader("Content-Type", "application/x-www-form-url-encoded; charset=utf-8");
Just try this for post method.
HttpPost request = new HttpPost(webServiceUrl);
StringEntity str = new StringEntity(YourData);
str.setContentType("application/json");
HttpPost.setEntity(new StringEntity(str, HTTP.UTF_8));
You should better change string to base64 encoded and then send.
I think I've found the cause by examining EntityBuilder decompiled code: the EntityBuilder ignores the contentEncoding field regarding the parameters, it uses the one from contentType field. And by looking on org.apache.http.entity.ContentType the only one predefined value having UTF-8 is org.apache.http.entity.ContentType.APPLICATION_JSON.
So in my case
HttpPost method = new HttPost("<URL>");
EntityBuilder builder = EntityBuilder.create();
builder.setContentType(ContentType.APPLICATION_JSON);
builder.setContentEncoding(StandardCharsets.UTF_8.name());
...
method.setEntity(builder.build());
did the job (although I think setting contentType is redundant here).
I'm using httpclient-osgi version 4.5.4.
PostMethod method = new PostMethod("URL");
method.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
In order to use a third-party API, I need to encode the Net::HTTP::Post request as an MD5 hex digest, which is then used as part of the signature. However, when I try to simply Digest::MD5.hexdigest(req), it throws a "Cannot convert to string error", and when I explicitly req.to_s, it just gives the MD5 of #<Net::HTTP::Post:0x112a0eef8>
I'm simply:
request = Net::HTTP::Post.new(url.path)
request.body = {
"key" => "val"
}.to_json
# later...
hexDigest = Digest::MD5.hexdigest(request)
which is the documented spec, I think: "[with the] JSON body containing the new information."
This is the relevant sample Java code they supply:
ByteArrayOutputStream requestOutputStream = new ByteArrayOutputStream();
httpMethod.getEntity().writeTo(requestOutputStream);
DigestUtils.md5Hex(requestOutputStream.toByteArray()).toLowerCase();
Any ideas?
Thanks!
Try to call 'to_s' method explicitly, it should help:
hexDigest = Digest::MD5.hexdigest(request.to_s)
The equivalent ruby code for those lines is:
OpenSSL::Digest::MD5.hexdigest(request.body)
httpMethod.getEntity() will return the json defined as the request body.
requestOutputStream.toByteArray() will return the array of bytes corresponding to the request body.