Java: What is the difference between addHeader and bodyString - java

I'm new to Java and have been looking at a couple of codes for Fluent Request. Most of it made sense except for a tiny bit. In the following code, can I know the difference between .addHeader("content-type", "application/json") and .bodyString(json, ContentType.APPLICATION_JSON), please. Aren't they both specifying that the content type should be Json?
httpResponse = Request.Post(URL)
.addHeader("content-type", "application/json")
.addHeader("Accept", "application/json")
.bodyString(json, ContentType.APPLICATION_JSON)
.execute()
.returnResponse();

My guess is that setting ContentType in bodystring() adds the "content-type" header itself.
So you would use addHeader("content-type", "application/json") explicitly if you need to send a request that does not contain any body data, otherwise just use bodystring().

Related

How to send hashmap as JsonObject to a webservice in 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

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

Accessing User Profile on Graph Microsoft using OKHttp returns special characters

I am trying to retrieve my user profile from graph.microsoft as show here. I am using a Java library OKHttp to achieve this however the server is returning special characters in the response. I checked my headers and I did include "Accept-Encoding: gzip". However the issue is not resolved. See code under;
Java Code
Request userProfileRequest = new Request.Builder()
.url("https://graph.microsoft.com/v1.0/me")
.get()
.addHeader("Authorization", "Bearer "+accessTkn)
.addHeader("Accept", "*/*")
.addHeader("Cache-Control", "no-cache")
.addHeader("Content-Type", "application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8")
.addHeader("Accept-Encoding", "gzip")
.addHeader("Connection", "keep-alive")
.addHeader("cache-control", "no-cache")
.build();
Response userProfileResponse = client2.newCall(userProfileRequest).execute();
System.out.println("Authorization is " +userProfileRequest.header("Authorization"));
System.out.println(userProfileResponse.body().string());
Console output
OkHttp does transparent compression for you. However by explicitly specifying "Accept-Encoding: gzip" you are indicating that you want gzip compression and will handle it yourself.
Removing everything except Authorization as you have done in your answer is the correct solution.
The solution that worked for me was to remove all the headers except for "Authorization"
Java Code
Request userProfileRequest = new Request.Builder()
.url("https://graph.microsoft.com/v1.0/me")
.get()
.addHeader("Authorization", "Bearer "+accessTkn)
.build();

post application/x-www-form-urlencoded request by using rest assured

I've tried in postman successfully,by adding Header"Content-Type=application/x-www-form-urlencoded" with x-www-form-urlencoded body.Apparently, this was my first time working on rest. Please advise me that below my code is correct or not. Thank You.
RestAssured.baseURI = AssignConfig.app.getProperty("RestURL");
Response request = RestAssured
.given()
.config(RestAssured.config()
.encoderConfig(EncoderConfig.encoderConfig()
.encodeContentTypeAs("x-www-form-urlencoded", ContentType.URLENC)))
.contentType("application/x-www-form-urlencoded; charset=UTF-8")
.header("Content-Type", "application/x-www-form-urlencoded")
.formParam("login","userName")
.formParam("password","password")

WireMock - Stubbing GET with body not working while POST stubbing work correctly

When trying to test Client class, POST call stubbing works correctly, while GET isn't. What I'm doing wrong here / not understanding correctly?
Client code (POST):
HttpResponse httpResponse = new DefaultHttpRequestBuilder(HttpMethod.POST, SERVICE_URL_GET_MAGIC)
.withBody(parseMagic(magicName))
.execute();
With stubbing (POST):
stubFor(post(urlEqualTo("/api/get-magic"))
.withRequestBody(equalToJson(magicNameParsed))
.willReturn(aResponse()
.withHeader("Content-Type", "application/json")
.withBody(magicDtoParsed)));
Works correctly (httpResponse will have 200 OK).
When GET use, it won't stub the api call (httpResponse will be 404 Not found).
HttpResponse httpResponse = new DefaultHttpRequestBuilder(HttpMethod.GET, SERVICE_URL_GET_MAGIC)
.withBody(parseMagic(magicName))
.execute();
stubFor(get(urlEqualTo("/api/get-magic"))
.withRequestBody(equalToJson(magicNameParsed))
.willReturn(aResponse()
.withHeader("Content-Type", "application/json")
.withBody(magicDtoParsed)));
I think the problem is that you're expecting a 'body' in your get request, but get requests cannot have a body (only PUT and POST requests can have a body).
try doing the following
stubFor(get(urlEqualTo("/api/get-magic"))
.willReturn(aResponse()
.withHeader("Content-Type", "application/json")
.withBody(magicDtoParsed)));
Note that I've removed the line .withRequestBody(equalToJson(magicNameParsed))
By the way. Stabbing is when you use a knife or sharp object to hurt someone/something. Stubbing is the word you want to use when talking in the context testing :)

Categories

Resources