在开始正式的内容之前,我们先来回顾一下大家比较熟悉的处理Web请求的模式。

经过了多年的发展,J2EE处理请求基本上是符合这样的模式的

  1. 接收用户参数
  2. 处理请求(这一步一般会引入Service层)
  3. 决定输出参数(绑定变量到request.attribute或者form bean等等)
  4. 渲染返回结果(直接返回json/通过jsp或者其他模板引擎渲染页面)

为了对比几种常见开发方式的异同,我们首先基于最传统的Servlet,实现一个简单的功能:

当用户访问/hello的时候,浏览器上就会出现Hello World!
而用户访问的时候传入username参数,如/hello?username=User的时候,后台程序会将用户传入的username转成大写,并输出到Hello World的前面。在这个例子中,浏览器上就会出现USER: Hello World!

[more]

在基于ServletJSP的开发模型中,Servlet负责响应请求,对用户提交的数据进行处理,JSP负责渲染结果页面

Java代码:

package cirnoworks;

import ...

public class HelloServlet extends HttpServlet{
  protected void doGet(HttpServletRequest req, HttpServletResponse resp)
      throws ServletException, IOException {
    // 1. 接收用户参数
    String username = req.getParameter("username");

    // 2. 处理请求
    if(username != null){
      username = username.toUpperCase();
    }

    // 3. 绑定结果
    req.setAttribute("username", username);

    // 4. 渲染页面
    req.getRequestDispatcher("/jsps/hello.jsp").forward(req, resp);
  }
}

JSP代码

<%@ page language="java" contentType="text/html; charset=UTF-8"
  pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
  <head><title></title></head>
  <body>
    <c:if test="${username not null}"><c:out value="${username}" />: </c:if>Hello World!
  </body>
</html>

web.xml

...前略
  <servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>cirnoworks.HelloServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello</url-pattern>
  </servlet-mapping>
...后略

可以看出,经典的基于Servlet / JSP开发的应用,主流程是这样的

  1. 用户请求被Servlet接收,Servlet将用户传入的参数读取到变量中(接收用户参数)
  2. Servlet通过用户传入的参数执行业务逻辑(处理请求,本例中是简单的toUpperCase)
  3. Servlet将转成大写的字符串放到request.attribute中(决定输出参数)
  4. Servlet将请求forward给JSP渲染

那么请各位读者想一想,如果用更加主流的Struts和SpringMVC来开发,代码应该怎么写,是不是也是类似的四个步骤,而用我们自己写的框架开发的话,这四个步骤有事怎么体现的呢?


修订

  • 2015-10-23 框架的名字从WebCraft改成了Mocha……