天天看點

springcloud中的feign使用

我們使用springcloud的feign,可以讓我們像調用本地方法似的調用遠端方法,就和dubbo類似。但是,使用feign的時候,

我們要注意幾點。

首先,我們要開啟feign。

@EnableFeignClients
           

該注解就可以開啟feign功能。

使用feign的時候,參數上我們一定要加@RequestParam,@RequestBody等注解,不然的話就會報錯。

使用方法:

@FeignClient(name = "projectName", path = "projectName")
public interface Facade{
    @RequestMapping(value="/test",method=RequestMethod.GET)
    @ResponseBody
    String test(@RequestParam("testParam")String testParam);
           

@FeignClient裡面指定要調用的工程的工程名,就是springboot的配置檔案中配置的應用名

spring.application.name=projectName
           

它會根據應用名在服務注冊中心查找到該應用的通路位址。

@RequestMapping()  指定的是通路方法的路徑

@RequestParam()     這裡要注意,如果使用feign,一定要在參數上加上這樣的注解,不然會出錯。

定義好接口後,隻要在projectName的應用中,引入該接口jar包,實作該接口,就可以了,不過要在參數上加注解,不必在實作類中加其他注解了。

然後調用方,引入該接口jar包,然後使用該接口直接像本地方法調用就可以直接調用projectName中的方法實作了。

還有一點,因為feign調用出錯後,傳回的資訊亂七八糟的,包含很多html格式,是以我們可以定義一個切面,在feign出錯的時候,通過該切面

解析一下傳回的出錯資訊就可以了。

@Component
@Aspect
public class ExceptionAdvice {
    private static final String prefix = "content:\n{";
    private static final int prefixLength = prefix.length();
    private static final String suffix = "}";
    private static final JsonParser jsonParser = new JacksonJsonParser();

    @AfterThrowing(value = "execution(
            "!execution(* (@org.springframework.web.bind.annotation.RestController *).*(..))" +
            "&& !execution(* (@org.springframework.stereotype.Controller *).*(..))", throwing="e")
    public Object afterThrowing(Throwable e) throws Throwable {
        if (e instanceof FeignException) {
            String m = e.getMessage();
            if (m.indexOf(prefix) != -1) {
                String s = m.substring(m.indexOf(prefix) + prefixLength - 1, m.indexOf(suffix) + 1);
                Map<String, Object> resMap = jsonParser.parseMap(s);
                String exceptionName = (String) resMap.get("exception");
                String message = (String) resMap.get("message");
                Class<Throwable> throwableClass;
                try {
                    throwableClass = (Class<Throwable>) Class.forName(exceptionName);
                } catch (ClassNotFoundException e1) {
                    throw new Exception(message);
                }

                Constructor<Throwable> constructor = throwableClass.getConstructor(String.class);
                Throwable throwable = constructor.newInstance(resMap.get("message"));
                throw throwable;
            }
        }

        throw e;
    }
}