Spring boot项目中自定义FeignClient的拦截器处理header和签名等信息

2023年6月3日08:09:56

我们在请求第三方接口的时候通常由比较复杂但是统一的header和签名计算的一系列处理。这个时候就可以使用RequestInterceptor来实现。上代码:

@Slf4j
@Configuration  // a  global feign client interceptor
public class FeignClientsConfigurationInterceptor implements RequestInterceptor {

    @Override
    public void apply(RequestTemplate template) {
        try {
            log.info("=======  FeignClientsConfigurationInterceptor ========");
//反序列化request body,拿到核心的参数projectId,用来获得请求接口用的appkey和appId
JSONObject requestBody= (JSONObject) JSON.parse(new String(template.body()));
            String projectId = (String) requestBody.get("projectId");
//过河拆桥,把projectId从 request body 移除(因为这个参数只是我方程序获取密钥时需要,但请求地第三方接口不需要)
            requestBody.remove("projectId");
            log.info("projectId =" + projectId);
            PingAnKeyProperties pingAnKeyProperties = PingAnKeyProperties.getPingAnKeys(projectId);
            String apiUrl = template.url();
            log.info("apiUrl =" + apiUrl);
            String app_id = pingAnKeyProperties.getAppId();
            String app_key= pingAnKeyProperties.getAppKey();

            log.info("app_id =" + app_id);
            log.info("app_key =" + app_key);
            String deviceId =SignUtils.getLocalMac();
            String timestamp = Long.toString(System.currentTimeMillis());
            Map<String, String> headers = new HashMap();
            headers.put("X-Appid", app_id);
            headers.put("Content-Type", "application/json;charset=utf-8");

            Iterator<String> it =  headers.keySet().iterator();
            while (it.hasNext()) {
                String header_key = it.next();
                template.header(header_key, headers.get(header_key));
            }
            String method = template.method();
            String bodyText = requestBody.toJSONString();
//使用template.body(bodyText) API重置移除projectId之后的reqeust body
            template.body(bodyText);    //reset body text
            String body_content = new String(template.body());
            log.debug("body_content = "+ body_content);
            String body_hash = SignUtils.SHA(body_content, "SHA-256");
//            log.info(body_hash);
            String sign_data = SignUtils.getSign(method,
                    apiUrl,
                    "", headers, body_hash,app_key);
            template.header("X-Authorization",
                    sign_data.toLowerCase());
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        log.info("===============");
    }
}

 总结:通过RequestTemplate对象我们可以拿到reqeust的几乎所有参数,url, reqeust body,method等等,熟悉RequestTemplate的API就能比较轻松的实现对原reqeust的拦截和改造。我是试了好久才找到重置requestbody的API原来是下面的方法,附源码截图:

  • 作者:麦宝萌宝都是宝宝的宝
  • 原文链接:https://blog.csdn.net/mablemengm/article/details/120647759
    更新时间:2023年6月3日08:09:56 ,共 2103 字。