Spring @Autowired restTemplate is null [duplicate]

筅森魡賤 提交于 2020-01-06 07:51:45

问题


I am new to Spring. I develop Service that Consuming RESTful service with certficate using Java

Here is my Config class:

package configuration;

import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.util.ResourceUtils;
import org.springframework.web.client.RestTemplate;

import javax.net.ssl.SSLContext;
import java.util.function.Supplier;

@Configuration
public class RestClientCertConfig {

    private char[] allPassword = "allpassword".toCharArray();

    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder) throws Exception {

        SSLContext sslContext = SSLContextBuilder
                .create()
                .loadKeyMaterial(ResourceUtils.getFile("classpath:keystore.jks"), allPassword, allPassword)
                .loadTrustMaterial(ResourceUtils.getFile("classpath:truststore.jks"), allPassword)
                .build();

        HttpClient client = HttpClients.custom()
                .setSSLContext(sslContext)
                .build();

        return builder
                .requestFactory((Supplier<ClientHttpRequestFactory>)new HttpComponentsClientHttpRequestFactory(client))
                .build();
    }
}

And here is the class where I consume Restful EndPoint:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import java.net.URISyntaxException;
import java.util.Collections;


public class ECSConfigGet {
    private static final String ECS_API_URI = "<RestEndPointToConsume";

    @Autowired
    private static RestTemplate restTemplate;


    public static void main(String[] args) {
        try {
            makeECSCall("myTestHeaderValue");
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
    }


    private static void makeECSCall(String entityCode) throws RestClientException, URISyntaxException {
        HttpHeaders headers = new HttpHeaders();
        headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
        headers.set("entityCode", entityCode);

        HttpEntity<String> entity = new HttpEntity<>("parameters", headers);

        ResponseEntity responseEntity  = restTemplate.exchange(ECS_API_URI, HttpMethod.GET, entity, String.class);
        }
    }

Did I completely misunderstood the concept? I would expect restTemplate would not be null with all the Annotations I use. Thank for any help!


NullPointerException is fixed. ECSConfigGet looks like:

package main;

import configuration.RestClientCertConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import services.modelsdto.ExpenseConfigDTO;


import java.util.Collections;

@SpringBootApplication
@Component
public class ECSConfigGet implements CommandLineRunner{

    //API to call
    private static final String ECS_API_URI = "<API_TO_CONSUME>";
    @Autowired
    private RestTemplate restTemplate;

    public static void main(String[] args) {

        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(RestClientCertConfig.class);
        applicationContext.getBean(RestTemplate.class);
        SpringApplication.run(ECSConfigGet.class, args);

    }

    private void makeECSCall(String entityCode) throws RestClientException {

        ExpenseConfigDTO expenseConfigDTO = new ExpenseConfigDTO();

        HttpHeaders headers = new HttpHeaders();
        headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
        headers.set("entityCode", entityCode);

        HttpEntity<String> entity = new HttpEntity<>("parameters", headers);

        ResponseEntity responseEntity  = restTemplate.exchange(ECS_API_URI, HttpMethod.GET, entity, String.class);
        }

    @Override
    public void run(String... args) {
        for (int i = 0; i < args.length; ++i) {
            makeECSCall("myTestHeaderValue");
        }
    }
}

回答1:


You're missing a bit of Spring boilerplate that you need to make @Autowired work. If you're using Spring Boot, you're close, but @Patrick is right generally: ECSConfigGet needs to be a bean by annotating it correctly, but you also need to run your application within an application context in order for any of the Spring magic to happen. I suggest checking out this tutorial on how to use Spring Boot in a command line application.

The high level is ECSConfigGet needs to be annotated with @SpringBootApplication and then have it implement CommandLineRunner and then from the run method, you will have access to the @Autowired component. Spring will instantiate ECSConfigGet and populate the properties. Also as @Roddy pointed out, RestTemplate cannot be static, either.




回答2:


The ECSConfigGet class is not a bean so it can not autowire a component. Add @Component as class annotation to ECSConfigGet



来源:https://stackoverflow.com/questions/51756411/spring-autowired-resttemplate-is-null

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!