restcontroller - No se pudo conectar automáticamente el campo: RestTemplate en la aplicación de arranque Spring
spring rest ejemplo (6)
Dado que las instancias de RestTemplate a menudo deben personalizarse antes de usarse, Spring Boot no proporciona ningún bean RestTemplate autoconfigurado.
RestTemplateBuilder ofrece una forma adecuada de configurar e instanciar el bean de plantilla rest, por ejemplo, para autenticación básica o interceptores.
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder
.basicAuthorization("user", "name") // Optional Basic auth example
.interceptors(new MyCustomInterceptor()) // Optional Custom interceptors, etc..
.build();
}
Estoy obteniendo una excepción por debajo mientras ejecuto la aplicación de arranque de primavera durante el inicio:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name ''testController'': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.web.client.RestTemplate com.micro.test.controller.TestController.restTemplate; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.web.client.RestTemplate] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
Estoy autowiring RestTemplate en mi TestController. Estoy usando Maven para la gestión de la dependencia.
TestMicroServiceApplication.java
package com.micro.test;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class TestMicroServiceApplication {
public static void main(String[] args) {
SpringApplication.run(TestMicroServiceApplication.class, args);
}
}
TestController.java
package com.micro.test.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class TestController {
@Autowired
private RestTemplate restTemplate;
@RequestMapping(value="/micro/order/{id}",
method=RequestMethod.GET,
produces=MediaType.ALL_VALUE)
public String placeOrder(@PathVariable("id") int customerId){
System.out.println("Hit ===> PlaceOrder");
Object[] customerJson = restTemplate.getForObject("http://localhost:8080/micro/customers", Object[].class);
System.out.println(customerJson.toString());
return "false";
}
}
POM.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.micro.test</groupId>
<artifactId>Test-MicroService</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Test-MicroService</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Asegúrate de dos cosas:
1- Usa la anotación
@Bean
con el método
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder){
return builder.build();
}
2- El alcance de este método debe ser público, no privado .
Ejemplo completo
@Service
public class MakeHttpsCallImpl implements MakeHttpsCall {
@Autowired
private RestTemplate restTemplate;
@Override
public String makeHttpsCall() {
return restTemplate.getForObject("https://localhost:8085/onewayssl/v1/test",String.class);
}
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder){
return builder.build();
}
}
Dependiendo de qué tecnologías esté utilizando y qué versiones influirán en cómo define un
RestTemplate
en su clase
@Configuration
.
Spring> = 4 sin Spring Boot
Simplemente defina un
@Bean
:
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
Spring Boot <= 1.3
No es necesario definir uno, Spring Boot define automáticamente uno para usted.
Spring Boot> = 1.4
Spring Boot ya no define automáticamente un
RestTemplate
sino que define un
RestTemplateBuilder
que le permite un mayor control sobre el RestTemplate que se crea.
Puede inyectar el
RestTemplateBuilder
como argumento en su método
@Bean
para crear un
RestTemplate
:
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
// Do any additional configuration here
return builder.build();
}
Usándolo en tu clase
@Autowired
private RestTemplate restTemplate;
El error señala directamente que el bean
RestTemplate
no está definido en contexto y no puede cargar los beans.
- Defina un bean para RestTemplate y luego úselo
- Use una nueva instancia de RestTemplate
Si está seguro de que el bean está definido para RestTemplate, utilice lo siguiente para imprimir los beans que están disponibles en el contexto cargado por la aplicación de arranque de primavera
ApplicationContext ctx = SpringApplication.run(Application.class, args);
String[] beanNames = ctx.getBeanDefinitionNames();
Arrays.sort(beanNames);
for (String beanName : beanNames) {
System.out.println(beanName);
}
Si esto contiene el bean por el nombre / tipo dado, entonces todo bien. O bien, defina un nuevo bean y luego úselo.
Es exactamente lo que dice el error.
No creó ningún bean
RestTemplate
, por lo que no se puede conectar automáticamente.
Si necesita un
RestTemplate
, deberá proporcionar uno.
Por ejemplo, agregue lo siguiente a
TestMicroServiceApplication.java
:
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
Tenga en cuenta que en versiones anteriores de Spring Cloud Starter para Eureka, se creó un bean
RestTemplate
para usted, pero esto ya no es cierto.
Si un TestRestTemplate es una opción válida en su prueba unitaria, esta documentación podría ser relevante
Respuesta corta: si usa
@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)
entonces
@Autowired
funcionará.
Si usa
@SpringBootTest(webEnvironment=WebEnvironment.MOCK)
luego cree un TestRestTemplate como este
private TestRestTemplate template = new TestRestTemplate();