Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cassandra/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring boot 如何获得;etag“;在使用springframework/SpringBoot的RestTemplate实现Firebase远程配置REST Api时?_Spring Boot_Httpurlconnection_Resttemplate_Etag_Firebase Remote Config - Fatal编程技术网

Spring boot 如何获得;etag“;在使用springframework/SpringBoot的RestTemplate实现Firebase远程配置REST Api时?

Spring boot 如何获得;etag“;在使用springframework/SpringBoot的RestTemplate实现Firebase远程配置REST Api时?,spring-boot,httpurlconnection,resttemplate,etag,firebase-remote-config,Spring Boot,Httpurlconnection,Resttemplate,Etag,Firebase Remote Config,为了学习,我正在一个Android应用程序的spring引导服务器中实现firebase远程配置rest api。我的spring boot版本是2.1.7.0版本。我正在尝试获取etag值,这样我就可以从服务器端更新密钥和值,而无需使用firebase控制台。我能够通过httpconnection获得etag。但是每当我使用RestTemplate时,我都无法获得etag,我得到的只是null 这是build.gradle文件 这是我创建的用于实验firebase远程配置的控制器 @RestC

为了学习,我正在一个Android应用程序的spring引导服务器中实现firebase远程配置rest api。我的spring boot版本是2.1.7.0版本。我正在尝试获取etag值,这样我就可以从服务器端更新密钥和值,而无需使用firebase控制台。我能够通过httpconnection获得etag。但是每当我使用RestTemplate时,我都无法获得etag,我得到的只是null

这是build.gradle文件

这是我创建的用于实验firebase远程配置的控制器

@RestController
@RequestMapping(value = "/api/remote-config")
public class FirebaseRestApiEndpoint {

    private final FirebaseRemoteConfigService firebaseRemoteConfigService;

    public FirebaseRestApiEndpoint(FirebaseRemoteConfigService firebaseRemoteConfigService) {
        this.firebaseRemoteConfigService = firebaseRemoteConfigService;
    }

    @GetMapping(value = "/get-template/{call-type}")
    public void getTemplate(@PathVariable("call-type") String callType) {
        switch (callType) {
            case "http":
                firebaseRemoteConfigService.getMetadataTemplateWithHttpCall();
                break;
            case "rest":
                firebaseRemoteConfigService.getMetadataTemplateWithRestCall();
                break;
            default:
                throw new RuntimeException("call-type is unknown. Should be rest or http");
        }
    }
}
这是我使用的accessToken()进程

// Constant File holds the url and other static final string values.
public static String getAccessToken() throws IOException {
    GoogleCredential googleCredential = GoogleCredential
            .fromStream(new FileInputStream(Constants.CERTIFICATE_FILE))
            .createScoped(Arrays.asList(Constants.SCOPES));
    googleCredential.refreshToken();
    return googleCredential.getAccessToken();
}
对于服务层,我只包括这里为简化而调用的方法

这是使用HttpUrlConnection的方法

public void getMetadataTemplateWithHttpCall() {
    try {
        URL url = new URL(Constants.BASE_URL + Constants.REMOTE_CONFIG_ENDPOINT);
        HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
        httpURLConnection.setRequestProperty("Authorization", "Bearer " + CommonConfig.getAccessToken());
        httpURLConnection.setRequestProperty("Content-Type", "application/json; UTF-8");
        httpURLConnection.setRequestMethod("GET");
        httpURLConnection.setRequestProperty("Accept-Encoding", "gzip");

        int code = httpURLConnection.getResponseCode();
        if (code == 200) {
            InputStream inputStream = new GZIPInputStream(httpURLConnection.getInputStream());
            JsonElement jsonElement = JsonParser.parseReader(new InputStreamReader(inputStream));

            Gson gson = new GsonBuilder()
                    .setPrettyPrinting()
                    .disableHtmlEscaping()
                    .enableComplexMapKeySerialization()
                    .serializeSpecialFloatingPointValues()
                    .create();
            String jsonStr = gson.toJson(jsonElement);
            RemoteConfig remoteConfig = gson.fromJson(jsonStr, RemoteConfig.class);
            String etag = httpURLConnection.getHeaderField("ETag");
            System.out.println(etag);
        }
    } catch (IOException e) {
        System.err.println(e.getMessage());
    }
}
此处根据Firebase远程配置REST Api的说明打印适当的etag

但是如果我尝试用RestTemplate实现相同的http get连接,我就无法获得etag

现在,这就是利用RestTemplate的方法。我为这个rest调用提供了非常类似的请求属性。但我还是拿不到etag

这是Rest调用的标题

Content-Type:"application/json; charset=UTF-8", 
Vary:"X-Origin", "Referer", "Origin,Accept-Encoding", 
Date:"Mon, 11 Nov 2019 05:15:10 GMT", 
Server:"ESF", 
Cache-Control:"private", 
X-XSS-Protection:"0", 
X-Frame-Options:"SAMEORIGIN", 
X-Content-Type-Options:"nosniff", 
Alt-Svc:"quic=":443"; ma=2592000; v="46,43",h3-Q050=":443"; ma=2592000,h3-Q049=":443"; ma=2592000,h3-Q048=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000", 
Accept-Ranges:"none", 
Transfer-Encoding:"chunked"
谁能帮帮我吗。我的目标是使用rest调用获取etag值,更准确地说是使用springframework的RestTemplate,因为它是一个RESTAPI


谢谢。

经过长时间的研究和调试,我终于找到了解决办法

在测试中,我们被告知添加标题接受编码:gzip。这就是为什么我使用
httpHeaders.add(httpHeaders.CONTENT_ENCODING,“gzip”)。它不起作用。我甚至添加了这样的头,
httpHeaders.add(“接受编码”,“gzip”)。它抛出异常,RestTemplate不接受gzip作为接受编码。如果您在调用之前使用定制的RestTemplate拦截器截获rest调用,并使用gzip和拦截器压缩请求,那么可以这样做。这意味着在使用RestTemplate的情况下,我们需要在http调用之前压缩请求,然后发送它。只有到那时,在回应中我得到了“etag”

我已经为指定的RestTemplate创建了一个
@Bean
,我在下面提供了它。如果您想使用springframework的RestTemplate,那么必须添加这种类型的拦截器以利用Firebase远程配置REST API

这是
@Bean

@Configuration
public class RestTemplateConfig {
    @Bean(value = "gzippedRestTemplate")
    public RestTemplate restTemplate() {
        HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(
                HttpClientBuilder.create().build());
        clientHttpRequestFactory.setConnectTimeout(2000);
        clientHttpRequestFactory.setReadTimeout(10000);
        RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory);
        List<ClientHttpRequestInterceptor> interceptors = restTemplate.getInterceptors();
        if (interceptors == null) {
            interceptors = new ArrayList<>();
            restTemplate.setInterceptors(interceptors);
        }
        interceptors.add(new GzipAcceptHeaderRequestInterceptor());
        return restTemplate;
    }
    public static class GzipAcceptHeaderRequestInterceptor implements ClientHttpRequestInterceptor {
        @Override
        public ClientHttpResponse intercept(HttpRequest request, @Nullable byte[] body, ClientHttpRequestExecution execution) throws IOException {
            request.getHeaders().set(HttpHeaders.ACCEPT_ENCODING, "gzip");
            return execution.execute(request, body);
        }
    }
}
@配置
公共类RestTemplateConfig{
@Bean(value=“gzip测试模板”)
公共RestTemplate RestTemplate(){
HttpComponents客户端HttpRequestFactory客户端HttpPrequestFactory=新的HttpComponents客户端HttpRequestFactory(
HttpClientBuilder.create().build());
clientHttpRequestFactory.setConnectTimeout(2000);
clientHttpRequestFactory.setReadTimeout(10000);
RestTemplate RestTemplate=新的RestTemplate(clientHttpRequestFactory);
List interceptors=restemplate.getInterceptors();
if(拦截器==null){
拦截器=新的ArrayList();
restTemplate.setInterceptors(拦截器);
}
add(新的GzipAcceptHeaderRequestInterceptor());
返回REST模板;
}
公共静态类GzipAcceptHeaderRequestInterceptor实现ClientHttpRequestInterceptor{
@凌驾
公共ClientHttpResponse截获(HttpRequest请求,@Nullable byte[]body,ClientHttpPrequesteExecution执行)引发IOException{
set(HttpHeaders.ACCEPT_编码,“gzip”);
返回执行。执行(请求,正文);
}
}
}
现在,您可以使用springframework的RestTemplate从
get
调用中获取“etag”值,发布您的工作

Transfer-Encoding=[chunked], 
null=[HTTP/1.1 200 OK],
Alt-Svc=[quic=":443"; ma=2592000; v="46,43",h3-Q050=":443"; ma=2592000,h3-Q049=":443"; ma=2592000,h3-Q048=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000], 
Server=[ESF], 
X-Content-Type-Options=[nosniff], 
Date=[Mon, 11 Nov 2019 04:59:04 GMT], 
X-Frame-Options=[SAMEORIGIN], 
Cache-Control=[private], 
ETag=[etag-111111311162-47],
Content-Encoding=[gzip],
Vary=[Referer, X-Origin, Origin], 
X-XSS-Protection=[0], 
Content-Type=[application/json; charset=UTF-8]
Content-Type:"application/json; charset=UTF-8", 
Vary:"X-Origin", "Referer", "Origin,Accept-Encoding", 
Date:"Mon, 11 Nov 2019 05:15:10 GMT", 
Server:"ESF", 
Cache-Control:"private", 
X-XSS-Protection:"0", 
X-Frame-Options:"SAMEORIGIN", 
X-Content-Type-Options:"nosniff", 
Alt-Svc:"quic=":443"; ma=2592000; v="46,43",h3-Q050=":443"; ma=2592000,h3-Q049=":443"; ma=2592000,h3-Q048=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000", 
Accept-Ranges:"none", 
Transfer-Encoding:"chunked"
@Configuration
public class RestTemplateConfig {
    @Bean(value = "gzippedRestTemplate")
    public RestTemplate restTemplate() {
        HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(
                HttpClientBuilder.create().build());
        clientHttpRequestFactory.setConnectTimeout(2000);
        clientHttpRequestFactory.setReadTimeout(10000);
        RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory);
        List<ClientHttpRequestInterceptor> interceptors = restTemplate.getInterceptors();
        if (interceptors == null) {
            interceptors = new ArrayList<>();
            restTemplate.setInterceptors(interceptors);
        }
        interceptors.add(new GzipAcceptHeaderRequestInterceptor());
        return restTemplate;
    }
    public static class GzipAcceptHeaderRequestInterceptor implements ClientHttpRequestInterceptor {
        @Override
        public ClientHttpResponse intercept(HttpRequest request, @Nullable byte[] body, ClientHttpRequestExecution execution) throws IOException {
            request.getHeaders().set(HttpHeaders.ACCEPT_ENCODING, "gzip");
            return execution.execute(request, body);
        }
    }
}