通过@FeignClient调用接口下载文件

欢迎关注微信公众号:

开发使用Feign做微服开发调用客户端时,几乎都是普通接口调用,返回一些JSON数据, 今天刚好要进行Feign客户端(服务消费者)调用服务提供者的文件下载接口,记录一下!代码如下

1、服务提供者:

@RequestMapping(value = "/mindmap", method = RequestMethod.POST)
public ModelAndView exportMindMapPOST(HttpServletResponse response, HttpServletRequest request, String type, String definition, String outline, String title, String chartId, String mind) throws Exception {
  if (!checkMemberFunction(request, chartId, type)) {
    ModelMap map = new ModelMap();
    map.put("result", "error");
    map.put("msg", "验证失败");
    return new ModelAndView("jsonView", map);
  }
  if (Validator.notEmpty(outline) && "outline".equals(outline) &&
    ("image".equals(type) || "opml".equals(type) || "jpg".equals(type) || "pdf".equals(type) || "pos".equals(type))) {
    return outlineExport(response, request, type, definition, title, chartId, "true");
  }
  return mindExport(response, request, type, definition, title, chartId, "true");
}

2、Feign客户端(服务消费者)的代码:

此处需要注意:Response必须引入import feign.Response;

import feign.Response;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;

@FeignClient(name = "processon-image", contextId = "diagramExportService", path = "/chart_image/diagram_export")
public interface DiagramExportService {

    @PostMapping(value = "/mindmap", consumes = MediaType.APPLICATION_PROBLEM_JSON_VALUE)
    Response exportMindMapPOST(@RequestParam(value = "type") String type,
                               @RequestParam(value = "definition") String definition,
                               @RequestParam(value = "outline") String outline,
                               @RequestParam(value = "title") String title,
                               @RequestParam(value = "chartId") String chartId,
                               @RequestParam(value = "mind") String mind,
                               @RequestParam(value = "width") String width,
                               @RequestParam(value = "height") String height,
                               @RequestParam(value = "ignore") String ignore);
}

3、Feign客户端(服务消费者)的Controller接口方法

@PostMapping(value = "/mindmap")
public ResultData exportMindMapPOST(HttpServletResponse response, HttpServletRequest request, String type, String definition, String outline, String title, String chartId, String mind) {
  UserContext uc = null;
  try {
    String token = Arrays.stream(request.getCookies()).filter(v -> v.getName().equals("token")).findFirst().get().getValue();
    uc = TokenUtil.getTokenUserInfo(token);
  } catch (Exception e) {
    throw new APIException(ResultCodeEnum.AUTH_FAIL);
  }

  //鉴权
  ResultData data = authentication(uc, chartId);
  if (!data.isOk()) {
    return data;
  }

  InputStream inputStream = null;
  try {
    log.info("definition:" + definition);
    String definitionEncode = UriUtils.encode(definition, "UTF-8");
    String width = request.getParameter("width");
    String height = request.getParameter("height");
    String ignore = request.getParameter("ignore");
    Response serviceResponse = this.diagramExportService.exportMindMapPOST(type, definitionEncode, outline, title, chartId, mind, width, height, ignore);
    Response.Body body = serviceResponse.body();
    inputStream = body.asInputStream();
    BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
    response.setHeader("Content-Disposition", serviceResponse.headers().get("Content-Disposition").toString().replace("[", "").replace("]", ""));
    BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(response.getOutputStream());
    int length = 0;
    byte[] temp = new byte[1024 * 10];
    while ((length = bufferedInputStream.read(temp)) != -1) {
      bufferedOutputStream.write(temp, 0, length);
    }
    bufferedOutputStream.flush();
    bufferedOutputStream.close();
    bufferedInputStream.close();
    inputStream.close();
  } catch (IOException e) {
    e.printStackTrace();
  }
  return ResultData.OK();
}

此处代码是为了保持服务提供者一致的文件下载输出,其中就包括文件名!

serviceResponse.headers().get("Content-Disposition").toString().replace("[","").replace("]","")

特殊处理部分:

消费者端部分是从Header种取值,所以需要特殊处理请求Feign请求头。加入FeignConfig类。

import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;

@Configuration
public class FeignConfig implements RequestInterceptor {
    /**
     * 复写feign请求对象
     *
     * @param requestTemplate hhh
     */
    @Override
    public void apply(RequestTemplate requestTemplate) {
        //获取请求头
        Map<String, String> headers = getHeaders(Objects.requireNonNull(getHttpServletRequest()));
        for (String headerName : headers.keySet()) {
            requestTemplate.header(headerName, getHeaders(getHttpServletRequest()).get(headerName));
        }
    }

    //获取请求对象
    private HttpServletRequest getHttpServletRequest() {
        try {
            return ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    //拿到请求头信息
    private Map<String, String> getHeaders(HttpServletRequest request) {
        Map<String, String> map = new LinkedHashMap<>();
        Enumeration<String> enumeration = request.getHeaderNames();
        while (enumeration.hasMoreElements()) {
            String key = enumeration.nextElement();
            String value = request.getHeader(key);

            // 切记跳过 content-length。否则会报内容长度不一致的错误。
            if (key.equals("content-length")) {
                continue;
            }

            map.put(key, value);
        }
        return map;
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java技术实践

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值