RestTemplateBuilder: problem sending audio to telegram api - java

I use RestTemaplteBuilder for send POST request to Telegram Bot API.
There was a problem creating the request to upload the audio file.
According to the documentation - https://core.telegram.org/bots/api#sending-files you need to send a request of type multipart/form-data.
Error: 413 Request Entity Too Large
MultiValueMap<String, Object> request= new LinkedMultiValueMap<String, Object>();
try {
parts.set("chat_id", "id");
parts.set("audio", (Files.readAllBytes(Paths.get(ClassLoader.getSystemResource("name.mp3").toURI()))));
} catch (Exception e) {
e.printStackTrace();
}
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<MultiValueMap<String, Object>>(request, headers);
ResponseEntity<String> responseEntity = restTemplateBuilder.build().postForEntity(requestFormatter(URL_BOT_PREFIX, method), requestEntity, String.class);

Related

No HttpMessageConverter for org.springframework.http.HttpEntity and content type "multipart/form-data" error when uploading MultipartFile

I followed all the steps from here to upload a multipart file: https://www.baeldung.com/spring-rest-template-multipart-upload.
The issue is that I get a 500 HTTP code, No HttpMessageConverter for org.springframework.http.HttpEntity and content type "multipart/form-data".
I searched about the error and it was suggested to add an additional converter to handle Multipart file upload. But I think it should work out of the box with built-in instruments.
Here is the upload file method:
public String uploadFile(MultipartFile file) {
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add(file.getName(), file);
HttpHeaders httpHeaders = new HttpHeaders();
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, httpHeaders);
return super.httpClient.doPostRequest(httpHeaders, myEndpoint, requestEntity, String.class, MediaType.MULTIPART_FORM_DATA);
}
In doPostRequest I do the following - set the headers content type, create an entity and call the exchange method from restTemplate, returning the body:
httpHeaders.setContentType(contentType);
HttpEntity<B> entity = new HttpEntity<>(body, httpHeaders);
ResponseEntity<T> result = restTemplate.exchange(url, HttpMethod.POST, entity, responseType);
return result.getBody();

ERROR 400: Bad request: Error parsing form fields <EOL> when uploading image to Cloudflare Java

I have been trying to upload an image to Cloudflare images, but no matter what I try it gets rejected with "400 Bad Request: "ERROR 5400: Bad request: Error parsing form fields""
https://api.cloudflare.com/#cloudflare-images-upload-an-image-using-a-single-http-request
I am currently using SpringBoot with Rest Templates, here's an example of what I have tried so far:
public String uploadImage(File file) {
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new ByteArrayHttpMessageConverter());
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
headers.add(HttpHeaders.AUTHORIZATION, "Bearer " + API_TOKEN);
LinkedMultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
//body.add("\"file\"", new FileSystemResource(file));
body.add("file", new FileSystemResource(file));
HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<>(body, headers);
ResponseEntity<String> response = restTemplate.exchange(URL, HttpMethod.POST, request, String.class);
return response.toString();
}
I have tried using different forms of the file, changing the parameters, using different methods to make the request, ex: restTemplate.exchange vs restTemplate.getForObject, etc... and I have had no luck. If anyone can help me out or point me in the right direction, I would be greatly appreciated!

Pass an Object and a String via RestTemplate

My rest endpoint:
#PostMapping("/customerPolicyInfo")
public Map<String, Object> getCustomerPolicyInfo(#RequestParam String policyNumber, #RequestParam Claims authenticatedUserDetails) {
}
How to call this endpoint from another service using RestTemplate? It is a HTTP POST request?
My current code where I am calling this above endpoint looks like this:
Claims authenticatedUserDetails = (Claims) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
// create a map for post parameters
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
map.add("policyNumber", policyNumber);
map.add("authenticatedUserDetails", authenticatedUserDetails.toString());
// build the request
HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<MultiValueMap<String, String>>(map, headers);
// send POST request
ResponseEntity<Map> response = null;
try {
response = restTemplate.postForEntity("http://localhost:8081/policy-service/customerPolicyInfo", entity, Map.class);
} catch (RestClientException e) {
e.printStackTrace();
}
return response.getBody();

Getting 400 Bad Request for Rest Template Spring Boot

I have a rest Controller where i am trying to get the Token from a service using the RestTemplate in Spring Boot. The application works fine when i use Postman but from Java Application i get 400 Bad Request.
My Java Sample :
#PostMapping("/service")
private String generateAuthenticationToken() {
HttpHeaders authenticationTokenHeaders = new HttpHeaders();
authenticationTokenHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
JSONObject sfmcBUCredential = new JSONObject();
JSONObject sfmcTokenResponseObject;
sfmcBUCredential.put("grant_type", sfmcConfig.getGrant_type());
sfmcBUCredential.put("client_id", sfmcConfig.getClient_id());
sfmcBUCredential.put("client_secret", sfmcConfig.getClient_secret());
String sfmcBUCredentialString = sfmcBUCredential.toString();
System.out.println("Values before sending to POST Request are :::" + sfmcBUCredentialString);
HttpEntity<String> getTokenEntity = new HttpEntity<>(sfmcBUCredentialString, authenticationTokenHeaders);
System.out.println("Values after sending to POST Request are :::" + getTokenEntity.toString());
System.out.println("URL is :::" + GET_SFMC_ENDPOINT_URL);
//String tokenResponse = restTemplate.postForObject(GET_SFMC_ENDPOINT_URL, getTokenEntity, String.class);
ResponseEntity<String> tokenResponse = restTemplate.exchange(GET_SFMC_ENDPOINT_URL, HttpMethod.POST, getTokenEntity, String.class);
sfmcTokenResponseObject = new JSONObject(tokenResponse.getBody());
System.out.println("tokenResponse::::::::" + sfmcTokenResponseObject.getString("access_token").toString());
return sfmcTokenResponseObject.getString("access_token");
}
Logs :
Values before sending to POST Request are :::{"grant_type":"client_credentials","client_secret":"c1ae4b4a-498e-46a0-a02e-cd2378cb8db6","client_id":"Y43iLAhr4e0SoJ9KkV4vLKnGhNmS1Y3c"}
Values after sending to POST Request are :::<{"grant_type":"client_credentials","client_secret":"c1ae4b4a-498e-46a0-a02e-cd2378cb8db6","client_id":"Y43iLAhr4e0SoJ9KkV4vLKnGhNmS1Y3c"},[Content-Type:"application/x-www-form-urlencoded"]>
URL is :::https://keycloak.lab.hci.aetna.com/auth/realms/master/protocol/openid-connect/token
Try something like this:
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("grant_type", sfmcConfig.getGrant_type());
map.add("client_id", sfmcConfig.getClient_id());
map.add("client_secret", sfmcConfig.getClient_secret());
HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(map, headers);
ResponseEntity<LabelCreationResponse> response =
restTemplate.exchange("url",
HttpMethod.POST,
entity,
String.class);

Spring RestTemplate POST Request with URL encoded data

I'm new to Spring and trying to do a rest request with RestTemplate. The Java code should do the same as below curl command:
curl --data "name=feature&color=#5843AD" --header "PRIVATE-TOKEN: xyz" "https://someserver.com/api/v3/projects/1/labels"
But the server rejects the RestTemplate with a 400 Bad Request
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.add("PRIVATE-TOKEN", "xyz");
HttpEntity<String> entity = new HttpEntity<String>("name=feature&color=#5843AD", headers);
ResponseEntity<LabelCreationResponse> response = restTemplate.exchange("https://someserver.com/api/v3/projects/1/labels", HttpMethod.POST, entity, LabelCreationResponse.class);
Can somebody tell me what I'm doing wrong?
I think the problem is that when you try to send data to server didn't set the content type header which should be one of the two: "application/json" or "application/x-www-form-urlencoded" . In your case is: "application/x-www-form-urlencoded" based on your sample params (name and color). This header means "what type of data my client sends to server".
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.add("PRIVATE-TOKEN", "xyz");
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("name","feature");
map.add("color","#5843AD");
HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(map, headers);
ResponseEntity<LabelCreationResponse> response =
restTemplate.exchange("https://foo/api/v3/projects/1/labels",
HttpMethod.POST,
entity,
LabelCreationResponse.class);
You need to set the Content-Type to application/json. Content-Type has to be set in the request. Below is the modified code to set the Content-Type
final String uri = "https://someserver.com/api/v3/projects/1/labels";
String input = "US";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.add("PRIVATE-TOKEN", "xyz");
HttpEntity<String> request = new HttpEntity<String>(input, headers);
ResponseEntity<LabelCreationResponse> response = restTemplate.postForObject(uri, request, LabelCreationResponse.class);
Here, HttpEntity is constructed with your input i.e "US" and with headers.
Let me know if this works, if not then please share the exception.
Cheers!
It may be a Header issue check if the header is a Valid header, are u referring to "BasicAuth" header?
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", MediaType.APPLICATION_FORM_URLENCODED.toString());
headers.add("Accept", MediaType.APPLICATION_JSON.toString()); //Optional in case server sends back JSON data
MultiValueMap<String, String> requestBody = new LinkedMultiValueMap<String, String>();
requestBody.add("name", "feature");
requestBody.add("color", "#5843AD");
HttpEntity formEntity = new HttpEntity<MultiValueMap<String, String>>(requestBody, headers);
ResponseEntity<LabelCreationResponse> response =
restTemplate.exchange("https://example.com/api/request", HttpMethod.POST, formEntity, LabelCreationResponse.class);
my issue, the MessageConverters contains other converters may converts then entity to json (like FastJsonHttpMessageConverter). So i added the FormHttpMessageConverter to ahead and it works well.
<T> JuheResult<T> postForm(final String url, final MultiValueMap<String, Object> body) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
return exchange(url, HttpMethod.POST, requestEntity);
}
<T> JuheResult<T> exchange(final String url, final HttpMethod method, final HttpEntity<?> requestEntity) {
ResponseEntity<JuheResult<T>> response = restTemplate.exchange(url, method, requestEntity,
new JuheResultTypeReference<>());
logger.debug("调用结果 {}", response.getBody());
return response.getBody();
}
public JuheSupplierServiceImpl(RestTemplateBuilder restTemplateBuilder) {
Duration connectTimeout = Duration.ofSeconds(5);
Duration readTimeout = Duration.ofSeconds(5);
restTemplate = restTemplateBuilder.setConnectTimeout(connectTimeout).setReadTimeout(readTimeout)
.additionalInterceptors(interceptor()).build();
restTemplate.getMessageConverters().add(0, new FormHttpMessageConverter());
}
fastjson prevent resttemplate converting other mediaTypes other than json

Categories

Resources