Hello Servlet
方式一:实现 Servlet 接口
1、新建 web 工程,编写一个类,实现 javax.servlet.Servlet
接口:
package com.zze.servlet;
import javax.servlet.*;
import java.io.IOException;
public class HelloServlet1 implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
servletResponse.getWriter().write("Hello Servlet1!!!");
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
2、在 WEB-INF/web.xml
的 web-app
节下加入如下配置:
<servlet>
<!--给Servlet起名-->
<servlet-name>HelloServlet1</servlet-name>
<!--Servlet地址-->
<servlet-class>com.zze.servlet.HelloServlet1</servlet-class>
</servlet>
<servlet-mapping>
<!--配置Servlet映射,该名称对应上面已定义的Servlet名-->
<servlet-name>HelloServlet1</servlet-name>
<!--访问时的路径-->
<url-pattern>/hello1</url-pattern>
</servlet-mapping>
3、接下来就可以启动服务,访问 localhost:8080/hello1
:
方式二:继承 HttpServlet 类
1、同方式一类似,因为 Tomcat 本身就为我们提供了 javax.servlet.Servlet
的实现类: javax.servlet.http.HttpServlet
,所以我们直接继承它,重写我们要使用的方法即可:
package com.zze.servlet;
import java.io.IOException;
public class HelloServlet2 extends javax.servlet.http.HttpServlet {
protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
doGet(request, response);
}
protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
response.getWriter().write("hello Servlet2!!!");
}
}
2、同方式一,在 WEB-INF/web.xml
的 web-app
加入配置:
<servlet>
<servlet-name>HelloServlet2</servlet-name>
<servlet-class>com.zze.servlet.HelloServlet2</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet2</servlet-name>
<url-pattern>/hello2</url-pattern>
</servlet-mapping>
3、重启 Tomcat ,访问 localhost:8080/hello2
:
Servlet 的执行流程
执行流程
创建 Servlet 如下,并加入配置:
package com.zze.servlet;
import javax.servlet.*;
import java.io.IOException;
public class TestServlet implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("from init");
}
@Override
public ServletConfig getServletConfig() {
System.out.println("from getServletConfig");
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("from service");
}
@Override
public String getServletInfo() {
System.out.println("from getServletInfo");
return null;
}
@Override
public void destroy() {
System.out.println("from destroy");
}
}
访问该 Servlet,接着通过 shutdown.bat
关闭 tomcat, 查看输出结果如下:
from init
from service
from destroy
结论:
- 当 Servlet 被访问时,会先执行它的
init
方法,接着才是执行service
方法,最后执行destroy
方法。 init
方法只有在程序启动后第一次访问时才会执行,service
方法会在每次访问时执行。destroy
执行有两种情况:第一种是通过 tomcat 的shutdown.bat
脚本关闭 tomcat 时会执行,第二种情况是将程序从 tomcat 中移除时会执行。
提前 init 方法的执行时机
可以通过在 servlet
节下加入 load-on-startup
节让指定 Servlet 实例的 init
方法在程序启动时执行,如下:
// com.zze.servlet.TestServlet1
package com.zze.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
public class TestServlet1 extends HttpServlet {
@Override
public void init() throws ServletException {
System.out.println("form TestServlet1.init");
}
}
// com.zze.servlet.TestServlet2
package com.zze.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
public class TestServlet2 extends HttpServlet {
@Override
public void init() throws ServletException {
System.out.println("form TestServlet2.init");
}
}
<!-- WEB-INF/web.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>testServlet1</servlet-name>
<servlet-class>com.zze.servlet.TestServlet1</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet>
<servlet-name>testServlet2</servlet-name>
<servlet-class>com.zze.servlet.TestServlet2</servlet-class>
<load-on-startup>6</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>testServlet1</servlet-name>
<url-pattern>/test1</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>testServlet2</servlet-name>
<url-pattern>/test2</url-pattern>
</servlet-mapping>
</web-app>
启动程序,查看控制台输出:
form TestServlet1.init
form TestServlet2.init
结论:
- 只要
servlet
节下指定了load-on-startup
,那么在程序启动时这个节对应的 Servlet 就会被加载。 - 它的值必须是一个整数,表示 Servlet 的加载顺序。
- 如果该元素的值为负数或者没有设置,则容器会当 Servlet 被请求时再加载。
- 如果值为正整数或者 0 时,表示容器在应用启动时就会加载并初始化该 Servlet,值越小,优先级越高,就越被先加载。值相同时,容器就会自己选择顺序来加载。
评论区