CMS使用freemarker实现页面静态化

(一) FreeMarker的优点
1. 可以彻底的分离表现层和业务逻辑。曾经在使用JSP 开发过程中发现在页面中大量的存在业务逻辑的代码,使得页面内容凌乱,在后期大量的修改维护过程中就变得非常困难。但是,FreeMarker不支持Java脚本代码。****FreeMarker的原理就是:模板+数据模型=输出,模板只负责数据在页面中的表现,不涉及任何的逻辑代码,而所有的逻辑都是由数据模型来处理的。用户最终看到的输出是模板和数据模型合并后创建的。

2.FreeMarker可以提高开发效率。根据以往的开发经验,使用的都是JSP 页面来展示数据的,即所谓的表现层。大家都知道,JSP在第一次执行的时候需要转换成Servlet类,开发阶段进行功能调适时,需要频繁的修改JSP,每次修改都要编译和转换,那么试想一天中我们浪费在程序编译的时间有多少。相对于JSP来说,FreeMarker模板技术不存在编译和转换的问题,所以就不会存在上述问题。而且开发过程中,大家在不必在等待界面设计开发人员完成页面原形后,大家再来开发程序。

3 . FreeMarker使得开发过程中的人员分工更加明确。以往用JSP展现数据时,作为程序员的我们,并不熟悉界面设计技术,反之界面开发人员,也并不熟悉程序语言。对两者而言,交替性的工作本身就有难度。有时候稍有不慎,可能会将某个页面元素删除或去掉了某个程序符号,使得页面走样或程序错误,这样就需要双方相互沟通协作,解决出现的问题。有时候因为项目中的时间,任务量等因素的存在,可能这个工作就由一个人来完成,这样就可能加大某一方开发人员的工作量。使用FreeMarker后,作为界面开发人员,只专心创建HTML文件、图像以及Web页面的其他可视化方面,不用理会数据;而程序开发人员则专注于系统实现,负责为页面准备要显示的数据。

(二)FreeMarker的缺点
1.FreeMarker模板技术,在修改模板后,可能会看到已经过期的数据。如:生成静态的HTML页面后,如果一旦模板改变,而没有及时更新模板生成的HTML页面的话,用户看到的就是过期的数据。

2.FreeMarker模板技术在应用过程中,FreeMarker中的变量必须要赋值,如果不赋值,那么就会抛出异常。想避免错误就要应用if/elseif/else 指令进行判段,如果对每一个变量都判断的话,那么则反而增加了编程的麻烦。

3.FreeMarker的map限定key必须是string,其他数据类型无法操作。

4.FreeMarker不支持集群应用。为了编成的方便性,把序列化的东西都放到了Session中,如Session,request等,在开发的过程中确实方便,但如果将应用放到集群中,就会出现错误。

(三)配置pom文件,引入所需jar包

<!-- FreeMarker -->
<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker-gae</artifactId>
    <version>2.3.25-incubating</version>
</dependency>

(四)后台源码

/**
 * 首页静态化
 * 首页有人访问直接生成html文件,如果存在则直接访问
 */
@Controller
@RequestMapping
public class index extends HttpServlet {
    private static final long serialVersionUID = 1L;
    @Autowired
    private ChannelService channelService;
    @Autowired
    private ContentService contentService;
    @Autowired
    private AdvertisementService advertisementService;

    @RequestMapping
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        this.doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html; charset=UTF-8");
        String saveDir = request.getServletContext().getRealPath(FreeMarkerConstants.index_dir);
        String indexPath = request.getServletContext()
                .getRealPath(FreeMarkerConstants.index_dir + FreeMarkerConstants.index_html);
        File file = new File(saveDir);
        if (!file.exists()) {
            file.mkdirs();
        }

        file = new File(indexPath);
        if (!file.exists()) {

            Configuration configuration = new Configuration(Configuration.VERSION_2_3_22);
            String templatePath = this.getClass().getClassLoader().getResource("/templates/index").getPath();
            configuration.setDirectoryForTemplateLoading(new File(templatePath));
            configuration.setDefaultEncoding("UTF-8");

            Map<String, Object> dataMap = new HashMap<String, Object>();
            List<Advertisement> advertisements = this.getAdvertisements();
            List<Channel> praentChannelList = this.getData();
            List<Content> stickContent = this.getStickContent();
            List<Content> subCourseContent = this.getStickCourseCourse();
            List<Content> stickExpertContent = this.getStickExpertContent();
            List<Content> stickActivityContent = this.getStickActivityContent();
            List<Content> stickGeneralContent = this.getStickGeneralContent();
            base ctx = this.initPath(request, response);

            dataMap.put("advertisements", advertisements);
            dataMap.put("praentChannelList", praentChannelList);
            dataMap.put("stickContent", stickContent);
            dataMap.put("subCourseContent", subCourseContent);
            dataMap.put("stickExpertContent", stickExpertContent);
            dataMap.put("stickActivityContent", stickActivityContent);
            dataMap.put("stickGeneralContent", stickGeneralContent);
            dataMap.put("ctx", ctx);


            Template template = configuration.getTemplate("index.ftl");

            try {

                Writer writer = new OutputStreamWriter(new FileOutputStream(file), "UTF-8");
                template.process(dataMap, writer);
                writer.flush();
                writer.close();
            } catch (TemplateException e) {
                e.printStackTrace();
            }
        }
        request.getRequestDispatcher(FreeMarkerConstants.index_dir + FreeMarkerConstants.index_html).forward(request,response);
    }


    /** basepath */
    @ModelAttribute
    public base initPath(HttpServletRequest request, HttpServletResponse response) {
        base ctx = new base();
        String path = request.getContextPath();
        String basepath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path;
        ctx.setBasepath(basepath);
        return ctx;
    }
}

(五)模板源码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>新课改网_新课标_新教学_新高考</title>
    <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=2.0,minimum-scale=0.5,user-scalable=no"/>
    <meta name="description" content="新课改网专注新课程理念与实践,为教育工作者提供关于新课标、新高考、教师研修和新教学的最前沿资讯、专业发展资源和教育服务">
    <meta name="keyword" content="新课标,新课程,新课程标准,新高考,新高考改革方案,教师研修">
    <meta name="baidu-site-verification" content="oq8mUxZ2YI" />
    <link href="${ctx.basepath}/resources/front/img/gf_favicon.ico" rel="shortcut icon" />

    <link rel="stylesheet" href="${ctx.basepath}/resources/front/css/bootstrap.min.css">
    <#--轮播图-->
    <link rel="stylesheet" href="${ctx.basepath}/resources/front/css/swiper.min.css">
    <#--返回顶部-->
    <link rel="stylesheet" href="${ctx.basepath}/resources/front/css/goTop.css">
    <link rel="stylesheet" href="${ctx.basepath}/resources/front/css/d-style.css">
    <script src="${ctx.basepath}/resources/front/js/jquery-3.2.1.min.js"></script>
    <script src="${ctx.basepath}/resources/front/js/bootstrap.min.js"></script>
    <#--轮播图-->
    <script src="${ctx.basepath}/resources/front/js/swiper.min.js"></script>
    <#--锚点导航-->
    <script src="${ctx.basepath}/resources/front/js/nav.js"></script>
    <#--返回顶部-->
    <script src="${ctx.basepath}/resources/front/js/goTop.js"></script>
</head>
<body>
    <#--顶部-->
    <div class="d-top">
        <div class="d-nav-fixed">
            <!--顶部-->
            <div class="d-nav-topW">
                <div class="container d-nav-top">
                    <img src="${ctx.basepath}/resources/front/img/nav-top.png" alt="">
                    <p class="d-nav-top-phone">010-89940851</p>
                </div>
            </div>
            <#--顶部导航-->
            <div class="d-nav-new-Wrap">
                <div class="container">
                    <a class="d-logo-text"><img src="${ctx.basepath}/resources/front/img/d-logo-text.png" alt=""></a>
                    <ul class="d-nav-new">
                        <li><a href="#d_observe_anchor">新课程观察</a></li>
                        <li><a href="#d_visual_anchor">专家视角</a></li>
                        <li><a href="#d_service_anchor">服务方案</a></li>
                        <li><a href="#d_fine_anchor">精品课程</a></li>
                        <li><a class="active" href="#d_training_anchor">研修活动</a></li>
                        <#--跳转的时候用事件跳转-->
                        <li class="d-about-us-nav"><span>关于我们</span></li>
                    </ul>
                </div>
            </div>
        </div>
        <div class="d-nav-fixed-seat"></div>
        <#--轮播-->
        <div class="d-swiper-wrap">
            <div class="swiper-container">
                <div class="swiper-wrapper">
                    <#list advertisements as advertisement>
                        <div class="swiper-slide">
                            <#if (advertisement.url)??>
                                <a target="_blank" href="${advertisement.link }">
                                <div class="swiper-slide-img" style="background: url(${ctx.basepath}${advertisement.url }) no-repeat center;"></div>
                                </a>
                                <#else>
                                <div class="swiper-slide-img" style="background: url(${ctx.basepath}/resources/front/img/banner3.png) no-repeat center;"></div>
                            </#if>
                        </div>
                   </#list>
                </div>
                <#-- 如果需要分页器 -->
                <div class="swiper-pagination"></div>
                <#-- 如果需要导航按钮 -->
                <div class="swiper-button-prev"></div>
                <div class="swiper-button-next"></div>

            </div>
        </div>
    </div>
    <#--中间内容-->
    <#--新课程观察-->
    <div class="container clearfix" id="d_observe_anchor">
        <h2 class="d-title">
            <#list praentChannelList as praent>
                <#if praent.channelId==1>
                        <b>${praent.channelName }</b>
                        <a target="_blank" href="/xkcgc.html" class="d-more">MORE</a>
                </#if>
            </#list>
        </h2>

        <div class="row">
            <#list stickContent as stick>
                <#if stick_index<3>
                    <div class="col-md-4">
                        <a target="_blank" href="/xkcgc/${stick.contentId}.html" class="d-observeWrap">
                            <div class="d-observe-img">
                                <#if (stick.picture)??>
                                    <img src="${stick.picture }" alt="">
                                    <#else>
                                        <img src="${ctx.basepath}/resources/front/img/observe.png" alt="">
                                </#if>
                            </div>
                            <h3 class="d-observe-title">${stick.title}</h3>
                            <p class="d-observe-con">${stick.description}</p>
                        </a>
                    </div>
                </#if>
            </#list>
        </div>

        <div class="row d-observe-listWrap">
            <#list praentChannelList as praent>
                <#if praent.channelId==1>
                    <#list praent.list as son>
                        <#if son.channelId==7||son.channelId==8>
                            <#list son.contentList as content>
                                <#if content.stickFlag=='0'>
                                    <#if son.channelId==7>
                                        <#if content_index<3>
                                        <div class="col-md-4">
                                            <ul class="d-observe-list">
                                                    <li><a target="_blank" href="/xkcgc/${content.contentId}.html">${content.title}</a></li>
                                            </ul>
                                        </div>
                                        </#if>
                                    </#if>
                                    <#if son.channelId==8>
                                        <div class="col-md-4">
                                            <ul class="d-observe-list">
                                                <li><a target="_blank" href="/xkcgc/${content.contentId}.html">${content.title}</a></li>
                                            </ul>
                                        </div>
                                    </#if>
                                </#if>
                            </#list>
                        </#if>
                    </#list>
                </#if>
            </#list>
        </div>
    </div>

    <#--专家视角-->
    <div class="d-visualWrap" id="d_visual_anchor">
        <div class="container">
            <h2 class="d-title">
            <#list praentChannelList as praent>
                <#if praent.channelId==2>
                    <b>${praent.channelName }</b>
                    <a target="_blank" href="/zjsj.html" class="d-more">MORE</a>
                </#if>
            </#list>
            </h2>
            <div class="row">
                <#list stickExpertContent as content>
                    <#if content_index<4>
                        <div class="col-md-3">
                            <a target="_blank" href="/zjsj/${content.contentId}.html" class="d-observe-conWrap">
                                <div class="d-visual-img">
                                    <#if (content.picture)??>
                                        <img src="${content.picture}" alt="">
                                        <#else>
                                            <img src="${ctx.basepath}/resources/front/img/visual%20-img.png" alt="">
                                    </#if>
                                </div>
                                <p class="d-visual-name">${content.person }</p>
                                <h3 class="d-visual-title">${content.title }</h3>
                                <p class="d-visual-con">${content.description }</p>
                            </a>
                        </div>
                    </#if>
                </#list>
            </div>
        </div>
    </div>

    <#--服务方案-->
    <#include "fuwufangan.ftl"/>

    <#--精品课程-->
    <div class="d-fineWrap" id="d_fine_anchor">
        <div class="container">
            <h2 class="d-title"><b>精品课程</b></h2>
            <h3 class="d-fine-title">通识课程 
                <#list praentChannelList as praent>
                    <#if praent.channelId==4>
                        <a target="_blank" href="/jpkc.html" class="d-more">MORE</a>
                    </#if>
                </#list>
            </h3>
            <div class="row">
                <#list stickGeneralContent as content>
                    <#if content_index<3>
                        <a class="col-md-4 d-fine-con" target="_blank" href="/jpkc/${content.contentId}.html">
                            <div class="d-fine-imgWrap">
                                <#if (content.picture)??>
                                    <img src="${content.picture }" alt="">
                                    <#else>
                                        <img src="${ctx.basepath}/resources/front/img/fine-img.png" alt="">
                                </#if>
                            </div>
                             <p class="d-fine-conTitle">${content.title }</p>
                        </a>
                    </#if>
                </#list>
            </div>
            <h3 class="d-fine-title">学科课程 
                <#list praentChannelList as praent>
                    <#if praent.channelId==4>
                        <a target="_blank" href="/jpkc.html" class="d-more">MORE</a>
                    </#if>
                </#list>
            </h3>
            <div class="row d-fine-conWrap">
                <#list subCourseContent as content>
                    <#if content_index<3>
                    <a class="col-md-4 d-fine-con" target="_blank" href="/jpkc/${content.contentId}.html">
                        <div class="d-fine-imgWrap">
                            <#if (content.picture)??>
                                <img src="${content.picture }" alt="">
                                <#else>
                                    <img src="${ctx.basepath}/resources/front/img/fine-img.png" alt="">
                            </#if>
                        </div>
                        <p class="d-fine-conTitle">${content.title }</p>
                    </a>
                    </#if>
                </#list>
            </div>
        </div>
    </div>

    <#--研修活动-->
    <div class="container d-training" id="d_training_anchor">
        <h2 class="d-title">
            <#list praentChannelList as praent>
                <#if praent.channelId==5>
                    <b>${praent.channelName }</b>
                    <a target="_blank" href="/yxhd.html" class="d-more">MORE</a>
                </#if>
            </#list>
        </h2>
        <div class="row d-training">
            <#list stickActivityContent as content>
                <#if content_index<3>
                    <a class="col-md-4 d-fine-con" target="_blank" href="/yxhd/${content.contentId}.html">
                        <div class="d-fine-imgWrap">
                            <#if (content.picture)??>
                                <img src="${content.picture }" alt="">
                                <#else>
                                    <img src="${ctx.basepath}/resources/front/img/fine-img.png" alt="">
                            </#if>
                            <#--遮罩层-->
                            <div class="cornerTL"></div>
                            <div class="cornerTR"></div>
                            <div class="cornerBL"></div>
                            <div class="cornerBR"></div>
                        </div>
                        <p class="d-fine-conTitle">${content.title }</p>
                    </a>
                 </#if>
             </#list>
        </div>
    </div>

    <#--尾部-->
    <#include "footer.ftl"/>
    <#--版权信息-->
    <#include "copy.ftl"/>
    <#--右侧悬浮按钮-->
    <div id="top"></div>

    <script>
        <#--服务方案tab-->
        $('.d-service-btnBg').mouseover(function(){
            $('.d-service-tab>div').eq($(this).index()/2).addClass('active').siblings().removeClass('active');
            $(this).find('.d-btn-icon').addClass('active').parent().siblings().find('.d-btn-icon').removeClass('active');
            $(this).addClass('active').siblings().removeClass('active');
            $(this).next().removeClass('active').siblings('.d-service-btnBg-replace').addClass('active');
        })

        <#--轮播图-->
        var mySwiper = new Swiper ('.swiper-container', {
            direction: 'horizontal',
            loop: true,
            autoplay: true,

            <#--如果需要分页器-->
            pagination: {
                el: '.swiper-pagination',
                clickable :true,
            },

            <#-- 如果需要前进后退按钮-->
            navigation: {
                nextEl: '.swiper-button-next',
                prevEl: '.swiper-button-prev',
            },

            <#--回调函数,文字描述动态效果-->
            on: {
                slideChangeTransitionEnd: function(){
                    $('.d-slide-text').eq(this.activeIndex).addClass('d-slide-text-active').parent().siblings().find('.d-slide-text').removeClass('d-slide-text-active');
                },
            },

        })


        <#--轮播图鼠标移入箭头效果-->
        $('.swiper-container').mouseover(function(){
            mySwiper.autoplay.stop();
            $('.swiper-button-prev').css('display', 'block');
            $('.swiper-button-next').css('display', 'block');

        }).mouseout(function(){
            mySwiper.autoplay.start();
            $('.swiper-button-prev').css('display', 'none');
            $('.swiper-button-next').css('display', 'none');
        })

        <#--内容信息导航锚点-->
        $('.d-nav-new-Wrap').navScroll({
            mobileDropdown: true,
            mobileBreakpoint: 768,
            scrollSpy: true
        });

        $('.hero__scroll').on('click', function(e) {
            $('html, body').animate({
                scrollTop: $(window).height()
            }, 1200);
        });

        <#--导航跳转-->
        $('.d-logo-text img').click(function(){
            window.location.href='/'; 
        })
        $('.d-about-us-nav').click(function(){
            window.location.href='/about/aboutUs.html'; 
        })


    </script>
    <script>
    //自动推送代码
    (function(){
        var bp = document.createElement('script');
        var curProtocol = window.location.protocol.split(':')[0];
        if (curProtocol === 'https') {
            bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
        }
        else {
            bp.src = 'http://push.zhanzhang.baidu.com/push.js';
        }
        var s = document.getElementsByTagName("script")[0];
        s.parentNode.insertBefore(bp, s);
    })();


    </script>

<!--     百度统计和cnzz统计 -->
<script src="${ctx.basepath}/resources/front/js/baidu-count.js"></script>
<script src="${ctx.basepath}/resources/front/js/cnzz-count.js"></script>

</body>
</html>

猜你喜欢

转载自blog.csdn.net/weixin_37519752/article/details/80770041