最近在使用Feign,总结了一下使用经验
@FeignClient(name = "NormalFeignClient", url = "localhost:9004/check") public interface NormalFeginClient { @GetMapping("userValidGet") Response normalGet(@RequestParam("userId") String userId, @RequestParam("userName") String userName); @GetMapping("userValidGet") Response mapGet(@HeaderMap Map<String, Object> headerMap, @SpringQueryMap Map<String, Object> requestMap); @GetMapping("userValidGet") Response pojoGet(@HeaderMap Map<String, Object> headerMap, @SpringQueryMap User user); @PostMapping("testAspectUserValidPost") Response normalPost(@RequestBody Map<String, Object> request); @PostMapping("testAspectUserValidPost") Response pojoPost(@HeaderMap Map<String, Object> headerMap, @SpringQueryMap User user); }
@GetMapping(value = "/thirdService") public Response requestThirdService(HttpServletRequest req) { String message = "test Jpa Message"; String result = "test Jpa Result"; Map<String, Object> headerMap = new HashMap<>(); headerMap.put("a", "A"); headerMap.put("a1", "A1"); Map<String, Object> requestMap = new HashMap<>(); requestMap.put("userId", "A"); requestMap.put("userName", "zero"); User user = new User(); user.setUserId("A"); user.setUserName("zero"); feign.Response requestResult1 = normalFeginClient.normalGet("A", "zero"); feign.Response requestResult2 = normalFeginClient.mapGet(headerMap, requestMap); feign.Response requestResult3 = normalFeginClient.pojoGet(headerMap, user); feign.Response requestResult4 = normalFeginClient.normalPost(requestMap); feign.Response requestResult5 = normalFeginClient.pojoPost(headerMap, user); System.out.println(FeignUtil.feignResponseBody(requestResult1)); System.out.println(FeignUtil.feignResponseBody(requestResult2)); System.out.println(FeignUtil.feignResponseBody(requestResult3)); System.out.println(FeignUtil.feignResponseBody(requestResult4)); System.out.println(FeignUtil.feignResponseBody(requestResult5)); return Response.ok(message).setData(result); }
{"code":"ok","data":"Hello zero","requestid":"d56b56a443a64b69b2b9cb22a9761532"} {"timestamp":"2020-04-13T09:52:57.842+0000","status":405,"error":"Method Not Allowed","message":"Request method 'POST' not supported","path":"/check/userValidGet"} {"timestamp":"2020-04-13T09:52:57.848+0000","status":405,"error":"Method Not Allowed","message":"Request method 'POST' not supported","path":"/check/userValidGet"} {"code":"ok","data":"Hello null","requestid":"b27fdf522c2943f6b750ecb770db0aa1"} {"code":"ok","data":"Hello null","requestid":"c50a2333b2ba4840ab77215fa1fc4ae9"}
在上面的调用中我们发现以这种方式调用有很多问题,调用地址无法动态修改,Get只要加上@HeaderMap就会被识别为POST方式调用,为了解决这些问题,有了以下方法
注解使用 @RequestLine,参数里应按指定格式
@QueryMap参数定义名称-值对(或POJO)的映射,展开后成为字符串,可以用于Get方式传递参数
@FeignClient(name = "CustomerFeignClient") public interface CustomerFeignClient { @RequestLine("GET") Response get(URI baseUri, @HeaderMap Map<String, Object> headerMap, @QueryMap Map<String, Object> requestMap); @RequestLine("POST") Response post(URI baseUri, @HeaderMap Map<String, Object> headerMap, @RequestBody Map<String, Object> request); }
有两点需要注意
package com.mantis.brac.common.feign; import com.mantis.brac.common.exception.BracBusinessException; import com.mantis.brac.common.http.RequestEnum; import feign.Feign; import feign.Response; import feign.Target; import feign.codec.Decoder; import feign.codec.Encoder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.openfeign.FeignClientsConfiguration; import org.springframework.context.annotation.Import; import org.springframework.stereotype.Component; import java.net.URI; import java.net.URISyntaxException; import java.util.Map; @Component @Import(FeignClientsConfiguration.class) public class CustomerFeignConfig { private CustomerFeignClient bracFeignClient; private String uri; private RequestEnum requestType; private Map<String, Object> header; private Map<String, Object> request; /** * 在构造函数中用 @Autowired 引入自定义参数和编解码器 * @param encoder * @param decoder */ @Autowired public CustomerFeignConfig(Encoder encoder, Decoder decoder) { bracFeignClient = Feign.builder().encoder(encoder).decoder(decoder) .target(Target.EmptyTarget.create(CustomerFeignClient.class)); } public CustomerFeignConfig get() { this.setRequestType(RequestEnum.GET); return this; } public CustomerFeignConfig post() { this.setRequestType(RequestEnum.POST); return this; } /** * 执行调用方法 * * @return */ public Response execute() { switch (getRequestType()) { case GET: return bracFeignClient.get(findUri(getUri()), getHeader(), getRequest()); case POST: return bracFeignClient.post(findUri(getUri()), getHeader(), getRequest()); default: throw new BracBusinessException("请选择调用方式!"); } } public String getUri() { return uri; } public CustomerFeignConfig setUri(String uri) { if (uri == null) { throw new BracBusinessException("uri == null"); } else { this.uri = uri; } return this; } public Map<String, Object> getRequest() { return request; } public CustomerFeignConfig setRequest(Map<String, Object> request) { this.request = request; return this; } public RequestEnum getRequestType() { return requestType; } public void setRequestType(RequestEnum requestType) { this.requestType = requestType; } public Map<String, Object> getHeader() { return header; } public CustomerFeignConfig setHeader(Map<String, Object> header) { this.header = header; return this; } /** * 获取请求URI * * @param uri * @return */ private URI findUri(String uri) { try { return new URI(uri); } catch (URISyntaxException e) { e.printStackTrace(); } throw new BracBusinessException("获取请求地址失败!"); } }
@Autowired CustomerFeignConfig customerFeignConfig; @PostMapping(value = "/lookup/customer/thirdService") public Response postQueryThirdService(HttpServletRequest req) { String message = "Message"; String result = "Result"; StringBuilder reqJson = JsonUtil.getJson(req); Map<String, Object> headerMap = new HashMap<>(); headerMap.put("a", "A"); headerMap.put("a1", "A1"); Map<String, Object> requestMap = new HashMap<>(); requestMap.put("userId", "A"); requestMap.put("userName", "zero"); feign.Response requestResult1 = customerFeignConfig.setHeader(headerMap).setUri("http://localhost:9004/check/userValidGet").setRequest(requestMap).get().execute(); feign.Response requestResult2 = customerFeignConfig.setHeader(headerMap).setUri("http://localhost:9004/check/testAspectUserValidPost").setRequest(requestMap).post().execute(); System.out.println(FeignUtil.feignResponseBody(requestResult1)); System.out.println(FeignUtil.feignResponseBody(requestResult2)); return Response.ok(message).setData(result); }
我们可以发现数据请求参数和Header正常传递
返回结果也可以正常拿到
{"code":"ok","data":"Hello zero","requestid":"3afdaf854b0946edb5b035c09198081e"} {"code":"ok","data":"Hello null","requestid":"6b4ec0b79ab94e67b182ac9fae9adf7c"}
git@github.com:A-mantis/brac-project-service.git