Vue获取并显示后端Feign返回的Activiti图片流

作者: 小疯子 分类: Feign,Java,Vue 发布时间: 2020-03-07 14:25

背景

Java后台生成Activiti流程图后,将图片流传送给vue前端,前端进行显示

1. Java端

A. Feign消费方

a1. 控制层端

@GetMapping(value = "/show_diagram")
    public void showDiagram(@RequestParam String processInstanceId,HttpServletResponse servletResponse){
        Response response = activitiConsumer.showDiagram(processInstanceId); // 通过consumer调用feign服务提供方
        Response.Body body = response.body(); // Response是feign.Response

        InputStream fileInputStream = null;
        OutputStream outStream;
        try {
            fileInputStream = body.asInputStream();
            outStream = servletResponse.getOutputStream();

            byte[] bytes = new byte[1024];
            int len = 0;
            while ((len = fileInputStream.read(bytes)) != -1) {
                outStream.write(bytes, 0, len);
            }
            fileInputStream.close();
            outStream.close();
            outStream.flush();
        } catch (Exception e) {

        }
    }

a2. consumer层
注意其中的Response需得是feign.Response

@GetMapping(value = "/user_activiti/show_diagram",consumes = MediaType.IMAGE_PNG_VALUE)
    Response showDiagram(@RequestParam(value = "processInstanceId") String processInstanceId);

B. feign服务提供方

b1. provider

// 显示流程图
    @GetMapping(value = "/show_diagram",produces = MediaType.IMAGE_PNG_VALUE)
    @ResponseStatus(HttpStatus.NO_CONTENT)
    public void showDiagram(@RequestParam String processInstanceId, HttpServletResponse response) {
        vacationBusiness.showDiagram(processInstanceId, response);
        return;
    }

b2. business获取diagram流到response中

@Override
    public void showDiagram(String processInstanceId, HttpServletResponse response) {
        OutputStream out = null;
        try {
            InputStream is = vacationProcessService.getDiagram(processInstanceId);
//            response.setContentType("multipart/form-data;charset=utf8");
            response.setContentType("image/png");
            out = response.getOutputStream();
            out.write(IOUtils.getImgByte(is));
            out.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                out.close();
            } catch (Exception e) {
            }
        }
    }

b3. activiti获取流程图

@Override
    public InputStream getDiagram(String processInstanceId) {
        // 查询流程实例
        ProcessInstance pi = this.runtimeService.createProcessInstanceQuery()
                .processInstanceId(processInstanceId).singleResult();
        // 查询流程实例
        ProcessDefinition pd = repositoryService.createProcessDefinitionQuery()
                .processDefinitionId(pi.getProcessDefinitionId()).singleResult();
        // 获取BPMN模型对象
        BpmnModel model = repositoryService.getBpmnModel(pd.getId());
        // 定义使用宋体
        String fontName = "宋体";
        // 获取流程实实例当前点的节点,需要高亮显示
        List currentActs = runtimeService.getActiveActivityIds(pi.getId());
        // BPMN模型对象、图片类型、显示的节点
        InputStream is = this.processEngine
                .getProcessEngineConfiguration()
                .getProcessDiagramGenerator()
                .generateDiagram(model, "png", currentActs, new ArrayList(),
                        fontName, fontName, fontName,null, 1.0);
        return is;
    }

2. Vue前端

2.1 访问请求

// 查看流程图
export const showDiagram = (params) => {
    return axios.request({
        url: /admin-api/user_activiti/show_diagram,
        method: 'get',
        responseType: 'arraybuffer', // 留意这个需要是arraybuffer
        params
      })
}

2.2 vue页面

<img :src="diagramUrl"/>
<script>
showdetail(v) {
                this.diagramModalVisible = true
                showDiagram({'processInstanceId': v.processInstanceId})
                .then(response => {
                // 流处理以下
                    return 'data:image/png;base64,' + btoa(
                    new Uint8Array(response)
                        .reduce((data, byte) => data + String.fromCharCode(byte), '')
                    );
                })
                .then(res => {
                // 图片显示
                    alert(JSON.stringify(res))
                    this.diagramUrl = res
                })
            }
</script>

参考链接

  1. vue axios请求图片流文件前端页面显示处理方法
  2. feign响应Image流对象
  3. feign文件下载遇到的坑
0