a1d3da8d3394877ea1ba8e4d93c445a9fdc54e41.svn-base 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. package org.jeecg.config;
  2. import java.io.IOException;
  3. import java.util.ArrayList;
  4. import java.util.Arrays;
  5. import java.util.List;
  6. import java.util.SortedMap;
  7. import javax.servlet.http.HttpServletRequest;
  8. import org.jeecg.common.constant.CommonConstant;
  9. import org.jeecg.common.util.DateUtils;
  10. import org.jeecg.common.util.PathMatcherUtil;
  11. import org.jeecg.common.config.mqtoken.UserTokenContext;
  12. import org.jeecg.config.sign.interceptor.SignAuthConfiguration;
  13. import org.jeecg.config.sign.util.HttpUtils;
  14. import org.jeecg.config.sign.util.SignUtil;
  15. import org.springframework.beans.factory.ObjectFactory;
  16. import org.springframework.boot.autoconfigure.AutoConfigureBefore;
  17. import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
  18. import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
  19. import org.springframework.cloud.openfeign.FeignAutoConfiguration;
  20. import org.springframework.cloud.openfeign.support.SpringDecoder;
  21. import org.springframework.cloud.openfeign.support.SpringEncoder;
  22. import org.springframework.context.annotation.Bean;
  23. import org.springframework.context.annotation.Configuration;
  24. import org.springframework.context.annotation.Primary;
  25. import org.springframework.context.annotation.Scope;
  26. import org.springframework.http.MediaType;
  27. import org.springframework.web.context.request.RequestContextHolder;
  28. import org.springframework.web.context.request.ServletRequestAttributes;
  29. import com.alibaba.fastjson.JSON;
  30. import com.alibaba.fastjson.serializer.SerializerFeature;
  31. import com.alibaba.fastjson.support.config.FastJsonConfig;
  32. import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
  33. import com.alibaba.fastjson.support.springfox.SwaggerJsonSerializer;
  34. import feign.Feign;
  35. import feign.Logger;
  36. import feign.RequestInterceptor;
  37. import feign.codec.Decoder;
  38. import feign.codec.Encoder;
  39. import feign.form.spring.SpringFormEncoder;
  40. import lombok.extern.slf4j.Slf4j;
  41. @ConditionalOnClass(Feign.class)
  42. @AutoConfigureBefore(FeignAutoConfiguration.class)
  43. @Slf4j
  44. @Configuration
  45. public class FeignConfig {
  46. @Bean
  47. public RequestInterceptor requestInterceptor() {
  48. return requestTemplate -> {
  49. ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
  50. if (null != attributes) {
  51. HttpServletRequest request = attributes.getRequest();
  52. log.debug("Feign request: {}", request.getRequestURI());
  53. // 将token信息放入header中
  54. String token = request.getHeader(CommonConstant.X_ACCESS_TOKEN);
  55. if(token==null || "".equals(token)){
  56. token = request.getParameter("token");
  57. }
  58. log.debug("Feign request token: {}", token);
  59. requestTemplate.header(CommonConstant.X_ACCESS_TOKEN, token);
  60. //根据URL地址过滤请求 【字典表参数签名验证】
  61. if (PathMatcherUtil.matches(Arrays.asList(SignAuthConfiguration.urlList),requestTemplate.path())) {
  62. try {
  63. log.info("============================ [begin] fegin api url ============================");
  64. log.info(requestTemplate.path());
  65. log.info(requestTemplate.method());
  66. String queryLine = requestTemplate.queryLine();
  67. if(queryLine!=null && queryLine.startsWith("?")){
  68. queryLine = queryLine.substring(1);
  69. }
  70. log.info(queryLine);
  71. if(requestTemplate.body()!=null){
  72. log.info(new String(requestTemplate.body()));
  73. }
  74. SortedMap<String, String> allParams = HttpUtils.getAllParams(requestTemplate.path(),queryLine,requestTemplate.body(),requestTemplate.method());
  75. String sign = SignUtil.getParamsSign(allParams);
  76. log.info(" Feign request params sign: {}",sign);
  77. log.info("============================ [end] fegin api url ============================");
  78. requestTemplate.header(CommonConstant.X_SIGN, sign);
  79. requestTemplate.header(CommonConstant.X_TIMESTAMP, DateUtils.getCurrentTimestamp().toString());
  80. } catch (IOException e) {
  81. e.printStackTrace();
  82. }
  83. }
  84. }else{
  85. String token = UserTokenContext.getToken();
  86. log.debug("Feign request token: {}", token);
  87. requestTemplate.header(CommonConstant.X_ACCESS_TOKEN, token);
  88. }
  89. };
  90. }
  91. /**
  92. * Feign 客户端的日志记录,默认级别为NONE
  93. * Logger.Level 的具体级别如下:
  94. * NONE:不记录任何信息
  95. * BASIC:仅记录请求方法、URL以及响应状态码和执行时间
  96. * HEADERS:除了记录 BASIC级别的信息外,还会记录请求和响应的头信息
  97. * FULL:记录所有请求与响应的明细,包括头信息、请求体、元数据
  98. */
  99. @Bean
  100. Logger.Level feignLoggerLevel() {
  101. return Logger.Level.FULL;
  102. }
  103. /**
  104. * Feign支持文件上传
  105. * @param messageConverters
  106. * @return
  107. */
  108. @Bean
  109. @Primary
  110. @Scope("prototype")
  111. public Encoder multipartFormEncoder(ObjectFactory<HttpMessageConverters> messageConverters) {
  112. return new SpringFormEncoder(new SpringEncoder(messageConverters));
  113. }
  114. // update-begin--Author:sunjianlei Date:20210604 for: 给 Feign 添加 FastJson 的解析支持 ----------
  115. @Bean
  116. public Encoder feignEncoder() {
  117. return new SpringEncoder(feignHttpMessageConverter());
  118. }
  119. @Bean
  120. public Decoder feignDecoder() {
  121. return new SpringDecoder(feignHttpMessageConverter());
  122. }
  123. /**
  124. * 设置解码器为fastjson
  125. *
  126. * @return
  127. */
  128. private ObjectFactory<HttpMessageConverters> feignHttpMessageConverter() {
  129. final HttpMessageConverters httpMessageConverters = new HttpMessageConverters(this.getFastJsonConverter());
  130. return () -> httpMessageConverters;
  131. }
  132. private FastJsonHttpMessageConverter getFastJsonConverter() {
  133. FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
  134. List<MediaType> supportedMediaTypes = new ArrayList<>();
  135. MediaType mediaTypeJson = MediaType.valueOf(MediaType.APPLICATION_JSON_VALUE);
  136. supportedMediaTypes.add(mediaTypeJson);
  137. converter.setSupportedMediaTypes(supportedMediaTypes);
  138. FastJsonConfig config = new FastJsonConfig();
  139. config.getSerializeConfig().put(JSON.class, new SwaggerJsonSerializer());
  140. config.setSerializerFeatures(SerializerFeature.DisableCircularReferenceDetect);
  141. converter.setFastJsonConfig(config);
  142. return converter;
  143. }
  144. // update-end--Author:sunjianlei Date:20210604 for: 给 Feign 添加 FastJson 的解析支持 ----------
  145. }