加载中…
个人资料
Blan丶Sun
Blan丶Sun
  • 博客等级:
  • 博客积分:0
  • 博客访问:210,155
  • 关注人气:11
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
相关博文
推荐博文
谁看过这篇博文
加载中…
正文 字体大小:

Jpress博客无法编辑内容包含HTML或XML代码的bug

(2018-03-01 23:24:37)

欢迎访问我的博客:http://www.belonk.com

原文地址:http://www.belonk.com/blog/c/Jpress博客无法编辑内容包含HTML或XML代码的bug.html

JPress是基于JFinal框架开发的java博客系统,也是本站采用的博客系统,功能强大而且快速,详细见官网:http://jpress.io

问题描述

采用jpress以来,发现一个比较严重的问题:当博客内容包含html代码或者xml代码时(确切的说是包含符号“>”或“<”),编辑博客内容时就无法正常显示(过滤掉了"<>"之间的内容)。这个问题困扰了我很久,不过一直没有心思来解决,最近突然心血来潮突然又想再定制下我们的网站,顺便把这个问题解决了。采用的JPress版本为:0.5.0,不知道后边的版本是否修复。

解决思路

要解决问题当然还是要看jpress源码。

跟踪jpress源码,发现编辑文章采用的富文本组件是tinymce(markdown暂时忽略),而tinymce初始化内容是从textarea中获取的,而jpress使用的前端渲染模板是freemarker,textarea获取内容代码如下:

模板位置:/WEB-INFO/admin/content/_index_include.html

<<span class="hljs-name" style="color: rgb(239, 239, 143);">div  class="box-body no-padding">
  <<span class="hljs-name" style="color: rgb(239, 239, 143);">textarea id="textarea"  name="content.text" >${(content.text)!}</<span class="hljs-name" style="color: rgb(239, 239, 143);">textarea>
</<span class="hljs-name" style="color: rgb(239, 239, 143);">div>

对应的后台处理器为:_ContentController.方法:

@Override
public void edit() {
        String moduleName = getModuleName();
        BigInteger contentId = getParaToBigInteger("id");
        Content content = ContentQuery.me().findById(contentId);
        if (content != null) {
                setAttr("content", content);
                moduleName = content.getModule();
        }
        TplModule module = TemplateManager.me().currentTemplateModule(moduleName);
        setAttr("module", module);
        String _editor = getCookie("_editor", "tinymce");
        setAttr("_editor", _editor);
        setAttr("urlPreffix", ContentRouter.getContentRouterPreffix(module.getName()));
        setAttr("urlSuffix", ContentRouter.getContentRouterSuffix(module.getName()));
        setSlugInputDisplay(moduleName);
        String templateHtml = String.format("admin_content_edit_%s.html", moduleName);
        for (int i = 0; i < 2; i++) {
                if (TemplateManager.me().existsFile(templateHtml)) {
                        setAttr("include", TemplateManager.me().currentTemplatePath() + "/" + templateHtml);
                        return;
                }
                templateHtml = templateHtml.substring(0, templateHtml.lastIndexOf("_")) + ".html";
        }
        setAttr("include", "_edit_include.html");
}

由于默认采用Freemarker模板渲染页面,文章内容包含在上述代码的Content对象中。对比了数据库存储的文章html内容、content对象的文章内容和页面上textarea标签中文章内容,发现结果如下:

  • 数据库文章内容与content对象中的一致,内容中包含"<>"符号的均被转义为<>,其他排版的html标签不变。
  • 页面上textarea中的内容与其他两者不一致,所有html标签"<>"符号全部被转义为<>

 图上为数据库存储内容,但是在页面的textarea中,所有"<>"符号均被转义。

于是猜测应该是在页面渲染的时候,将HTML转义了,但是已经被转义的内容没有再进行深层次转义:即将&转义为&。

具体代码逻辑不详细描述了,跟踪代码,发现确实是freemarker在渲染时将html内容全部进行了转义,关键代码如下:

private String getHtmlContent(Map data) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        OutputStreamWriter osWriter = null;
        try {
                osWriter = new OutputStreamWriter(baos, Consts.CHARTSET_UTF8);
                Template template = getConfiguration().getTemplate(view);
                template.process(data, osWriter);
                osWriter.flush();
                return baos.toString(Consts.CHARTSET_UTF8);
        } catch (Exception e) {
                if (Jpress.isDevMode()) {
                        e.printStackTrace();
                }
                throw new RenderException(e);
        } finally {
                close(baos);
                close(osWriter);
        }
}

注意template.process(data, osWriter)方法,该方法将数据和模板进行合并,得到转染的结果页面内容。

最终结果与猜测一致, 只要将被转义的属于文章内容的"<>"做深层次转义即可解决问题。于是打算将查询出来的文章内容做修改,将被转义的<>符号做再次转义,即:将<或>中的&替换为&。但是仔细想了下,在freemarker中应该会考虑到这样的功能,查询freemarker文档,果然,freemarker的#escape指令就是用于这种情况该指令说明如下:

当你使用 escape 指令包围模板中的一部分时,在块中出现的插值( ${...} )会和
转义表达式自动结合。这是一个避免编写相似表达式的很方便的方法。它不会影响在字符串
形式的插值(比如在

0

阅读 评论 收藏 转载 喜欢 打印举报/Report
  • 评论加载中,请稍候...
发评论

    发评论

    以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

      

    新浪BLOG意见反馈留言板 电话:4000520066 提示音后按1键(按当地市话标准计费) 欢迎批评指正

    新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 会员注册 | 产品答疑

    新浪公司 版权所有