1.4.1. 编写基本的servlet

在你的源代码目录的events包中创建一个新的类:

package events;

// Imports

public class EventManagerServlet extends HttpServlet {

    // Servlet code
}

我们后面会用到dateFormatter 的工具, 它把Date对象转换为字符串。只要一个formatter作为servlet的成员就可以了。

这个servlet只处理 HTTP GET 请求,因此,我们要实现的是doGet()方法:

protected void doGet(HttpServletRequest request,
                     HttpServletResponse response)
        throws ServletException, IOException {

    SimpleDateFormat dateFormatter = new SimpleDateFormat("dd.MM.yyyy");

    try {
        // Begin unit of work
        HibernateUtil.getSessionFactory()
                .getCurrentSession().beginTransaction();

        // Process request and render page...

        // End unit of work
        HibernateUtil.getSessionFactory()
                .getCurrentSession().getTransaction().commit();

    } catch (Exception ex) {
        HibernateUtil.getSessionFactory()
                .getCurrentSession().getTransaction().rollback();
        throw new ServletException(ex);
    }

}

我们称这里应用的模式为每次请求一个session(session-per-request)。当有请求到达这个servlet的时候,通过对SessionFactory的第一次调用,打开一个新的Hibernate Session。然后启动一个数据库事务—所有的数据访问都是在事务中进行,不管是读还是写(我们在应用程序中不使用auto-commit模式)。

不要为每次数据库操作都使用一个新的Hibernate Session。将Hibernate Session的范围设置为整个请求。要用getCurrentSession(),这样它自动会绑定到当前Java线程。

下一步,对请求的可能动作进行处理,渲染出反馈的HTML。我们很快就会涉及到那部分。

最后,当处理与渲染都结束的时候,这个工作单元就结束了。假若在处理或渲染的时候有任何错误发生,会抛出一个异常,回滚数据库事务。这样,session-per-request模式就完成了。为了避免在每个servlet中都编写事务边界界定的代码,可以考虑写一个servlet 过滤器(filter)来更好地解决。关于这一模式的更多信息,请参阅Hibernate网站和Wiki,这一模式叫做Open Session in View—只要你考虑用JSP来渲染你的视图(view),而不是在servlet中,你就会很快用到它。