Hi I am trying to upload an image to Linkedin via Spring RestTemplate, the steps followed are as follows 1.Initialize the upload and the upload url 2.Use the upload url to PUT the image linked in server
below is the method for step 2
public String uploadImageToURL(MultipartFile file, String uploadURL) throws IOException {
HttpHeaders headers = new HttpHeaders();
headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
headers.add("Authorization", "Bearer Redacted");
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("file", file.getBytes());
HttpEntity<MultiValueMap<String, Object>> reqEntity = new HttpEntity<>(body, headers);
try {
ResponseEntity<String> resp = new RestTemplate().exchange(uploadURL, HttpMethod.PUT, reqEntity, String.class);
} catch (HttpClientErrorException e) {
e.printStackTrace();
}
}
the method is giving -
org.springframework.web.client.HttpClientErrorException$BadRequest: 400 Bad Request: [no body]
I am not able to figure out what's wrong here also from the documentation of linkedin apis its not clear they have given a basic curl request which working fine on postman but programmatically its not working
Curl for the above method as per documentation
Any help is appreciated, I have tried giving content-type to header as image/png but no effect.
PS: I have already referred this link Linkedin v2 API Image upload get error 400 Bad Request but its not helping
CodePudding user response:
You can try something like the following: 1- Generate and print/get the url that the image has to be uploaded to (first part of the upload process). 2- Try to upload it by using the curl tool, just like in the docs. If 2 works then you know the preceding step is working fine and the problem is on the method you posted. Otherwise, you know you have to look elsewhere (steps before 2).
In the case that curl works, then it might just be that the server of the upload link accepts requests not in HTTP(S) but FTP or something similar. In that case you would need to find a solution for that protocol.
Regarding your current implementation:
- using RestTemplate is discouraged since it will soon no longer be supported.
- use
WebClient
instead: link to defining the body of a request - don't use MultiValueMap since it adds the file as a key-value pair and judging from the example on the docs there is no "file" key like you have defined.
As a last resort, in case the curl call works and nothing else does, you could create a simple Bash/Shell script that is called only for part 2 of the process. Happy coding! :)
CodePudding user response:
I would try to use some other Http clients. Here are a few options:
- Apache HttpClient - a very widely used library
- OK HttpClient - Open Source library
- And my favorite (Open Source library written by me) MgntUtils library
With MgntUtils library your code could be as simple as
private static void testHttpClient(String urlStr, File file) {
HttpClient client = new HttpClient();
client.setContentType(MediaType.MULTIPART_FORM_DATA);
client.setRequestHeader("Authorization", "Bearer Redacted");
client.setConnectionUrl(urlStr);
String response = null;
ByteBuffer buff = ByteBuffer.wrap(file.getBytes())
try {
response = client.sendHttpRequest(HttpMethod.PUT, buff);
} catch (IOException e) {
response = TextUtils.getStacktrace(e, false);
}
System.out.println(response);
}
Here is Javadoc for MgntUtils HTTPClient class. The library itself could be found here as Maven artifacts or on Git (including sources and JavaDoc). An article about the library (although it doesn't describe HttpClient feature) could be found here