How can i change charset encoding in HTTP response in Java - java

I have to fetch some JSON object from a remote server and for that i am using this function which is working great except that for sometime some weird data is getting fetched which i believe is because it is using ASCII charset to decode.
Please find below thw method that i am using
public HttpResponse call(String serviceURL,String serviceHost,String namespace,String methodName,String payloadKey, String payloadValue) throws ClientProtocolException,IOException,JSONException
{
HttpResponse response = null;
HttpContext HTTP_CONTEXT = new BasicHttpContext();
HTTP_CONTEXT.setAttribute(CoreProtocolPNames.USER_AGENT, "Mozilla/5.0");
HttpPost httppost = new HttpPost(serviceURL);
httppost.setHeader("User-Agent",Constants.USER_AGENT_BROWSER_FIREFOX);
httppost.setHeader("Accept", "application/json, text/javascript, */*");
httppost.setHeader("Accept-Language","en-US,en;q=0.8");
httppost.setHeader("Content-Encoding", "foo-1.0");
httppost.setHeader("Content-Type", "application/json; charset=UTF-8");
httppost.setHeader("X-Requested-With","XMLHttpRequest");
httppost.setHeader("Host",serviceHost);
httppost.setHeader("X-Foo-Target", String.format("%s.%s", namespace,methodName));
/*Making Payload*/
JSONObject objectForPayload = new JSONObject();
objectForPayload.put(payloadKey, payloadValue);
StringEntity stringentity = new StringEntity(objectForPayload.toString());
httppost.setEntity(stringentity);
response = client.execute(httppost);
return response;
}
All these headers that i am passing are correct and i have verified the same via inspect element in Google chrome or Firebug plugin if you are familiar with Mozilla.
Now the problem is that most of the time i am getting the readable data but sometimes i do get unreadable data.
I debugged using eclipse and noticed that the charset under wrappedEntity is showing as "US-ASCII". I am attaching a jpg for reference
Can someone please tell me how can i change the charset from ASCII to UTF-8 of the response before i do response = client.execute(httppost); .
PS:As you have noticed that i am passing charset=utf-8 in the header and that i have already verified using firebug and google chrome that i am passing the exact headers .
Please zoom in to see the image more clearly
Thanks in advance

i was able to resolve the issue just mentioning it for people that may face similar issue.
after getting the response first get the entity by using
HttpEntity entity = response.getEntity();
and since my response was a json object convert entity to string but using "UTF-8" something like this
responseJsonObject = new JSONObject(EntityUtils.toString(entity,"UTF-8"));
previously i was just doing
responseJsonObject = new JSONObject(EntityUtils.toString(entity));

I don't think it's a problem with your headers, I think it's a problem with your string. Just having the header say it's utf-8 doesn't mean the string you write is utf-8, and that depends a lot on how the string was encoded and what's in the "payloadValue"
That said, you can always re-encode the thing correctly before sending it across the wire, for example:
objectForPayload.put(payloadKey, payloadValue);
StringEntity stringentity = new StringEntity(
new String(
objectForPayload.toString().getBytes(),
"UTF8"));
See if that works for you.

You may need to add an "Accept-Encoding"-header and set this to "UTF-8"

Just for the record: the "Content-Encoding" header field is incorrect - a correct server would reject the request as it contains an undefined content coding format.
Furthermore, attaching a charset parameter to application/json is meaningless.

bourne already answered that in the above comment though.
Changing entity = IOUtils.toString(response.getEntity().getContent())
TO entity = EntityUtils.toString(response.getEntity(),"UTF-8")
did the trick.

Related

How to make Java HttpPost NOT include url in body

We have some old java code that POSTs some fields and values to a dotnet5 web api - The api is having problems dealing with the body of the POST as it includes the url/uri as the first part of the body.
The Java sends: http://127.0.0.1:5555?producerRef=GREEN&systemId=78&status=false
But the api is expecting something like: producerRef=GREEN&systemId=78&status=false
as per https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST#example. If we send a test message via Postman then the api has no problems.
This is the Java code:
List<NameValuePair> params = new ArrayList<NameValuePair>(queryParams.size());
for (Map.Entry<String, String> entry : queryParams.entrySet()) {
params.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
}
// the address is just that, there's NO parameters
HttpPost post = new HttpPost(this.cmAddress.toURI());
post.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
post.setHeader(HttpHeaders.CONTENT_TYPE, "application/x-www-form-urlencoded");
CloseableHttpResponse response = httpClient.execute(post);
It's quite simple, but always adds the url to the start of the body of the request. If this is the only way to produce this, what could I do to produce something that looks like this: https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST#example
Many Thanks.
This request seems like a GET request rather than a POST since the request params are in the URL. i don't know about the specifications of the Api you're using, but you can try OKHTTP, you can easily copy the code directly from postman
Postman Get example:
Your issue seems to be at below line
HttpPost post = new HttpPost(this.cmAddress.toURI());
This is the only place which will set the POST url ( another way is to use setURI which is not called anywhere in the code sample you have shared).
If you can use a debugger try checking the value of cmAdress variable

Post with HttpClient returns Bad Request

I am using Java, Spring boot and Apache HttpClient to try send a post request. The documentation of the resource I am trying to reach can be found here:
https://docs.enotasgw.com.br/v2/reference#incluiralterar-empresa
Below is my code:
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost post = new HttpPost(incluirEmpresa);
post.setHeader("Content-Type", "application/json");
post.setHeader("Accept", "application/json");
post.setHeader("Authorization", "Basic " + apiKey);
try {
StringEntity entity = new StringEntity(json);
//tried to add these two lines to see if they would fix the error, but it is the same
entity.setContentEncoding("application/json");
entity.setContentType("application/json");
post.setEntity(entity);
System.out.println(json);
System.out.println("======================");
CloseableHttpResponse response = httpClient.execute(post);
System.out.println(response.getStatusLine().getReasonPhrase() + " - " + response.getStatusLine().getReasonPhrase());
idEmpresa = response.getEntity().getContent().toString();
}
My response is 400 - Bad Request. On the interactive documentation link above, when I post my Json, I receive the error of duplicate entry, which is what I expect since the information I am sending is already on the database.
Since the interactive documentation returns the error of duplicate, I know the problem is not within my json format, but on my post request. The documentation have samples on C#, but not on Java, which is what I am using.
By the way, the json is variable is a string in case this is relevant.
Could someone try to point to me what is wrong with my post code?
Found out what I was missing.
After reviewing what was being sent to the API, i noticed the json was not in the expected format. So I did some research and found that, at least for my case, setting the headers with the content type was not enough, I also had to set the Entity that was being set to the HttpPost, to do that, i had to change this line of the code:
StringEntity entity = new StringEntity(json);
to this:
StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
After that change, the requests started to work as expected.

POST request to server using java URLConnnection with params and file inputs

POST request to server using java URLConnnection
I need to send a POST request with the two parameters below:
param1=value1
param2=value2
And also I need to send a file.
In the case of Apache these 2 two(sending params and file) things are handled like below
post.setQueryString(queryString) // queryString is url encoded for eg: param1=value1&param2=value2
post.setRequestEntity(entity) // entity is constructed using file input stream with corresponding format
Please let me know if you have anything related to this problem.
Please note: When I try using Google Chrome REST client plug-in, I am getting the response as below (tried with all request content-types)
UNSUPPORTED FILE FORMAT: 'multipart/form-data' is not a supported content-type
Response code is 400.
Try this API from Apache to send request internally with POST method.
The below is the sample Code to use API
List<org.apache.http.NameValuePair> list =new ArrayList<org.apache.http.NameValuePair>();
HttpPost postMethod = new HttpPost("http://yoururl/ProjectName");
list.add(new BasicNameValuePair("param1", "param1 Value")) ;
postMethod.setEntity(new UrlEncodedFormEntity(list));
HttpClient client = HttpClientBuilder.create().build();
HttpResponse response = client.execute(postMethod);
InputStream is = response.getEntity().getContent();

Using Robolectric, how to test JSON values sent along POST *request*

In my app I'm going to be sending JSON in a POST request to the server.
I want to test to make sure I'm sending the right values.
Since I'm using Robolectric, my conclusion is that I should get the request that is being sent to the FakeHttpLayer, pull out the JSON, and test that it matches my expectations.
Sounds simple, but I'm having a hell of a time figuring out how to see what JSON I've POSTed.
My code vaguely looks like this:
HttpClient client = new DefaultHttpClient();
HttpResponse response;
JSONObject json = new JSONObject();
try{
HttpPost post = new HttpPost("http://google.com");
json.put("blah", "blah");
StringEntity se = new StringEntity( "JSON: " + json.toString());
se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
post.setEntity(se);
response = client.execute(post);
} catch(Exception e){
e.printStackTrace();
}
I want to have something which is like
assertTrue(myRequestJSON.matches("blah"));
But I can't seem to get that using anything inside of
Robolectric.getFakeHttpLayer().getLastSentHttpRequestInfo();
...or any of the other variations on that.
Help?
By the way, I'm certainly open to thinking about this in a different way, if you think my testing approach is misguided.
Thank you!
EDIT: I realized I had "myResponseJSON" in my dummy code rather than "myRequestJSON," which may have made it unclear--fixed.
I was completely wrong in my previous solution. You can do this rather simply it would appear. I found the solution (predictably) in the Robolectric example code:
HttpPost sentHttpRequest = (HttpPost) Robolectric.getSentHttpRequest(0);
StringEntity entity = (StringEntity) sentHttpRequest.getEntity();
String sentPostBody = fromStream(entity.getContent());
assertThat(sentPostBody, equalTo("a post body"));
assertThat(entity.getContentType().getValue(), equalTo("text/plain; charset=UTF-8"));
(from here)

# converted to %40 in HTTPPost request

i m trying to send post request to webservice..
when i add special character # in parameter it is coverted to %40.i have checked server side..they are getting %40 instead of #.
can any one help me??
here is my code..
httpclient = new DefaultHttpClient();
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("Email", "abc#gmail.com"));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
ResponseHandler<String> responseHandler = new BasicResponseHandler();
String response = httpclient.execute(httppost,responseHandler);
i have also tried this method to prevent my parameter from encoding.
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs, HTTP.PLAIN_TEXT_TYPE));
but it raised unsupported encoded algorithm
pls help me out of this.
You're using UrlEncodedFormEntity, which will URL-encode the content. Turning # into %40 is normal with this encoding. The recipient should be able to decode that automatically, although you may have to use the correct content type for it to do so, probably application/x-www-form-urlencoded.
You can use
URLDecoder.decode("urlcontext", "UTF-8");
to remove any special character from the url which your passing
You need to use something such as URLDecoder on your server side so that you can convert the %40 back to #. The same applies for other special characters.
Use URLDecoder.decode(url) this will be helpful.
I'm definitly late for this party, but I had a similar issue. If you want to decode your url string you need to use decodeURIComponent(url). Where url is the string you are trying to decode.
W3schools does a great job of explaining it. https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_decodeuricomponent

Categories

Resources