Activiti 流程圖片顯示亂碼問(wèn)題分析與解決

Activiti新手常見(jiàn)的問(wèn)題是,部署成功流程后沙庐,獲取顯示的流程圖片(PNG)為亂碼鲤妥,主要體現(xiàn)為中文無(wú)法正確顯示佳吞。在這里分析一下亂碼出現(xiàn)的原因,以及解決方案棉安。不喜歡問(wèn)為什么的同學(xué)可以直接跳到解決方法段落底扳。

表現(xiàn)

Activiti流程圖亂碼常見(jiàn)有兩種情況:

  1. 所有中文字符變成方塊


  2. 所有中文字符變成無(wú)意義漢字


造成這兩種情況的錯(cuò)誤原因以及解決方法并不相同,但都與Activiti部署贡耽、生成流程圖的方法有關(guān)衷模。下面先介紹Activiti的流程圖生成方式。

背景介紹

Activiti中菇爪,使用的流程定義一般都是符合BPMN2.0標(biāo)準(zhǔn)的xml文本文件算芯,后綴可以是.bpmn20.xml,.xml凳宙。其中包含了流程的全部定義內(nèi)容熙揍,包括各節(jié)點(diǎn)、節(jié)點(diǎn)關(guān)聯(lián)關(guān)系氏涩,以及用于定義顯示的DI元素届囚。

在部署流程定義時(shí),Activiti引擎會(huì)判斷是尖,是否同時(shí)提供了流程圖文件意系?如果一起提供了流程圖文件,Activiti就省事了饺汹,直接使用這個(gè)文件作為流程圖蛔添。

一般來(lái)說(shuō)我們都不會(huì)先制作好流程圖文件再部署,也就是說(shuō)兜辞,部署時(shí)只有一個(gè)xml文件迎瞧。這時(shí)候Activiti就需要自己生成對(duì)應(yīng)的流程圖文件了。

流程圖文件會(huì)保存在Activiti的數(shù)據(jù)庫(kù)ACT_GE_BYTEARRAY表中逸吵,作為BLOB保存凶硅。每個(gè)流程對(duì)應(yīng)一個(gè)流程圖文件。所以流程圖在部署時(shí)就已經(jīng)確定扫皱,除非重新部署或手動(dòng)處理足绅,否則不管配置怎么修改,顯示的都是最初的流程圖韩脑。

Activiti用于生成流程圖的工具類(lèi)是

org.activiti.image.impl.DefaultProcessDiagramGenerator

這個(gè)類(lèi)不止可以生成流程圖氢妈,還可以生成流程運(yùn)行狀態(tài)圖。具體可以參閱其中各方法的注釋扰才。

出錯(cuò)原因分析

中文字符變成方塊

在部署流程時(shí)允懂,生成流程圖的代碼位于

org.activiti.engine.impl.bpmn.deployer.BpmnDeployer.deploy():154 (Activiti 5.22中)

byte[] diagramBytes = IoUtil.readInputStream(processEngineConfiguration.
                    getProcessDiagramGenerator().generateDiagram(bpmnParse.getBpmnModel(), "png", processEngineConfiguration.getActivityFontName(),
                        processEngineConfiguration.getLabelFontName(),processEngineConfiguration.getAnnotationFontName(), processEngineConfiguration.getClassLoader()), null);

可見(jiàn)在這里,需要在processEngineConfiguration里衩匣,保存有正確的LabelFontName蕾总,以及AnnotationFontName作為參數(shù)粥航,Generator才能正確生成(非英文)的流程圖片。

中文字符變成無(wú)意義漢字

出現(xiàn)這種問(wèn)題生百,基本上都是在Activiti提供的demo程序——Explorer中設(shè)計(jì)递雀、部署流程的時(shí)候出現(xiàn)的。原因是demo程序有bug蚀浆。

Activiti Explorer中提供的Activiti Modeler缀程,是一個(gè)Web流程設(shè)計(jì)器。用于編輯市俊、保存流程模型杨凑。這里請(qǐng)注意,不能用于新建摆昧,它生成的也只是流程模型撩满,不是流程定義。生成的流程模型是Json格式的绅你,也保存在ACT_GE_BYTEARRAY表中伺帘。

然后在Activiti Explorer中提供了“部署”的操作。對(duì)應(yīng)的代碼為(Activiti 5.22中)(實(shí)際有兩個(gè)部署方式忌锯,不過(guò)畫(huà)線(xiàn)部署的是這個(gè)伪嫁。另一個(gè)是填表單方式部署,問(wèn)題類(lèi)似)

org.activiti.editor.ui.EditorProcessDefinitionDetailPanel.deployModelerModel()

protected void deployModelerModel(final ObjectNode modelNode) {
    BpmnModel model = new BpmnJsonConverter().convertToBpmnModel(modelNode);
    byte[] bpmnBytes = new BpmnXMLConverter().convertToXML(model);
    
    String processName = modelData.getName() + ".bpmn20.xml";
    Deployment deployment = repositoryService.createDeployment()
            .name(modelData.getName())
            .addString(processName, new String(bpmnBytes))
            .deploy();
    
    ExplorerApp.get().getViewManager().showDeploymentPage(deployment.getId());
}

大意是偶垮,將Modeler的數(shù)據(jù)格式(Json modelNode),轉(zhuǎn)換為Activiti內(nèi)部交換格式(BpmnModel model)张咳,再轉(zhuǎn)成xmlbyte(byte[] bpmnBytes),然后在部署的時(shí)候再作為String加入部署
.addString(processName, new String(bpmnBytes))

很繞是不是似舵?Activiti的開(kāi)發(fā)者也把自己繞暈了晶伦,導(dǎo)致這里出現(xiàn)了bug。

public byte[] convertToXML(BpmnModel model) {
  return convertToXML(model, DEFAULT_ENCODING);
}

轉(zhuǎn)換為xmlbyte的方法里啄枕,指定了編碼方式(為UTF-8)。但是再轉(zhuǎn)回字符串的時(shí)候族沃,卻沒(méi)有指定編碼方式频祝!
new String(bpmnBytes)

在未指定編碼方式的時(shí)候,new String使用jvm定義的默認(rèn)編碼方式解析脆淹,而我們一般使用的都是gb2312常空,因此導(dǎo)致問(wèn)題。

解決方法

再次強(qiáng)調(diào)盖溺,修改之后漓糙,需要重新部署或手動(dòng)生成流程圖片,才能看到效果烘嘱!

中文字符變成方塊

在Activiti的配置中昆禽,加上字體配置即可蝗蛙。

對(duì)于Spring用戶(hù),在Spring配置文件中找到Activiti流程引擎定義的地方

<bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
    <property name="dataSource" ref="dataSource"/>
    <property name="transactionManager" ref="transactionManager"/>
    <property name="databaseSchemaUpdate" value="true"/>
    ...

在其中加上幾個(gè)參數(shù)(按照Activiti的版本不同醉鳖,參數(shù)數(shù)量不一定捡硅。用IDE提示,把所有帶有font的都設(shè)置上就好了)盗棵。字體可以按照喜好設(shè)置壮韭,但需要保證tomcat運(yùn)行時(shí)可以找到(例如默認(rèn)安裝的linux服務(wù)器很可能就沒(méi)有)。

<property name="activityFontName" value="宋體"/>
<property name="labelFontName" value="宋體"/>
<property name="annotationFontName" value="宋體"/>

重啟tomcat使配置生效纹因,重新部署流程以重新生成流程圖喷屋。方塊字就ok啦。

中文字符變成無(wú)意義漢字

由于問(wèn)題出在編碼方式上瞭恰,因此有幾種修改方式

1. 修改jvm默認(rèn)參數(shù)屯曹。

在tomcat的vm運(yùn)行參數(shù)上,加上-Dfile.encoding=UTF-8寄疏。不過(guò)副作用是導(dǎo)致整個(gè)項(xiàng)目都運(yùn)行在utf-8下是牢,對(duì)于寫(xiě)的不嚴(yán)謹(jǐn)?shù)捻?xiàng)目,可能導(dǎo)致其它地方默認(rèn)使用gb2312編碼的代碼出錯(cuò)陕截。

2. 修改Explorer部署部分的代碼

org.activiti.editor.ui.EditorProcessDefinitionDetailPanel.deployModelerModel():348
修改為.addString(processName, new String(bpmnBytes, "UTF-8"))即可驳棱。

  • 可以直接修改activiti的源碼,編譯后使用农曲。

  • 也可以在自己的項(xiàng)目下社搅,手動(dòng)創(chuàng)建org.activiti.editor.ui.EditorProcessDefinitionDetailPanel類(lèi),把Activiti的源碼貼進(jìn)去乳规,再修改正確形葬。這樣我們重寫(xiě)的類(lèi)就會(huì)由classloader優(yōu)先加載,覆蓋Activiti自己的實(shí)現(xiàn)暮的,達(dá)到修改的目的笙以。

3. 說(shuō)到底Explorer只是Activiti提供的demo樣例。自己寫(xiě)的時(shí)候冻辩,可以參考Explorer的代碼猖腕,可別直接拿來(lái)用哦。
顯示字符為空白

這個(gè)嚴(yán)格來(lái)說(shuō)并不是“亂碼”恨闪,解決方法也很簡(jiǎn)單:畫(huà)流程圖的時(shí)候倘感,少寫(xiě)幾個(gè)字,或者把框框拖動(dòng)搞大一點(diǎn)就可以了~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末咙咽,一起剝皮案震驚了整個(gè)濱河市老玛,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖蜡豹,帶你破解...
    沈念sama閱讀 211,348評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件麸粮,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡余素,警方通過(guò)查閱死者的電腦和手機(jī)豹休,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,122評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)桨吊,“玉大人威根,你說(shuō)我怎么就攤上這事∈永郑” “怎么了洛搀?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,936評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀(guān)的道長(zhǎng)佑淀。 經(jīng)常有香客問(wèn)我留美,道長(zhǎng),這世上最難降的妖魔是什么伸刃? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,427評(píng)論 1 283
  • 正文 為了忘掉前任谎砾,我火速辦了婚禮,結(jié)果婚禮上捧颅,老公的妹妹穿的比我還像新娘景图。我一直安慰自己,他們只是感情好碉哑,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,467評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布挚币。 她就那樣靜靜地躺著,像睡著了一般扣典。 火紅的嫁衣襯著肌膚如雪妆毕。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,785評(píng)論 1 290
  • 那天贮尖,我揣著相機(jī)與錄音笛粘,去河邊找鬼。 笑死湿硝,一個(gè)胖子當(dāng)著我的面吹牛闰蛔,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播图柏,決...
    沈念sama閱讀 38,931評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼任连!你這毒婦竟也來(lái)了蚤吹?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,696評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎裁着,沒(méi)想到半個(gè)月后繁涂,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,141評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡二驰,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,483評(píng)論 2 327
  • 正文 我和宋清朗相戀三年扔罪,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片桶雀。...
    茶點(diǎn)故事閱讀 38,625評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡矿酵,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出矗积,到底是詐尸還是另有隱情全肮,我是刑警寧澤,帶...
    沈念sama閱讀 34,291評(píng)論 4 329
  • 正文 年R本政府宣布棘捣,位于F島的核電站辜腺,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏乍恐。R本人自食惡果不足惜评疗,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,892評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望茵烈。 院中可真熱鬧百匆,春花似錦、人聲如沸瞧毙。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)宙彪。三九已至矩动,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間释漆,已是汗流浹背悲没。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留男图,地道東北人示姿。 一個(gè)月前我還...
    沈念sama閱讀 46,324評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像逊笆,于是被迫代替她去往敵國(guó)和親栈戳。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,492評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容