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