禁止粘貼的網(wǎng)站如何優(yōu)化搜索引擎的準(zhǔn)確性
背景
最近在編寫多個(gè)系統(tǒng)數(shù)據(jù)集成過(guò)程中,經(jīng)常會(huì)使用到@FeignClient注解標(biāo)記一個(gè)類,類里面編寫很多請(qǐng)求方法,如果第三方系統(tǒng)有非常多的URL請(qǐng)求,每個(gè)方法對(duì)應(yīng)一個(gè)URL請(qǐng)求,那么這個(gè)類就會(huì)非常的龐大,是否有一種方法能夠動(dòng)態(tài)的設(shè)置URL,只需要編寫一個(gè)或者兩三個(gè)通用的方法解決這個(gè)問(wèn)題,筆者最近就在項(xiàng)目中親測(cè)過(guò)以下封裝方式。
最初的方式
假如有一個(gè)TestFeignClient,如下所示:
@FeignClient(name = "test", url = "http://localhost", contextId = "testFeignClient")
public interface TestFeignClient {/*** 獲取產(chǎn)品列表數(shù)據(jù)** @param map* @return*/@PostMapping(value = "/api/v1/getProductList")String getProductList(@RequestBody Map<String, Object> map);/*** 獲取訂單列表數(shù)據(jù)** @param map* @return*/@PostMapping(value = "/api/v1/getOrderList")String getOrderList(@RequestBody Map<String, Object> map);
}
以上,如果這個(gè)TestFeignClient方法特別多,這個(gè)類會(huì)非常龐大
改進(jìn)的方式
將TestFeignClient中兩個(gè)方法統(tǒng)一封裝成一個(gè)doPost方法,只需要傳遞URL請(qǐng)求參數(shù)到Map集合中即可通過(guò)攔截器自動(dòng)替換,從而做到了通用,如下:
@FeignClient(name = "test", url = "http://localhost", contextId = "testFeignClient", configuration = TestConfiguration.class)
public interface TestCommonFeignClient {/*** POST通用請(qǐng)求** @param map* @return*/@PostMapping(value = "templateReqUrlKey")String doPost( @RequestBody Map<String, Object> map);
}
關(guān)鍵類在于TestConfiguration攔截并在請(qǐng)求之前替換了對(duì)應(yīng)的真實(shí)URL,大致代碼如下:
@Slf4j
@AllArgsConstructor
public class TestConfiguration {public final ObjectMapper objectMapper;@Beanpublic Retryer retryer() {return new TestRetryer();}/*** 配置請(qǐng)求攔截器** @return*/@Beanpublic RequestInterceptor testRequestInterceptor() {return template -> {template.header("Content-Type", "application/json");if (template.method().equals(Request.HttpMethod.POST.name())) {String body = new String(template.body(), StandardCharsets.UTF_8);Map<String, Object> bodyMap = new HashMap<>();try {bodyMap = objectMapper.readValue(body,new TypeReference<Map<String, Object>>() {});} catch (JsonProcessingException e) {log.error("json解析出錯(cuò),", e);}String srcUrl = template.url();String templateUrl = "";if (bodyMap.containsKey("templateReqUrlKey") && srcUrl.contains("templateReqUrlKey")) {templateUrl = bodyMap.get("templateReqUrlKey").toString();template.uri(templateUrl);}bodyMap.remove("templateReqUrlKey");template.body(JSONUtil.toJsonStr(bodyMap));}};}@Beanpublic Decoder decoder() {return (response, type) -> {String resultStr = IOUtils.toString(response.body().asInputStream(), String.valueOf(StandardCharsets.UTF_8));JSONObject obj = JSONUtil.parseObj(resultStr);String code = obj.get("code").toString();if (Objects.equals("200", code)) {// TODO throw new RetryableException(500, obj.getStr("msg"), response.request().httpMethod(), null, response.request());}return resultStr;};}}
以上攔截器testRequestInterceptor中替換了原始templateReqUrlKey,從而實(shí)現(xiàn)了客戶端設(shè)置真實(shí)url到bodyMap中,請(qǐng)求之前替換templateReqUrlKey,這樣就比較靈活的應(yīng)對(duì)第三方系統(tǒng)數(shù)據(jù)集成。
最后
以上提到的bodyMap可設(shè)置真實(shí)的URL地址,筆者將這個(gè)真實(shí)URL地址做成了一個(gè)config配置表存儲(chǔ),每次獲取對(duì)應(yīng)接口的URL即可,同時(shí)筆者將bodyMap中整個(gè)URL請(qǐng)求的json數(shù)據(jù)都可以做成配置,完全做到了只需要修改數(shù)據(jù)庫(kù)配置表,即可完成接口數(shù)據(jù)集成,實(shí)現(xiàn)了動(dòng)態(tài)控制請(qǐng)求,有興趣的可嘗試。