《Java EE 7精粹》—— 第2章 Servlets 2.1 WebServlet

本节书摘来异步社区《Java EE 7精粹》一书中的第2章,第2.1节,作者:【美】Arun Gupta,更多章节内容可以访问云栖社区“异步社区”公众号查看。

第2章 Servlets

Servlet是一种托管在Servlet容器的Web组件,可以生成动态内容。Web客户端使用请求/响应模式与Servlet交互。Servlet容器负责Servlet的生命周期,接收请求和发送响应,并执行这一过程中所需的编码/解码。

2.1 WebServlet

Servlet类是使用@WebServlet注解并继承javax.servlet.http.HttpServlet类的POJO。

下面是一个Servlet定义的示例:

5859dab3667ebc764e324f0ca3f6cbfda2d600a3

默认的Servlet名是完全限定的类名,可使用注解的name属性覆盖。Servlet可以部署在多个URL:

2ea26cf59c0c07496727ec9a7652e36f947a90db

@WebInitParam可以用于指定Servlet的初始化参数:

66c77974c24fe52672e2f52fae77a952eb631c89

HttpServlet接口为每个HTTP请求:GET、POST、PUT、DELETE、HEAD、OPTIONS和TRACE的处理,提供了一个doXXX方法。通常情况下,开发人员只关注覆盖doGet和doPost方法。下面的代码显示了处理GET请求的Servlet。

f224ebe9b481940e19013be3c95d7a02f0006619

在这段代码中:

HttpServletRequest和HttpServletResponse捕获Web客户端的请求/响应。

可以从HttpServletRequest中获取请求参数,HTTP头,请求路径的不同部分如主机名称、端口和上下文,以及更多的信息。

同时,可以发送和检索HTTP Cookie。开发人员负责填充HttpServletResponse,然后容器将捕获的HTTP头信息或体消息发送给客户端。

这段代码显示了Servlet接收的HTTP GET请求是如何显示一个简单的响应给客户端的。

e371851d07fabf747ec4bc99f1ff6bda995efcbd

请求参数可以由GET和POST请求传递。在一个GET请求中,这些参数通过键/值对形式的查询字符串来传递。下面是一个使用请求参数调用前述Servlet的URL示例:

d8889483b85ca078704d4efe7d889a9b64bc79ed

在一个POST请求中,请求参数也可以通过编码在请求体的POST数据中来传递。GET和POST的请求参数都可以从HttpServletRequest中获得:

3a40806765e300a6ca1a4be100777572fd204560

每次请求的请求参数可以不同。

初始化参数也被称为init params,可以在Servlet上定义来存储启动和配置信息。如前所述,@WebInitParam用于为一个Servlet指定初始化参数:

8495401273fb042c77b538043c5429c1de1aa932

可以通过覆盖javax.servlet.Servlet接口的生命周期调用方法init、service和destroy来操控servlet的默认行为。通常情况下,数据库连接的初始化发生在init方法中,数据库连接的释放发生在destroy方法中。

还可以使用Web应用程序的部署描述文件web.xml中的servlet和servlet-mapping元素定义Servlet。如下,在web.xml中定义了一个Account Servlet:

ac90ba19fa576c319725486fe313642f46b2705d

注解配置的方式覆盖了大部分的常见用例,因此web.xml不是必需的。但某些情况下web.xml是必需的,例如指定servlet的顺序只能使用web.xml中完成。

如果web.xml中的metadata-complete元素的值设置为true,那么类中定义的注解将不被处理:

928c8acb787ac2fb042c312f28ac6cc8ddec7ed4

在部署描述文件web.xml中定义的值会覆盖使用注解定义的值。

Servlet被打包在一个以.war文件形式存在的Web应用程序中。多个Servlet可以被打包在一起,他们共享一个Servlet上下文。Servlet上下文类ServletContext中提供了有关Servlet运行环境的详细信息,用于与容器通信。例如,读取封装在Web应用程序中的资源、写入日志文件或者分派一个请求。

可以从HttpServletRequest中获得ServletContext实例:

c783acdffb002b6a51708b229b6711b5e2104697

为实现Session跟踪,Servlet可以发送一个名为JSESSIONID的HTTP Cookie到客户端。这个Cookie可以标记为HttpOnly,从而确保Cookie不会暴露给客户端的脚本代码,因此有助于减轻多种跨站脚本的攻击:

61d7c6199a4d1ef9e19bfc469a31df112007727f

此外,Servlet可以使用URL rewriting作为Session跟踪的基础。ServletContext. getSessionCookieConfig方法返回一个SessionCookieConfig实例,该实例可以用于配置Cookie的不同属性。

HttpSession接口用于查看和操控有关Session的信息,比如Session标识符和创建时间,并且可以将对象绑定到Session中。如下,创建了一个新的Session对象:

b46ffa12d2cf3422b4e447f060bd5f0a5c91fa20

session.setAttributesession.getAttribute方法用于将对象绑定到session中。

如果需要进一步处理一个请求,Servlet可以将该请求转发(forward)到另一个Servlet中。使用RequestDispatcher可以将请求分派到不同的资源中,RequestDispatcher实例可以从HttpServletRequest.getRequestDispatcher方法或者ServletContext. getRequestDispatcher方法中获得。前者可以接受相对路径,而后者可以接受当前上下文的相对路径:

e7fb70ead52b6f18e60aa26b4a20deed45e350c6

在这段代码中,bank代指部署在相同上下文中另一个Servlet

ServletContext.getContext方法可以获得不同上下文的ServletContext实例。从中可以获得RequestDispatcher实例来分派该上下文的请求。

可以通过调用HttpServletResponse.sendRedirect方法重定向(redirect)一个Servlet响应到另一个资源。这个临时的重定向响应到客户端,然后客户端发出一个新的请求到指定的URL。注意,在本例中,原始请求的对象在重定向的URL中不可用。重定向可能会稍微慢一些,因为它需要客户端发送两次请求,而转发(forward)是在容器内进行的:

d259f844c56c95deeaf06abddd5a3caefc7ad3c8

在这里,响应重定向到http://example.com/SomeOtherServlet。注意,这个URL可以是不同的主机/端口,并且可以向容器发送相对或绝对路径。

除了使用@WebServletweb.xml声明Servlet,也可以使用ServletContext.addServlet方法以编程方式来定义。该方法可以编码在ServletContainerInitializer.onStartup方法或者ServletContextListener.contextInitialized方法中。Event Listeners一节有更多的描述。

当应用程序启动时,使用给定的ServletContext调用ServletContainerInitializer. onStartup方法。addServlet方法返回ServletRegistration.Dynamic,用于创建URL映射、设置安全角色、设置初始化参数和管理其他配置项:

250db2f34271e84af06e2121506489274053eff2
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值