Spring MVC中使用自定義TemplateLoader對freemarker模板做全局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);
    }

}

 

這里使用了一個delegate模式, 因為我們只需要對getReader()方法做小幅的更改, (其他的則委托給默認的TemplateLoader去做就可以), 實現方式很簡單, 就是在讀取template文件之后, 在前后套上<#escape>標簽而已. 

為了和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="com.ananda.oa.web.assistant.freemarker.AnandaFreeMarkerConfigurer">
<!-- 其他配置跟之前相同 -->
</bean>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM