• SpringCloud Feign通过FallbackFactory显示异常信息


    SpringCloud Feign可以进行服务消费,而且内置了Hystrix,能够进行熔断。
    Feign可以通过fallback指定熔断回调的类。代码示例及讲解可见:
    https://www.cnblogs.com/expiator/p/10826852.html
    但是,有时候我们还需要记录异常信息,可以通过fallbackFactory实现。

    服务提供者

    示例如下:

    @RestController
    public class UserController {
    
            @PostMapping("/user/name/{id}")
            public JSONObject getUserNameById(@PathVariable("id") Integer id ) throws Exception {
                System.out.println("==========================>getUserNameById(),id为:"+id);
                //直接抛异常,是为了方便测试服务熔断和降级。
                throw  new Exception("getUserNameByIdException");
            }
    
           @PostMapping("/user")
           public User getUserById(@RequestParam("id") Integer id  ) throws Exception {
             System.out.println("=====================>getUserById(),id为:"+id);
             throw  new Exception("getUserByIdException");
          }
    
    }
    

    服务消费者

    FeignClient接口

    首先是@FeignClient,属性fallbackFactory指定实现类,如下:

    /**
     *  使用fallbackFactory捕获异常,并进行服务熔断、服务降级。
     */
    @FeignClient(value = "eureka-client",fallbackFactory = UserFeignClientFallbackFactory.class)
    public interface UserFeignClient {
    
        @PostMapping(value = "/user/name/{id}")
        JSONObject getUserNameById(@PathVariable("id") Integer id);
    
        @PostMapping(value = "/user")
        User getUserById(@RequestParam("id") Integer id);
    }
    
    

    FallbackFactory实现类

    接下来是FallbackFactory的实现类,需要重写create()方法,这个方法的参数为Throwable异常类,可以借此记录异常信息。
    create()返回进行服务熔断/降级的Hystrix类。

     @Component
    public class UserFeignClientFallbackFactory implements FallbackFactory<UserFeignClient> {
    
        @Override
        public UserFeignClient create(Throwable cause) {
            System.out.println("=================》fallback reason was:  " + cause.getMessage());
    
            return new UserFeignClientHystrix();
            //也可以不写UserClientFallbackFactory类,直接用匿名对象写成以下形式:
    //        return new UserFeignClient(Integer id) {
    //            @Override
    //            public JSONObject getUserNameById() {
    //                 JSONObject resultJson = new JSONObject();
    //                 resultJson.put("id",  "-1" );
    //                 resultJson.put("name", "null"   );
    //                 return resultJson;
    //            }
    //        };
    
        }
    
    }
    

    FeignClient实现类(也就是Hystrix类)

    Hystrix类如下所示:

    @Component
    public class UserFeignClientHystrix implements UserFeignClient {
    
        /**
         * 服务熔断
         * @param id
         * @return
         */
        @Override
        public JSONObject getUserNameById(Integer id) {
            System.out.println("=======================>UserFeignClientHystrix ");
            JSONObject resultJson = new JSONObject();
            resultJson.put("errCode",  "0404" );
            String description="查询id为"+id+"的用户,服务异常,暂时熔断";
            resultJson.put("description", description  );
            return resultJson;
        }
    
    
        @Override
        public User getUserById(Integer id) {
            System.out.println("=======================>UserFeignClientHystrix ");
             //直接返回id为-1的用户
            User user = new User();
            user.setId(-1);
            return user;
         }
    
    }
    
    

    测试

    启动注册中心,服务提供者,服务消费者。
    访问服务消费者的接口,就能够得到服务提供者抛出的熔断结果和异常信息。
    访问getUserById对应的接口,结果如下:

    访问另一个接口,返回结果如下:

    异常信息如下所示:

    ======================》fallback reason was: {} status 500 reading UserFeignClient#getUserNameById(Integer); content:
    {"timestamp":1557456567128,"status":500,"error":"Internal Server Error","exception":"java.lang.Exception","message":"getUserNameByIdException","path":"/user/name/2"}
    =======================>UserFeignClientHystrix 
    

    可以看到message中的异常getUserNameByIdException,就是我们在服务提供者中抛出的异常。

    完整代码见Github

    https://github.com/firefoxer1992/SpringCloudProject/tree/master/eureka-consumer-feign/src/main/java/com/example/demo

  • 相关阅读:
    SpringMVC使用ResponseEntity实现文件下载,及图片base64的字节数组上传于下载
    File类的createNewFile()和mkdirs() mkdir()
    为什么Java里的Arrays.asList不能用add和remove方法?
    java如何向数组里添加元素
    java里getPath、 getAbsolutePath、getCanonicalPath的区别
    MultipartFile 类
    File类的createNewFile()与createTempFile()的区别
    IntelliJ Idea解决Could not autowire. No beans of 'xxxx' type found的错误提示
    FileInputStream读取的两种方法:逐字节读;以字节数组读取
    JCE cannot authenticate the provider BC
  • 原文地址:https://www.cnblogs.com/expiator/p/10859372.html
Copyright © 2020-2023  润新知