HTTP PATCH request in Java - java

I am trying to make a HTTP PATCH request in Java, but despite my efforts this is not working.
I am trying to PATCH a Json, here is my code:
HttpResponse response = null;
BufferedReader rd = null;
StringBuffer result = new StringBuffer();
String line = "";
HttpClient httpclient = HttpClients.createDefault();
HttpPatch httpPatch = new HttpPatch("http://myURL");
JsonArrayBuilder Abuilder = Json.createArrayBuilder();
JsonObjectBuilder oBuilder = Json.createObjectBuilder();
for(int i=0;i<48;i++){
Abuilder.add(i+1);
}
oBuilder.add("date", "2016-09-08");
oBuilder.add("values",Abuilder);
JsonObject jo = Json.createObjectBuilder().add("puissance", Json.createObjectBuilder().add("curves",Json.createArrayBuilder().add(oBuilder))).build();
try{
//Execute and get the response.
StringEntity params =new StringEntity(jo.toString());
params.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
httpPatch.setEntity(params);
response = httpclient.execute(httpPatch);
System.out.println("Response Code : " + response.getStatusLine().getStatusCode());
rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
while ((line = rd.readLine()) != null) {
System.out.println(line);
result.append(line);
}
}catch(Exception e){
}
When I execute this request, I get a
"400 Error: The request has an invalid header name".
When I execute this request using Postman, this is working fine.
I am quite new at HTTP requests so do not hesitate to ask if you need more details.

StringEntity.setContentEncoding is used to set the Encoding type,
You should use StringEntity.setContentType to set the ContentType

Problem-
RestTemplate restTemplate = new RestTemplate();
restTemplate.patchForObject("http://localhost:8080/employee/1", requestBody, String.class);
Solution-
RestTemplate restTemplate = new RestTemplate();
restTemplate.postForObject("http://localhost:8080/employee/1?_method=patch", requestBody, String.class);

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.

Java - Sending a post request with HtmlUnit

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;

Pass and receive JSON object from Jersey Resftul webservice from android

Scenario : Pass username and password in a json object to restful webservice and get a json object in return. Yeah, I know, Its simple but I can't get it work.
I have been trying to this from several days. So far, I have tried this:
My restful webservice code
#POST
#Path("/testJson")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public JSONObject testJson(JSONObject inputJsonObj) throws Exception {
JSONObject myjson = new JSONObject();
if(inputJsonObj != null){
System.out.println("=================================");
System.out.println("JSON object = " + inputJsonObj.toString());
System.out.println("=================================");
}
else{
System.out.println("JSON is NULL");
}
myjson.put("success", "1");
System.out.println(myjson.toString());
// return "string returned";
return myjson;
}
And inside my android acivity, the code is
// POST request to <service>/SaveVehicle
HttpPost request = new HttpPost(myURL);
request.setHeader("Accept", "application/json");
request.setHeader("Content-type", "application/json");
request.setHeader("user-agent", "Yoda");
try {
// Build JSON string
// JSONStringer vehicle = new JSONStringer().object()
// .key("getItInputTO").object().key("zipCode").value("90505")
// .key("financingOption").value("B").key("make")
// .value("Scion").key("baseAmountFinanced").value("12000")
// .key("modelYear").value("2010").key("trimCode")
// .value("6221").key("totalMSRP").value("15000")
// .key("aprRate").value("").endObject().endObject();
JSONObject myjson = new JSONObject();
myjson.put("1", "first");
myjson.put("2", "second");
StringEntity entity = new StringEntity(myjson.toString());
entity.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE,"application/json; charset=utf-8"));
request.setEntity(entity);
// Send request to WCF service
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
// HttpResponse response = httpClient.execute(request, localContext);
HttpResponse response = httpClient.execute(request);
resCode = response.getStatusLine().getStatusCode();
Toast.makeText(getApplicationContext(),
response.getStatusLine().getStatusCode() + "",
Toast.LENGTH_LONG).show();
if (resCode == 200) {
Toast.makeText(getApplicationContext(),
response.getStatusLine().getStatusCode() + "",
Toast.LENGTH_LONG).show();
HttpEntity entity2 = (HttpEntity) response.getEntity().getContent();
String text = getASCIIContentFromEntity(entity);
if(text!=null){
JSONObject obj = new JSONObject(text);
lblMsg.setText("Successful!");
}
// BufferedReader in = new BufferedReader(new
// InputStreamReader(response.getEntity().getContent()));
//
//
// String line = "";
// StringBuffer returnFromServer = new StringBuffer();
//
// while ((line = in.readLine()) != null) {
// returnFromServer.append(line);
// }
// // Toast what we got from server
// Toast.makeText(getApplicationContext(),
// returnFromServer.toString(), Toast.LENGTH_LONG).show();
//
// if (entity != null) {
// entity.consumeContent();
// }
}
} catch (Exception e) {
// TODO: handle exception
}
The commented sections show previous tries.
Output that I get on server console
=================================
JSON object = {}
=================================
{"success":"1"}
My server side receiver json object is not getting populated i don't know why.
Note:
I have INTERNET and many other permissions in my android manifest.
My webservice is up and running.
I have all the required jars i.e. jersey, json etc
I am using Tomcat 7 for restful webservice
I would highly appreciate any help.
Thanks
I have the same problem as yours.
I don't know why, but the temporary solution i am using is creating a class to handle those parameters.
That means using Jackson to convert Json Object <=> "Your Class"
See this tutorial for more information:
http://www.mkyong.com/webservices/jax-rs/json-example-with-jersey-jackson/
===================================
And I just found this topic, it may be more useful than the upper solution:
Jersey POST Method is receiving null values as parameters

Java HttpClient: Not able to read json data in the post request

Here I am posting the JSON data using HttpClient. But I am not able to read the data on the other application. When I do request.getParameter("username"), it returns me null. Both my applications are deployed on the same server. Please tell me what I am doing wrong. Thank you
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost postRequest = new HttpPost("http://localhost:8080/AuthenticationService/UserIdentificationServlet");
postRequest.setHeader("Content-type", "application/json");
StringEntity input = new StringEntity("{\"username\":\""+username+"\"}");
input.setContentType("application/json");
postRequest.setEntity(input);
HttpResponse postResponse = httpClient.execute(postRequest);
BufferedReader br = new BufferedReader(new InputStreamReader((postResponse.getEntity().getContent())));
String output;
System.out.println("Output from Server .... \n");
while ((output = br.readLine()) != null) {
System.out.println(output);
}
httpClient.getConnectionManager().shutdown();
}
If you want to use request.getParameter, then you have to post the data in a URL encoded format.
//this example from apache httpcomponents doc
List<NameValuePair> formparams = new ArrayList<NameValuePair>();
formparams.add(new BasicNameValuePair("param1", "value1"));
formparams.add(new BasicNameValuePair("param2", "value2"));
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, "UTF-8");
HttpPost httppost = new HttpPost("http://localhost/handler.do");
httppost.setEntity(entity);

VIEWSTATE value in the HttpPost

Here is the case, I want to post to a website, but before that I must retrieve the viewstate value and then make the post using this value, but the problem is that viewstate value is changing every time i make posts, so I am a little confused how can I use it's value in the second post if the value on the server will be already different.
Is there any solution or am I doing everything wrong?
main with httppost
try {
HttpClient client = new DefaultHttpClient();
HttpPost request = new HttpPost(
"www.website.com/Login.aspx");
String viewstate = getViewState(client, request,
"www.website.com/Login.aspx");
System.out.println(viewstate);
request.getParams().setBooleanParameter(
CoreProtocolPNames.USE_EXPECT_CONTINUE, false);
request.setHeader("Content-Type", "text/html; charset=utf-8");
List<NameValuePair> postParameters = new ArrayList<NameValuePair>();
postParameters.add(new BasicNameValuePair("__VIEWSTATE",
viewstate))
postParameters.add(new BasicNameValuePair("__EVENTTARGET", ""));
postParameters.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
postParameters.add(new BasicNameValuePair("ctl00$tbUsername",
"name"));
postParameters
.add(new BasicNameValuePair("ctl00$tbPwd", "psw"));
postParameters.add(new BasicNameValuePair("ctl00$chkRememberLogin",
"0"));
postParameters
.add(new BasicNameValuePair("ctl00$cmdLogin", "Login"));
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(
postParameters);
request.setEntity(formEntity);
HttpResponse response = client.execute(request);
String responseBody2 = EntityUtils.toString(response.getEntity());
System.out.println(responseBody2);
}
// print page wap
// System.out.println(responseBody2);
}
and then send httpget
String html = "";
try {
URL url1 = new URL("www.website.com/Login.aspx");
URLConnection conn = url1.openConnection();
// Get the response
BufferedReader rd = new BufferedReader(new InputStreamReader(
conn.getInputStream()));
StringBuffer sb = new StringBuffer();
String line;
while ((line = rd.readLine()) != null) {
sb.append(line+"\n");
}
rd.close();
html = sb.toString();
} catch (Exception e) {
e.printStackTrace();
}
return findViewstate(html);
So what I was thinking, maybe I should reuse the same httpClient with the cookies or anything, so that the next request will be to the same page...
If I recall correctly ViewState values are encrypted by default and have information in them to prevent tampering, therefore, multiple requests WILL result in different values. But if you do a request, then make a post back to the page as the user would you should be ok, but you will need to make sure that all data goes back or you are going to hit issues with ASP.NET's event validation.

Categories