博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
jsp改造之sitemesh注意事项
阅读量:5827 次
发布时间:2019-06-18

本文共 7593 字,大约阅读时间需要 25 分钟。


title: jsp改造之sitemesh注意事项 tags:

  • sitemesh
  • jsp
  • html
  • body categories: 工作日志 date: 2017-12-23 10:50:38

背景

  1. 现在各种现代化的浏览器确实惯坏了开发者 智能纠错 无论是忘记关闭标签甚至重复等等都有可能被chrome这些浏览器智能纠错===》chrome会合并多个body
  2. 使用jsp开发的小伙伴新开一个新的组件页面时可能从原先的页面拷贝而来 那么里面包含了如下一些
                                        
复制代码
 复制代码

这样造成一个页面从jsp处理完毕后输出的响应流会包含多个

可以参考

 

问题

多个body对于chrome来说会做自动忽略,那么对于我们使用sitemesh呢???

这个问题自然是存在的 否则也就不会有这篇博客了!

sitemesh的工作原理很单纯 使用filter对响应进行拦截,如果返回的是html那么判断是否需要进行装饰。如果需要找到合适的装饰模板进行装饰 并返回新的响应!

代码

对于sitemesh 默认来说会注入规则CoreHtmlTagRuleBundle

public void install(State defaultState, ContentProperty contentProperty, SiteMeshContext siteMeshContext) {        // Core rules for SiteMesh to be functional.        defaultState.addRule("head", new ExportTagToContentRule(siteMeshContext, contentProperty.getChild("head"), false));        defaultState.addRule("title", new ExportTagToContentRule(siteMeshContext, contentProperty.getChild("title"), false));        defaultState.addRule("body", new ExportTagToContentRule(siteMeshContext, contentProperty.getChild("body"), false));        defaultState.addRule("meta", new MetaTagRule(contentProperty.getChild("meta")));             // Ensure that while in 
tag, none of the other rules kick in. // For example
hello
should not affect the title of the page. defaultState.addRule("xml", new StateTransitionRule(new State())); } public void cleanUp(State defaultState, ContentProperty contentProperty, SiteMeshContext siteMeshContext) { // In the event that no tag was captured, use the default buffer contents instead // (i.e. the whole document, except anything that was written to other buffers). if (!contentProperty.getChild("body").hasValue()) { contentProperty.getChild("body").setValue(contentProperty.getValue()); } }复制代码

从这边可以看出body使用的规则是ExportTagToContentRule

我们细看一下ExportTagToContentRulede的源码

/**     * Exports the contents of a match tag to property of the passed in {
@link ContentProperty}. * * Additionally, if this tag has attributes, they will be written as child properties. * *

Example

* *
     * // Java     * myState.addRule("foo", new ExportTagToContentRule(content, "bar");     *     * // Input     * 
hello</foo> * * // Exported properties of Content * bar=hello * bar.x=1 * bar.b=2 *
* * @author Joe Walnes */ public class ExportTagToContentRule extends BasicBlockRule { private final ContentProperty targetProperty; private final boolean includeInContent; private final SiteMeshContext context; ; /** * @param targetProperty ContentProperty to export tag contents to. * @param includeInContent Whether the tag should be included in the content (if false, it will be stripped * from the current ContentProperty that is being written to. * @see ExportTagToContentRule */ public ExportTagToContentRule(SiteMeshContext context, ContentProperty targetProperty, boolean includeInContent) { this.targetProperty = targetProperty; this.includeInContent = includeInContent; this.context = context; } @Override protected Object processStart(Tag tag) throws IOException { // Some terminology: // Given a tag: '
hello
' // INNER contents refers to 'hello' // OUTER contents refers to '
hello
' Tag t = tag; // Export all attributes of the opening tag as child nodes on the target ContentProperty. for (int i = 0; i < t.getAttributeCount(); i++) { // attributes of tags using this rule doesn't expand sitemesh:write // https://github.com/sitemesh/sitemesh3/issues/23 String value = t.getAttributeValue(i); // only if there might be another tag inside the attribute if(value != null && (value.indexOf('<') < value.indexOf('>'))){ StringBuilder sb = new StringBuilder(); context.getContentProcessor().build(CharBuffer.wrap(value), context).getData().writeValueTo(sb); value = sb.toString(); if(!(t instanceof CustomTag)){ t = new CustomTag(t); } CustomTag custom = (CustomTag) t; custom.setAttributeValue(i, value); } targetProperty.getChild(t.getAttributeName(i)).setValue(value); } // Push a buffer for the OUTER contents. if (!includeInContent) { // If the tag should NOT be included in the contents, we use a data-only buffer, // which means that although the contents won't be written // back to the ContentProperty, they will be available in the main Content data. // See Content.createDataOnlyBuffer() tagProcessorContext.pushBuffer(targetProperty.getOwningContent().createDataOnlyBuffer()); } else { tagProcessorContext.pushBuffer(); } // Write opening tag to OUTER buffer. t.writeTo(tagProcessorContext.currentBuffer()); // Push a new buffer for storing the INNER contents. tagProcessorContext.pushBuffer(); return null; } @Override protected void processEnd(Tag tag, Object data) throws IOException { // Get INNER content, and pop the buffer for INNER contents. CharSequence innerContent = tagProcessorContext.currentBufferContents(); tagProcessorContext.popBuffer(); // Write the INNER content and closing tag, to OUTER buffer and pop it. tagProcessorContext.currentBuffer().append(innerContent); if (tag.getType() != Tag.Type.EMPTY) { // if the tag is empty we have already written it in processStart(). tag.writeTo(tagProcessorContext.currentBuffer()); } CharSequence outerContent = tagProcessorContext.currentBufferContents(); tagProcessorContext.popBuffer(); // Write the OUTER contents to the current buffer, which is now the buffer before the // tag was processed. Note that if !includeInContent, this buffer will not be written // to the ContentProperty (though it will be available in Content.getData()). // See comment in processStart(). tagProcessorContext.currentBuffer().append(outerContent); // Export the tag's inner contents to if (!targetProperty.hasValue()) { targetProperty.setValue(innerContent); } } }复制代码

可以看到export的最后做了判断为

if (!targetProperty.hasValue()) {               targetProperty.setValue(innerContent);           }复制代码

可以看到当页面上存在多个body标签时sitemesh只会输出第一个body里面的内容!!!

措施

虽然chrome如此智能,虽然我们也不用考虑对其他老旧慢浏览器的支持。但是对于一个合格的后端开发来说

html的输出格式还是要注意的。因此考虑将多余的body删除【大量引入popup的jsp的都包含了一整套的html body】

那么需要清除一些jsp中的多余的body

建议

新建的jsp如果不是页面【是指将会被include其他的jsp中】那么而建议用_打头

比如一个关于左侧导航的可以考虑使用_left.jsp

以_打头的jsp中不允许出现html body 等标签

小问题

有小伙伴发现 也有同样的问题么?^_^

转载地址:http://gjodx.baihongyu.com/

你可能感兴趣的文章
Cocos2dx 3.0开发环境的搭建--Eclipse建立在Android工程
查看>>
基本概念复习
查看>>
重构第10天:提取方法(Extract Method)
查看>>
Android Fragment使用(四) Toolbar使用及Fragment中的Toolbar处理
查看>>
解决pycharm在ubuntu下搜狗输入法一直固定在左下角的问题
查看>>
多线程day01
查看>>
react-native 模仿原生 实现下拉刷新/上拉加载更多(RefreshListView)
查看>>
MySQL出现Access denied for user ‘root’@’localhost’ (using password:YES)
查看>>
通过Roslyn构建自己的C#脚本(更新版)(转)
查看>>
红黑树
查看>>
python调用windows api
查看>>
第四章 mybatis批量insert
查看>>
Java并发框架——什么是AQS框架
查看>>
【数据库】
查看>>
Win配置Apache+mod_wsgi+django环境+域名
查看>>
linux清除文件内容
查看>>
WindowManager.LayoutParams 详解
查看>>
find的命令的使用和文件名的后缀
查看>>
Android的Aidl安装方法
查看>>
Linux中rc的含义
查看>>