How to send hashmap as JsonObject to a webservice in Java - java

I am trying to make a POST request with a hashmap. The accepted format by the webservice is given below.
{
"students": [
{
"firstName": "Abc",
"lastName": "XYZ",
"courses": [
"Math",
"English"
]
}
}
This is my code
HttpClient client2 = HttpClient.newBuilder().build();
HttpRequest request2 = HttpRequest.newBuilder()
.uri(URI.create(POST_URI))
.header("Content-Type", "application/json")
.POST(new JSONObject(myMap))
.build();
However, this doesn't work. All the examples I have seen so far only accept string as POST parameter and not map.

In your case it seems that you are using the java http client introduced in Java 11. This client required a BodyPublisher to send POST requests.
The java.net.http.BodyPublishers class provide you a method named #ofString(String body) that you can use to send body.
So you can just build your HttpRequest like that :
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(POST_URI))
.header("Content-Type", "application/json")
.POST(BodyPublishers.ofString(yourBody))
.build();
In this case you need to pass a string to the ofString method, so you can use a library like Jackson or Gson. I don't know how to do this using Gson but using Jackson it is very simple :
ObjectMapper mapper = new ObjectMapper();
String yourBody = mapper.writeValueAsString(yourMap);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(POST_URI))
.header("Content-Type", "application/json")
.POST(BodyPublishers.ofString(yourBody))
.build();
That's all :)
EDIT: After a second reading, I would like to point out that you cannot send java objects as is in an http request. You already need to transform your objects in a readable format for the server like json or XML. Java objects are part of the programs we write, the Http protocol is not able to pass these objects as is. That's why we use an intermediate format, thus the server is able to read this format and transform it back into an object

Related

Can I just send Object Body using java 11 HttpClient using Custom Body Publisher?

I would like to know that I can send Object itself as a body without converting them to String using BodyPublishers.ofString(requestBody) like below
HttpRequest request = HttpRequest.newBuilder(new URI("http://localhost:8080/api/test"))
.version(HttpClient.Version.HTTP_2)
.POST(BodyPublishers.ofString(requestBody))
.header("Content-Type", "application/json")
.build();
According to official doc http://cr.openjdk.java.net/~prappo/8087113/javadoc.02/java/net/http/HttpRequest.html#fromFile-java.nio.file.Path-
There's no method that I can use to just send the object as body.
Request bodies are sent using one of the request processor implementations below provided in HttpRequest, or else a custom implementation can be used.
[fromByteArray(byte[])](http://cr.openjdk.java.net/~prappo/8087113/javadoc.02/java/net/http/HttpRequest.html#fromByteArray-byte:A-) from byte array
[fromByteArrays(Iterator)](http://cr.openjdk.java.net/~prappo/8087113/javadoc.02/java/net/http/HttpRequest.html#fromByteArrays-java.util.Iterator-) from an iterator of byte arrays
[fromFile(Path)](http://cr.openjdk.java.net/~prappo/8087113/javadoc.02/java/net/http/HttpRequest.html#fromFile-java.nio.file.Path-) from the file located at the given Path
[fromString(String)](http://cr.openjdk.java.net/~prappo/8087113/javadoc.02/java/net/http/HttpRequest.html#fromString-java.lang.String-) from a String
[fromInputStream(InputStream)](http://cr.openjdk.java.net/~prappo/8087113/javadoc.02/java/net/http/HttpRequest.html#fromInputStream-java.io.InputStream-) request body from InputStream
[noBody()](http://cr.openjdk.java.net/~prappo/8087113/javadoc.02/java/net/http/HttpRequest.html#noBody--) no request body is sent
Can I customize BodyPublishers?
I would like to use java 11 httpClient and want to send Object as a body like org.springframework.web.client.RestTemplate's postForEntity()

how to send the data in request body as json to resttemplate.exchange

Assume I am getting the values from one API, need to send that data to other API through resttemplate.exchange
I am iterating the values like below
String Data="";
for(String value: receivedvalues){
Data=Data.concat(","+val)
}
List<map> result=resttemplate.exchange(url+Data,HttpMethod.GET,ArrayList.class).getBody);
The above problem is I'm adding data to request url, but i need to send through the request body but in this case how we can send data through the resttemplate.exchange.Can any one have any idea on this.
Thanks in advance.
Map your JSON object to POJO class and then use RestTemplate.exchange(...) method.
Usage example:
ReceivedValuesClass receivedValuesPojo = mapJson(receivedValues);
RequestEntity request = RequestEntity
.get(new URI(url))
.accept(MediaType.APPLICATION_JSON)
.body(receivedValuesPojo);
ResponseClass result=resttemplate.exchange(url,HttpMethod.GET,ResponseClass.class).getBody;
More information here: https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html#exchange-org.springframework.http.RequestEntity-java.lang.Class-

What is the difference between UniRest and Spring RestTemplate giving an http 400 Bad Request?

What is the difference with UniRest and Spring RestTemplate which is giving back a 400 Bad Request with apparently the same header and body sent ?
I try to reach the HubSpot API to create a BlogPost, but using RestTemplate I have a 400 Bad Request error, and using UniRest works alright (returns an OK response). However, I do not want to include a library just to make one REST call: I'd rather stick to RestTemplate.
The request data I need to send
HttpMethod: POST
URL: https://api.hubapi.com/content/api/v2/blog-posts?hapikey=*****************
Header: Content-Type: application/json
Body: (represented by a class instance as blogpostSendPost further down)
{
"name": "My first API blog post!",
"content_group_id": 351076997
}
Using RestTemplate
Setting up the request:
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<BlogpostSendPost> request = new HttpEntity<>(blogpostSendPost, headers);
log(request.toString());
//LOG PRINT: <BlogpostSendPost(name=My first API blog post!, content_group_id=351076997),[Content-Type:"application/json"]>
OR in JSON
The .json() method converts my object in Json like you can see in the logs
HttpEntity<String> request = new HttpEntity<>(blogpostSendPost.toJson(), headers);
log(request.toString());
//LOG PRINT: <{"name":"My first API blog post!","content_group_id":"351076997"},[Content-Type:"application/json"]>
With .postForObject(): 400 Bad Request
BlogpostResponsePost answer = restTemplate.postForObject(
"https://api.hubapi.com/content/api/v2/blog-posts?hapikey=***********",
request,
BlogpostResponsePost.class);
With .exchange(): 400 Bad Request
BlogpostResponsePost answer = restTemplate.exchange(
"https://api.hubapi.com/content/api/v2/blog-posts?hapikey=**********",
HttpMethod.POST,
request,
BlogpostResponsePost.class);
Using UniRest: OK
HttpResponse<JsonNode> resp = Unirest
.post("https://api.hubapi.com/content/api/v2/blog-posts?hapikey=**********")
.header("Content-Type", "application/json")
.body(blogpostSendPost)
.asJson();
I am using PostMan to call my REST SpringBoot Application which is using theses Services : when I am calling the HubSpot API directly from PostMan it works fine, just like with UniRest lib.
Thanks for your help guys !!
Please refer https://community.hubspot.com/t5/APIs-Integrations/Getting-400-Bad-Request-when-trying-to-add-a-Blog-Post/td-p/306532
Instead of converting request object to json, pass request object directly. It worked for me.
// TRY 1: CONTACTS - RestTemplate - OK - contact is created (API V1)
HttpEntity request1 = new HttpEntity<>(contactSendList, headers);
ContactResponseInformations answer1 = restTemplate
.postForObject(
HubSpotConfiguration.URL_CREATE_CONTACT,
request1,
ContactResponseInformations.class);
log.info(answer1.toString()); // OK

Getting header values, Status code etc from Jax-Rs Response class in Junit

I am using Restful web Service using Dropwizard. And generating response as:
Response response = resources.client().resource("/url")
.header("CONTENT-TYPE","value")
.post(Response.class, jsonRequestString);
Now I want to write unit test to ensure the returned content type is corrected in Response Object. how to do that?
You can use the ClientResponse type in Jackson. For example, using a GET operation:
ClientResponse response = Client.create()
.resource(url)
.get(ClientResponse.class);
String contentType = response.getHeaders()
.getFirst("Content-Type");
System.out.println(contentType);

google-http-java-client json update existing object

i'm trying to use google-http-java-client on android and parse JSON responses from my server.
do do that i'm using the following code (provided by the examples of the project)
private static final HttpTransport HTTP_TRANSPORT = AndroidHttp.newCompatibleTransport();
private static final JsonFactory JSON_FACTORY = new JacksonFactory();
HttpRequestFactory requestFactory = HTTP_TRANSPORT
.createRequestFactory(new HttpRequestInitializer() {
#Override
public void initialize(HttpRequest request) {
request.setParser(new JsonObjectParser(JSON_FACTORY));
}
});
HttpRequest request = requestFactory.buildGetRequest(new GenericUrl(url + paramsList));
HttpResponse response = request.execute();
and everything works fine for new objects with
result = response.parseAs(PxUser.class);
but i need to update an existing object with the data from the json string.
with jackson only i can use the following code but with the google client i cannot find any solution.
InputStream in = -get-http-reponse-
ObjectMapper mapper = new ObjectMapper();
ObjectReader reader = mapper.readerForUpdating(MySingleton.getInstance());
reader.readValue(InputStream in);
so i need a way to update an existing object just like with this jackson example but by using the client.
is there a way? do i have to use jackson-databind.jar? how can i accomplish this?
thanks in advance
PS: i can switch to gson if its needed, no problem
It depends on whatever endpoint is receiving the API call, and what it expects the request to look like.
The Google HTTP Java Client simply handles the processes like making the call, encoding and decoding an object, exponential backoff, etc for you. It's up to you to create the request that does what you want and how the server expects it to look.
Likely, the API you're making the request to expects an object update to be made with a PUT request. The updated object is likely going to be the content of the request, encoded in some specific format. Let's assume JSON, since you're parsing JSON responses. So for the purpose of example, let's say you're going to request an object, modify it, then send it back.
First, you get the resource and parse it into your object:
PxUser myUser = response.parseAs(PxUser.class);
Then you modify the object somehow
myUser.setName("Frodo Baggins");
Now you want to send it back to the server as a JSON object in a PUT request:
// httpbin.org is a wonderful URL to test API calls against as it returns whatever if received.
GenericUrl url = new GenericUrl("http://httpbin.org/put");
JsonHttpContent content = new JsonHttpContent(new JacksonFactory(), myUser);
HttpRequest request = requestFactory.buildPutRequest(url, content);
HttpResponse response = request.execute();
System.out.println(response.parseAsString());
The specifics of how you encode and update your content is totally up to you and the API's specification. This is especially easy if you're creating the server receiving the call too.
If you're working with a preexisting API, you may want to update the question with the
specific problem (API "x" requires a response that looks like Blah; how do I do that in the google-http-java-client).
If you're working with a Google API, you'll want to be using the google-api-java-client which does all of this work for you.

Categories

Resources