I have created application in Spring using RestTemplate, Using Rest-Template I am consuming an external webservice which is having a header as Accept as "application/json". In my Rest-Template I have added the header but still it is giveing me the following exception
org.springframework.web.client.RestClientException: Could not extract response: no suitable HttpMessageConverter found for response type [class com.site.Employee] and content type [application/octet-stream]
My code is as given below
private static String BASE_URI = "http://localhost:8181/test/employee"
final HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setAccept(Collections.singletonList(new MediaType("application", "json")));
requestHeaders.setContentType(new MediaType("application", "json"));
final HttpEntity<?> requestEntity = new HttpEntity<Object>(requestHeaders);
final RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
final ResponseEntity<Employee> responseEntity = restTemplate.exchange(BASE_URI, HttpMethod.GET, requestEntity, Employee.class);
Can anyone please tell me some solution for this
Update 1
When I tries the below code, it is working fine
final ResponseEntity<String> responseEntity = restTemplate.exchange(BASE_URI, HttpMethod.GET, requestEntity, String.class);
Employee employee = new ObjectMapper().readValue(responseEntity.getBody(), Employee.class);
You'll need to add application/octet-stream to the list of supported mimetypes in MappingJackson2HttpMessageConverter:
final MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
mappingJackson2HttpMessageConverter.setSupportedMediaTypes(Arrays.asList(MediaType.APPLICATION_JSON, MediaType.APPLICATION_OCTET_STREAM));
restTemplate.getMessageConverters().add(mappingJackson2HttpMessageConverter);
Related
i am calling a rest API with below restTemplate set up. API is returning response of type [text/html] but i am not able to convert it into
RestTemplate restTemplate = new RestTemplate();
String url = UriComponentsBuilder.fromUriString(host + "/api").toUriString();
HttpHeaders requestHeaders = new HttpHeaders();
List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
Jaxb2RootElementHttpMessageConverter jaxbMessageConverter = new Jaxb2RootElementHttpMessageConverter();
List<MediaType> mediaTypes = new ArrayList<MediaType>();
mediaTypes.add(MediaType.ALL);
jaxbMessageConverter.setSupportedMediaTypes(mediaTypes);
messageConverters.add(jaxbMessageConverter);
restTemplate.setMessageConverters(messageConverters);
requestHeaders.setContentType(MediaType.TEXT_HTML);
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setSupportedMediaTypes(Arrays.asList(MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON));
converter.getObjectMapper().configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
restTemplate.getMessageConverters().add(0, converter);
But getting below exception
No HttpMessageConverter for [com.fasterxml.jackson.databind.node.ObjectNode] and content type [text/html]
at org.springframework.web.client.RestTemplate$HttpEntityRequestCallback.doWithRequest(RestTemplate.java:956)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:732)
I throw when post request via Rest Api, result is
Content-Type: application/json
{
"error": "file content is not in the appropriate format",
"file_name": "15-10-2019-11-19-32_KKK.csv"
}
When I try code on my side, I use the below code
public RestTemplate restTemplateBuilder() {
RestTemplate restTemplate = new RestTemplate(new HttpComponentsClientHttpRequestFactory());
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
ObjectMapper mapper = new ObjectMapper();
mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);
converter.setObjectMapper(mapper);
restTemplate.getMessageConverters().add(0, converter);
restTemplate.setErrorHandler(new RestTemplateHandler());
return restTemplate;
}
RestTemplate restTemplate = restTemplateBuilder();
ResponseEntity<FileUploadResponseDTO> serviceResponse = restTemplate.exchange(url, HttpMethod.POST, requestEntity, FileUploadResponseDTO.class);
org.springframework.web.client.RestClientException: Could not extract response: no suitable HttpMessageConverter found for response type [....FileUploadResponseDTO] and content type [text/html]
Gives a fault. how do I convert?
You can add content-type header to RestTemplate:
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> requestEntity = new HttpEntity<String>(headers);
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
I have spring rest service such this
#RequestMapping(method = RequestMethod.POST,
path = "/getdata", consumes = {"multipart/form-data"}, produces = MediaType.APPLICATION_JSON)
public
#ResponseBody
Result getBarcode(#RequestParam("text") String sl,
#RequestParam("imageFile") MultipartFile file) {
... some logic
return new Result(text, message, !processingError);
}
When i call this from http form it works fine and return json text. But when i trying to call this from java code
RestTemplate restTemplate = new RestTemplate();
MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
map.add("text", "123");
map.add("imageFile", new File("...path to file..."));
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
headers.setAccept(MediaType.parseMediaTypes("application/json,text/html,application/xhtml+xml,application/xml"));
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(map, headers);
ResponseEntity<BcResult> response = restTemplate.exchange("http://localhost:8080/getdata", HttpMethod.POST, requestEntity, BcResult.class);
Then i am getting 400 Bad request error. Can`t figure out what is wrong with this code...
Set your file like this.
map.add("imageFile", new FileSystemResource(new File("...path to file...")));
or like this
map.add("imageFile", new ClassPathResource("...path to file..."));
I have Spring Rest service defined as below.
#RequestMapping(value = "/mobilebuild", method = RequestMethod.POST)
public StringWrapper buildApp(#RequestParam("projectName") String projectName, #RequestParam("appId") String projectId, #RequestParam("version") String version, #RequestParam("app") MultipartFile file) {
//Process to build app
return WMUtils.SUCCESS_RESPONSE;
}
From client side i am using rest template as follows
final List<HttpMessageConverter<?>> messageConverters = new ArrayList<>();
messageConverters.add(new ByteArrayHttpMessageConverter());
messageConverters.add(new StringHttpMessageConverter(Charset.forName(CommonConstants.UTF8)));
messageConverters.add(new ResourceHttpMessageConverter());
messageConverters.add(new SourceHttpMessageConverter<Source>());
messageConverters.add(new AllEncompassingFormHttpMessageConverter());
messageConverters.add(new FormHttpMessageConverter());
RestTemplate template = new RestTemplate(messageConverters);
MultiValueMap<String, Object> parts = new LinkedMultiValueMap<String, Object>();
//Post Parameters
parts.add("projectName", "FirstProject");
parts.add("appId", "app12345");
parts.add("version", "1.0");
// MultipartFile
parts.add("app", new FileSystemResource(tempFilesStorageManager.getFilePath("/tmp/app.zip")));
HttpHeaders headers = new HttpHeaders();
headers.add("Cookie", auth);
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
String url = "http://localhost:8080/AppManager/services/mobilebuild";
HttpEntity<MultiValueMap> requestEntity = new HttpEntity<MultiValueMap>(parts, headers);
ResponseEntity<String> responseEntity = template.postForEntity(endpointAddress, requestEntity, String.class);
String response = responseEntity.getBody();
I am unable to read the request parameters from controller (server): getting the following error
Error: request parameter projectName is not present in the request.
So please suggest me the way to achieve this.
According to javadoc of HttpEntity , the first parameter is request body and second one is request headers, but your client is sending request parameters inside request body and your controller is expecting them as #RequestParam, hence the error.
So either change your client to send the request parameters in the end point address URL to match your server side as ...projectName=FirstProject&appId= app12345&version=1.0....
Or encapsulate all your #RequestParam fields inside a single DTO class and add #RequestBody annotation on server side if your client wants to send in request body.