zoukankan      html  css  js  c++  java
  • How to Send an HTTP Header With Every Request With Spring RestTemplate

    In Know Which Apps Are Hitting Your Web Service, I showed how to write a servlet filter that enforces the existence of a special HTTP request header.

    From a client perspective, it would be nice to send this header automatically, instead of having to set the header manually with every request. This post shows how we can use Spring’s RestTemplate and ClientHttpRequestInterceptor to accomplish this.

    First we need to implement a ClientHttpRequestInterceptor:

    package com.myapp.connector;
    
    import java.io.IOException;
    import org.springframework.http.HttpHeaders;
    import org.springframework.http.HttpRequest;
    import org.springframework.http.client.ClientHttpRequestExecution;
    import org.springframework.http.client.ClientHttpRequestInterceptor;
    import org.springframework.http.client.ClientHttpResponse;
    
    public class XUserAgentInterceptor implements ClientHttpRequestInterceptor {
    
        @Override
        public ClientHttpResponse intercept(
                HttpRequest request, byte[] body, ClientHttpRequestExecution execution)
                throws IOException {
    
            HttpHeaders headers = request.getHeaders();
            headers.add("X-User-Agent", "My App v2.1");
            return execution.execute(request, body);
        }
    }
    

    Now we need to configure our RestTemplate to use it. Here I’m using Spring’s Java-based configuration, but you can implement the same thing with the XML-based configuration too:

    package com.myapp;
    
    import java.util.Collections;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.http.client.ClientHttpRequestInterceptor;
    import org.springframework.web.client.RestTemplate;
    import com.myapp.connector.XUserAgentInterceptor;
    
    @Configuration
    public class MyAppConfig {
    
        @Bean
        public RestTemplate restTemplate() {
            RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory());
            restTemplate.setInterceptors(Collections.singletonList(new XUserAgentInterceptor()));
            return restTemplate;
        }
    }
    

    With this configuration, any requests you make through the RestTemplate will automatically carry the desired HTTP request header.

    To learn how to set request timeouts automatically, see my post How to Set HTTP Request Timeouts With Spring RestTemplate.

    http://springinpractice.com/2013/10/27/how-to-send-an-http-header-with-every-request-with-spring-resttemplate/

    When creating a web service, it’s often useful to know which apps are hitting it. I don’t mean which users, but instead which apps. The reason is that you may want to coordinate with some other team on something. For example, maybe the team is being too aggressive about request retries, or maybe you want to alert the team to a change in the API. Whatever the reason, it’s good to know which apps are calling your service.

    HTTP has a User-Agent header that can help here. One possible approach is to make that a required header. Unfortunately, this approach isn’t ideal. The problem is that HTTP client libraries usually set that header automatically. So if the client application forgets to set the header explicitly, you end up with user agents like Apache-HttpClient/release (java 1.5), which isn’t much help at all.

    An approach I like better is to define a custom header and make it required. I use X-User-Agent, since it really is a user agent we’re talking about here.

    Here’s how to implement this with a servlet filter. No Spring involved here at all; it’s just servlet stuff.

    package com.myapp.web.filter;
    
    import java.io.IOException;
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class XUserAgentFilter implements Filter {
        private static final String X_USER_AGENT = "X-User-Agent";
    
        private String errorJson;
    
        public XUserAgentFilter() {
            String message = 
                "HTTP header '" + X_USER_AGENT + "' is required. Please set it to your application name so we know " +
                "who to contact if there's an issue.";
            this.errorJson = "{ " + wrap("message") + " : " + wrap(message) + " }";
        }
    
        private String wrap(String s) { return """ + s + """; }
    
        @Override
        public void init(FilterConfig config) throws ServletException { }
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                throws IOException, ServletException {
    
            HttpServletRequest httpRequest = (HttpServletRequest) request;
            HttpServletResponse httpResponse = (HttpServletResponse) response;
    
            if (httpRequest.getHeader(X_USER_AGENT) == null) {//不走chain.doFilter即结束
                httpResponse.setStatus(422);
                httpResponse.getWriter().println(errorJson);
            } else {
                chain.doFilter(request, response);
            }
        }
    
        @Override
        public void destroy() { }
    }
    

    Of course, you need to configure this filter and a filter mapping in your web.xml file.

    In the next post I’ll show you how to set up your Spring RestTemplate to send the X-User-Agent header with each request automatically.

    http://springinpractice.com/2013/10/25/know-which-apps-are-hitting-your-web-service/

    In How to Send an HTTP Header With Every Request With Spring RestTemplate, we looked at how to send a given HTTP header automatically with every request. Here we’ll do something similar, which is to automatically apply a request timeout to every request.

    Here’s the Java-based configuration for this technique:

    package com.myapp;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.http.client.ClientHttpRequestFactory;
    import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
    import org.springframework.web.client.RestTemplate;
    
    @Configuration
    public class MyAppConfig {
    
        @Bean
        public RestTemplate restTemplate() {
            return new RestTemplate(clientHttpRequestFactory());
        }
    
        private ClientHttpRequestFactory clientHttpRequestFactory() {
            HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
            factory.setReadTimeout(2000);
            factory.setConnectTimeout(2000);
            return factory;
        }
    }
    

    The XML-based configuration is this:

    <bean class="org.springframework.web.client.RestTemplate">
        <constructor-arg>
            <bean class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory"
                p:readTimeout="2000"
                p:connectTimeout="2000" />
        </constructor-arg>
    </bean>
    

    http://springinpractice.com/2013/10/27/how-to-set-http-request-timeouts-with-spring-resttemplate/

    Basic Auth:

    // Set the username and password for creating a Basic Auth request
    HttpAuthentication authHeader = new HttpBasicAuthentication(username, password);
    HttpHeaders requestHeaders = new HttpHeaders();
    requestHeaders.setAuthorization(authHeader);
    HttpEntity<?> requestEntity = new HttpEntity<Object>(requestHeaders);
    
    // Create a new RestTemplate instance
    RestTemplate restTemplate = new RestTemplate();
    
    // Add the String message converter
    restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
    
    try {
        // Make the HTTP GET request to the Basic Auth protected URL
        ResponseEntity<Message> response = restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class);
        return response.getBody();
    } catch (HttpClientErrorException e) {
        Log.e(TAG, e.getLocalizedMessage(), e);
        // Handle 401 Unauthorized response
    }

    http://docs.spring.io/autorepo/docs/spring-android/1.0.x/reference/html/rest-template.html

    https://www.cnblogs.com/rinack/p/7815064.html

  • 相关阅读:
    USACO2018 DEC(Platinum) (树上乱搞,期望+凸包)
    USACO2018 DEC (Gold) (dp,容斥+哈希,最短路)
    《信息学奥赛一本通》题库 1034 计算三角形面积——基础
    UNR#3 Day1——[ 堆+ST表+复杂度分析 ][ 结论 ][ 线段树合并 ]
    bzoj 4298 [ONTAK2015]Bajtocja——哈希+启发式合并
    玲珑杯#20 C 漆黑的太阳——莫队
    链表写法
    传址函数写法
    bzoj 4650 & 洛谷 P1117 优秀的拆分 —— 枚举关键点+后缀数组
    bzoj 2119 股市的预测 —— 枚举关键点+后缀数组
  • 原文地址:https://www.cnblogs.com/softidea/p/5981831.html
Copyright © 2011-2022 走看看