web-dev-qa-db-fra.com

Meilleures pratiques sur le client Rest à l'aide de Spring RestTemplate

J'ai lu quelques tutoriels sur l'implémentation du client REST dans Java qui utilise SPRING pour gérer les beans).

Chaque exemple que j'ai trouvé, chaque fois que je fais une demande REST, il crée un nouveau RestTemplate.

Normalement, les applications Web utilisent un haricot de printemps singleton.

Donc, je veux savoir quelle est la meilleure pratique pour utiliser RestTemplate dans Spring configure l'application?
Utilisez singleton RestTemplate?
Créez RestTemplate dans chaque demande. ?

Veuillez conseiller et décrire toutes les situations.

10
Chamly Idunil

L'une des meilleures façons de le faire est de créer un bean qui retournerait un RestTemplate et ensuite de le câbler automatiquement dans la classe dont vous avez besoin.

Quelque chose comme ça.

@Configuration
public class ProductServiceConfig {

    @Value("${product.username}")
    private String productServiceUsername;

    @Value("${product.password}")
    private String productServicePassword;

    @Bean(name = "restTemplateForProductService")
    public RestTemplate prepareRestTemplateForProductService() {

        BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(productServiceUsername, productServicePassword));

        RequestConfig.Builder requestBuilder = RequestConfig.custom();
        requestBuilder = requestBuilder.setConnectTimeout(1000);

        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
        httpClientBuilder.setDefaultRequestConfig(requestBuilder.build());
        CloseableHttpClient httpClient = httpClientBuilder.build();

        HttpComponentsClientHttpRequestFactory rf = new HttpComponentsClientHttpRequestFactory(httpClient);

        return new RestTemplate(rf);
    }
}

De cette façon, vous pouvez définir différents paramètres que vous souhaitez pour votre appel de repos, comme les délais d'expiration ou les informations d'identification, etc. Et lorsque vous souhaitez utiliser, vous pouvez simplement faire

@Autowired
RestTemplate restTemplateForProductService;

restTemplateForProductService.......

Un autre avantage de cela par rapport à l'utilisation de new RestTemplate () est que si vous devez appeler différents services via REST, vous pouvez définir plusieurs beans (avec une configuration différente) qui renvoie RestTemplates et le câbler automatiquement en utilisant le nom

12
pvpkiran

Vous devez adopter l'une des approches suivantes lorsque vous utilisez RestTemplate.

Instance statique:

/**
 * Rest template client
 */
private static final RestTemplate TEMPLATE = new RestTemplate(new RestClientRequestFactory());


static{
    //Set your options here
    Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
    builder.featuresToEnable(SerializationFeature.WRITE_DATES_WITH_ZONE_ID);

    builder.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
    builder.featuresToDisable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE);

    MappingJackson2HttpMessageConverter jsonMessageConverter = new MappingJackson2HttpMessageConverter();
    jsonMessageConverter.setObjectMapper(builder.build());

    TEMPLATE.setMessageConverters(Arrays.asList(jsonMessageConverter));
}

Ou supprimez un Spring Bean dans une classe @Configuration:

@Bean
public RestTemplate restTemplate(){
    RestTemplate template = new RestTemplate(new RestClientRequestFactory())
            //customize
    return template;
}

Si vous regardez la classe RestTemplate, vous voulez éviter de toucher trop souvent le constructeur par défaut:

public RestTemplate() {
    this.messageConverters = new ArrayList();
    this.errorHandler = new DefaultResponseErrorHandler();
    this.uriTemplateHandler = new DefaultUriTemplateHandler();
    this.headersExtractor = new RestTemplate.HeadersExtractor();
    this.messageConverters.add(new ByteArrayHttpMessageConverter());
    this.messageConverters.add(new StringHttpMessageConverter());
    this.messageConverters.add(new ResourceHttpMessageConverter());
    this.messageConverters.add(new SourceHttpMessageConverter());
    this.messageConverters.add(new AllEncompassingFormHttpMessageConverter());
    if (romePresent) {
        this.messageConverters.add(new AtomFeedHttpMessageConverter());
        this.messageConverters.add(new RssChannelHttpMessageConverter());
    }

    if (jackson2XmlPresent) {
        this.messageConverters.add(new MappingJackson2XmlHttpMessageConverter());
    } else if (jaxb2Present) {
        this.messageConverters.add(new Jaxb2RootElementHttpMessageConverter());
    }

    if (jackson2Present) {
        this.messageConverters.add(new MappingJackson2HttpMessageConverter());
    } else if (gsonPresent) {
        this.messageConverters.add(new GsonHttpMessageConverter());
    }

}
2
Johnny.Minty