Jersey Client post binary data application-octet/stream - java

I would like to perform a post with binary data using Jersey Client.
The equivalent with curl would be:
curl -v --header "Content-Type:application/octet-stream" --data-binary "abc" http://example.com
I could not find how to do it in the official docs: http://jersey.java.net/documentation/latest/user-guide.html#client
Thanks.

I think you can invoke a POST request with Entity which encapsulates binary data like this:
Client client = ClientBuilder.newClient();
WebTarget webTarget = client.target("http://example.com/rest");
Response response = webTarget.request(MediaType.TEXT_PLAIN_TYPE)
.post(Entity.entity("abc", MediaType.APPLICATION_OCTET_STREAM));

Related

How to send a PUT request with multipart/form-data body with Java Http Client?

I am using the HttpClient and HttpRequest available on java.net.http. I have successfully sent some GET and POST requests, but I have no clue about how to send a PUT/POST request with multipart/form-data body:
HttpRequest dataRequest = HttpRequest.newBuilder()
.header("accept", "*/*")
.header("Content-Type", "multipart/form-data")
// .POST() ??
.uri(URI.create(DATA_URL)
.build();
The curl equivalent of this request would be something like:
curl -X PUT "https://www.example.com/data" -H "accept: */*" -H "Content-Type: multipart/form-data" -F "file=#audiofile.wav;type=audio/wav"
Should I use some kind of BodyPublishers in the POST() or PUT() method in order to achieve that? Any clue?
Multipart/form-data is not supported out of the box by the HttpClient API yet.
In JDK 16 there is a new HttpRequest.BodyPublishers.concat(BodyPublisher...) method that can be used to help build a request body built from the concatenation of bytes coming from heterogeneous sources.
But you would have to manually compose all the different parts, and handle base64 encoding when/if that's needed.
You could also try out methanol

Binance Margin Borrow API in java

I am new to Binance API and I'm having some difficulty to invoke Binance margin borrow API. I have referred their API documentation, But don't know how to invoke the margin borrow API through java. So, I would like to someone guide or share me an example code to invoke their margin API in java.
Thanks in advance
The request used by their website has the following curl structure:
curl --location --request GET 'https://www.binance.com/gateway-api/v1/public/margin/vip/spec/list-all' \
--header 'content-type: application/json'
In Java with apache http client, you can do it like this:
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet httpGet = new HttpGet();
httpGet.setURI(new URI("https://www.binance.com/gateway-api/v1/public/margin/vip/spec/list-all"));
httpGet.setHeader("content-type", "application/json");
CloseableHttpResponse response = httpclient.execute(httpGet);
String responseJson = EntityUtils.toString(response.getEntity());
System.out.println(responseJson);
From what I could understand by a quick look at the docs, you will have to generate a HMAC SHA256 signature from your secretKey as the key and totalParams as the value for the HMAC operation and your API-key is passed into the Rest API via the X-MBX-APIKEY header.
String hmac = HMAC_SHA256("secret_key", "totalParams")
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("api uri here"))
.timeout(Duration.ofMinutes(1))
.header("X-MBX-APIKEY", "api-key here")
.POST(totalParamsHere)
.build()

How to convert curl call with "-i --upload-file" into java Unirest or any other http request?

The example below uses cURL to upload image file included as a binary file.
curl -i --upload-file /path/to/image.png --header "Authorization: Token" 'https://url....'
It works fine. I need to make this request from my Java application.
I have tried next code
URL image_url = Thread.currentThread().getContextClassLoader().getResource("jobs_image.jpg");
String path = image_url.getFile();
HttpResponse<String> response = Unirest.post(uploadUrl)
.header("cache-control", "no-cache")
.header("X-Restli-Protocol-Version", "2.0.0")
.header("Authorization", "Bearer " + token + "")
.field("file", new File(path))
.asString();
However, it returns status 400 Bad Request.
Is there any way to call such request from Java?
This is a request from LinkedIn v2 API:
https://learn.microsoft.com/en-us/linkedin/consumer/integrations/self-serve/share-on-linkedin?context=linkedin/consumer/context#upload-image-binary-file
After several hours of banging my head against the wall, I finally figured out how to convert the curl call into a RestClient one (I'm using Ruby on Rails).
I think the problem you're having is that you have to pass the MIME type as the Content-Type in the request headers.
I'm using MiniMagick to figure out the MIME type of the image I'm uploading to LinkedIn. MiniMagick can also give you the binary string of the image that LinkedIn requires, so it's a win-win situation.
This is the call that finally worked:
file = MiniMagick::Image.open(FILE_PATH)
RestClient.post(UPLOAD_URL, file.to_blob, { 'Authorization': 'Bearer TOKEN', 'Content-Type': file.mime_type })
Below method will upload the image to linkedIn
Reference : https://learn.microsoft.com/en-us/linkedin/marketing/integrations/community-management/shares/vector-asset-api#upload-the-image
private void uploadMedia(String uploadUrl,String accessToken) throws IOException {
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization","Bearer "+accessToken);
byte[] fileContents = Files.readAllBytes(new
File("path_to_local_file").toPath());
HttpEntity<byte[]> entity = new HttpEntity<>(fileContents, headers);
restTemplate.exchange(uploadUrl,HttpMethod.PUT, entity, String.class);
}
I think the curl command
curl -i --upload-file /path/to/image.png --header "Authorization: Token" 'https://url....'
uses PUT while your Java client uses POST
Source: The man page of curl.
-T, --upload-file <file>
This transfers the specified local file to the remote URL. If
there is no file part in the specified URL, Curl will append the
local file name. NOTE that you must use a trailing / on the last
directory to really prove to Curl that there is no file name or
curl will think that your last directory name is the remote file
name to use. That will most likely cause the upload operation to
fail. If this is used on an HTTP(S) server, the PUT command will
be used.
Not sure if this is the actual problem though. Your API doc link actually specifies POST.

Query parameter not being extracted - JAX-RS and Jersey

I'm using Jersey 2.19 to implement a REST API but I'm having difficulty using #QueryParam to extract the query parameters from a POST request even though my resource method is being called.
This is my resource method:
#POST
#Produces(MediaType.TEXT_PLAIN)
public Response test(#QueryParam("test-param") String testParam)
{
String response = "testParam is: " + testParam + "\n";
return Response.status(Response.Status.OK).entity(response).build();
}
I'm using cURL to submit the HTTP POST request as follows:
curl -X POST http://192.168.0.2:8080/myApp/test --data test-param=Hello
The value returned is always null.
What am I doing wrong?
The --data in curl will provide the whole text test-param=Hello. The correct way to request it is:
curl -X POST http://192.168.0.2:8080/myApp/test?test-param=Hello
try to use curl -X POST '192.168.0.2:8080/myApp/test?test-param=Hello';
-d, --data
(HTTP) Sends the specified data in a POST request to the HTTP server, in the same way that a browser does when a user has filled in an HTML form and presses the submit button. This will cause curl to pass the data to the server using the content-type application/x-www-form-urlencoded. Compare to -F, --form.

Jersey Test Equivalent to curl request

First trip into the Java web services world. Trying to write a test for a post request. The post looks like this in curl:
url -v -X POST -H 'Content-Type: application/json' -d '{"transaction_zips": ["78732"],"condition": "good"}' http://localhost:8080/PricingService/vin/1GTEC19J37E152026/usedValues
I've attempted:
#Test
public void testVinPricing200() {
int status = target.path("PricingService/vin/1GTEC19J37E152026/usedValues").request(MediaType.APPLICATION_JSON_TYPE).
post(Entity.entity("{\"transaction_zips\": [\"78732\"],\"condition\": \"good\"}", MediaType.APPLICATION_JSON)).getStatus();
assertEquals(200, status);
}
This results in:
Failed tests: testVinPricing200(com.comp.platform.PricingServiceTest): expected:<200> but was:<406>
So the question is simple, I'm obviously not posting correctly, what am I doing wrong?
The difference between your curl request and your junit test in your junit test you are requesting a response of type MediaType.APPLICATION_JSON_TYPE, but your webservice is not capable of responding via JSON.
Http Status code: 406
The resource identified by the request is only capable of generating response entities
which have content characteristics not acceptable according to the accept headers sent in
the request.

Categories