本节书摘来异步社区《Java EE 7精粹》一书中的第2章,第2.1节,作者:【美】Arun Gupta,更多章节内容可以访问云栖社区“异步社区”公众号查看。
Servlet是一种托管在Servlet容器的Web组件,可以生成动态内容。Web客户端使用请求/响应模式与Servlet交互。Servlet容器负责Servlet的生命周期,接收请求和发送响应,并执行这一过程中所需的编码/解码。
Servlet类是使用@WebServlet注解并继承javax.servlet.http.HttpServlet类的POJO。
下面是一个Servlet定义的示例:
默认的Servlet名是完全限定的类名,可使用注解的name属性覆盖。Servlet可以部署在多个URL:
@WebInitParam可以用于指定Servlet的初始化参数:
HttpServlet接口为每个HTTP请求:GET、POST、PUT、DELETE、HEAD、OPTIONS和TRACE的处理,提供了一个doXXX方法。通常情况下,开发人员只关注覆盖doGet和doPost方法。下面的代码显示了处理GET请求的Servlet。
在这段代码中:
HttpServletRequest和HttpServletResponse捕获Web客户端的请求/响应。
可以从HttpServletRequest中获取请求参数,HTTP头,请求路径的不同部分如主机名称、端口和上下文,以及更多的信息。
同时,可以发送和检索HTTP Cookie。开发人员负责填充HttpServletResponse,然后容器将捕获的HTTP头信息或体消息发送给客户端。
这段代码显示了Servlet接收的HTTP GET请求是如何显示一个简单的响应给客户端的。
请求参数可以由GET和POST请求传递。在一个GET请求中,这些参数通过键/值对形式的查询字符串来传递。下面是一个使用请求参数调用前述Servlet的URL示例:
在一个POST请求中,请求参数也可以通过编码在请求体的POST数据中来传递。GET和POST的请求参数都可以从HttpServletRequest中获得:
每次请求的请求参数可以不同。
初始化参数也被称为init params,可以在Servlet上定义来存储启动和配置信息。如前所述,@WebInitParam用于为一个Servlet指定初始化参数:
可以通过覆盖javax.servlet.Servlet接口的生命周期调用方法init、service和destroy来操控servlet的默认行为。通常情况下,数据库连接的初始化发生在init方法中,数据库连接的释放发生在destroy方法中。
还可以使用Web应用程序的部署描述文件web.xml中的servlet和servlet-mapping元素定义Servlet。如下,在web.xml中定义了一个Account Servlet:
注解配置的方式覆盖了大部分的常见用例,因此web.xml不是必需的。但某些情况下web.xml是必需的,例如指定servlet的顺序只能使用web.xml中完成。
如果web.xml中的metadata-complete元素的值设置为true,那么类中定义的注解将不被处理:
在部署描述文件web.xml中定义的值会覆盖使用注解定义的值。
Servlet被打包在一个以.war文件形式存在的Web应用程序中。多个Servlet可以被打包在一起,他们共享一个Servlet上下文。Servlet上下文类ServletContext中提供了有关Servlet运行环境的详细信息,用于与容器通信。例如,读取封装在Web应用程序中的资源、写入日志文件或者分派一个请求。
可以从HttpServletRequest中获得ServletContext实例:
为实现Session跟踪,Servlet可以发送一个名为JSESSIONID的HTTP Cookie到客户端。这个Cookie可以标记为HttpOnly,从而确保Cookie不会暴露给客户端的脚本代码,因此有助于减轻多种跨站脚本的攻击:
此外,Servlet可以使用URL rewriting作为Session跟踪的基础。ServletContext. getSessionCookieConfig方法返回一个SessionCookieConfig实例,该实例可以用于配置Cookie的不同属性。
HttpSession接口用于查看和操控有关Session的信息,比如Session标识符和创建时间,并且可以将对象绑定到Session中。如下,创建了一个新的Session对象:
session.setAttribute和session.getAttribute方法用于将对象绑定到session中。
如果需要进一步处理一个请求,Servlet可以将该请求转发(forward)到另一个Servlet中。使用RequestDispatcher可以将请求分派到不同的资源中,RequestDispatcher实例可以从HttpServletRequest.getRequestDispatcher方法或者ServletContext. getRequestDispatcher方法中获得。前者可以接受相对路径,而后者可以接受当前上下文的相对路径:
在这段代码中,bank代指部署在相同上下文中另一个Servlet。
ServletContext.getContext方法可以获得不同上下文的ServletContext实例。从中可以获得RequestDispatcher实例来分派该上下文的请求。
可以通过调用HttpServletResponse.sendRedirect方法重定向(redirect)一个Servlet响应到另一个资源。这个临时的重定向响应到客户端,然后客户端发出一个新的请求到指定的URL。注意,在本例中,原始请求的对象在重定向的URL中不可用。重定向可能会稍微慢一些,因为它需要客户端发送两次请求,而转发(forward)是在容器内进行的:
在这里,响应重定向到http://example.com/SomeOtherServlet。注意,这个URL可以是不同的主机/端口,并且可以向容器发送相对或绝对路径。
除了使用@WebServlet和web.xml声明Servlet,也可以使用ServletContext.addServlet方法以编程方式来定义。该方法可以编码在ServletContainerInitializer.onStartup方法或者ServletContextListener.contextInitialized方法中。Event Listeners一节有更多的描述。
当应用程序启动时,使用给定的ServletContext调用ServletContainerInitializer. onStartup方法。addServlet方法返回ServletRegistration.Dynamic,用于创建URL映射、设置安全角色、设置初始化参数和管理其他配置项:
相关资源:敏捷开发V1.0.pptx