Feign经典错误

December 17, 2023
测试
测试
测试
测试
10 分钟阅读

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);
            }
        }

    }

前端 如何请求

如何接收

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);

继续阅读

更多来自我们博客的帖子

如何安装 BuddyPress
由 测试 December 17, 2023
经过差不多一年的开发,BuddyPress 这个基于 WordPress Mu 的 SNS 插件正式版终于发布了。BuddyPress...
阅读更多
Filter如何工作
由 测试 December 17, 2023
在 web.xml...
阅读更多
如何理解CGAffineTransform
由 测试 December 17, 2023
CGAffineTransform A structure for holding an affine transformation matrix. ...
阅读更多