带注解的 Servlet
正如我们在前几章中所了解的,Servlet 生命周期将由 Web/Application 服务器下的 Servlet 容器管理。每当 HttpRequest 来自客户端浏览器时,servlet 容器都会根据部署描述符文件 web.xml 中提供的 URL 映射将请求映射到相应的 servlet。例如:考虑以下 web.xml 文件中的 servlet 映射。
XML
HelloServlet
HelloServlet
HelloServlet
/hello
Java
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
// Code to be executed...
}
Java
public @interface WebServlet
HTML
Home
Java
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
// set the response content type
response.setContentType("text/html");
PrintWriter out = response.getWriter();
// Print hello message to the client browser in
// response object
out.println(
"Hello, Welcome to GeeksforGeeks!!
");
out.close();
}
}
Java
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(name = "Hello Servlet",
displayName = "Annotated Hello Servlet",
description
= "This is annotated servlet example.",
value = "/hello")
public class HelloServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
// set the response content type
response.setContentType("text/html");
PrintWriter out = response.getWriter();
// Print hello message to the client browser in
// response object
out.println(
"Hello, Welcome to GeeksforGeeks!!
");
out.println(
"Annotated servlet with elements - name, displayName, description and value
");
out.close();
}
}
Java
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(
value = "/hello",
initParams
= { @WebInitParam(name = "name", value = "Geek")
, })
public class HelloServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
// Get the initialized parameter value
String name = getInitParameter("name");
// set the response content type
response.setContentType("text/html");
PrintWriter out = response.getWriter();
// Print hello message to the client browser in
// response object
out.println("Hello " + name
+ ", Welcome to GeeksforGeeks!!
");
out.println(
"Annotated servlet with Initialization parameter.
");
out.close();
}
}
Java
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(value = "/hello", loadOnStartup = 1,
asyncSupported = true)
public class HelloServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public void init(ServletConfig config)
{
System.out.println(
"Hello Servlet has been initialized");
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
// set the response content type
response.setContentType("text/html");
PrintWriter out = response.getWriter();
// Print hello message to the client browser in
// response object
out.println(
"Hello, Welcome to GeeksforGeeks!!
");
out.println(
"Annotated servlet with load-on-start up value and asynchronous support.
");
out.close();
}
}
HTML
Home
Java
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(urlPatterns = { "/welcome", "/hello" })
public class HelloServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
// set the response content type
response.setContentType("text/html");
PrintWriter out = response.getWriter();
// Print hello message to the client browser in
// response object
out.println(
"Hello, Welcome to GeeksforGeeks!!
");
out.println(
"Annotated servlet with multiple URLs inside Get method.
");
out.close();
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
// set the response content type
response.setContentType("text/html");
PrintWriter out = response.getWriter();
// Print hello message to the client browser in
// response object
out.println(
"Hello, Welcome to GeeksforGeeks!!
");
out.println(
"Annotated servlet with multiple URLs inside Post method.
");
out.close();
}
}
在这里,只要有来自客户端请求的“ /hello ” URL,我们就会将其映射到“ HelloServlet ”类。除了在web.xml文件中提供这些映射,我们可以简单地在 Servlet 中提供一个注释,如下所示,
Java
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
// Code to be executed...
}
Servlet 注释
Java Servlet 提供了许多注解,允许用户在javax.servlet.annotation包中声明 servlet、过滤器、侦听器。它还提供注释来指定声明的组件的元数据。
注释类型 WebServlet:
Java
public @interface WebServlet
- 在 javax.servlet.annotation 包中可用。
- 用于声明一个 Servlet。
- 在部署时,servlet 容器将识别和处理注解,并使相应的 servlet 在指定的 URL 模式下可用。
@WebServlet 注解的元素: Name Modifier and Type Description Default valueasyncSupported boolean To specify whether the servlet supports asynchronous mode or not. false description String To provide a description of the servlet. “” displayName String To provide the Display name of the Servlet. “” initParams WebInitParam[] To specify initialization parameters of the servlet. {} name String To provide the name of the servlet. “” value String[] To specify the URL pattern of the servlet that is to be mapped. {} urlPatterns String[] To provide the URL patterns of the servlet that are to be mapped. {} smallIcon String To specify the small icon name of the servlet. “” loadOnStartup int To provide the load on the startup order of the servlet. -1 largeIcon String To specify the large icon name of the servlet. “”
元素 displayName、description、smallIcon 和 largeIcon 基本上由 IDE、工具或 servlet 容器使用。这些不影响 servlet 的执行。
带有注释示例的 Servlet
为了更好地理解,我们将创建一个简单的 HTML 页面来映射 Servlet 和 URL。
示例 1:
仅使用 URL 模式注释的 Servlet:
索引.html
HTML
Home
将 servlet 映射到 URL “/hello” 的 Html 页面。
你好Servlet。Java
Java
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
// set the response content type
response.setContentType("text/html");
PrintWriter out = response.getWriter();
// Print hello message to the client browser in
// response object
out.println(
"Hello, Welcome to GeeksforGeeks!!
");
out.close();
}
}
- 当用户点击欢迎页面的提交时,容器将处理“ @WebServlet(“/hello”) ”注解并映射“ HelloServlet ”类。
- 由于该方法在 Html 页面中被称为“ post ”,容器将执行“ HelloServlet ”类中的“ doPost() ”方法。
输出:
- 在服务器上运行项目以获取输出。
- 网址: http://localhost:8081/ServletFlow/index.html
- 点击提交。
您可以看到到“HelloServlet”类的 URL 映射和输出。
示例 2:
使用 servlet 信息注释的 Servlet:
你好Servlet。Java
Java
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(name = "Hello Servlet",
displayName = "Annotated Hello Servlet",
description
= "This is annotated servlet example.",
value = "/hello")
public class HelloServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
// set the response content type
response.setContentType("text/html");
PrintWriter out = response.getWriter();
// Print hello message to the client browser in
// response object
out.println(
"Hello, Welcome to GeeksforGeeks!!
");
out.println(
"Annotated servlet with elements - name, displayName, description and value
");
out.close();
}
}
- 要包含 servlet 的名称和与 servlet 相关的任何描述,我们可以使用如上所示的带注释的元素。
- 可以使用value元素指定 URL 映射。
输出:
- 运行项目并单击提交。
示例 3:
使用初始化参数注释的 Servlet:
你好Servlet。Java
Java
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(
value = "/hello",
initParams
= { @WebInitParam(name = "name", value = "Geek")
, })
public class HelloServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
// Get the initialized parameter value
String name = getInitParameter("name");
// set the response content type
response.setContentType("text/html");
PrintWriter out = response.getWriter();
// Print hello message to the client browser in
// response object
out.println("Hello " + name
+ ", Welcome to GeeksforGeeks!!
");
out.println(
"Annotated servlet with Initialization parameter.
");
out.close();
}
}
- 在这里,我们使用@WebInitParam注释指定参数值。我们需要提供要初始化的参数名称和要设置的值。
- Servlet初始化时,容器会处理@WebServlet注解内部的@WebInitParam注解,并初始化指定的值。
- 因此,我们将参数“ name”初始化为值“ Geek ”,同样的内容将写入响应中的输出。
输出:
- 运行项目并单击提交。
示例 4:
使用启动时加载值和异步支持注释的 Servlet:
你好Servlet。Java
Java
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(value = "/hello", loadOnStartup = 1,
asyncSupported = true)
public class HelloServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public void init(ServletConfig config)
{
System.out.println(
"Hello Servlet has been initialized");
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
// set the response content type
response.setContentType("text/html");
PrintWriter out = response.getWriter();
// Print hello message to the client browser in
// response object
out.println(
"Hello, Welcome to GeeksforGeeks!!
");
out.println(
"Annotated servlet with load-on-start up value and asynchronous support.
");
out.close();
}
}
- 通常,当第一个请求来自客户端时,servlet 容器会识别相应的 servlet,并加载、实例化和初始化 servlet。
- 因此,与下一个客户端请求相比,对客户端的第一个请求的响应时间更长。
- 如果我们将Load-on-startup值指定为1 ,则在将 servlet 部署到服务器本身时,容器将在服务器启动时加载、实例化和初始化 servlet。
- 要指定此 servlet 可以支持异步模式,请将元素asyncSupported值设置为true。
输出:
- 在服务器上运行项目。
- 您可以在将 servlet 部署到服务器时看到 servlet 已加载、实例化(init() 方法)和初始化。
- 您可以在服务器启动和 servlet 部署时在控制台中看到初始化消息。
- 响应将在浏览器中生成,如下所示。
示例 5:
使用多个 URL 模式注释的 Servlet:
索引.html
HTML
Home
包括两个具有不同 URL 映射的表单页面。
你好Servlet。Java
Java
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(urlPatterns = { "/welcome", "/hello" })
public class HelloServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
// set the response content type
response.setContentType("text/html");
PrintWriter out = response.getWriter();
// Print hello message to the client browser in
// response object
out.println(
"Hello, Welcome to GeeksforGeeks!!
");
out.println(
"Annotated servlet with multiple URLs inside Get method.
");
out.close();
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
// set the response content type
response.setContentType("text/html");
PrintWriter out = response.getWriter();
// Print hello message to the client browser in
// response object
out.println(
"Hello, Welcome to GeeksforGeeks!!
");
out.println(
"Annotated servlet with multiple URLs inside Post method.
");
out.close();
}
}
- 当 URL 请求到达 servlet 时,无论是“ /hello”还是“/welcome”,都会映射到同一个 servlet。
- 正如 HTML 表单中所指定的,“ /hello”操作使用方法“ /post”。所以, 容器将在 servlet 中执行“ doPost() ”方法,并且“/ welcome ”动作与“/ get ”方法一起执行。因此,容器将在 servlet 中执行“ doGet() ”方法。
输出:
- 运行项目。
- 当单击“ /hello”提交按钮时,容器将执行“ HelloServlet ”中的“ doPost() ”方法,并使用该 URL 生成下面的输出。
- 当点击“ /welcome ”提交按钮时,容器将执行“ HelloServlet ”中的“ doGet() ”方法,并使用该URL生成下面的输出。
- 您可以根据我们调用相应 servlet 的操作来查看 URL 之间的差异。
- 由于我们在 Servlet 中包含了多个 URL,因此容器能够将来自“/hello”和“/welcome”的请求映射到“HelloServlet”并生成响应。
结论
这样,我们可以使用javax.servlet.annotation包中可用的不同注解来声明和设置 servlet 本身内部的Java Servlet的元数据,而不是根据我们的项目要求使用web.xml文件。