RestTemplate配置API 拦截器,增加请求头信息,JWT

目标 对第三方的请求增加请求头信息.

  1. 目标在调用第三方接口时候,需要在请求里面增加请求头信息。springboot 利用restTemplate 模板进行http请求转发。

  2. 编写拦截器类 实现接口ClientHttpRequestInterceptor,实现具体的往请求头里面增加具体的有信息:

package com.feifan;

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;

import java.io.IOException;

/**
 * @author Donald
 * @create 2019-09-28 12:26
 * 自定义 请求拦截器
 */
public class UserClientInterCeptor implements ClientHttpRequestInterceptor {
    
    

    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
    
    
        /// 获取请求头
        HttpHeaders headers = request.getHeaders();
        // 加入请求头信息
        headers.add("koko","kiki");
        // TODO 增加其他的请求头信息

        // 执行请求
        ClientHttpResponse execute = execution.execute(request, body);

        System.err.println(execute.getStatusCode()+execute.getStatusText());

        return execute;
    }
}

  1. 配置Bean 的时候增加,具体的拦截器信息,
@Bean
    public RestTemplate getBeanRstTemplate(RestTemplateBuilder builder )
    {
    
    
        RestTemplate restTemplate =
                builder
                        //
                        .basicAuthentication("ki", "dd")
                // 增加请求拦截器
                .interceptors(new UserClientInterCeptor())
                .build();
        // 消息转换器
        restTemplate.getMessageConverters().add(new RestMessageInterceptor());
        return restTemplate;
    }
  1. 方法调用:
 @Autowired
    private RestTemplate restTemplate ;

    @GetMapping("header")
    @ResponseBody
    public Object getHeader()
    {
    
    
        Object forObject = restTemplate.getForObject("http://127.0.0.1:8080/find/list/47", Object.class);
        return forObject;

    }
  1. 结果:请求中增加了具体的请求头信息
    6.

增加消息转换器

消息装换器等层接口:HttpMessageConverter.calss

/*
 * Copyright 2002-2018 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.http.converter;

import java.io.IOException;
import java.util.List;

import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.lang.Nullable;

/**
 * Strategy interface that specifies a converter that can convert from and to HTTP requests and responses.
 *
 * @author Arjen Poutsma
 * @author Juergen Hoeller
 * @since 3.0
 * @param <T> the converted object type
 */
public interface HttpMessageConverter<T> {
    
    

	/**
	 * Indicates whether the given class can be read by this converter.
	 * @param clazz the class to test for readability
	 * @param mediaType the media type to read (can be {@code null} if not specified);
	 * typically the value of a {@code Content-Type} header.
	 * @return {@code true} if readable; {@code false} otherwise
	 */
	boolean canRead(Class<?> clazz, @Nullable MediaType mediaType);

	/**
	 * Indicates whether the given class can be written by this converter.
	 * @param clazz the class to test for writability
	 * @param mediaType the media type to write (can be {@code null} if not specified);
	 * typically the value of an {@code Accept} header.
	 * @return {@code true} if writable; {@code false} otherwise
	 */
	boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType);

	/**
	 * Return the list of {@link MediaType} objects supported by this converter.
	 * @return the list of supported media types
	 */
	List<MediaType> getSupportedMediaTypes();

	/**
	 * Read an object of the given type from the given input message, and returns it.
	 * @param clazz the type of object to return. This type must have previously been passed to the
	 * {@link #canRead canRead} method of this interface, which must have returned {@code true}.
	 * @param inputMessage the HTTP input message to read from
	 * @return the converted object
	 * @throws IOException in case of I/O errors
	 * @throws HttpMessageNotReadableException in case of conversion errors
	 */
	T read(Class<? extends T> clazz, HttpInputMessage inputMessage)
			throws IOException, HttpMessageNotReadableException;

	/**
	 * Write an given object to the given output message.
	 * @param t the object to write to the output message. The type of this object must have previously been
	 * passed to the {@link #canWrite canWrite} method of this interface, which must have returned {@code true}.
	 * @param contentType the content type to use when writing. May be {@code null} to indicate that the
	 * default content type of the converter must be used. If not {@code null}, this media type must have
	 * previously been passed to the {@link #canWrite canWrite} method of this interface, which must have
	 * returned {@code true}.
	 * @param outputMessage the message to write to
	 * @throws IOException in case of I/O errors
	 * @throws HttpMessageNotWritableException in case of conversion errors
	 */
	void write(T t, @Nullable MediaType contentType, HttpOutputMessage outputMessage)
			throws IOException, HttpMessageNotWritableException;

}

  1. 在SpringMVC进入controller方法前,会根据@RequestBody注解选择适当的HttpMessageConverter实现类来将请求参数解析到string变量中,具体来说是使用了StringHttpMessageConverter类,它的canRead()方法返回true,然后它的read()方法会从请求中读出请求参数,绑定到readString()方法的string变量中。
  2. 由于返回值标识了@ResponseBody,SpringMVC将使用StringHttpMessageConverter的write()方法,将结果作为String值写入响应报文,当然,此时canWrite()方法返回true。
  3. 在SpringMVC的设计者眼中,一次请求报文和一次响应报文,分别被抽象为一个请求消息HttpInputMessage和一个响应消息HttpOutputMessage。
    在这里插入图片描述
  4. 自定义消息转换器
package com.feifan;

import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Donald
 * @create 2019-10-09 22:13
 */
public class RestMessageInterceptor implements HttpMessageConverter {
    
    
    @Override
    public boolean canRead(Class clazz, MediaType mediaType) {
    
    
        System.err.println("canRead inside");
        return true;
    }

    @Override
    public boolean canWrite(Class clazz, MediaType mediaType) {
    
    
        System.err.println("canWrite inside");
        return false;
    }

    @Override
    public List<MediaType> getSupportedMediaTypes() {
    
    
        System.err.println("getSupportedMediaTypes");
        return new ArrayList<>();
    }

    @Override
    public Object read(Class clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
    
    
        System.err.println("read");
        return null;
    }

    @Override
    public void write(Object o, MediaType contentType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
    
    
        System.err.println("write");
    }
}


  1. 配置类中加入消息转换器的信息:
@Bean
    public RestTemplate getBeanRstTemplate(RestTemplateBuilder builder )
    {
    
    
        RestTemplate restTemplate =
                builder
                        //
                        .basicAuthentication("ki", "dd")
                // 增加请求拦截器
                .interceptors(new UserClientInterCeptor())
                .build();
        // 消息转换器
        restTemplate.getMessageConverters().add(new RestMessageInterceptor());
        return restTemplate;
    }
  1. xml配置方式

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
   <property name="messageConverters">
       <list>
           <ref bean="jsonConverter" />
           <ref bean="marshallingConverter" />
           <ref bean="atomConverter" />
       </list>
   </property>
</bean>
 
<bean id="jsonConverter"   class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
   <property name="supportedMediaTypes" value="application/json" />

参考连接:

https://www.iteye.com/blog/rensanning-2362105

RestTemplate包含:
HttpMessageConverter 对象转换器
ClientHttpRequestFactory 默认是JDK的HttpURLConnection
ResponseErrorHandler 异常处理
ClientHttpRequestInterceptor 请求拦截器
在这里插入图片描述
8. 自定义异常处理信息

package com.feifan;

import org.springframework.http.HttpMethod;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.web.client.DefaultResponseErrorHandler;

import java.io.IOException;
import java.net.URI;

/**
 * @author Donald
 * @create 2019-10-09 23:24
 */
public class ResponeException extends DefaultResponseErrorHandler {
    
    

    @Override
    public void handleError(URI url, HttpMethod method, ClientHttpResponse response) throws IOException {
    
    
        // 自定义异常信息, 记录关键日志信息
    }
}
  1. 配置异常信息处理器
//  配置异常处理
        restTemplate.setErrorHandler(new ResponeException());
  1. 利用模板发送文件
MultiValueMap<String, Object> multiPartBody = new LinkedMultiValueMap<>();  
multiPartBody.add("file", new ClassPathResource("/tmpd/userrt.txt"));  
RequestEntity<MultiValueMap<String, Object>> requestEntity = RequestEntity  
        .post(uri)  
        .contentType(MediaType.MULTIPART_FORM_DATA)  
        .body(multiPartBody);

  1. 下载文件信息
// 小文件  
RequestEntity requestEntity = RequestEntity.get(uri).build();  
ResponseEntity<byte[]> responseEntity = restTemplate.exchange(requestEntity, byte[].class);  
byte[] downloadContent = responseEntity.getBody();  
  
// 大文件  
ResponseExtractor<ResponseEntity<File>> responseExtractor = new ResponseExtractor<ResponseEntity<File>>() {
    
      
    @Override  
    public ResponseEntity<File> extractData(ClientHttpResponse response) throws IOException {
    
      
        File rcvFile = File.createTempFile("rcvFile", "zip");  
        FileCopyUtils.copy(response.getBody(), new FileOutputStream(rcvFile));  
        return ResponseEntity.status(response.getStatusCode()).headers(response.getHeaders()).body(rcvFile);  
    }  
};  
File getFile = this.restTemplate.execute(targetUri, HttpMethod.GET, null, responseExtractor);  

猜你喜欢

转载自blog.csdn.net/qq_16183731/article/details/102471771
今日推荐