4 votes

Spring boot - modèle de repos et constructeur de modèle de repos

Comme je sais que le RestTemplateBuilder est une sorte d'usine pour RestTemplate . J'ai quelques questions sur son utilisation :

  1. Très souvent dans les exemples, il y a quelque chose comme ceci dans @Configuration classe :

    @Bean
    public RestTemplate getRestClient() {
        RestTemplate restClient = new RestTemplate();
        ...
        return restClient;
    }

    Il ne faut pas RestTemplate être instancié par @Service classe ? Si oui, comment la personnaliser ?

  2. La référence de printemps dit que RestTemplateBuilder doit être personnalisé via RestTemplateCustomizer . Comment gérer plusieurs URI à partir de plusieurs adresses IP avec un seul constructeur ?

  3. Comment ajouter BasicAuthentication globalement à tous RestTemplates via RestTemplateBuilder et s'agit-il d'une bonne pratique ?

Merci pour votre aide.

UPDATE :

Mon application fait appel à des services de repos à partir de plusieurs serveurs, à des adresses IP et des URL différentes. RestTemplates .

J'essaie d'avoir une usine ( RestTemplateBuilder ) par serveur - disons les serveurs A, B, C. Je sais comment ajouter une authentification de base. Mais que faire par exemple si je veux une authentification de base pour le serveur A mais pas pour le serveur B ?

Je pense à en avoir un RestTemplateBuilder par serveur. Je ne veux pas faire cela manuellement - je préférerais utiliser les mécanismes de Spring.

Une aide ?

6voto

kuhajeyan Points 6302
  1. Non, vous n'en avez pas besoin, typiquement vous aurez une instance de modèle de repos, et vous passerez une url différente, et des paramètres de requête en conséquence à chaque fois.

    String result = restTemplate.getForObject("http://example.com/hotels/{hotel}/bookings/{booking}", String.class, vars);
    
    Foo foo = restTemplate.getForObject(fooResourceUrl + "/1", Foo.class);
  2. Un exemple descriptif tiré de doc de printemps vous pouvez ajouter autant de personnalisateurs au constructeur que vous le souhaitez.

    public class ProxyCustomizer implements RestTemplateCustomizer {
    
        @Override
        public void customize(RestTemplate restTemplate) {
            HttpHost proxy = new HttpHost("proxy.example.com");
            HttpClient httpClient = HttpClientBuilder.create()
                    .setRoutePlanner(new DefaultProxyRoutePlanner(proxy) {
    
                        @Override
                        public HttpHost determineProxy(HttpHost target,
                                HttpRequest request, HttpContext context)
                                        throws HttpException {
                            if (target.getHostName().equals("192.168.0.5")) {
                                return null;
                            }
                            return super.determineProxy(target, request, context);
                        }
    
                    }).build();
            restTemplate.setRequestFactory(
                    new HttpComponentsClientHttpRequestFactory(httpClient));
        }
    
    }

Tous les haricots RestTemplateCustomizer seront automatiquement ajoutés à l'interface de l'utilisateur. RestTemplateBuilder auto-configuré. En outre, un nouveau RestTemplateBuilder avec des personnalisateurs supplémentaires peut être créé en appelant additionalCustomizers(RestTemplateCustomizer )

@Bean
public RestTemplateBuilder restTemplateBuilder() {
   return new RestTemplateBuilder()
        .rootUri(rootUri)
        .basicAuthorization(username, password);
}

2voto

whistling_marmot Points 1422

J'ai mis en place ma configuration comme suit :

@Bean
public RestTemplateCustomizer restTemplateCustomizer() {
    return restTemplate -> {
        restTemplate.setRequestFactory(clientHttpRequestFactory());
    };
}

@Bean
public ClientHttpRequestFactory clientHttpRequestFactory() {
    SimpleClientHttpRequestFactory clientHttpRequestFactory = new SimpleClientHttpRequestFactory();
    clientHttpRequestFactory.setConnectTimeout(connectionTimeoutMs);
    clientHttpRequestFactory.setReadTimeout(connectionTimeoutMs);
    clientHttpRequestFactory.setBufferRequestBody(false);
    return clientHttpRequestFactory;
}

Chaque fois que Spring injecte un RestTemplateBuilder, il le configure à l'aide de ce RestTemplateCustomizer pour utiliser le ClientHttpRequestFactory. Vous pouvez avoir besoin de faire d'autres personnalisations, ou peut-être aucune, auquel cas ne déclarez pas le bean.

Pour ajouter l'en-tête d'authentification, vous devrez connaître le nom d'utilisateur et le mot de passe, que vous ne connaîtrez probablement pas avant l'exécution. J'ai donc créé un bean Authenticator :

@Component
public class Authenticator {

    @Autowired
    private RestTemplateBuilder restTemplateBuilder;

    public void withAuthenticationHeader(String username, String password, Consumer<RestTemplate> doAuthenticated) {
        RestTemplate restTemplate =
            restTemplateBuilder
                .basicAuthorization(username, password)
                .build();

        try {
            doAuthenticated.accept(restTemplate);

        } catch (HttpClientErrorException exception) {
            // handle the exception
        }
    }
}

Cela me permet de gérer les échecs d'authentification de manière standard pour toutes les demandes, ce dont j'ai besoin dans mon application.

Il est injecté dans d'autres haricots et utilisé comme tel :

@Autowired
private Authenticator authenticator;

public void transmit() {
    authenticator.withAuthenticationHeader(username, password, restTemplate -> 
        restTemplate.postForLocation(url, request));
}

Donc vous utilisez l'Authenticator plutôt que d'utiliser le RestTemple directement. Je n'ai pas pu trouver de modèle standard pour ce genre de chose, mais cela semble fonctionner.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X