MarkDown版本:http://www.reibang.com/p/c1fb9324b476
flowable每個節(jié)點(diǎn)自帶的屬性是有限的芽狗,而在實(shí)際業(yè)務(wù)中可能會遇到一些比較適合配置到各個節(jié)點(diǎn)屬性,但是自帶屬性里面又沒有的禁筏,所以這個時(shí)候我們就需要自己自定義屬性了,這里主要記錄下自己處理的過程喷兼,方便以后遇到該問題好查閱碎紊。
修改前端
? ? ?(1).修改文件:stencilset_bpmn.json
? ? ?(2).新增2個屬性:
? ? ?(3).把新增的屬性添加到UserTask 節(jié)點(diǎn)
? ? 前端修改之后頁面的效果:
這樣配好之后我們?nèi)ハ螺dxml的時(shí)候會發(fā)現(xiàn)沒有這兩個新增的屬性,這個時(shí)候在流程實(shí)例流轉(zhuǎn)的時(shí)候也是獲取不到新增屬性的值的搞乏。
是因?yàn)閒lowable并沒有支持自定義屬性的存儲,所以這個時(shí)候就要自己對自定義屬性進(jìn)行解析了戒努。
后端修改
?(1).我們可以從頁面找到下載的請求路徑请敦。可以看到是app/rest/models/**
因?yàn)槭窃创a我這邊為了盡量不改他的源碼储玫,所以自己修改了請求地址侍筛,自己寫了下載的實(shí)現(xiàn)。
修改url-config跳轉(zhuǎn)地址:app/rest/models/** 改成? XX/app/rest/models/**
(2).新建ModelController 繼承 AbstractModelBpmnResource:
@RestController
@RequestMapping("/XX/app")
//@Transactional
public class ModelControllerextends AbstractModelBpmnResource {
private static final Logger LOGGER = LoggerFactory.getLogger(ModelController.class);
? ? @Autowired
protected XXModelServiceImpl?xxModelService;
? ? /**
* GET /rest/models/{modelId}/bpmn20 -> Get BPMN 2.0 xml
*/
? ? @RequestMapping(value ="/rest/models/{processModelId}/bpmn20", method = RequestMethod.GET)
public void getProcessModelBpmn20Xml(HttpServletResponse response, @PathVariable String processModelId)throws IOException {
LOGGER.info("開始下載xml文件1");
? ? ? ? if (processModelId ==null) {
throw new BadRequestException("No process model id provided");
? ? ? ? }
Model model = xxModelService.getModel(processModelId);
? ? ? ? generateBpmn20Xml(response, model);
? ? }
protected void generateBpmn20Xml(HttpServletResponse response, AbstractModel model) {
String name = model.getName().replaceAll(" ", "_") +".bpmn20.xml";
? ? ? ? String encodedName =null;
? ? ? ? try {
encodedName ="UTF-8''" + URLEncoder.encode(name, "UTF-8");
? ? ? ? }catch (Exception e) {
LOGGER.warn("Failed to encode name " + name);
? ? ? ? }
String contentDispositionValue ="attachment; filename=" + name;
? ? ? ? if (encodedName !=null) {
contentDispositionValue +="; filename*=" + encodedName;
? ? ? ? }
response.setHeader("Content-Disposition", contentDispositionValue);
? ? ? ? if (model.getModelEditorJson() !=null) {
try {
ServletOutputStream servletOutputStream = response.getOutputStream();
? ? ? ? ? ? ? ? response.setContentType("application/xml");
? ? ? ? ? ? ? ? BpmnModel bpmnModel = xxModelService.getBpmnModel(model);
? ? ? ? ? ? ? ? byte[] xmlBytes = xxModelService.getBpmnXML(bpmnModel);
? ? ? ? ? ? ? ? BufferedInputStream in =new BufferedInputStream(new ByteArrayInputStream(xmlBytes));
? ? ? ? ? ? ? ? byte[] buffer =new byte[8096];
? ? ? ? ? ? ? ? while (true) {
int count = in.read(buffer);
? ? ? ? ? ? ? ? ? ? if (count == -1) {
break;
? ? ? ? ? ? ? ? ? ? }
servletOutputStream.write(buffer, 0, count);
? ? ? ? ? ? ? ? }
// Flush and close stream
? ? ? ? ? ? ? ? servletOutputStream.flush();
? ? ? ? ? ? ? ? servletOutputStream.close();
? ? ? ? ? ? }catch (BaseModelerRestException e) {
throw e;
? ? ? ? ? ? }catch (Exception e) {
LOGGER.error("Could not generate BPMN 2.0 XML", e);
? ? ? ? ? ? ? ? throw new InternalServerErrorException("Could not generate BPMN 2.0 xml");
? ? ? ? ? ? }
}
}
}
(3).新建XXModelServiceImpl 繼承?ModelServiceImpl
(4).新建XXBpmnJsonConverter 繼承 BpmnJsonConverter
(5).新建自定義userTaskjson解析器XXCustomizeUserTaskJsonConverter 繼承UserTaskJsonConverter```public class XXCustomizeUserTaskJsonConverterextends UserTaskJsonConverter {
private static final Logger LOGGER = LoggerFactory.getLogger(XXCustomizeUserTaskJsonConverterextends.class);
? ? private static final String RETURN_TO_THE_SPECIFIED_NODE ="returntothespecifiednode";
? ? private static final String RETURN_TO_THE_SPECIFIED_NODE_KEY ="returnToTheSpecifiedNode";
? ? private static final String APPROVAL_OPERATION ="approvaloperation";
? ? private static final String APPROVAL_OPERATION_KEY ="approvalOperation";
? ? public static void fillBpmnTypes(
Map, Class> convertersToJsonMap) {
convertersToJsonMap.put(UserTask.class, XXCustomizeUserTaskJsonConverter.class);
? ? }
@Override
protected FlowElement convertJsonToElement(JsonNode elementNode, JsonNode modelNode,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Map shapeMap) {
FlowElement flowElement =super.convertJsonToElement(elementNode, modelNode, shapeMap);
? ? ? ? LOGGER.info("進(jìn)入自定義屬性解析");
? ? ? ? if(flowElementinstanceof UserTask){
ObjectMapper objectMapper =new ObjectMapper();
? ? ? ? ? ? UserTask userTask = (UserTask) flowElement;
? ? ? ? ? ? try {
LOGGER.info("節(jié)點(diǎn):" + objectMapper.writeValueAsString(userTask));
? ? ? ? ? ? }catch (JsonProcessingException e) {
LOGGER.error("節(jié)點(diǎn)序列化異常.");
? ? ? ? ? ? }
String? returnToTheSpecifiedNode = getPropertyValueAsString(RETURN_TO_THE_SPECIFIED_NODE, elementNode);
? ? ? ? ? ? LOGGER.info("新增自定義屬性[" + RETURN_TO_THE_SPECIFIED_NODE +"]=" + returnToTheSpecifiedNode);
? ? ? ? ? ? String? approvalOperation = getPropertyValueAsString(APPROVAL_OPERATION, elementNode);
? ? ? ? ? ? LOGGER.info("新增自定義屬性[" + APPROVAL_OPERATION +"]=" + approvalOperation);
? ? ? ? ? ? Map> atts =new HashMap>();
? ? ? ? ? ? ExtensionAttribute ea1 = ExtensionAttributeUtils.generate(RETURN_TO_THE_SPECIFIED_NODE_KEY,returnToTheSpecifiedNode);
? ? ? ? ? ? ExtensionAttribute ea2 = ExtensionAttributeUtils.generate(APPROVAL_OPERATION_KEY,approvalOperation);
? ? ? ? ? ? atts.put("XX-FLOWABLE-EXT ",Arrays.asList(ea1,ea2));
? ? ? ? ? ? flowElement.setAttributes(atts);
? ? ? ? }
return flowElement;
? ? }
}
```
修改代碼重新部署之后再下載xml:
可以看到新增屬性再xml里面已經(jīng)保存成功了撒穷。
發(fā)起一支流程匣椰,去實(shí)例中看看能不能取到該新增屬性的值。