How to map curl into java okhttp? - java

I have got a basic curl like below:
curl -X POST \
'https://aogt.pl/auth/' \
-H 'Authorization: Basic NGZjMjExNWQyYTZk' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'client_id=4fc2115'
When I run it in the console on e.g. Ubuntu everything work correctly, I get a good response. Now I would like to map this curl into the java code using okhttp. I write below code:
public class TestMain {
private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
public static void main(String[] args) throws IOException {
String data = "client_id=4fc2115";
RequestBody body = RequestBody.create(JSON, data);
Request request = new Request.Builder()
.url("https://aogt.pl/auth/")
.addHeader("Authorization", "Basic NGZjMjExNWQyYTZk")
.addHeader("Content-Type", "application/x-www-form-urlencoded")
.post(body)
.build();
OkHttpClient client = new OkHttpClient();
Response response = client.newCall(request).execute();
System.out.println(response.body().string());
}
}
The pom file look like:
<dependencies>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.2.0</version>
</dependency>
</dependencies>
The problem is that when I run this code I get "400 Bad Request" so this is problem with server. I wrong map above curl into the java code into the http. Probably the problem is in POST body, because it is not JSON, but what I need to change here, could you please tell me what is wrong? Thank you very much.

The request you want to send has content-type as "application/x-www-form-urlencoded".
So creating the body as a JSON would not work.
You should try forming body in following way:
RequestBody body = new FormBody.Builder().add("client_id", "id_value").build();

RequestBody body = new FormBody.Builder() .add("client_id", "id_value");
Hi hope you had resolved this problem.
Actually, if u want to send a request with 'form-body' instead of 'json', you can easily use this class: 'FormBody'. It inherits RequestBody.

Related

Java Spring WebClient request equivalent of curl with multiple --data-raw

Small question regarding a curl request with multiple --data-raw, and how to construct its Java WebClient counterpart please.
I am having a very simple curl request:
curl -X GET https://some-url:8080/services/auth/login --data-raw username="some-user" --data-raw password="some-password"
The part I am having difficulties with is the double --data-raw, username="some-user" --data-raw password="some-password"
I first thought I could wrap them in a JSON, and combine with .body(BodyInserters.fromValue()) but that is not the case.
--data-raw '{"username": "some-user", "password": "some-password"}'
I then tried (based on this post comment):
webClient.mutate().baseUrl(someUrl).defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE).build().get().uri(uriBuilder -> uriBuilder.path(someRoute).queryParam("username", "some-user").queryParam("password", "some-password").build()).retrieve().bodyToMono(String.class);
None of above worked.
How to send this equivalent of this curl request, using Java Spring WebClient please?
Thank you
Thanks to the comments, the correct use is:
Create a
private final MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
On the WebCLient:
webClient.mutate().baseUrl("https://...").build().post().uri("/route").headers(httpHeaders -> httpHeaders.setAll(headers))
Where headers is the formData

How to use RestTemplate to make a POST call with a request body

I'm trying to make a POST request using RestTemplate to send a request body and headers.
To do this, I saw that many are using HTTPEntity class. But this class a generic type which needs to be passed. The content type is application/json.
In most cases, I saw that HttpEntity was created with String generic type. Like this:
HttpEntity<String> requestEntity = new HttpEntity<String>(body, headers);
responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);
What I didn't get is, how do I know which data type to use while creating HttpEntity object?
I understood that we do ResponseEntity parse the response from the http call into a string. But I didn't understand the same for http entity.
I tried to create the body in http entity object using google's JsonObject, like this:
JsonObject body = new JsonObject();
body.addProperty("key", "value");
.....
The request when tried in postman works, but didn't work in code using RestTemplate when I used String http entity.
When using JsonObject type, I'm getting this error:
org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: Not a JSON Primitive
When using String type http entity, I'm getting some generic error message saying the request isn't valid.
Adding the complete request body :
JsonObject body = new JsonObject();
body.addProperty("transaction_id", transaction_id);
body.addProperty("timestamp", timestamp);
body.addProperty("device_token", deviceToken);
if (forUpdate)
body.addProperty("bit0", true);
The working curl from postman:
curl -X POST \
https://api.devicecheck.apple.com/v1/query_two_bits \
-H 'Content-Type: application/json' \
-H 'authorization: Bearer SOME_BEARER_TOKEN_STRING' \
-H 'cache-control: no-cache' \
-d '{
"device_token": "SOME_DEVICE_TOKEN",
"transaction_id": "f0bc2e5d-5bd9-4437-a455-fd1e210a6268",
"timestamp": 1557073737608
}'
So can someone please help me in understanding how to send this request?

Getting status code 415 for Rest API URI Via Rest Assured but working fine via Rest Client

Getting 415 error in rest assured. Same URI is working fine with Rest client in browser. From Rest client i am getting response code 200.
public static Response response;
public static String jsonAsString;
#BeforeClass
public static void setupURL()
{
// here we setup the default URL and API base path to use throughout the tests
RestAssured.baseURI = "######url##########";
//RestAssured.basePath = "/api/v1";
RestAssured.authentication = basic("password", "password");
Header acceptJson = new Header("content-type", "application/json");
//RestAssured.given().contentType(ContentType.JSON);
RestAssured.given().header(acceptJson);
}
#Test
public void getImageThroughImageid(){
RequestSpecification httpRequest = RestAssured.given();
Response response = httpRequest.request(Method.GET, "/images/imageid");
System.out.println(response.getStatusCode());
}
Need to add Both
.header("Content-Type","application/json" )
.header("Accept","application/json" )
You're using the wrong header for your accept. content-type tells the server what request body you're sending; you want to use accept to tell the server what type of response you want.
Try this:
EncoderConfig encoderConfig = RestAssured.config().getEncoderConfig()
.appendDefaultContentCharsetToContentTypeIfUndefined(false);
RestAssured.config = RestAssured.config().encoderConfig(encoderConfig);
In my case problem was caused by rest assured, which appends "charset" to request header "content-type=application/json".
Such request header may be refused when the server is principled and strict comply RFC 7159
Simply update rest-assured dependency & try to post a payload.
Older rest-assured library appends charset after 'content-type' even if you explicitly set it "application/json".
Headers: Accept=*/*
Authorization=Bearer --token**
Content-Type=application/json; charset=UTF-8
but new rest-assured library will furnish header this way..
Headers: Accept=/
Authorization=Bearer --token**
Content-Type=application/json
I updated below dependency which resolved my issue.
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<version>5.3.0</version>
<scope>test</scope>
</dependency>

How to POST XML string using RestTemplate

I have the following scenario. I have an XML file:
query-users.xml
<?xml version="1.0"?>
<q:query xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3">
</q:query>
When executing the curl commend:
curl.exe --user administrator:5ecr3t -H "Content-Type: application/xml" -X POST http://localhost:8080/midpoint/ws/rest/users/search -d #C:\Users\user\query-users.xml
I get the desired response in XML.
I am trying to do the same POST request using RestTemplate from JAVA code:
try{
StringBuilder builder = new StringBuilder();
builder.append("http://localhost:8080/midpoint/ws/rest/users/search");
builder.append("?query=");
builder.append(URLEncoder.encode("<?xml version=\"1.0\"?><q:query xmlns:q=\"http://prism.evolveum.com/xml/ns/public/query-3\"></q:query>"));
URI uri = URI.create(builder.toString());
restOperations.postForEntity(uri, new HttpEntity<String>(createHeaders("username", "pass")), String.class);
logger.info(response);
}catch(Exception e){
logger.info(e.getMessage());
}
}
I get Internal Servel Error .
There is something that I am doing wrong passing the XML string to the POST request with RestTemplate, but I am not figuring out what it is.
Is there a way how to solve this?
Thanks
Your curl invocation and RestTemplate call are not equivalent. In first one you pass your xml as a a body of HTTP Request (this is what -d option does). In your RestTemplate you assign your xml to query and consequently HTTP Request has no payload and your data is encoded in URL.
If you want to pass your xml as a HTTP Body, you should use different HttpEntity constuctor: http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/http/HttpEntity.html#HttpEntity-T-org.springframework.util.MultiValueMap-

Curl oAuth equivalent in Java

I can't find the way to reproduce the following curl oAuth authentication call in Java:
curl 'https://id.herokuapp.com/oauth/token' -H 'Content-Type: application/x-www-form-urlencoded' -H 'Accept: application/json' -H 'Authorization: Basic AUTH_VALUE' -H 'Connection: keep-alive' --data 'username=_USERNAME&password=_PASSWORD&grant_type=password&scope=read%20write&client_secret=_SECRET&client_id=_CLIENT_ID' --compressed
I don't know how to pass the --data value to the call.
If you're using standard java.net.URL it can be done but the syntax is rather cumbersome, I suggest that you try using HTTP Components library. You should end up with something like this:
final HttpUriRequest request = RequestBuilder.get()
.setUri("https://id.herokuapp.com/oauth/token")
.setHeader("Content-Type", "application/x-www-form-urlencoded")
.setHeader("Accept", "application/json")
.setHeader("Authorization", "Basic AUTH_VALUE")
.addParameter("username", "_USERNAME")
.addParameter("password", "_PASSWORD")
.addParameter("grant_type", "password")
.addParameter("scope", "read write")
.addParameter("client_secret", "_SECRET")
.addParameter("client_id", "_CLIENT_ID")
.build();
final HttpClient client = HttpClientBuilder.create().build();
final HttpResponse response = client.execute(request);
final HttpEntity entity = response.getEntity();
System.out.println(EntityUtils.toString(entity)); // or whatever processing you need
GZip/deflate and keep alive handling is provided out of the box if the HttpClient is created using HttpClientBuilder.

Categories

Resources