Reputation: 6114
I am trying to consume REST
API which takes JSON
payload and returns plain/text in the response. But I am getting following error during runtime.
SpotifyIntegrationApplication.java
@SpringBootApplication
public class SpotifyIntegrationApplication {
private static final Logger LOGGER = LoggerFactory.getLogger(SpotifyIntegrationApplication.class);
public static void main(String[] args) {
SpringApplication.run(SpotifyIntegrationApplication.class, args);
}
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}
@Bean
public CommandLineRunner run(RestTemplate restTemplate) {
NewOrder newOrder = new NewOrder();
return args -> {
ResponseEntity<String> responseEntity = restTemplate.postForEntity("http://localhost:9999/order-sold", newOrder, String.class);
LOGGER.info("responseEntity: " + responseEntity);
};
}
}
NewOrder.java
public class NewOrder {
String orderId;
}
build.gradle
buildscript {
ext {
springBootVersion = '1.5.10.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
group = 'com.synapse.integration'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile('org.springframework.boot:spring-boot-starter-web')
runtime('com.h2database:h2')
runtime('mysql:mysql-connector-java')
compileOnly('org.projectlombok:lombok')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
Error:
java.lang.IllegalStateException: Failed to execute CommandLineRunner
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:735) [spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:716) [spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:703) [spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:304) [spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118) [spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107) [spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
at com.synapse.integration.spotify.SpotifyIntegrationApplication.main(SpotifyIntegrationApplication.java:20) [classes/:na]
Caused by: org.springframework.web.client.RestClientException: Could not write request: no suitable HttpMessageConverter found for request type [com.synapse.integration.spotify.model.NewOrder]
at org.springframework.web.client.RestTemplate$HttpEntityRequestCallback.doWithRequest(RestTemplate.java:907) ~[spring-web-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:658) ~[spring-web-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:621) ~[spring-web-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.client.RestTemplate.postForEntity(RestTemplate.java:415) ~[spring-web-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at com.synapse.integration.spotify.SpotifyIntegrationApplication.lambda$run$0(SpotifyIntegrationApplication.java:32) [classes/:na]
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:732) [spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
... 6 common frames omitted
Upvotes: 3
Views: 1676
Reputation: 256
Hmm, the answers are all a bit confusing, when looking at Spring's documentation at: https://spring.io/guides/gs/consuming-rest/
It seems you should be able to successfully consume a response, map to a JSON object via annotated object.
However, even in doing this:
@Bean
public CommandLineRunner run(RestTemplate restTemplate) throws Exception {
return args -> {
Quote quote = restTemplate.getForObject(
"http://localhost:8978/greeting", Quote.class);
System.out.println(quote.toString());
log.info(quote.toString());
};
I'm still getting the above Failed to execute CommandLineRunner error, going to have to investigate if its worth actually mapping to the HttpResponseObject. Hopefully there are some thoughts on my comment here.
Upvotes: 0
Reputation: 6114
Found the solution from above responses plus from some additional googling.
SpotifyIntegrationApplication.java
@SpringBootApplication
public class SpotifyIntegrationApplication {
private static final Logger LOGGER = LoggerFactory.getLogger(SpotifyIntegrationApplication.class);
public static final String ENDPOINT = "http://localhost:9999/order-sold";
public static void main(String[] args) {
SpringApplication.run(SpotifyIntegrationApplication.class, args);
}
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}
@Bean
public CommandLineRunner run(RestTemplate restTemplate) {
return args -> {
NewOrder newOrder = new NewOrder();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<NewOrder> entity = new HttpEntity<>(newOrder, headers);
ResponseEntity<String> responseEntity = restTemplate.exchange(ENDPOINT, POST, entity, String.class);
LOGGER.info("responseEntity: " + responseEntity);
};
}
}
NewOrder.java
@Data
public class NewOrder {
private String orderId;
}
Although this was not part of the original question but also removed Tomcat library dependency since I am just consuming the API and not building one.
build.gradle
compile('org.springframework.boot:spring-boot-starter-web') {
exclude module: "spring-boot-starter-tomcat"
}
Upvotes: 0
Reputation: 131
If the request made accepts only json, then provide headers specifying the content-type and convert the object to json( use Gson to convert object to json) and make a post request by setting all these to a HttpEntity
HttpHeaders headers = new HttpHeaders();
headers.add("content-type", "application/json");
headers.add("accept", "application/json");
String requestBody = gson.toJson(requestObject);
HttpEntity<String> httpEntity = new HttpEntity(requestBody,headers);
and make the rest call as
restTemplate.exchange(requestUrl,HttpMethod.POST,httpEntity,MyResponse.class)
Upvotes: 0
Reputation: 154
I have used restTemplate.exchange but you can modify to use postForEntity
or postForObject. Hope this helps.
private HttpHeaders createHttpHeaders() {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
return headers;
}
@RequestMapping("/testClient")
public String testClient() {
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = createHttpHeaders();
HttpEntity<String> entity = new HttpEntity<String>("parameters",
headers);
ResponseEntity<String> response = restTemplate.exchange(url,
HttpMethod.GET, entity, String.class);
if (response.getStatusCode().equals(HttpStatus.OK)) {
System.out.println("getbody -" + response.getBody());
}
return "Test Client";
}
Upvotes: 1