Wrapper class for HttpGet / Post in Java? - java

Sorry, I'm quite new to Java.
I've stumbled across HttpGet and HttpPost which seem to be perfect for my needs, but a little long winded. I have written a rather bad wrapper class, but does anyone know of where to get a better one?
Ideally, I'd be able to do
String response = fetchContent("http://url/", postdata);
where postdata is optional.
Thanks!

HttpClient sounds like what you want. You certainly can't do stuff like the above in one line, but it's a fully-fledged HTTP library that wraps up Get/Post requests (and the rest).

I would consider using the HttpClient library. From their documentation, you can generate a POST like this:
PostMethod post = new PostMethod("http://jakarata.apache.org/");
NameValuePair[] data = {
new NameValuePair("user", "joe"),
new NameValuePair("password", "bloggs")
};
post.setRequestBody(data);
// execute method and handle any error responses.
...
InputStream in = post.getResponseBodyAsStream();
// handle response.
There are a number of advanced options for configuring the client should you eventually required those.

Related

How can I be sure that an HttpClient PostMethod contains UTF-8 strings in the parameters?

In our webapp, we have to send a POST request via HttpClient to an endpoint on our network, which will receive this and do some work with it. We are having trouble with character encoding, and I am having difficulties finding an answer to my question.
We have used the postMethod.getParams().setContentCharset("UTF-8") method when sending the request, but on the receiving end, it seems like the characters are still encoded in ISO 8859-1. I have determined this because when I inspect the String on the receiving side, it has garbage characters in it that go away once I follow the steps found at https://stackoverflow.com/a/16549329/1130549. Is there any extra steps I need to take on the sending end to ensure that I am actually writing characters in UTF-8 as expected? All we are doing now is using postMethod.addParameter(paramKey, paramValue) with native String objects.
Edit: Here is a very simple example of how we're sending the POST request. For what it's worth, the values are being taken from an XMLBeans object.
PostMethod postMethod = new PostMethod(url);
postMethod.getParams().setContentCharset("UTF-8");
postMethod.addParameter("key1", "value1");
postMethod.addParameter("key2", "value2");
HttpClient httpClient = new HttpClient();
int status = httpClient.executeMethod(postMethod);
EDIT
Simpler solution is to encode the value
postMethod.addParameter("key1", URLEncoder.encode("value1","UTF-8"));
To encode properly UTF-8, you can execute differently, using StringEntity and NameValuePair, e.g.:
try (CloseableHttpClient httpClient = HttpClients.custom().build()) {
URIBuilder uriBuilder = new URIBuilder(url);
HttpHost target = new HttpHost(uriBuilder.getHost(), uriBuilder.getPort(), uriBuilder.getScheme());
List<NameValuePair> nameValuePairs = new ArrayList<>();
nameValuePairs.add(new BasicNameValuePair("key1", "value1"));
nameValuePairs.add(new BasicNameValuePair("key2", "value2"));
String entityValue = URLEncodedUtils.format(nameValuePairs, StandardCharsets.UTF_8.name());
StringEntity entity = new StringEntity(entityValue, StandardCharsets.UTF_8.name());
post.setEntity(entity);
httpClient.execute(target, post);
First of all, you do need to make sure that the string that you are actually writing is encoded in UTF-8. I realized that you already know that but still double-check that it is so, as it would be the prime suspect of your problem. Also, I would recommend trying a much simpler HTTP client. Apache HTTP client (I believe that's the library that you are using) is an excellent library. But due to covering a very wide range of options it tends to be a bit bulky. So, or simple requests I would suggest a lightweight HTTP client that maybe not that comprehensive as Apache library but offers simplicity as a trade-off. Here how your code may look like:
private static void testHttpClient() {
HttpClient client = new HttpClient();
// client.setContentType("text/html; charset=utf-8");
client.setContentType("application/json; charset=utf-8");
client.setConnectionUrl("http://www.my-url.com");
String content = null;
try {
String myMessage = getMyMessage() // get the string that you want to send
content = client.sendHttpRequest(HttpMethod.POST, myMessage);
} catch (IOException e) {
content = client.getLastResponseMessage() + TextUtils.getStacktrace(e, false);
}
System.out.println(content);
}
It looks much more simple, I think. Also in the same library, there is another utility that allows you to convert any string in any language into a sequence of unicodes and vice-versa. This helped me numerous times to diagnose encoding thorny issues. For instance, if you see some gibberish symbols that could be a wrong display of a valid character or actual character loss. Here is an example of how it works:
result = "Hello World";
result = StringUnicodeEncoderDecoder.encodeStringToUnicodeSequence(result);
System.out.println(result);
result = StringUnicodeEncoderDecoder.decodeUnicodeSequenceToString(result);
System.out.println(result);
The output of this code is:
\u0048\u0065\u006c\u006c\u006f\u0020\u0057\u006f\u0072\u006c\u0064
Hello World
That might help you to check if the string you passed is valid or not. The library is called MgntUtils and could be found at Maven Central or at Github It comes as maven artifact and with sources and Javadoc. Javadoc could be found separately here
Disclaimer: The MgntUtils library is written by me

In Java "&curren" is encoded to "¤". How to prevent this

From Java code I want to call a webservice like this:
"http://example.com/mytarget?firstParam=xxx&currency=EUR"
But no matter what I do. As soon as I compose a String with "&currency=" in it, it gets replaced by "¤cy=" instantly, which the webservice doesn't like and responds with an error.
To illustrate, here is a small code snipet I use:
String uri = "http://example.com?test=1&currency=EUR";
HttpGet request = new HttpGet(uri); //string got replaced already!
request.addHeader("content-type", "application/json");
HttpResponse result = httpClient.execute(request);
String json = EntityUtils.toString(result.getEntity(), "UTF-8");
The above code makes a call to:"http://example.com?test=1¤cy=EUR"
Similar Question, no answer:
https://stackoverflow.com/questions/29890388/how-to-get-curren-to-display-literally-not-as-an-html-entity-in-Java
Any ideas?
Or is there a "proper" way to call a webservice from Java code that avoids this problem?

Put request parameters not getting set

This may be standard stuff but unable to get it wokring.
I'm using org.apache.commons.httpclient.methods for making Http request from my Java code. In one instance I've to make a PUT request and pass some parameters. I'm doing it the following way:
PutMethod putMethod = new PutMethod(url);
putMethod.getParams().setParameter("param1", "param1Value");
putMethod.getParams().setParameter("param2", "param2Value");
httpClient.executeMethod(putMethod);
But at the server, when it tries to read these parameters - it can only get null.
However, When I modify my url as url?param1=param1Value&param2=param2Value it works.
How do I get it working using setParameter method?
To add Query Params to PutMethod, follow this method.
NameValuePair[] putParameters = new NameValuePair[2];
putParameters[0] = new NameValuePair(Param1, value1);
putParameters[1] = new NameValuePair(Param2, value2);
HttpClient client = new HttpClient();
PutMethod putMethod = new PutMethod(url);
putMethod.setQueryString(putParameters);
Then Call,
int response = client.executeMethod(putMethod);
Instead of putMethod.setQueryString(putParameters); you could also use
putMethod.setRequestBody(EncodingUtil.formUrlEncode(putParameters, "UTF-8"));
(This is deprecated)
GetMethod, PostMethod have slight differences when adding Query Params compared to the above code.
For More Code Examples : http://www.massapi.com/class/pu/PutMethod.html
Hope this helps.
your server side code has to support the PUT method
for example if its a Servlet you can include the method
doPUT(); // your put request will be delivered to this method
if you use REST based frameworks such as jersey
you can use
#PUT
Response yourPutMethod(){..}

Multiple Difficulties with HttpURLConnection class in Java for Android

--Update--
Apologies for those who helped me, it turns out this is just a problem with Eclipse's debugger. After suspecting that it was leading me wrong, I placed down a couple of System.out.println to watch the variables, and according to them they ARE being changed, and that the debugger was just showing me old information for whatever reason. No clue why that's happening, but the important thing is that the code does apparently actually work.
I'm working on a method to share with twitter for an Android application, and I'm having errors when setting up the HttpURLConnection. I create the connection object as per usual, using the openconnection function of a url then casting it to a HttpURLConnection, and when I subsequently run SetRequestMethod("POST") on the connection, it does absolutely nothing. When I run the code in the debugger line by line, as I go through that line the request method just remains as the default ("GET"). Anyone have any idea as to why this may be happening? I'm getting the same problem with setDoOutput(true) also not changing anything. However, adding a request property does still work. I've been searching around and haven't been able to find anything on this problem, not even another person reporting these problems.
I am not sur whether using HttpURLConnection is the best here.
Did you try the following way?
// Building the POST request
final BasicNameValuePair message = new BasicNameValuePair("yourField", "yourContent");
final List<NameValuePair> list = new ArrayList<NameValuePair>(1);
list.add(message);
final HttpPost httppost = createHttpPost(UrlEncodedFormEntity(list));
// Building the HTTP client
final HttpParams httpParameters = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParameters, YOUR_CHOSEN_CONN_TIMEOUT);
HttpConnectionParams.setSoTimeout (httpParameters, YOUR_CHOSEN_SO_TIMEOUT);
final HttpClient httpClient = new DefaultHttpClient(httpParameters);
// Execution of the POST request
final HttpResponse response = httpClient.execute(httppost);
This is the way I usually do, with no problems.
[EDIT: 04-25-2014] Apache's HttpClient was the best approach for Froyo and former versions. Now, according to this article from Android Developers Blog (written after this Q&A), it is better to use URLConnection.

java: apache HttpClient > how to disable retry

I'm using Apache Httpclient for Ajax-calls on a website. In some cases requests to external webservice fail, often with:
I/O exception (java.net.ConnectException) caught when processing request: Connection timed out: connect.
In that case, more often than not, I want to skip retrying the request (something that Httpclient seems to do automatically) .
However, I can't find any method, param, etc. to skip retrying.
anyone?
Thanks Geert-Jan
From httpclient 4.3 use HttpClientBuilder
HttpClientBuilder.create().disableAutomaticRetries().build();
client.setHttpRequestRetryHandler(new DefaultHttpRequestRetryHandler(0, false));
That would do it.
OK. There is issue in the Documentation. Also there has been change in API and methods.
So if you want to use DefaultHttpRequestRetryHandler , here are the ways to do that,
DefaultHttpClient httpClient = new DefaultHttpClient();
DefaultHttpRequestRetryHandler retryHandler = new DefaultHttpRequestRetryHandler(0, false);
httpClient.setHttpRequestRetryHandler(retryHandler);
or
HttpClient httpClient = new DefaultHttpClient();
DefaultHttpRequestRetryHandler retryHandler = new DefaultHttpRequestRetryHandler(0, false);
((AbstractHttpClient)httpClient).setHttpRequestRetryHandler(retryHandler);
In first one, we use concrete DefaultHttpClient (which is a subclass of AbstractHttpClient and so has the setHttpRequestRetryHandler() method.)
In second one, we are programming to the HttpClient interface (which sadly doesn't expose that method, and this is weird !! ehh), so we have to do that nasty cast.
There's a description in the HttpClient tutorial.
client.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
new DefaultHttpMethodRetryHandler());
See the tutorial for more information, for instance this may be harmful if the request has side effects (i.e. is not idempotent).
The cast to AbstractHttpClient is not necessary. Another way is to use a strategy with AutoRetryHttpClient with DefaultServiceUnavailableRetryStrategy set to 0 for retry parameter. A better way would be to extend the AbstractHttpClient or implement HttpClient to expose the desired method.

Categories