OAuth2RestTemplate.postForEntity RestClientException: No HttpMessageConverter for [org.x.xx] and content type [application/json] - java

I'm using OAuth2RestTemplate to query an external api that accept a JSON object.
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
HttpEntity<XX> request = new HttpEntity<>(xX, headers);
ResponseEntity<String> response = oAuth2RestTemplate.postForEntity(url , request, String.class);
And I got this error :
org.springframework.web.client.RestClientException: No HttpMessageConverter for [com.yy.XX] and content type [application/json]
at org.springframework.web.client.RestTemplate$HttpEntityRequestCallback.doWithRequest(RestTemplate.java:956) ~[spring-web-5.1.4.RELEASE.jar:5.1.4.RELEASE]
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:732) ~[spring-web-5.1.4.RELEASE.jar:5.1.4.RELEASE]
I tried to add MappingJackson2HttpMessageConverter to my oAuth2RestTemplate but I got the same error.

Related

OAuth2RestTemplate access_denied errror requesting access token

I have a simple OAuth2RestTemplate that I want to use to send an application/xml to a server, and it would respond back with an application/xml. However, I am having problems requesting the access token:
<The RuntimeException could not be mapped to a response, re-throwing to the HTTP container
error="access_denied", error_description="Error requesting access token."
at org.springframework.security.oauth2.client.token.OAuth2AccessTokenSupport.retrieveToken(OAuth2AccessTokenSupport.java:145)
at org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsAccessTokenProvider.obtainAccessToken(ClientCredentialsAccessTokenProvider.java:44)
at org.springframework.security.oauth2.client.token.AccessTokenProviderChain.obtainNewAccessTokenInternal(AccessTokenProviderChain.java:148)
at org.springframework.security.oauth2.client.token.AccessTokenProviderChain.obtainAccessToken(AccessTokenProviderChain.java:121)
at org.springframework.security.oauth2.client.OAuth2RestTemplate.acquireAccessToken(OAuth2RestTemplate.java:221)
Truncated. see log file for complete stacktrace
Caused By: org.springframework.web.client.RestClientException: Could not extract response: no suitable HttpMessageConverter found for response type [interface org.springframework.security.oauth2.common.OAuth2AccessToken] and content type [application/json;charset=UTF-8]
at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:109)
at org.springframework.security.oauth2.client.token.OAuth2AccessTokenSupport$2.extractData(OAuth2AccessTokenSupport.java:134)
at org.springframework.security.oauth2.client.token.OAuth2AccessTokenSupport$2.extractData(OAuth2AccessTokenSupport.java:128)
I see that this error is caused by my response not accepting the correct type, but I believe that response type is coming from Pivotal Cloud Foundry where I am getting the access token from, so it's not even making it to the actual server.
Can someone guide me on this? Am I missing something?
Here's my code:
String server_url = "http://localhost:8282/api/star/start-visit";
ClientCredentialsResourceDetails resource = new ClientCredentialsResourceDetails();
resource.setAuthenticationScheme(AuthenticationScheme.query);
resource.setAccessTokenUri("https://pivotalcloudfoundry.zxc.com/oauth/token");
resource.setClientId("asdasd");
resource.setClientSecret("cxzcxz");
OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(resource);
List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
List<MediaType> mediaTypes = new ArrayList<>();
mediaTypes.add(MediaType.APPLICATION_XML);
customConverter.setSupportedMediaTypes(mediaTypes);
messageConverters.add(customConverter);
restTemplate.setMessageConverters(messageConverters);
restTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));
StartVisit request = TransformationHelper.createStartVisit (visit);
MultiValueMap<String, String> headers = new LinkedMultiValueMap<String, String>();
headers.add("Content-Type", "application/xml");
headers.add("Accept", "application/xml");
HttpEntity<StartVisit> entity = new HttpEntity<>(request, headers);
restTemplate.exchange(server_url, org.springframework.http.HttpMethod.PUT, entity, EndVisit.class);

RestTemplate POST image exception

LinkedMultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
map.add("file", new ClassPathResource("multimediaImage.jpg"));
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.IMAGE_JPEG);
token="eabcd";
headers.set(HttpHeaders.AUTHORIZATION, "Bearer "+token);
HttpEntity<LinkedMultiValueMap<String, Object>> requestEntity = new HttpEntity<LinkedMultiValueMap<String, Object>>(
map, headers);
RestTemplate template = new RestTemplate(); // restTemplate made
String url ="https://xyz";
ResponseEntity<String> result = template.exchange(
url, HttpMethod.POST, requestEntity,
String.class);
System.out.println(result);
Please note i have changed url and token for security purposes. In reality they are valid.
The exception:
SEVERE: Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.web.client.RestClientException: Could not write request: no suitable HttpMessageConverter found for request type [org.springframework.util.LinkedMultiValueMap] and content type [image/jpeg]] with root cause
org.springframework.web.client.RestClientException: Could not write request: no suitable HttpMessageConverter found for request type [org.springframework.util.LinkedMultiValueMap] and content type [image/jpeg]
I do not want to decode it first because the point is to test to see if images work. So i want to send the image, I used httpconverter, but i was unable to use that it wasnt working for me (odds are i wasnt doing it properly)
Thanks in advance.

Spring Boot RestTemplate: Error 415 Unsupported Media Type

I was using below code to call one REST web API,
WebTarget target = client.target(CommonConfig.getProperty(APIX_SEND_EMAIL_URL));
Response response = target.request("application/json").accept(MediaType.APPLICATION_JSON_TYPE).header("Authorization", token)
.post(Entity.json(email));
Now I want to use Spring Boot RestTemplate to call this web service, and I am using below code:
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
List<MediaType> mediaList = new ArrayList<MediaType>();
mediaList.add(MediaType.APPLICATION_JSON);
mediaList.add(MediaType.TEXT_PLAIN);
headers.setAccept(mediaList);
//Json is the json object of the request data
HttpEntity<String> entity = new HttpEntity<String>(json.toString(), headers);
ResponseEntity<String> loginResponse = restTemplate
.exchange(url, HttpMethod.POST, entity, String.class);
But I get error 415 Unsupported Media Type. Can anyone help me understand what cause of mistake, How I can fix it with RestTemplate?
Why not use postForObject() method of RestTemplate?
SomeObject json = SomeObject();
SomeOtherObject response = restTemplate.postForObject("url", json , SomeOtherObject.class);

org.springframework.web.client.RestClientException: Could not extract response:

I'm creating a restful API which will consume json from server. But i'm getting the foll exception :
org.springframework.web.client.RestClientException: Could not extract response: no suitable HttpMessageConverter found for response type [[Lexamples.dto.DummyDTO;] and content type [text/json;charset=utf-8]
at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:84)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:454)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:409)
at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:207)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoCachedMethodSite.invoke(PojoMetaMethodSite.java:189)
at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:53)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:120)
Code snippet :
List<HttpMessageConverter<?>> msgConverters = restTemplate.getMessageConverters();
msgConverters.add(new MappingJacksonHttpMessageConverter());
restTemplate.setMessageConverters(msgConverters);
DummyDTO[] dummy= restTemplate.getForObject(URI, DummyDTO[].class);
Controller method code :
public UserDTO[] getUserList(){
List<MediaType> acceptableMediaTypes = new ArrayList<MediaType>();
acceptableMediaTypes.add(MediaType.APPLICATION_JSON);
// Set the Accept and Content type header
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setAccept(acceptableMediaTypes);
HttpEntity<?> entity = new HttpEntity<Object>(headers);
// Add the Jackson message converter
List<HttpMessageConverter<?>> msgConverters = restTemplate.getMessageConverters();
msgConverters.add(new MappingJacksonHttpMessageConverter());
restTemplate.setMessageConverters(msgConverters);
// Make the HTTP GET request, marshalling the response from JSON to an array of Users
ResponseEntity<UserDTO[]> responseEntity = restTemplate.exchange("http://server.com",HttpMethod.GET, entity, UserDTO[].class);
return responseEntity.getBody();
}
Please tell me where am i going wrong
Looks like you change content type for request, but "application/json" have to be in the response headers, and the fact that you still have the same exception tells that you have wrong media type "text/json" in the response, there are no such media type in HTTP. Just look at implementation of restTemplate.exchange("http://server.com",HttpMethod.GET, entity, UserDTO[].class); there the problem should be.

How to pass key value pair using resttemplate in java

I've to pass key value pair in the body of post request. But when I run my code, I get the error as "Could not write request: no suitable HttpMessageConverter found for request type [org.springframework.util.LinkedMultiValueMap] and content type [text/plain]"
My code is as follows:
MultiValueMap<String, String> bodyMap = new LinkedMultiValueMap<String, String>();
bodyMap.add(GiftangoRewardProviderConstants.GIFTANGO_SOLUTION_ID, giftango_solution_id);
bodyMap.add(GiftangoRewardProviderConstants.SECURITY_TOKEN, security_token);
bodyMap.add(GiftangoRewardProviderConstants.REQUEST_TYPE, request_type);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.TEXT_PLAIN);
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(bodyMap, headers);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> model = restTemplate.exchange(giftango_us_url, HttpMethod.POST, request, String.class);
String response = model.getBody();
The FormHttpMessageConverter is used to convert MultiValueMap objects for sending in HTTP requests. The default media types for this converter are application/x-www-form-urlencoded and multipart/form-data. By specifying the content-type as text/plain, you are telling RestTemplate to use the StringHttpMessageConverter
headers.setContentType(MediaType.TEXT_PLAIN);
But that converter doesn't support converting a MultiValueMap, which is why you are getting the error. You have a couple of options. You can change the content-type to application/x-www-form-urlencoded
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
Or you can NOT set the content-type and let RestTemplate handle it for you. It will determine this based on the object you are attempting to convert. Try using the following request as an alternative.
ResponseEntity<String> model = restTemplate.postForEntity(giftango_us_url, bodyMap, String.class);

Resources