Java - Sending a post request with HtmlUnit - java

Can't really find any help on this but I've been trying to send a post request with HtmlUnit. The code I have is:
final WebClient webClient = new WebClient();
// Instead of requesting the page directly we create a WebRequestSettings object
WebRequest requestSettings = new WebRequest(
new URL("www.URLHERE.com"), HttpMethod.POST);
// Then we set the request parameters
requestSettings.setRequestParameters(new ArrayList());
requestSettings.getRequestParameters().add(new NameValuePair("name", "value"));
// Finally, we can get the page
HtmlPage page = webClient.getPage(requestSettings);
Is there an easier way I could carry out a POST request?

This is how it's done
public void post() throws Exception
{
URL url = new URL("YOURURL");
WebRequest requestSettings = new WebRequest(url, HttpMethod.POST);
requestSettings.setAdditionalHeader("Accept", "*/*");
requestSettings.setAdditionalHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
requestSettings.setAdditionalHeader("Referer", "REFURLHERE");
requestSettings.setAdditionalHeader("Accept-Language", "en-US,en;q=0.8");
requestSettings.setAdditionalHeader("Accept-Encoding", "gzip,deflate,sdch");
requestSettings.setAdditionalHeader("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.3");
requestSettings.setAdditionalHeader("X-Requested-With", "XMLHttpRequest");
requestSettings.setAdditionalHeader("Cache-Control", "no-cache");
requestSettings.setAdditionalHeader("Pragma", "no-cache");
requestSettings.setAdditionalHeader("Origin", "https://YOURHOST");
requestSettings.setRequestBody("REQUESTBODY");
Page redirectPage = webClient.getPage(requestSettings);
}
You can customize it however you want. Add/remove headers, add/remove request body, etc ...

There are n numbers of possible libraries using which you can call rest web services.
1) Apache Http client
2) Retrofit from Square
3) Volley from google
I have used Http Apache client and Retrofit both. Both are awesome.
Here is code example of Apache HTTP client to send Post request
String token = null;
HttpClient httpClient = HttpClientBuilder.create().build();
HttpPost postRequest = new HttpPost(LOGIN_URL);
StringBuilder sb = new StringBuilder();
sb.append("{\"userName\":\"").append(user).append("\",").append("\"password\":\"").append(password).append("\"}");
String content = sb.toString();
StringEntity input = new StringEntity(content);
input.setContentType("application/json");
postRequest.setHeader("Content-Type", "application/json");
postRequest.setHeader("Accept", "application/json");
postRequest.setEntity(input);
HttpResponse response = httpClient.execute(postRequest);
if (response.getStatusLine().getStatusCode() != 201)
{
throw new RuntimeException("Failed : HTTP error code : " + response.getStatusLine().getStatusCode());
}
Header[] headers = response.getHeaders("X-Auth-Token");
if (headers != null && headers.length > 0)
{
token = headers[0].getValue();
}
return token;

Related

Send HTTPS request with JSON through Java [duplicate]

I would like to make a simple HTTP POST using JSON in Java.
Let's say the URL is www.site.com
and it takes in the value {"name":"myname","age":"20"} labeled as 'details' for example.
How would I go about creating the syntax for the POST?
I also can't seem to find a POST method in the JSON Javadocs.
Here is what you need to do:
Get the Apache HttpClient, this would enable you to make the required request
Create an HttpPost request with it and add the header application/x-www-form-urlencoded
Create a StringEntity that you will pass JSON to it
Execute the call
The code roughly looks like (you will still need to debug it and make it work):
// #Deprecated HttpClient httpClient = new DefaultHttpClient();
HttpClient httpClient = HttpClientBuilder.create().build();
try {
HttpPost request = new HttpPost("http://yoururl");
StringEntity params = new StringEntity("details={\"name\":\"xyz\",\"age\":\"20\"} ");
request.addHeader("content-type", "application/x-www-form-urlencoded");
request.setEntity(params);
HttpResponse response = httpClient.execute(request);
} catch (Exception ex) {
} finally {
// #Deprecated httpClient.getConnectionManager().shutdown();
}
You can make use of Gson library to convert your java classes to JSON objects.
Create a pojo class for variables you want to send
as per above Example
{"name":"myname","age":"20"}
becomes
class pojo1
{
String name;
String age;
//generate setter and getters
}
once you set the variables in pojo1 class you can send that using the following code
String postUrl = "www.site.com";// put in your url
Gson gson = new Gson();
HttpClient httpClient = HttpClientBuilder.create().build();
HttpPost post = new HttpPost(postUrl);
StringEntity postingString = new StringEntity(gson.toJson(pojo1));//gson.tojson() converts your pojo to json
post.setEntity(postingString);
post.setHeader("Content-type", "application/json");
HttpResponse response = httpClient.execute(post);
and these are the imports
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClientBuilder;
and for GSON
import com.google.gson.Gson;
#momo's answer for Apache HttpClient, version 4.3.1 or later. I'm using JSON-Java to build my JSON object:
JSONObject json = new JSONObject();
json.put("someKey", "someValue");
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
try {
HttpPost request = new HttpPost("http://yoururl");
StringEntity params = new StringEntity(json.toString());
request.addHeader("content-type", "application/json");
request.setEntity(params);
httpClient.execute(request);
// handle response here...
} catch (Exception ex) {
// handle exception here
} finally {
httpClient.close();
}
It's probably easiest to use HttpURLConnection.
http://www.xyzws.com/Javafaq/how-to-use-httpurlconnection-post-data-to-web-server/139
You'll use JSONObject or whatever to construct your JSON, but not to handle the network; you need to serialize it and then pass it to an HttpURLConnection to POST.
protected void sendJson(final String play, final String prop) {
Thread t = new Thread() {
public void run() {
Looper.prepare(); //For Preparing Message Pool for the childThread
HttpClient client = new DefaultHttpClient();
HttpConnectionParams.setConnectionTimeout(client.getParams(), 1000); //Timeout Limit
HttpResponse response;
JSONObject json = new JSONObject();
try {
HttpPost post = new HttpPost("http://192.168.0.44:80");
json.put("play", play);
json.put("Properties", prop);
StringEntity se = new StringEntity(json.toString());
se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
post.setEntity(se);
response = client.execute(post);
/*Checking response */
if (response != null) {
InputStream in = response.getEntity().getContent(); //Get the data in the entity
}
} catch (Exception e) {
e.printStackTrace();
showMessage("Error", "Cannot Estabilish Connection");
}
Looper.loop(); //Loop in the message queue
}
};
t.start();
}
Try this code:
HttpClient httpClient = new DefaultHttpClient();
try {
HttpPost request = new HttpPost("http://yoururl");
StringEntity params =new StringEntity("details={\"name\":\"myname\",\"age\":\"20\"} ");
request.addHeader("content-type", "application/json");
request.addHeader("Accept","application/json");
request.setEntity(params);
HttpResponse response = httpClient.execute(request);
// handle response here...
}catch (Exception ex) {
// handle exception here
} finally {
httpClient.getConnectionManager().shutdown();
}
I found this question looking for solution about how to send post request from java client to Google Endpoints. Above answers, very likely correct, but not work in case of Google Endpoints.
Solution for Google Endpoints.
Request body must contains only JSON string, not name=value pair.
Content type header must be set to "application/json".
post("http://localhost:8888/_ah/api/langapi/v1/createLanguage",
"{\"language\":\"russian\", \"description\":\"dsfsdfsdfsdfsd\"}");
public static void post(String url, String json ) throws Exception{
String charset = "UTF-8";
URLConnection connection = new URL(url).openConnection();
connection.setDoOutput(true); // Triggers POST.
connection.setRequestProperty("Accept-Charset", charset);
connection.setRequestProperty("Content-Type", "application/json;charset=" + charset);
try (OutputStream output = connection.getOutputStream()) {
output.write(json.getBytes(charset));
}
InputStream response = connection.getInputStream();
}
It sure can be done using HttpClient as well.
You can use the following code with Apache HTTP:
String payload = "{\"name\": \"myname\", \"age\": \"20\"}";
post.setEntity(new StringEntity(payload, ContentType.APPLICATION_JSON));
response = client.execute(request);
Additionally you can create a json object and put in fields into the object like this
HttpPost post = new HttpPost(URL);
JSONObject payload = new JSONObject();
payload.put("name", "myName");
payload.put("age", "20");
post.setEntity(new StringEntity(payload.toString(), ContentType.APPLICATION_JSON));
For Java 11 you can use the new HTTP client:
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("http://localhost/api"))
.header("Content-Type", "application/json")
.POST(ofInputStream(() -> getClass().getResourceAsStream(
"/some-data.json")))
.build();
client.sendAsync(request, BodyHandlers.ofString())
.thenApply(HttpResponse::body)
.thenAccept(System.out::println)
.join();
You can use publishers from InputStream, String, File. Converting JSON to a String or IS can be done with Jackson.
Java 11 standardization of HTTP client API that implements HTTP/2 and Web Socket, and can be found at java.net.HTTP.*:
String payload = "{\"name\": \"myname\", \"age\": \"20\"}";
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder(URI.create("www.site.com"))
.header("content-type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(payload))
.build();
HttpResponse<String> response = client.send(request, BodyHandlers.ofString());
Java 8 with apache httpClient 4
CloseableHttpClient client = HttpClientBuilder.create().build();
HttpPost httpPost = new HttpPost("www.site.com");
String json = "details={\"name\":\"myname\",\"age\":\"20\"} ";
try {
StringEntity entity = new StringEntity(json);
httpPost.setEntity(entity);
// set your POST request headers to accept json contents
httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("Content-type", "application/json");
try {
// your closeablehttp response
CloseableHttpResponse response = client.execute(httpPost);
// print your status code from the response
System.out.println(response.getStatusLine().getStatusCode());
// take the response body as a json formatted string
String responseJSON = EntityUtils.toString(response.getEntity());
// convert/parse the json formatted string to a json object
JSONObject jobj = new JSONObject(responseJSON);
//print your response body that formatted into json
System.out.println(jobj);
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
I recomend http-request built on apache http api.
HttpRequest<String> httpRequest = HttpRequestBuilder.createPost(yourUri, String.class)
.responseDeserializer(ResponseDeserializer.ignorableDeserializer()).build();
public void send(){
ResponseHandler<String> responseHandler = httpRequest.execute("details", yourJsonData);
int statusCode = responseHandler.getStatusCode();
String responseContent = responseHandler.orElse(null); // returns Content from response. If content isn't present returns null.
}
If you want send JSON as request body you can:
ResponseHandler<String> responseHandler = httpRequest.executeWithBody(yourJsonData);
I higly recomend read documentation before use.

How to send url encoded data using post method in java

I am trying to send url encoded data using HttpURLConnection method in java. Client shared the below string from Soap UI tester as a sample request:
http://www.clienturl.com/payment?username=bk&password=bk&customerid=100039085&amountcredit=100&operationdate=2018-07-17&event=9977773&reference=2323900&account=00000000&valuedate=2018-07-17&terminal=00010
I've tried all combinations of sending data using java. Am getting response code as 200, but the response is showing that missing mandatory parameters in the request. Please help if there are any error in my code, in writing the request.
StringBuffer response = new StringBuffer();
String EndPointURL = url;
String requestXML = "username=bk&password=bk&customerid=78233209438&amountcredit=100&operationdate=2018-07-17&event=9977773&reference=13903232&account=000000&valuedate=2018-07-17&terminal=00010";
String encodedData = URLEncoder.encode(requestXML, "UTF-8");
System.out.println("Encoded data: " + encodedData);
URL localURL = new URL(EndPointURL);
HttpURLConnection con = (HttpURLConnection) localURL.openConnection();
con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
con.setRequestProperty("Accept-Charset", charset);
con.setRequestProperty("Content-Length", Integer.toString(encodedData.length()));
OutputStream os = con.getOutputStream();
if you are using Okhttp3, use this code :
OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
RequestBody body = RequestBody.create(mediaType, "string-that-you-need-to-pass-in-body");
Request request = new Request.Builder()
.url("url-string")
.post(body)
.addHeader("content-type", "application/x-www-form-urlencoded")
.build();
Response response = client.newCall(request).execute();
For Unirest :
HttpResponse<String> response = Unirest.post("url-string")
.header("content-type", "application/x-www-form-urlencoded")
.body("string-that-you-need-to-pass-in-body")
.asString();

Empty request when sending special characters to API with Java

I'm using Java to send http requests to my API which is created using Laravel (5.4). If I send a request without any special characters it all works like a charm. But if there are any 'special' characters like: é, å, ö and such the request in Laravel is empty:
dd(request()->all()) outputs []
I guess this has to do with some wrong settings while creating the request in Java. I couldn't find a solution.
Here is the code responsible for creating the request.
public class HttpClient {
org.apache.http.client.HttpClient client;
public HttpClient() {
client = HttpClientBuilder.create().build();
}
public void post(String json) {
try {
HttpPost request = buildPostRequest(json);
HttpResponse response = createClient().execute(request);
int code = getStatusCode(response);
if (code != 200) {
throw new Exception("Error (" + code + ") on server.");
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
private org.apache.http.client.HttpClient createClient() {
return HttpClientBuilder.create().build();
}
private HttpPost buildPostRequest(String json) throws Exception {
HttpPost request = new HttpPost("some uri");
request.addHeader("Content-type", "application/json; charset=utf-8");
request.addHeader("Accept", "application/json");
StringEntity params = new StringEntity(json);
params.setContentEncoding("utf-8");
params.setContentType("application/json; charset=utf-8");
request.setEntity(params);
return request;
}
private int getStatusCode(HttpResponse response) {
StatusLine line = response.getStatusLine();
return line.getStatusCode();
}
}
EDIT
Dump of the request before it get's send to the API.
I found a solution to the problem. In the buildPostRequest() method I changed from a StringEntity to a ByteArrayEntity and coverted the string to UTF-8 bytes.
ByteArrayEntity params = new ByteArrayEntity(json.getBytes("UTF-8"));
If I send special characters to the API the request isn't empty anymore.
try this way
HttpPost request = new HttpPost(URLEncoder.encode("url here", "UTF-8"));

Invalid HTTP method: PATCH

After trying other solutions from HttpURLConnection Invalid HTTP method: PATCH
I am getting Invalid HTTP Method: PATCH Exception with JAVA 7.
Updating JAVA is not in option so i have to stick to the workarounds.
I am using Invocation to invoke the request like this
Invocation invoke = reqBuilder.build(getHTTPVerb(), Entity.entity(requestJSON, MediaType.APPLICATION_JSON));
getWebTarget().request(MediaType.APPLICATION_JSON).header("Authorization", getAuthorization()).accept(MediaType.APPLICATION_JSON);
getHTTPVerb() returns String "POST" or "PATCH".
With PATCH method I am having problem.
In the mentioned question, i have not tried one solution with:
conn.setRequestProperty("X-HTTP-Method-Override", "PATCH");
conn.setRequestMethod("POST");
conn is HttpURLConnection instance.
But I am not sure how I can get HttpURLConnection from Invocation class or any property.
Any pointers or help would be highly appreciated.
An example of PATCH method with apache http client:
try {
//This is just to avoid ssl hostname verification and to trust all, you can use simple Http client also
CloseableHttpClient httpClient = HttpClientBuilder.create().setSSLContext(new SSLContextBuilder().loadTrustMaterial(null, TrustAllStrategy.INSTANCE).build())
.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE).build();
HttpPatch request = new HttpPatch(REST_SERVICE_URL);
StringEntity params = new StringEntity(JSON.toJSONString(payload), ContentType.APPLICATION_JSON);
request.setEntity(params);
request.addHeader(org.apache.http.HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
request.addHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE);
request.addHeader(HttpHeaders.AUTHORIZATION, OAuth2AccessToken.BEARER_TYPE + " " + accessToken);
HttpResponse response = httpClient.execute(request);
String statusCode = response.getStatusLine().getStatusCode();
} catch (Exception ex) {
// handle exception here
}
Equivalent example with RestTemplate:
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.add("Authorization", OAuth2AccessToken.BEARER_TYPE + " " + accessToken);
final HttpEntity<String> entity = new HttpEntity<String>(JSON.toJSONString(payload), headers);
RestTemplate restTemplate = new RestTemplate();
try {
ResponseEntity<String> response = restTemplate.exchange(REST_SERVICE_URL, HttpMethod.PATCH, entity, String.class);
String statusCode = response.getStatusCode();
} catch (HttpClientErrorException e) {
// handle exception here
}

Sending and Parsing Response using HTTP Client for a JSON List

With in my java code, I need to send a http post request to a specific URL with 3 headers:
URL: http://localhost/something
Referer: http://localhost/something
Authorization: Basic (with a username and password)
Content-type: application/json
This returns a response with a JSON "key":"value" pair in it that I then need to parse somehow to store the key/value (Alan/72) in a MAP. The response is (when using SOAPUI or Postman Rest):
{
"analyzedNames": [
{
"alternate": false
}
],
"nameResults": [
{
"alternate": false,
"givenName": "John",
"nameCategory": "PERSONAL",
"originalGivenName": "",
"originalSurname": "",
"score": 72,
"scriptType": "NOSCRIPT",
}
]
}
I can do this using SOAPUI or Postman Rest but how can I do this within Java as I'm getting an error:
****DEBUG main org.apache.http.impl.conn.DefaultClientConnection - Receiving response: HTTP/1.1 500 Internal Server Error****
My code is:
public class NameSearch {
/**
* #param args
* #throws IOException
* #throws ClientProtocolException
*/
public static void main(String[] args) throws ClientProtocolException, IOException {
// TODO Auto-generated method stub
DefaultHttpClient defaultHttpClient = new DefaultHttpClient();
StringWriter writer = new StringWriter();
//Define a postRequest request
HttpPost postRequest = new HttpPost("http://127.0.0.1:1400/dispatcher/api/rest/search");
//Set the content-type header
postRequest.addHeader("content-type", "application/json");
postRequest.addHeader("Authorization", "Basic ZW5zYWRtaW46ZW5zYWRtaW4=");
try {
//Set the request post body
StringEntity userEntity = new StringEntity(writer.getBuffer().toString());
postRequest.setEntity(userEntity);
//Send the request; return the response in HttpResponse object if any
HttpResponse response = defaultHttpClient.execute(postRequest);
//verify if any error code first
int statusCode = response.getStatusLine().getStatusCode();
}
finally
{
//Important: Close the connect
defaultHttpClient.getConnectionManager().shutdown();
}
}
}
Any help (with some sample code including which libraries to import) will be most appreciated.
THANKS
Yes, you can do it with java
You need apache HTTP client library http://hc.apache.org/ and commons-io
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost("http://localhost/something");
post.setHeader("Referer", "http://localhost/something");
post.setHeader("Authorization", "Basic (with a username and password)");
post.setHeader("Content-type", "application/json");
// if you need any parameters
List<NameValuePair> urlParameters = new ArrayList<NameValuePair>();
urlParameters.add(new BasicNameValuePair("paramName", "paramValue"));
post.setEntity(new UrlEncodedFormEntity(urlParameters));
HttpResponse response = client.execute(post);
HttpEntity entity = response.getEntity();
Header encodingHeader = entity.getContentEncoding();
// you need to know the encoding to parse correctly
Charset encoding = encodingHeader == null ? StandardCharsets.UTF_8 :
Charsets.toCharset(encodingHeader.getValue());
// use org.apache.http.util.EntityUtils to read json as string
String json = EntityUtils.toString(entity, StandardCharsets.UTF_8);
JSONObject o = new JSONObject(json);
I recommend http-request built on Apache HTTP API.
HttpRequest<String> httpRequest = HttpRequestBuilder.createPost(yourUri
new TypeReference<Map<String, List<Map<String, Object>>>>{})
.basicAuth(userName, password)
.addContentType(ContentType.APPLICATION_JSON)
.build();
public void send(){
ResponseHandler<String> responseHandler = httpRequest.executeWithBody(yourJsonData);
int statusCode = responseHandler.getStatusCode();
Map<String, List<Map<String, Object>>> response = responseHandler.get(); // Before calling the get () method, make sure the response is present: responseHandler.hasContent()
System.out.println(response.get("nameResults").get(0).get("givenName")); //John
}
I highly recommend reading the documentation before use.
Note: You can create your custom type instead of Map to parse response. See my answer here.

Categories