`
杨胜寒
  • 浏览: 284628 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

FreeMarker模板输出转义html

阅读更多

本文转载自:http://www.yshjava.cn/post/333.html

 

FreeMarker作为"通用"模版引擎, 默认情况下不会对model中的值进行html转义, 然而在web项目中, 为了防止跨站脚本攻击等问题, 必须在对model中的值进行转义.
解决办法:
方法1. 是使用 ${x?html} 可以用于对单个值的转义
方法2. 使用<#escape x as x?html> ... </#escape> 将需要转义的html代码包起来, 这样其中所有的值都会被转义了.
毫无疑问这两个方法都需要大量的重复操作, 如果我所有的模板都需要转义, 有没有一劳永逸的办法呢?
方法3. 使用自定义TemplateLoader

首先我们需要实现一个TemplateLoader. 代码如下:

public class HtmlTemplateLoader implements TemplateLoader {
    
    private static final String HTML_ESCAPE_PREFIX= "<#escape x as x?html>";
    private static final String HTML_ESCAPE_SUFFIX = "</#escape>";
    
    private final TemplateLoader delegate;

    public HtmlTemplateLoader(TemplateLoader delegate) {
        this.delegate = delegate;
    }

    @Override
    public Object findTemplateSource(String name) throws IOException {
        return delegate.findTemplateSource(name);
    }

    @Override
    public long getLastModified(Object templateSource) {
        return delegate.getLastModified(templateSource);
    }

    @Override
    public Reader getReader(Object templateSource, String encoding) throws IOException {
        Reader reader = delegate.getReader(templateSource, encoding);
        String templateText = IOUtils.toString(reader);
        return new StringReader(HTML_ESCAPE_PREFIX+templateText + HTML_ESCAPE_SUFFIX);
    }

    @Override
    public void closeTemplateSource(Object templateSource) throws IOException {
        delegate.closeTemplateSource(templateSource);
    }

}

 

为了和SpringMVC结合起来使用呢, 我们还需要自定义一个FreeMarkerConfigurer

 

public class CustomFreeMarkerConfigurer extends FreeMarkerConfigurer{
    
    @Override
    protected TemplateLoader getAggregateTemplateLoader(List<TemplateLoader> templateLoaders) {

        return new HtmlTemplateLoader(super.getAggregateTemplateLoader(templateLoaders));

    }
  
}

 然后在spring的xml配置中, 使用它来代替默认的FreeMarkerConfigurer即可

<bean id="freemarkerConfigurer" class="cn.ysh.studio.freemarker.SimpleFreeMarkerConfigurer">
	<!-- 其他配置跟之前相同 -->
</bean>

 当然,如果你觉得使用<#escape>标签不舒服的话,那么也可以自己对html字符串进行转义。HTML中的转义字符的数量不多,如下代码可以将带有跨站脚本攻击风险的html字符转义为安全字符(仅供参考):

String html = "8888</title><body><script type='text/javascript'>alert(\"跨站脚本\");</script>";
html = html.replace("'", "&apos;");//替换单引号
html = html.replaceAll("&", "&amp;");//替换&
html = html.replace("\"", "&quot;"); // 替换双引号
html = html.replace("\t", "&nbsp;&nbsp;");// 替换跳格
html = html.replace(" ", "&nbsp;");// 替换空格
html = html.replace("<", "&lt;");//替换左尖括号
html = html.replaceAll(">", "&gt;");//替换右尖括号

 

本文转载自http://www.cnblogs.com/nixil/archive/2012/04/23/2466364.html,并稍作修改!

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics