调试实战:判断Liferay中编辑WebContent 时使用何种富文本编辑器分析 ,顺便分享下页面调试经验-阿里云开发者社区

开发者社区> 余二五> 正文

调试实战:判断Liferay中编辑WebContent 时使用何种富文本编辑器分析 ,顺便分享下页面调试经验

简介:
+关注继续查看

引入:

我们经常在Liferay网站中编辑文章,而且它常常会弹出我们非常熟悉的富文本编辑器,其实稍微有经验的人一看就知道它是一个加强版的CKEditor,为什么我们确定这个控件是ckeditor而不是其他富文本编辑器控件呢?这个控件是如何被集成在我们的页面中的呢?这是我们要解决的问题。


调试分析:

我们还是从原点开始,(小插曲:这也受益于我中学时代数学老师的教的一句话,学习就是用已知的东西解释未知的东西,而学习的过程就是建立从已知知识到未知知识的桥梁,要让A->B的每一步都满足A是B的充分条件,而不要想当然,只有这样,知识体系结构才足够牢固)


我们肯定从页面点击开始,当点击下图中图标按钮最右边那个带绿色加号的图标时:

151432914.png

它会发出如下请求,我们可以从web工具中看出来,这个对应请求参数的struts_action是/journal/edit_article


所以我们去struts-config.xml中去找action mapping:

152118522.png


这里可以看到,它会把请求转发到portlet.journal.edit_article 这个key对应的页面中:

我们去tiles-def.xml中找到这个key 对应的页面,结果是edit_article.jsp

152310625.png


因为我们的目标是富文本编辑器,所以我们必须在edit_article.jsp中找到对应的代码,我一看这个页面,傻眼了,它全是用的自定义标记写的,要看内容我不得不单独调试标记对应的java代码。 而且这里面充斥着scriptlet,所以我很难直接命中代码片段。我只能用排除法。


显然,在页面上"New Web Content"

152704501.png

对应的从Web调试器返回的代码是:

152752992.png

它一定满足以下代码(edit_article.jsp的第173行):

152839871.png

而这个<table>元素从第173行一直延伸到了第311行,所以我们的目标代码就在这从173-311行这些代码之间。(旁白:这就是缩小目标范围,也是警察甄别犯罪嫌疑人的常用方法)但是这段代码非常复杂,各种逻辑判断,我用肉眼已经没办法准确的判断走的流程了,只能借助调试器了。


首先,调试器在第88行到第93行会去获取当前languageId,这里是"en_US", 然后toLanguageId""

153137325.png


然后当运行到第107mainSections时候,我眼前一亮,因为以往经验,为了让jsp片断能更好的重用,多数是以section的形式来存放一个一个小的页面片断的,稍微初级点的人一般会在页面上用N jsp:include来引入这些页面片断,稍微高级点的人则会定义一个页面片断数组,然后把所有片断页面的名字都存放在这个数组中,至少我以前经常这么做,所以感觉很熟悉。

153316514.png


结果果然和我猜想一致(旁白:果然经验和感觉很重要啊)因为我们是点“绿色加号”页面图标进来的,所以它的mainSections的取值就是上图第107行的PropsValues.JOURNAL_ARTICLE_FORM_ADD指定的值,我们去portal.properties中找,果然找到了,而且从注释上看也证实了我们的猜想:

153435178.png

结合调试信息:

153520416.png

所以我们确定,要在这里添加多个jsp片断的内容,包括content.jsp,abstract.jsp等。并categorySections:

153650685.png


然后因为我们的toLanguageId为"",所以符合第281行的条件Validator.isNull(toLanguageId)==true

153818651.png


所以我们断定,这个标记对应的jsp片断就是应该包含若干jsp页面,它要包含的页面名字数组放在刚才生成的categorySections,而页面的路径应该是jspPath指定的路径,我们现在来证明这个猜想:


为此,我们去liferay-ui.tld中找到这个标记对应的处理类:

154143167.png


所以,它对应的标记处理类是FormNavigatorTag类:

154252283.png

而这个类的getPage()方法会吧页面转到/html/taglib/ui/form_navigator/page.jsp中:


154429689.png

我们看到,它会在第48行循环的吧所有的sectionJsp从传入的categorySections入参中读取出来,,然后分别拼接页面路径前缀(jspPath),最后在第56行,分别包含这些页面内容插入到当前页面中。因为我们刚才已经分析了,这些页面列表都在categorySection入参中,而jspPath前缀也传递进来,叫/html/portlet/journal/article,所以一切谜底都解开了,他们会从webapps/ROOT/html/portlet/journal/article中吧相应的页面片断包含进来。


我们现在来看第一个页面content.jsp,这个页面还是比较简单的, 它是一个典型的自顶向下结构:

154914211.png

结合页面很容易就把每块区域和对应的代码联系起来:


其中Structure:Default    和Template: None 这些所在的容器对应的是conent.jsp第211行的article-structure-template-toolbar

155055166.png

接下来Default language:所在的容器对应的是content.jsp第347行article-translation-toolbar

155124796.png

接下来Title(Required)所在容器对应的是content.jsp第480行journal-article-general-fields

155156677.png

接下来的Content以及富文本编辑器对应的是content.jsp的第488行journal-article-container:

155221559.png


很快的, 我们就在journal-article-container下面找到了富文本编辑器对应的代码,它也是用liferay-ui标记库中的标记写的:

155322520.png


为此,我们又回到liferay-ui.tld中找input-editor对应的标记处理类为InputEditorTag

155422999.png


从InputEditorTag类的调试信息中,我们终于发现,它使用ckeditor作为富文本编辑器的内容:(长叹一下:终于找到目标了)

155556102.png

从调试信息中看到,它会在108行包含一个页面叫/html/js/editor/ckeditor.jsp


我们进入这个页面继续调试后发现,这个ckeditor使用的配置信息(存于变量ckeditorConfigFileName中)位于文件ckconfig.jsp中:

160009492.png稍微瞄了一眼ckconfig.jsp,发现它提供了ckeditor很多配置参数包括定制显示的按钮,甚至包括样式,这也能解释为什么我们看到的ckeditor和我们看到原版的有一定的区别.


第62-68行定义了ckeditor的主要样式,让其绝对定位:

160251212.png


然后第74行指定了ckeditor控件的具体呈现,原来它是封装在一段叫ckeditor.js的javascript代码中的,它的路径在/html/js/editor/ckeditor/ckeditor.js

160428126.png


最后,在我们用ckeditor编辑完文章后,liferay会自动收集这个控件产生的内容和数据,并且进一步处理。


总结:

页面调试经验

我从事框架研究,架构很多年了,虽然自己没怎么写过jsp页面:)。

我看过很多同事,对于这种复杂页面嵌套页面的调试,他们的做法是:直接打开Firebug然后对照Dom树去找对应的jsp文件,但是这样效果不好,一来是现在主流网站多数用了很多前端框架,比如tile框架,还大量使用自定义标记库,jstl等,所以你很难直接从最终的Dom找到对应的jsp片断来满足你要求。二来是这样泛搜经常搜不到结果或者搜到很多结果,你无法判断到底哪个片断才是你所需要的, 也许这些片断彼此都很相似。

我的经验是:对于简单的,你直接一目了然就可以看到页面,页帧的嵌套包含关系,那么只要go-through一下就可以了,但是对于复杂的,尤其是页面中嵌套许多<c:if><c:choose>这种分支,判断的,你也许无法直接判断走那个分支,那么必须通过调试器。java调试工具对于jsp页面的调试支持并不完美,但是至少其中的scriptlet和expression部分是可以敲断点调试的,而条件分支,判断,循环中用到的变量值往往来自于这些scriptlet和 expression,所以知道这些代码段中出现的变量的值可以帮助我们正确的选择分支。还有就是如果页面很乱很杂,那么就可以先尽量排除不想干代码,而把目标代码局限在很小的范围中,然后断点打的细一点,就很容易搞定了。在我写着文章时候,虽然我猜想可能是用ckeditor,但我没查证过,我完全是边写博客边调试,然后结果就自动出来了。


本文中的知识:

本文其实大多数我的篇幅都是在如何进行调试和从各种复杂文件包含,引入中准确定位我们的目标的。知识本身不是很多,主要就是以下几点:

(1)Liferay在编辑博客内容时使用的富文本编辑器是一个加强版本的ckeditor

ckeditor基本知识可以参见http://ckeditor.com/

(2)这个ckeditor其实封装在一段js脚本中,其内容在/html/js/editor/ckeditor/ckeditor.js中。

(3)Liferay对于ckeditor进行了很多配置和定制,这些配置内容放在/html/js/editor/ckeditor_diffs/ckconfig.jsp中

(4)Liferay使用了大量自定义标记库,其中和页面显示的很多都放在liferay-ui.tld中定义。





本文转自 charles_wang888 51CTO博客,原文链接:http://blog.51cto.com/supercharles888/1288618,如需转载请自行联系原作者

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
springboot业务功能实战(四)告别轮询,websocket的集成使用
springboot业务功能实战(四)告别轮询,websocket的集成使用
11 0
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
10081 0
SpringBoot实战(三)之使用RestFul Web服务
一、导入maven依赖 4.0.0 org.springframework gs-consuming-rest 0.1.0 org.springframework.
1775 0
逆向分析——使用IDA动态调试WanaCrypt0r中的tasksche.exe
本文讲的是逆向分析——使用IDA动态调试WanaCrypt0r中的tasksche.exe,2017年5月12日全球爆发大规模蠕虫勒索软件WanaCrypt0r感染事件,各大厂商对该软件做了深入分析,但针对初学者的分析教程还比较少,复现过程需要解决的问题有很多,而且没有文章具体介绍勒索软件的实际运行流程,所以我写了这篇面向初学者的教程,希望帮助大家。
2369 0
富文本编辑器的技术演进之路
如果你的业务也将面向国际市场,面向移动端设备访问,不要犹豫了,Hugo.js 就是你最好的选择!
2589 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
13887 0
给微赞程序富文本编辑器加上传附件功能
微赞程序中,新闻编辑中,使用的ueditor,做了定制,去掉了一些按钮,但是一些情况下需要上传附件 如果给ueditor加上上传附件的图标,富文本编辑的调用是使用了以下函数的 function tpl_ueditor($id, $value = '', $options = array()) { 函数所在位置在/web/common/tpl.func.php这个文件中约985
2080 0
+关注
20382
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载