什么是servlet
servlet是一个运行在服务器端的小程序,这个小程序负责接收来自客户端请求,然后对客户端请求时发送的数据进行处理、解析,最后将客户请求资源的结果返回到客户端。
有了servlet我们才能够对客户端的一些请求做出对应的处理。那么我们应该如何实现自己的servlet呢?
怎么实现servlet
实现servlet一共有三种方式:
- 实现javax.servlet.Servlet接口;
- 继承javax.servlet.GenericServlet类;
- 继承javax.servlet.http.HttpServlet类;
自定义servlet的继承结构是这样的:
接下来我们看一看这三种实现servlet的方式所涉及到的接口和类都是干嘛的。
Servlet接口: 定义所有 servlet 都必须实现的方法。
servlet 是运行在 Web 服务器中的小型 Java 程序。servlet 通常通过 HTTP(超文本传输协议)接收和响应来自 Web 客户端的请求。
要实现此接口,可以编写一个扩展 javax.servlet.GenericServlet 的一般 servlet,或者编写一个扩展 javax.servlet.http.HttpServlet 的 HTTP servlet。
拥有的方法:
方法 | 作用 | 参数 | 返回值 |
---|---|---|---|
init(ServletConfig config) | 由 servlet 容器调用,初始化servlet | ServletConfig config,config 包含 servlet 的配置和初始化参数的 ServletConfig 对象 | 无 |
getServletConfig() | 获取Servlet的配置信息 | 无 | ServletConfig,该对象包含此 servlet 的初始化和启动参数。 |
getServletInfo() | 获得Servlet的信息 | 无 | String,包含 servlet 信息的 String |
service(ServletRequest req, ServletResponse res) | 由 servlet 容器调用,以允许 servlet 响应某个请求。 | req,包含客户端请求的 ServletRequest 对象 res,包含 servlet 的响应的 ServletResponse 对象 |
无 |
destroy() | 由 servlet 容器调用,从服务中取出该 servlet,即销毁servlet | 无 | 无 |
GenericServlet: 定义一般的、与协议无关的 servlet。
HttpServlet: 提供将要被子类化以创建适用于 Web 站点的 HTTP servlet 的抽象类。
方法 | 作用 | 参数 | 返回值 |
---|---|---|---|
doGet(HttpServletRequest req, HttpServletResponse resp) | 由服务器调用(通过 service 方法),以允许 servlet 处理 GET 请求。 | HttpServletRequest,包含客户端对 servlet 发出的请求的 HttpServletRequest 对象 HttpServletResponse,包含 servlet 向客户端发送的响应的 HttpServletResponse 对象 |
无 |
doPost(HttpServletRequest req, HttpServletResponse resp) | 由服务器调用(通过 service 方法),以允许 servlet 处理 POST 请求。 | HttpServletRequest,包含客户端对 servlet 发出的请求的 HttpServletRequest 对象 HttpServletResponse ,包含 servlet 向客户端发送的响应的 HttpServletResponse 对象 |
无 |
doPut(HttpServletRequest req, HttpServletResponse resp) | 由服务器调用(通过 service 方法),以允许 servlet 处理 PUT 请求。 | HttpServletRequest,包含客户端对 servlet 发出的请求的 HttpServletRequest 对象 HttpServletResponse ,包含 servlet 向客户端发送的响应的 HttpServletResponse 对象 |
无 |
doDelete(HttpServletRequest req, HttpServletResponse resp) | 由服务器调用(通过 service 方法),以允许 servlet 处理 DELETE 请求。 | HttpServletRequest,包含客户端对 servlet 发出的请求的 HttpServletRequest 对象 HttpServletResponse ,包含 servlet 向客户端发送的响应的 HttpServletResponse 对象 |
无 |
HttpServlet 的子类至少必须重写一个方法,该方法通常是以下这些方法之一:
- doGet,如果 servlet 支持 HTTP GET 请求
- doPost,用于 HTTP POST 请求
- doPut,用于 HTTP PUT 请求
- doDelete,用于 HTTP DELETE 请求
- init 和 destroy,用于管理 servlet 的生命周期内保存的资源
- getServletInfo,servlet 使用它提供有关其自身的信息
几乎没有理由重写 service 方法。service 通过将标准 HTTP 请求分发给每个 HTTP 请求类型的处理程序方法(上面列出的 doXXX 方法)来处理它们。
同样,几乎没有理由重写 doOptions 和 doTrace 方法。
那么如何自己实现一个servlet呢?
实现一个servlet很简单,一共有步:
-
创建一个maven项目
- 选择一个Maven项目
- 填写项目的定位
- 配置Maven
- 确认项目的信息
- 引入Maven所需要的配置
-
配置tomcat
- 进入配置的界面
- 选择配置tomcat
- 基础设置
- 添加程序上下文
-
引入servlet包
在Maven的配置文件中加入servlet的包,也就是在<dependencies>
标签中加入这么一段:<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency>
便可以导入servlet包
-
制作servlet类
servlet类的代码:public class servlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("this is doGet()........."); PrintWriter out = resp.getWriter(); // 定义响应的类型是文本或超文本 resp.setContentType("text/html"); out.println("<b><i>这里是doGet()</i></b>"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("this is doPost()........."); } }
-
在web.xml注册服务器
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <display-name>Archetype Created Web Application</display-name> <servlet> <!--servlet的名字,可以随便命名--> <servlet-name>hello</servlet-name> <!--这个servlet所对应的类--> <servlet-class>servlet</servlet-class> </servlet> <!--为servlet提供信息--> <servlet-mapping> <!--这个servlet-mapping所对应的servlet的名字,它会根据名字去为对应的servlet提供信息--> <servlet-name>hello</servlet-name> <!--与JSP文件访问的路径一致,对应的是客户端请求的路径--> <url-pattern>/servlets/servlet</url-pattern> </servlet-mapping> </web-app>
<url-pattern>
是<servlet-mapping>
的子元素,用来指定Servlet的访问路径,即URL。它必须是以“/”开头。- 可以在
<servlet-mapping>
中给出多个<url-pattern>
,那么这说明Servlet绑定多个URL - 还可以在中使用通配符,所谓通配符就是星号“*”,星号可以匹配任何URL前缀或后缀,使用通配符可以命名一个Servlet绑定一组URL。通配符要么为前缀,要么为后缀,不能出现在URL中间位置,也不能只有通配符。
- 可以在
在web.xml中对servlet进行配置
-
设置servlet的启动优先级
默认情况下,服务器会在某个Servlet第一次收到请求时创建它,也可以在web.xml中对Servlet进行配置,使服务器启动时就创建Servlet。
在
<servlet>
标签中,配置<load-on-startup>
,其中给出一个非负整数,当有多个Servlet在服务器启动时创建,那么根据值的大小决定先后顺序,小的在先。可以通过init()方法测试Servlet的创建时机。在web.xml中配置servlet,加上
<load-on-startup>
标签<servlet> <servlet-name>Demo</servlet-name> <servlet-class>com.demo.DemoServlet</servlet-class> <load-on-startup>0</load-on-startup> </servlet> <servlet> <servlet-name>A</servlet-name> <servlet-class>com.demo.HttpServletDemo</servlet-class> <load-on-startup>1</load-on-startup> </servlet>
-
指定Servlet的访问路径
<url-pattern>
是<servlet-mapping>
的子元素,用来指定Servlet的访问路径,即URL。它必须是以“/”开头。可以在
<servlet-mapping>
中给出多个<url-pattern>
,如:<servlet-mapping> <servlet-name>DemoServlet</servlet-name> <url-pattern>/AServlet</url-pattern> <url-pattern>/BServlet</url-pattern> </servlet-mapping>
那么这说明Servlet绑定两个URL,无论访问 /AServlet 还是 /BServlet,访问的都是DemoServlet。
还可以在
<url-pattern>
中使用通配符,所谓通配符就是星号“*”,星号可以匹配任何URL前缀或后缀,使用通配符可以命名一个Servlet绑定一组URL,例如:<url-pattern>/servlet/*</url-pattern>
:代表/servlet/a、/servlet/b,都匹配;<url-pattern>*.do</url-pattern>
:/abc/def/ghi.do、/a.do,都可以匹配;<url-pattern>/*</url-pattern>
:匹配所有URL
注意:通配符要么为前缀,要么为后缀,不能出现在URL中间位置,也不能只有通配符。例如:/*.do就是错误的,因为星号出现在URL的中间位置了。<ur-pattern>*.*</url-pattern>
也是不对的,因为一个URL最多只能有一个通配符。
通配符是一种模糊匹配URl的方式,如果存在更具体的<url-pattern>
,那么访问路径会去匹配具体的<url-pattern>
。
-
设置初始化参数
在web.xml中配置Servlet时,可以配置一些初始化参数。而在Servlet中可以通过ServletConfig接口提供的方法来取得这些参数。
<servlet> <servlet-name>HelloServlet</servlet-name> <servlet-class>com.oracle.servlet.HelloServlet</servlet-class> <init-param> <param-name>username</param-name> <param-value>admin</param-value> </init-param> <init-param> <param-name>pwd</param-name> <param-value>1234</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/servlet/HelloServlet</url-pattern> </servlet-mapping>
在servlet类中重写init()方法来获得初始化参数:
@Override public void init() throws ServletException { this.setUsername(this.getInitParameter("username")); this.setPwd(this.getInitParameter("pwd")); }