簡體   English   中英

使用 RESTTemplate springboot 使用公共 REST API

[英]consuming public REST API using RESTTemplate springboot

我正在嘗試使用公共 API,雖然調用從 RestTemplate 編碼的 UTF-8 的 URL 沒有得到響應,因為在從 URL 返回的 responseHeader 中可以看到它正在將 UTF-8 編碼也作為參數值

為避免這種情況,嘗試使用 URLDecoder 解碼 URL,但隨后出現錯誤,例如

java.lang.IllegalArgumentException: 沒有足夠的變量值可用於擴展 '!join%20from=id%20to= root '

UTF-8 編碼的網址:

https://registers.esma.europa.eu/solr/esma_registers_upreg/select?q=%7B!join+from%3Did+to%3D_root_%7Dae_entityTypeCode%3AMIR&fq=(type_s%3Aparent)(entity_type%3AaeActivity)(entity_type%3AaeActivityHistory)&rows=1000&wt=json&indent=true

解碼后的網址:

https://registers.esma.europa.eu/solr/esma_registers_upreg/select?q={!join from=id to=_root_}ae_entityTypeCode:MIR&fq=(type_s:parent)(entity_type:aeActivity)(entity_type:aeActivityHistory)&rows=1000&wt=json&indent=true

代碼片段:

@Component
@Slf4j
public class RestClient {

   private final RestTemplate restTemplate;

   public RestClient(RestTemplate restTemplate) {
      this.restTemplate = restTemplate;
   }

   private Object callExternalRestService(String url) throws FirdsFailureException {
      try {
         MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
         converter.setSupportedMediaTypes(Arrays.asList(MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON));
         restTemplate.getMessageConverters().add(converter);
         ResponseEntity<Object> response = restTemplate.exchange(
               url,
               HttpMethod.GET,
               null,
               new ParameterizedTypeReference<Object>() {
               });
         log.info("Response from External Service : {}", response);
         log.info("Response Body from External Service : {}", response.getBody());
         return response.getBody();
      }catch (Exception e){
         log.error("",e);
      }
      return null;
   }

}

例外 -

請參考以下例外情況 -

Caused by: com.demo.adapter.firds.FirdsFailureException: java.lang.IllegalArgumentException: Not enough variable values available to expand '!join%20from=id%20to=_root_'
        at com.demo.adapter.firds.RestClient.callExternalRestService(RestClient.java:58)
        at com.demo.adapter.firds.RestClient.getExternalServiceData(RestClient.java:35)
        at com.demo.adapter.firds.RestClient$$FastClassBySpringCGLIB$$341b0269.invoke(<generated>)
        at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
        at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
        at org.springframework.retry.interceptor.RetryOperationsInterceptor$1.doWithRetry(RetryOperationsInterceptor.java:91)
        at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:287)
        ... 22 common frames omitted
Caused by: java.lang.IllegalArgumentException: Not enough variable values available to expand '!join%20from=id%20to=_root_'
        at org.springframework.web.util.UriComponents$VarArgsTemplateVariables.getValue(UriComponents.java:329)
        at org.springframework.web.util.HierarchicalUriComponents$QueryUriTemplateVariables.getValue(HierarchicalUriComponents.java:899)
        at org.springframework.web.util.UriComponents.expandUriComponent(UriComponents.java:232)
        at org.springframework.web.util.HierarchicalUriComponents.expandQueryParams(HierarchicalUriComponents.java:347)
        at org.springframework.web.util.HierarchicalUriComponents.expandInternal(HierarchicalUriComponents.java:332)
        at org.springframework.web.util.HierarchicalUriComponents.expandInternal(HierarchicalUriComponents.java:48)
        at org.springframework.web.util.UriComponents.expand(UriComponents.java:165)
        at org.springframework.web.util.UriComponentsBuilder.buildAndExpand(UriComponentsBuilder.java:360)
        at org.springframework.web.util.DefaultUriTemplateHandler.expandAndEncode(DefaultUriTemplateHandler.java:140)
        at org.springframework.web.util.DefaultUriTemplateHandler.expandInternal(DefaultUriTemplateHandler.java:104)
        at org.springframework.web.util.AbstractUriTemplateHandler.expand(AbstractUriTemplateHandler.java:106)
        at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:612)
        at org.springframework.web.client.RestTemplate.getForEntity(RestTemplate.java:312)
        at com.demo.adapter.firds.RestClient.callExternalRestService(RestClient.java:46)
        ... 29 common frames omitted

有人可以讓我知道我是否遺漏了什么或做錯了什么

只需在傳入rest模板之前解碼url,如下所示:

String url = "https://registers.esma.europa.eu/solr/esma_registers_upreg/select?q=%7B!join+from%3Did+to%3D_root_%7Dae_entityTypeCode%3AMIR&fq=(type_s%3Aparent)(entity_type%3AaeActivity)(entity_type%3AaeActivityHistory)&rows=1000&wt=json&indent=true";
String decodedUrl =  URLDecoder.decode(url.toString(), "UTF-8");

創建一個像這樣的 bean 並自動裝配 Resttemplate 以使用它

import org.apache.http.client.HttpClient;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;

import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;


import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.SecureRandom;

@Configuration
public class RestTemplateConfig{

    @Bean
    public RestTemplate restTemplate() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
        TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;
        HttpClient httpClient = RestTemplateConfig.getHttpClient();
        HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
        requestFactory.setHttpClient(httpClient);
        RestTemplate restTemplate = new RestTemplate(requestFactory);
        return restTemplate;
    }
    
    private static HttpClient getHttpClient() {

        try {
            SSLContext sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null,
                    new TrustManager[]{new X509TrustManager() {
                        public X509Certificate[] getAcceptedIssuers() {
                            return null;
                        }
                        public void checkClientTrusted(
                                X509Certificate[] certs, String authType) {
                        }
                        public void checkServerTrusted(
                                X509Certificate[] certs, String authType) {
                        }
                    }}, new SecureRandom());
            SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext,SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
            //  SSLSocketFactory socketFactory = new SSLSocketFactory(sslContext, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
            HttpClient httpClient = HttpClientBuilder.create().setSSLSocketFactory(socketFactory).build();
            return httpClient;
        } catch (Exception e) {
            e.printStackTrace();
            return HttpClientBuilder.create().build();
        }
    }


}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM