2017-11-20 2 views
3

Ich habe einige Tutorials über implementieren REST-Client in Java-Webanwendung gelesen, die SPRING verwenden, um Beans zu verwalten.Best Practices auf Rest-Client mit Spring RestTemplate

Jedes Beispiel, das ich fand, jedes Mal, wenn Sie eine REST-Anfrage machen, erstellen Sie ein neues RestTemplate.

Normalerweise Webanwendung Singleton Spring Bean.
Also ich möchte wissen, wann was ist die beste Praxis, um RestTemplate im Frühjahr zu verwenden konfiguriert Anwendungen?
Verwenden Singleton RestTemplate?
Erstellen Sie RestTemplate in jeder Anfrage. ?

Bitte Beratung und beschreiben Sie alle Situationen.

Antwort

1

Sie sollten eine der folgenden Vorgehensweisen verwenden, wenn Sie RestTemplate verwenden.

Static Beispiel:

/** 
* 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)); 
} 

oder ein Feder Bean in einer @Configuration Klasse delcare:

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

Wenn man sich die RestTemplate Klasse suchen die Sie wollen zu den Standard-Konstruktor zu vermeiden, schlagen viele Zeiten:

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()); 
    } 

} 
+0

wegen großen Anforderungen Menge, ich habe "Too many open file "Auf meiner App. Ein Problem bei vielen Konvertern beim Laden. Kann ich eine Liste von Konvertern für viele Vorlagen wiederverwenden? Ist es threadsicher? – demon101

+0

Ja, RestTemplate ist threadsicher https://spring.io/blog/2009/03/27/rest-in-spring-3-resttemplate – demon101

6

Eine der besten Möglichkeiten, dies zu tun, ist eine Bohne zu erstellen, die zurückkehren würde ein RestTemplate und dann Autowire es in welcher Klasse auch immer du brauchst.

So etwas wie das.

@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); 
    } 
} 

Auf diese Weise können verschiedene Parameter einstellen, die Sie für Ihre Erholung Anruf möchten, wie Timeouts oder Berechtigungsnachweise etc. Und wenn Sie verwenden möchten, können Sie einfach tun

@Autowired 
RestTemplate restTemplateForProductService; 

restTemplateForProductService....... 

Ein weiterer Vorteil dieser über die Verwendung von new RestTemplate() ist, wenn Sie verschiedene Dienste über REST aufrufen müssen, können Sie mehrere Beans (mit unterschiedlicher Konfiguration) definieren, die RestTemplates zurückgibt und es mit dem Namen