欢迎关注微信公众号:
开发使用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;
}
}