1.4.1. 编写基本的servlet

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

  1. package events;
  2. // Imports
  3. public class EventManagerServlet extends HttpServlet {
  4. // Servlet code
  5. }

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

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

  1. protected void doGet(HttpServletRequest request,
  2. HttpServletResponse response)
  3. throws ServletException, IOException {
  4. SimpleDateFormat dateFormatter = new SimpleDateFormat("dd.MM.yyyy");
  5. try {
  6. // Begin unit of work
  7. HibernateUtil.getSessionFactory()
  8. .getCurrentSession().beginTransaction();
  9. // Process request and render page...
  10. // End unit of work
  11. HibernateUtil.getSessionFactory()
  12. .getCurrentSession().getTransaction().commit();
  13. } catch (Exception ex) {
  14. HibernateUtil.getSessionFactory()
  15. .getCurrentSession().getTransaction().rollback();
  16. throw new ServletException(ex);
  17. }
  18. }

我们称这里应用的模式为每次请求一个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中,你就会很快用到它。