maven配置环境

<?xml version="1.0" encoding="UTF-8"?>  
<project xmlns="http://maven.apache.org/POM/4.0.0"  
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>itbto</groupId>
    <artifactId>freemarkerdemo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>freemarkerdemo</name>

    <properties>
        <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-web-api</artifactId>
            <version>7.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.3.2</version>
        </dependency>
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.22</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                    <compilerArguments>
                        <endorseddirs>${endorsed.dir}</endorseddirs>
                    </compilerArguments>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.3</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>2.6</version>
                <executions>
                    <execution>
                        <phase>validate</phase>
                        <goals>
                            <goal>copy</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${endorsed.dir}</outputDirectory>
                            <silent>true</silent>
                            <artifactItems>
                                <artifactItem>
                                    <groupId>javax</groupId>
                                    <artifactId>javaee-endorsed-api</artifactId>
                                    <version>7.0</version>
                                    <type>jar</type>
                                </artifactItem>
                            </artifactItems>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>  

web.xml

<?xml version="1.0" encoding="UTF-8"?>  
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:web="http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee">

    <servlet>
        <servlet-name>freemarkerServlet</servlet-name>
        <servlet-class>freemarker.ext.servlet.FreemarkerServlet</servlet-class>
        <init-param>
            <param-name>TemplatePath</param-name>
            <param-value>/WEB-INF/ftl</param-value>
        </init-param>
        <init-param>
            <param-name>NoCache</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
            <!-- 强制使用 UTF-8作为输出编码格式! -->
            <param-name>ContentType</param-name>
            <param-value>text/html; charset=UTF-8</param-value>
        </init-param>
        <!-- FreeMarker 设置: -->
        <init-param>
            <!-- 0 只对开发使用! 否则使用大一点的值. -->
            <param-name>template_update_delay</param-name>
            <param-value>0</param-value>
        </init-param>
        <init-param>
            <!-- 模板文件的编码方式. -->
            <param-name>default_encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>number_format</param-name>
            <param-value>0.##</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>freemarkerServlet</servlet-name>
        <url-pattern>*.ftl</url-pattern>
    </servlet-mapping>
</web-app>  

UserModel实体类

package com.itbto.freemarker;

import java.util.Date;

public class UserModel {  
    private Integer id;
    private String title;
    private String author;
    private Date postTime;

    public UserModel() {
    }

    public UserModel(Integer id, String title, String author, Date postTime) {
        this.id = id;
        this.author = author;
        this.title = title;
        this.postTime = postTime;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public Date getPostTime() {
        return postTime;
    }

    public void setPostTime(Date postTime) {
        this.postTime = postTime;
    }

    @Override
    public String toString() {
        return "UserModel{" +
                "id=" + id +
                ", title='" + title + '\'' +
                '}';
    }
}

模拟数据库数据

package com.itbto.freemarker;

import java.util.ArrayList;  
import java.util.Date;  
import java.util.List;

/**
 * 模拟数据库数据
 */
public class UserData {

    private static List<UserModel> data = new ArrayList<>();

    static {
        data.add(new UserModel(1, "新闻1", "张三", new Date()));
        data.add(new UserModel(2, "新闻2", "张三", new Date()));
        data.add(new UserModel(3, "新闻3", "张三", new Date()));
        data.add(new UserModel(4, "新闻4", "张三", new Date()));
        data.add(new UserModel(5, "新闻5", "张三", new Date()));
        data.add(new UserModel(6, "新闻6", "张三", new Date()));
        data.add(new UserModel(7, "新闻7", "张三", new Date()));
        data.add(new UserModel(8, "新闻8", "张三", new Date()));
        data.add(new UserModel(9, "新闻9", "张三", new Date()));
    }

    public static List<UserModel> getUserModel(){
        return data;
    }

}

分页类

package com.itbto.freemarker;

import java.util.List;

/**
 * 分页信息工具类
 * @param <T> 实体类
 */
public class Pager<T> {  
    /**
     * 分页码
     */
    private int page;
    /**
     * 每页的记录数,默认是4条
     */
    private int record = 4;
    /**
     * 总记录数
     */
    private int totalRecords;
    /**
     * 显示的数据信息
     */
    private List<T> data;

    /**
     *
     * @param page 分页码
     * @param totalRecords 总记录数
     */
    public Pager(int page, int totalRecords) {
        this.totalRecords = totalRecords;
        setPage(page);
    }

    /**
     *
     * @param record 每页记录数
     * @param page 分页码
     * @param totalRecords 总记录数
     */
    public Pager(int record, int page, int totalRecords) {
        this.record = record;
        this.totalRecords = totalRecords;
        setPage(page);
    }

    /**
     *
     * @param page 分页码
     */
    private void setPage(int page){
        if (page > getTotalPages()){
            this.page = getTotalPages();
        }else {
            this.page = page;
        }
    }

    /**
     *
     * @return
     */
    public int getPage() {
        return page;
    }

    /**
     * 获得总页数
     * @return
     */
    public int getTotalPages() {
        if (totalRecords % record == 0){
            return totalRecords / record;
        }else {
            return totalRecords / record + 1;
        }
    }

    /**
     *
     * @return
     */
    public int getRecord() {
        return record;
    }

    /**
     *
     * @return
     */
    public int getTotalRecords() {

        return totalRecords;
    }

    /**
     * 获取当前页实际显示的记录数
     * @return
     */
    public int getCurrentRecord() {
        if (page < getTotalPages()){
            return record;
        }else {
            return totalRecords % record;
        }
    }

    /**
     * 页面开始记录数
     * @return
     */
    public int getStart() {
        return (page-1) * record;
    }

    /**
     * 页面结束记录数
     * @return
     */
    public int getEnd() {
        return (page-1) * record + getCurrentRecord();
    }

    /**
     *
     * @return
     */
    public List<T> getData() {
        return data;
    }

    /**
     *
     * @param data
     */
    public void setData(List<T> data) {
        this.data = data;
    }
}

Servlet访问类

package com.itbto.freemarker;

import org.apache.commons.lang3.StringUtils;

import javax.servlet.ServletException;  
import javax.servlet.annotation.WebServlet;  
import javax.servlet.http.HttpServlet;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  
import java.io.IOException;

@WebServlet(name = "user", urlPatterns = "/user")
public class UserServlet extends HttpServlet{

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        resp.setCharacterEncoding("UTF-8");

        String p = req.getParameter("p");
        if (StringUtils.isBlank(p)){
            p = "1";
        }

        int page = Integer.parseInt(p);
        UserDao dao = new UserDao();
        req.setAttribute("root", dao.getPagerUsers(page));

        req.getRequestDispatcher("/user.ftl").forward(req, resp);
    }
}

分页模板pager.ftl

<#-- 分页数字 -->  
<#macro pager page totalPage url>  
    <#list 1..totalPage as p>
        <#if p==page>
            ${p}
        <#else>
        <a href="${url + p}">${p}</a>
        </#if>
    </#list>
</#macro>

<#-- 分页下拉列表 -->  
<#macro select page totalPage url>  
    <select onchange="javascript:location.href='${url}'+this.value">
        <#list 1..totalPage as p>
            <#if p==page>
                <option value="${p}" selected>${p}</option>
            <#else>
                <option value="${p}">${p}</option>
            </#if>
        </#list>
    </select>
</#macro>  

用户信息显示模板user.ftl

<#include "pager.ftl">

<!DOCTYPE html>  
<html lang="zh-CN">  
<head>  
    <title>User</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>  
<body>

<table border="1">  
    <tr>
        <td>ID</td>
        <td>标题</td>
        <td>作者</td>
        <td>日期</td>
    </tr>
    <#list root.getData() as user>
        <tr>
            <td>${user.id}</td>
            <td>${user.title}</td>
            <td>${user.author}</td>
            <td>${user.postTime?string("yyyy-MM-dd HH:mm:ss")}</td>
        </tr>
    </#list>
</table>

<@pager page=root.getPage() totalPage=root.getTotalPages() url="/user?p="/>  
<@select page=root.getPage() totalPage=root.getTotalPages() url="/user?p="/>  
</body>  
</html>