I am having a mess of a time finding up to date information on sending a JSON request to a local server. I keep coming across examples that use deprecated code, and I'd really like to do this with code that isn't.
I can at least say that I now have a working example, and I am not receiving any deprecated messages from NetBeans, but I would like to know if what I've put together is the right way:
public void sendUpdateRequest() {
String updateString =
"{\"jsonrpc\": \"2.0\", \"method\": \"VideoLibrary.Scan\"}" ;
StringEntity entity = new StringEntity(updateString, Consts.UTF_8);
HttpPost httpPost = new HttpPost(getURL()); // http://xbmc:xbmc#10.0.0.151:8080/jsonrpc
entity.setContentType("application/json");
httpPost.setEntity(entity);
try (CloseableHttpClient client = HttpClientBuilder.create().build()) {
HttpResponse response = client.execute(httpPost);
System.out.println(response.getStatusLine()); // move to log
}
catch (IOException e) {
e.printStackTrace(); // move to log
}
}
This is something I'm working on to update XBMC with a JSON HTTP request
Edit
Changed the code to try with resources per the comment -- hopefully this will be useful for someone else dealing with JSON and Java
but I would like to know if what I've put together is the right way:
Yes, you are doing it correctly given the details you've posted.
The StringEntity contains the body of the request. You can set any appropriate headers there. Any other headers can be set directly on the HttpPost object.
As stated in the comments, don't take any chances, close() the CloseableHttpClient in a finally block.
Related
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
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.
I have implemented a PerformHttpPostRequest function which is supposed to send a post request contains a JSON type body and get a JSON response via Apache HttpClient.
public static String PerformHttpPostRequest(String url, String requestBody) throws IOException {
CloseableHttpClient client = HttpClients.createDefault();
HttpPost httpPost = new HttpPost(url);
StringEntity entity = new StringEntity(requestBody);
httpPost.setEntity(entity);
httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("Content-type", "application/json");
CloseableHttpResponse response = client.execute(httpPost);
HttpEntity httpEntity = response.getEntity();
InputStream is = httpEntity.getContent();
return (new BufferedReader(new InputStreamReader(is, "UTF-8"))).readLine();
}
The problem is, the code works perfect on developing environment, but when running the war file with a tomcat server but the request is not executed.
I've tried adding several catch blocks such as IOException, Exception and the code doesn't get there.
I've added debug prints which demonstrated that the code stops responding at the client.execute(...) command.
The function is called inside a try block, and after executing the .execute(...) command the code does get to the finally block.
I've already searched for a similar problem and didn't find an answer.
Is it a known issue? Does anyone have any idea of what can cause that? Or how can I fix it?
Hi Talor nice to meet you,
Please try to use HttpURLConnection to solve this issue like so:
Java - sending HTTP parameters via POST method easily
Have a nice day.
el profesor
I have tried with RestTemplate.
RequestObject requestObject = new RequestObject();
requestObject.setKey("abcd");
requestObject.setEndpoint(serviceEndPoint);
RestTemplate restTemplate = new RestTemplate();
HttpEntity<RequestObject> requestBody = new HttpEntity<RequestObject>(
requestObject);
ResponseEntity<RequestObject> result = restTemplate.postForEntity(
serviceEndPoint, requestBody, RequestObject.class);
Its very simple and hassle free, hope it helps
Few things you can try out.
- Try to do ping/curl from that box where you are running tomcat.
- Try to have a test method which make a get request to a server which is always reachable. For ex google.com and print the status. That way you could be able to know that you code is actually working or not in server env.
Hope this helps. :)
If the code doesn't pass beyond client.execute(...) but it does execute the finally block in the calling code, then you can find out what caused the aborted execution by adding this catch block to the try block that contains the finally:
catch(Throwable x) {
x.printStackTrace();
}
Throwable is the superclass for all exception and error classes, so catching a Throwable will catch everything.
I am using the below process,
1)Create a String template for a SOAP request and substitute user-supplied values at runtime in this template to create a valid request.
2) Wrap this string in a StringEntity and set its content type as text/xml
3) Set this entity in the SOAP request.
and with the help of httppost I am posting the request,
I am using a demo webservice from w3schools.com
url--->
http://www.w3schools.com/webservices/tempconvert.asmx
What I have tried is,
HttpPost httppost = new HttpPost("http://www.w3schools.com/webservices/tempconvert.asmx");
StringEntity se;
try {
SOAPRequestXML="<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:tem=\"http://tempuri.org/\"><soapenv:Header/><soapenv:Body><tem:CelsiusToFahrenheit><!--Optional:--><tem:Celsius>30</tem:Celsius></tem:CelsiusToFahrenheit></soapenv:Body></soapenv:Envelope>";
Log.d("request is ", SOAPRequestXML+"!!!");
se = new StringEntity(SOAPRequestXML,HTTP.UTF_8);
se.setContentType("text/xml");
httppost.setHeader("Content-Type","application/soap+xml;charset=UTF-8");
httppost.setEntity(se);
HttpClient httpclient = new DefaultHttpClient();
BasicHttpResponse httpResponse =
(BasicHttpResponse) httpclient.execute(httppost);
HttpEntity resEntity = httpResponse.getEntity();
t.setText(EntityUtils.toString(resEntity));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
I am able to get the response in soapui, so surely the code is wrong because in emulator I am getting the output,
"the server cannot service the request because the media type is unsupported".
Am I passing the correct parameter in the constructor of HttpPost or am I making the correct xml request.I tried a lot but could not figure it out.
Thanks
The only problem with your code is you are setting Header as,
httppost.setHeader("Content-Type","application/soap+xml;charset=UTF-8");
instead of,
httppost.setHeader("Content-Type", "text/xml;charset=UTF-8");
As you can see the request in the URL that is -> w3schoools, they are using,
Content-Type: text/xml; charset=utf-8
and you where not passing the same content type. So, it was giving you error as,
The server cannot service the request because the media type is unsupported.
So, just change the Header and you will get the desired response.
I have written an article on How to Call Web Service in Android Using SOAP at c-sharpcorner.com.
So many person get helped from that article. You can also download it and run. I will help you to understand how to use SOAP for web service.
Edit
Take a look at following links. It has complex data handling with ksoap.
Complex objects tutorial with sample code
http://bimbim.in/post/2010/10/08/Android-Calling-Web-Service-with-complex-types.aspx
http://seesharpgears.blogspot.in/2010/10/web-service-that-returns-array-of.html
I have a hunch that the emulator android version and the phone version are different.
But I have few suggestions. Use following:
httppost.setHeader("Accept-Charset","utf-8");
httppost.setHeader("Accept","text/xml,application/text+xml,application/soap+xml");
similarly, set content type as all of the above.
Have you tried using the ksoap2 library for Android ?
you can find it here, give it a shot :
https://code.google.com/p/ksoap2-android/
Hope this helps !
This way the html form is posting 123 celsius. No SOAP or envelops, just working:)
try {
HttpPost httppost = new HttpPost("http://www.w3schools.com/webservices/tempconvert.asmx/CelsiusToFahrenheit");
StringEntity se = new StringEntity("Celsius=123");
httppost.setEntity(se);
httppost.setHeader("Content-Type", "application/x-www-form-urlencoded");
HttpResponse httpResponse = new DefaultHttpClient().execute(httppost);
HttpEntity resEntity = httpResponse.getEntity();
return EntityUtils.toString(resEntity);
} catch (Exception e) {
e.printStackTrace();
return e.getMessage();
}
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)