Feign经典错误

Incompatible fallbackFactory instance. Fallback/fallbackFactory of type clas

失败原因:是我用的是fallbackFactory来进行回退,但是feignclient注解定义回退的类型是fallback,类型不一致。在调用报错时会校验fallabck或fallbackFactory是不是符合要求
正常fallback模式示例

@FeignClient(name = "mall-shop-e",
        url = "${feign.urls.mall-shop-e:}",
        fallback = MallOrderEClientFallback.class,
        configuration = FeignConfiguration.class)
public interface MallOrderEClient {

    @PostMapping("/rpc/external/channelPrice/get/list")
    public CommonResult<PageWrapper<List<ChannelPriceVo>>> queryChannelPriceList(@RequestBody ChannelPriceSearchReq req);
}



@Slf4j
@Component
public class MallOrderEClientFallback implements MallOrderEClient{
    @Override
    public CommonResult<PageWrapper<List<ChannelPriceVo>>> queryChannelPriceList(ChannelPriceSearchReq req) {
        return null;
    }
}

正常fallbackfactory示例。与fallback相比可以获取回滚的原因

@FeignClient(name = "finance-product",
        contextId = "MallPaymentClient",
        fallbackFactory = com.fosunhealth.orcas.service.feign.MallPaymentClientFallback.class,
        configuration = FeignConfiguration.class)
public interface MallPaymentClient {

    /**
     * 获取业务单元列表
     */
    @PostMapping("/rpc/costRelationManager/costRelationDetail")
    Result<CostRelationDetailResp> getBusinessUintList();

}


@Slf4j
@Component
public class MallPaymentClientFallback implements FallbackFactory<MallPaymentClient> {
    @Override
    public MallPaymentClient create(Throwable cause) {
        return new MallPaymentClient() {
            @Override
            public Result<CostRelationDetailResp> getBusinessUintList() {
                log.error("getBusinessUintList error ", cause);
                return null;
            }
        };
    }
}

上传文件使用Feign在不同服务之间传递

    /**
     * 导入
     * @param file 文件
     * @return
     */
    @PostMapping(value = "/import", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public CommonResult<ImportResp> imports(@RequestPart("file") MultipartFile file,@RequestParam String userName);

主要是consumes = MediaType.MULTIPART_FORM_DATA_VALUE 。不加上这个就无法在服务之间传递文件

feign导出文件如何传递

服务提供方

    /**
     * 导出报表
     * @param response
     */
    @PostMapping("export")
    public void export(HttpServletResponse response,BizProjectPriceSearchReq req){
        bizProjectPriceService.export(response,req);
    }

feignclient内

    /**
     * 导出报表
     */
    @PostMapping("export")
    public Response export(BizProjectPriceSearchReq req);

导出文件处理

  /**
     * 导出报表
     * @param response
     */
    public void export(HttpServletResponse response, BizProjectPriceSearchReq req){
        Response feignResponse = projectPriceClient.export(req);
        if (!CollectionUtils.isEmpty(feignResponse.headers().get("content-type"))) {
            response.setHeader("content-type", feignResponse.headers().get("content-type").stream().findFirst().get());
        }
        if (!CollectionUtils.isEmpty(feignResponse.headers().get("content-disposition"))) {
            response.setHeader("Content-disposition", feignResponse.headers().get("content-disposition").stream().findFirst().get());
        }
        response.setCharacterEncoding("utf-8");

        Response.Body body = feignResponse.body();
        InputStream fileInputStream = null;
        OutputStream outputStream = null;
        try {
            fileInputStream = body.asInputStream();
            outputStream = response.getOutputStream();
            byte[] bytes = new byte[1024];
            int len;
            while ((len = fileInputStream.read(bytes)) != -1) {
                outputStream.write(bytes, 0, len);
            }
        } catch (Exception e) {
            log.warn("export throw exception e={}", e);
        } finally {
            try {
                if (fileInputStream != null) {
                    fileInputStream.close();
                }
                if (outputStream != null) {
                    outputStream.close();
                    outputStream.flush();
                }
            } catch (Exception e) {
                log.error("export close stream throw exception e={}", e);
            }
        }

    }

前端
如何请求
![image.png](https://img-blog.csdnimg.cn/img_convert/fc8125b830038646f99c0a55bb63c62b.png#clientId=u08b83371-430a-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=249&id=u745249a6&margin=[object Object]&name=image.png&originHeight=498&originWidth=1332&originalType=binary&ratio=1&rotation=0&showTitle=false&size=69467&status=done&style=none&taskId=uaedb6609-42b5-4c94-b6ae-964074c70d0&title=&width=666)
如何接收

export function downloadFile(res, type, fileName) {
  const blob = new Blob([res.data], {type: type||'application/octet-stream'});
  console.log('blob', blob);
  const downloadElement = document.createElement('a');
  const href = window.URL.createObjectURL(blob);
  const contentDisposition=res.headers['content-disposition'];
  let subIndex=contentDisposition.lastIndexOf('\'');
  if (subIndex==-1) {
    subIndex=contentDisposition.lastIndexOf('=');
  }
  downloadElement.download = fileName||decodeURIComponent(contentDisposition.substring(subIndex+1));
  downloadElement.href = href;
  document.body.appendChild(downloadElement);
  downloadElement.click();
  document.body.removeChild(downloadElement);
  window.URL.revokeObjectURL(href);
}

Body parameters cannot be used with form parameters

传递文件时,其他参数也需要使用@RequestParam

/**
* 导入
* @param file 文件
* @return
*/
@PostMapping(value = "/import", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public CommonResult<ImportResp> imports(@RequestPart("file") MultipartFile file,@RequestParam String userName);

请求方式为get但是提示为Request method ‘POST’ not supported"

"errMsg":"org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported"}

原因就是为在声明时未使用@RequestParam

    public CommonResult<ChannelPriceGoodsInfoVO> channelPriceInfo( Long id);
Feign是一个声明式的HTTP客户端,它简化了HTTP客户端的开发。在使用Feign进行服务调用时,我们可能会遇到一些异常,例如HTTP响应码不是200,或者响应体格式不符合预期等等。为了更好地处理这些异常情况,我们可以自定义一个ErrorDecoder来处理错误响应。下面是一个示例: ```java public class MyErrorDecoder implements ErrorDecoder { @Override public Exception decode(String methodKey, Response response) { Exception exception = null; try { // 解析响应体中的错误信息 String body = Util.toString(response.body().asReader()); JSONObject json = JSONObject.parseObject(body); String errorMsg = json.getString("msg"); // 根据响应码选择不同的异常类型 if (response.status() == 400) { exception = new BadRequestException(errorMsg); } else if (response.status() == 401) { exception = new UnauthorizedException(errorMsg); } else if (response.status() == 404) { exception = new NotFoundException(errorMsg); } else if (response.status() == 500) { exception = new InternalServerErrorException(errorMsg); } } catch (IOException e) { exception = new RuntimeException(e); } if (exception != null) { return exception; } // 返回默认的异常 return new FeignException.Default( response.status(), response.reason(), response.request().url(), null); } } ``` 在上面的示例中,我们自定义了一个MyErrorDecoder类实现了Feign的ErrorDecoder接口,并实现了其中的decode方法。在该方法中,我们首先解析了响应体中的错误信息,然后根据响应码选择不同的异常类型进行抛出。如果响应码不在我们预期的范围内,则返回默认的异常类型。 接着,在使用Feign进行服务调用时,我们可以通过@FeignClient注解的errorDecoder属性指定我们自定义的ErrorDecoder类,如下所示: ```java @FeignClient(name = "example-service", errorDecoder = MyErrorDecoder.class) public interface ExampleServiceClient { @RequestMapping(value = "/example", method = RequestMethod.GET) String getExample(); } ``` 这样,在服务调用时,如果遇到了异常情况,就会调用我们自定义的ErrorDecoder类来处理错误响应,并抛出对应的异常。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值