美文网首页
Http拦截器(请求拦截+响应拦截+RestTemplate拦截

Http拦截器(请求拦截+响应拦截+RestTemplate拦截

作者: BenjaminY | 来源:发表于2021-04-06 11:00 被阅读0次

    拦截器(interceptor)是那些有助于阻止或改变请求或响应的拦截器。协议拦截器通常作用于特定标头或一组相关标头。HttpClient库为拦截器提供支持。

    HttpClient

    请求拦截器

    HttpRequestInterceptor接口表示请求拦截器。此接口包含一个称为进程的方法,需要编写代码块来拦截请求。

    在客户端,此方法在将请求发送到服务器之前验证/处理请求,并且在服务器端,此方法在评估请求的主体之前执行。

    创建请求拦截器

    可以按照以下步骤创建请求拦截器。

    第1步 - 创建HttpRequestInterceptor的对象

    通过实现其抽象方法过程来创建HttpRequestInterceptor接口的对象。

    HttpRequestInterceptor requestInterceptor = new HttpRequestInterceptor() {
     @Override
     public void process(HttpRequest request, HttpContext context) throws
    HttpException, IOException {
       //Method implementation . . . . .
    };
    
    

    第2步 - 实例化CloseableHttpClient对象

    通过将以上创建的拦截器添加到它来构建自定义的CloseableHttpClient对象,如下所示 -

    //Creating a CloseableHttpClient object
    CloseableHttpClient httpclient =
    HttpClients.custom().addInterceptorFirst(requestInterceptor).build();
    
    

    使用此对象,可以照常执行请求执行。

    示例

    以下示例演示了请求拦截器的用法。在此示例中,创建了一个HTTP GET请求对象,并添加了三个标头:sample-headerdemoheadertest-header

    在拦截器processor()方法中,验证发送请求的头部; 如果这些标头中的任何一个是sample-header,我们尝试删除它并显示特定请求的标头列表。

    import java.io.IOException;
    import org.apache.http.Header;
    import org.apache.http.HttpException;
    import org.apache.http.HttpRequest;
    import org.apache.http.HttpRequestInterceptor;
    import org.apache.http.HttpResponse;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClients;
    import org.apache.http.message.BasicHeader;
    import org.apache.http.protocol.HttpContext;
    
    public class InterceptorsExample {
    
       public static void main(String args[]) throws Exception{
    
          //Creating an HttpRequestInterceptor
          HttpRequestInterceptor requestInterceptor = new HttpRequestInterceptor() {
             @Override
             public void process(HttpRequest request, HttpContext context) throws
             HttpException, IOException {
                if(request.containsHeader("sample-header")){
                   System.out.println("Contains header sample-header, removing it..");
                   request.removeHeaders("sample-header"); 
                }
                //Printing remaining list of headers
                Header[] headers= request.getAllHeaders();
                for (int i = 0; i<headers.length;i++){
                   System.out.println(headers[i].getName());
                }
             }
          };
    
          //Creating a CloseableHttpClient object
          CloseableHttpClient httpclient =
          HttpClients.custom().addInterceptorFirst(requestInterceptor).build();
    
          //Creating a request object
          HttpGet httpget1 = new HttpGet("https://www.kaops.com/");
    
          //Setting the header to it
          httpget1.setHeader(new BasicHeader("sample-header","My first header"));
          httpget1.setHeader(new BasicHeader("demo-header","My second header"));
          httpget1.setHeader(new BasicHeader("test-header","My third header"));
    
          //Executing the request
          HttpResponse httpresponse = httpclient.execute(httpget1);
    
          //Printing the status line
          System.out.println(httpresponse.getStatusLine());
       }
    }
    
    

    执行上面示例代码,得到以下结果:

    Contains header sample-header, removing it..
    demo-header
    test-header
    HTTP/1.1 200 OK
    
    

    响应拦截器

    HttpResponseInterceptor接口表示响应拦截器。该接口包含一个称为process()的方法。在此方法中,需要编写代码块来拦截响应。

    在服务器端,此方法在将响应发送到客户端之前验证/处理响应,在客户端,此方法在评估响应主体之前执行。

    创建响应拦截器

    可以按照以下步骤创建响应拦截器 -

    第1步 - 创建HttpResponseInterceptor的对象

    通过实现其抽象方法过程来创建HttpResponseInterceptor接口的对象。

    HttpResponseInterceptor responseInterceptor = new HttpResponseInterceptor() {
       @Override
       public void process(HttpResponse response, HttpContext context) throws HttpException, IOException {
          //Method implementation . . . . . . . .
       }
    };
    
    

    第2步 - 实例化CloseableHttpClient对象
    通过向其添加上面创建的拦截器来构建自定义的CloseableHttpClient对象,如下所示 -

    //Creating a CloseableHttpClient object
    CloseableHttpClient httpclient =
    HttpClients.custom().addInterceptorFirst(responseInterceptor).build();
    
    

    使用此对象,可以照常执行请求执行。

    示例

    以下示例演示了响应拦截器的用法。在此示例中,向处理器中的响应添加了三个标头:sample-headerdemo-headertest-header
    执行请求并获得响应后,使用getAllHeaders()方法打印响应的所有标头的名称。
    在输出中,可以观察列表中三个标题的名称。

    import java.io.IOException;
    import org.apache.http.Header;
    import org.apache.http.HttpException;
    import org.apache.http.HttpResponse;
    import org.apache.http.HttpResponseInterceptor;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClients;
    import org.apache.http.protocol.HttpContext;
    
    public class ResponseInterceptorsExample {
    
       public static void main(String args[]) throws Exception{
    
          //Creating an HttpRequestInterceptor
          HttpResponseInterceptor responseInterceptor = new HttpResponseInterceptor() {
             @Override
             public void process(HttpResponse response, HttpContext context) throws
             HttpException, IOException {
                System.out.println("Adding header sample_header, demo-header, test_header to the response");
                response.setHeader("sample-header", "My first header");
                response.setHeader("demo-header", "My second header");
                response.setHeader("test-header", "My third header"); 
             }
          };
    
          //Creating a CloseableHttpClient object
          CloseableHttpClient httpclient = HttpClients.custom().addInterceptorFirst(responseInterceptor).build();
    
          //Creating a request object
          HttpGet httpget1 = new HttpGet("https://www.kaops.com/");
    
          //Executing the request
          HttpResponse httpresponse = httpclient.execute(httpget1); 
    
          //Printing remaining list of headers
          Header[] headers = httpresponse.getAllHeaders();
    
          for (int i = 0; i<headers.length;i++){
             System.out.println(headers[i].getName());
          }
       }
    }
    
    

    执行上面示例代码,得到以下结果:

    On executing the above program generates the following output.
    Adding header sample_header, demo-header, test_header to the response
    Accept-Ranges
    Access-Control-Allow-Headers
    Access-Control-Allow-Origin
    Cache-Control
    Content-Type
    Date
    Expires
    Last-Modified
    Server
    Vary
    X-Cache
    sample-header
    demo-header
    test-header
    

    RestTemplate

    实现org.springframework.http.client.ClientHttpRequestInterceptor接口,跟httpClient拦截器的原理类似,只是略有不同

     public class RestTemplateIntercetor implements ClientHttpRequestInterceptor {
    private static Logger logger = LoggerFactory.getLogger(RestTemplateIntercetor.class);
    private static String NOTICE_MESSAGE_HOST = "www.zjzr.com.cn";
    @Override
    public ClientHttpResponse intercept(HttpRequest httpRequest, byte[] bytes, ClientHttpRequestExecution clientHttpRequestExecution) throws IOException {
       
        String authority = httpRequest.getURI().getAuthority();
        if(NOTICE_MESSAGE_HOST.equals(authority)){
            HttpHeaders headers = httpRequest.getHeaders();
            boolean contains = headers.containsKey("token");
            if(!contains){
                logger.warn("您对www.zjzr.com.cn的访问没有认证标识token,有可能被网关拦截无权访问,请注意");
            }
        }
        //继续执行请求
        return clientHttpRequestExecution.execute(httpRequest,bytes);
       }
    }
    

    配置文件
    META-INFO/spring.factories

    org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
     com.ruijie.springframework.core.configuration.HttpAutoConfiguration
    

    设置自动化配置类 HttpAutoConfiguration

    @Configuration
    public class HttpAutoConfiguration {
    
    @Bean
    @ConditionalOnClass(HttpRequestInterceptor.class)
    public HttpRequestInterceptor HttpClientRequestInterceptor(){
        return  new HttpClientRequestInterceptor();
    }
    
    @Bean
    @ConditionalOnClass(ClientHttpRequestInterceptor.class)
    public ClientHttpRequestInterceptor clientHttpRequestInterceptor(){
        return  new RestTemplateIntercetor();
    }
    
    @Bean
    @ConditionalOnBean(ClientHttpRequestInterceptor.class)
    public RestTemplate restTemplate(ClientHttpRequestInterceptor clientHttpRequestInterceptor){
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.setInterceptors(Collections.singletonList(clientHttpRequestInterceptor));
        return restTemplate;
    }
    
    
    @Autowired
    private ConfigurableEnvironment configurableEnvironment;
    
    @PostConstruct
    public void init(){
        String property = configurableEnvironment.getProperty("token");
        HttpClientUtil.setToken(property);
      }
    }
    

    这样 我们在使用HttpClientUtil或resttemplate的时候 ,拦截器就会生效,验证Token是否存在,并且给出相应提示或抛出异常.

    相关文章

      网友评论

          本文标题:Http拦截器(请求拦截+响应拦截+RestTemplate拦截

          本文链接:https://www.haomeiwen.com/subject/czjskltx.html