日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Fegin拦截器解决各微服务之间数据下沉

發布時間:2025/3/15 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Fegin拦截器解决各微服务之间数据下沉 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

上篇說了當前端訪問微服務網關,借助ZuulFilter過濾器來過濾所有請求,獲取request,判斷cookie是否有身份短令牌,request的header中是否有Jwt令牌,redis中是否有Jwt令牌。但是這個數據傳遞只能是前端訪問微服務時,網關進行過濾,在微服務訪問微服務時,則沒有數據向下傳遞。

所以我們使用Fegin攔截器來做微服務之間的數據下沉,數據傳遞。

因為在每個微服務使用Fegin遠程調用時都會使用,所以寫在了common包下。

import feign.RequestInterceptor; import feign.RequestTemplate; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes;import javax.servlet.http.HttpServletRequest; import java.util.Enumeration;/** Fegin遠程調用攔截器*/ public class FeignClientInterceptor implements RequestInterceptor {/*** 每次遠程調用都會走這個方法* @param requestTemplate*/@Overridepublic void apply(RequestTemplate requestTemplate) {//的到requst中Header數據ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();if(requestAttributes!=null){HttpServletRequest request = requestAttributes.getRequest();//取出header中的Jwt令牌Enumeration<String> headerNames = request.getHeaderNames();if(headerNames!=null){while(headerNames.hasMoreElements()){String headerName = headerNames.nextElement();String headerValue = request.getHeader(headerName);//向下傳遞requestTemplate.header(headerName,headerValue);}}}}}

可以從代碼中看到,implements RequestInterceptor每個微服務遠程調用都會走下面的實現方法,在apply()方法中,我們獲取當前的request中Header中所有數據,然后用requestTemplate.header(headerName,headerValue) 將所有數據下沉。

?

所以在使用fegin遠程調用時是可以這樣利用fegin攔截器進行數據下沉的,但是在使用別的方法遠程調用微服務時這個攔截器是不會處理的。

比如說,當我們使用的是restTemplate進行遠程調用時,

//注入restTemplate@Bean@LoadBalanced//開啟客戶端負載均衡public RestTemplate restTemplate(){return new RestTemplate(new OkHttp3ClientHttpRequestFactory());} //rest遠程獲取數據ResponseEntity<Map> forEntity = restTemplate.getForEntity(dataUrl, Map.class);

此時進行數據下沉需要進行數據處理,借助request中header的HttpEntity進行數據存儲,數據傳遞。

比如

private AuthToken applyToken(String clientId, String clientSecret, String username, String password) {//獲取認證服務 的微服務實例ServiceInstance serviceInstance = loadBalancerClient.choose(XcServiceList.XC_SERVICE_UCENTER_AUTH);if (serviceInstance == null) {LOGGER.error("choose an auth instance fail");ExceptionCast.cast(AuthCode.AUTH_LOGIN_AUTHSERVER_NOTFOUND);}// http://IP:port/URI uri = serviceInstance.getUri();String authUrl = uri + "/auth/oauth/token";//HttpEntity//bodyLinkedMultiValueMap<String, String> body = new LinkedMultiValueMap<>();body.add("grant_type","password");body.add("username",username);body.add("password",password);//headersLinkedMultiValueMap<String, String> header = new LinkedMultiValueMap<>();header.add("Authorization",getHttpBasic(clientId,clientSecret));HttpEntity<MultiValueMap<String, String>> httpEntity = new HttpEntity<>(body, header);//設置restTemplate遠程調用時,對400,401錯誤不報錯,正確返回數據restTemplate.setErrorHandler(new DefaultResponseErrorHandler(){@Overridepublic void handleError(ClientHttpResponse response) throws IOException {if(response.getRawStatusCode()!=400&&response.getRawStatusCode()!=401){super.handleError(response);}}});//申請令牌的信息Map map = null;try {ResponseEntity<Map> bodyMap = restTemplate.exchange(authUrl, HttpMethod.POST, httpEntity, Map.class);map = bodyMap.getBody();} catch (RestClientException e) {e.printStackTrace();LOGGER.error("request oauth_token_password error: {}",e.getMessage());e.printStackTrace();ExceptionCast.cast(AuthCode.AUTH_LOGIN_APPLYTOKEN_FAIL);}if(map == null ||map.get("access_token") == null ||map.get("refresh_token") == null ||map.get("jti") == null){//確定用戶名 或者 密碼錯誤異常拋出if(map!=null){String error_description = (String) map.get("error_description");if(error_description.indexOf("UserDetailsService returned null")>=0){ExceptionCast.cast(AuthCode.AUTH_ACCOUNT_NOTEXISTS);}else if(error_description.indexOf("壞的憑證")>=0){ExceptionCast.cast(AuthCode.AUTH_CREDENTIAL_ERROR);}}//jti是jwt令牌的唯一標識作為用戶身份令牌ExceptionCast.cast(AuthCode.AUTH_LOGIN_APPLYTOKEN_FAIL);}AuthToken authToken = new AuthToken();//訪問令牌(jwt)String jwt_token = (String) map.get("access_token");//刷新令牌(jwt)String refresh_token = (String) map.get("refresh_token");//jti,作為用戶的身份標識String access_token = (String) map.get("jti");authToken.setJwt_token(jwt_token);authToken.setAccess_token(access_token);authToken.setRefresh_token(refresh_token);return authToken;}

?

總結

以上是生活随笔為你收集整理的Fegin拦截器解决各微服务之间数据下沉的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。