动手实现运行servlet

Cookie和Session

Cookie 本质上就是一份存储在用户本地的文件,里面包含了每次请求中都需要传递的信息。Session可以理解为服务器端开辟的存储空间,里面保存了用户的状态, 用户信息以 Session 的形式存储在服务端。
服务器在创建Session的同时,会为该Session 生成唯一的Session ID,通过set-cookie放在http的响应头里,然后浏览器写到 cookie里,当浏览器再次发送请求的时候,会将这个Session ID带上,服务器接受到请 求之后就会依据 Session ID 找到相应的 Session,找到 Session 后,就可以在Session中 获取或者添加内容了。而这些内容只会保存在服务器中, 发到客户端的只有Session ID, 这样相对安全,也节省了网络流量,因为不需要在Cookie中存储大量用户信息。在 Java 中,是 Web 应用程序在调用 HttpServletRequest 的 getSession 方法时,由 Web 容器(比如 Tomcat)创建的.

Servlet容器和Servlet规范

Servlet接口其实是Servlet容器跟具体业务类之间的接口
avatar
Servlet 接口定义了下面五个方法:

1
2
3
4
5
6
7
8
9
10
public interface Servlet {
void init(ServletConfig config) throws ServletException;

ServletConfig getServletConfig();

void service(ServletRequest req, ServletResponse res)throws ServletException, IOExc 7
String getServletInfo();

void destroy();
}

Servlet 容器在加载 Servlet 类的时候会调用 init 方法,在卸载的时候会调用 destroy 方法。我们可能会在 init 方法里初始化一些资源,并在 destroy 方法里释放这些资源,比 如 Spring MVC 中的 DispatcherServlet,就是在 init 方法里创建了自己的 Spring 容器。
ServletConfig 的作用就是封装 Servlet 的初始化参 数。你可以在 web.xml 给 Servlet 配置参数,并在程序里通过 getServletConfig 方法拿到 这些参数。
Servlet 规范提供了 GenericServlet 抽象类,我们可以通过扩展它来实现 Servlet。虽然 Servlet 规 范并不在乎通信协议是什么,但是大多数的 Servlet 都是在 HTTP 环境中处理的,因此 Servet 规范还提供了 HttpServlet 来继承 GenericServlet,并且加入了 HTTP 特性。这样我们通过继承 HttpServlet 类来实现自己的 Servlet,只需要重写两个方法:doGet 和 doPost。
当客户请求某个资源时,HTTP 服务器会用一个 ServletRequest 对象把客户的请求信息封 装起来,然后调用 Servlet 容器的 service 方法,Servlet 容器拿到请求后,根据请求的 URL 和 Servlet 的映射关系,找到相应的 Servlet,如果 Servlet 还没有被加载,就用反射 机制创建这个 Servlet,并调用 Servlet 的 init 方法来完成初始化,接着调用 Servlet 的 service 方法来处理请求,把 ServletResponse 对象返回给 HTTP 服务器,HTTP 服务器会 把响应发送给客户端。同样我通过一张图来帮助你理解。
avatar
Servlet 规范提供了两种扩展机制:Filter和Listener。
Filter是过滤器,这个接口允许你对请求和响应做一些统一的定制化处理,比如你可以根据 请求的频率来限制访问,或者根据国家地区的不同来修 改响应内容。过滤器的工作原理是这 样的:Web 应用部署完成后,Servlet 容器需要实例化 Filter 并把 Filter 链接成一个 FilterChain。当请求进来时,获取第一个 Filter 并调用 doFilter 方法,doFilter 方法负责 调用这个 FilterChain 中的下一个 Filter。
Listener是监听器,这是另一种扩展机制。当 Web 应用在 Servlet 容器中运行时,Servlet 容器内部会不断的发生各种事件,如 Web 应用的启动和停止、用户请求到达等。 Servlet容器提供了一些默认的监听器来监听这些事件, 当事件发生时 ,Servlet 容器会负责调用监 听器的方法。当然,你可以定义自己的监听器去监听你感兴趣的事件,将监听器配置在 web.xml 中。比如 Spring 就实现了自己的监听器,来监听 ServletContext 的启动事件, 目的是当 Servlet 容器启动时,创建并初始化全局的 Spring 容器。

servlet容器,web容器,spring容器,springmvc容器的区别

web容器中有servlet容器,spring项目部署后存在spring容器和springmvc容器。其中spring控制service层和dao层的bean对象。springmvc容器控制controller层bean对象。servlet容器控制servlet对象。项目启动是,首先 servlet初始化,初始化过程中通过web.xml中spring的配置加载spring配置, 初始化spring容器和springmvc容器。待容器加载完成。servlet初始化完成,则完成启动。HTTP请求到达web容器后,会到达Servlet容器,容器通过分发器分发到具体的spring的Controller层。执行业务操作后返回结果。
avatar

Filter和Listener

Filter是过滤器,这个接口允许你对请求和响应做一些统一的定制化处理,比如你可以根据 请求的频率来限制访问,或者根据国家地区的不同来修改响应内容。过滤器的工作原理是这 样的:Web 应用部署完成后,Servlet 容器需要实例化 Filter 并把 Filter 链接成一个 FilterChain。当请求进来时,获取第一个 Filter 并调用 doFilter 方法,doFilter 方法负责 调用这个 FilterChain 中的下一个 Filter。
Listener是监听器,这是另一种扩展机制。当 Web 应用在 Servlet 容器中运行时,Servlet 容器内部会不断的发生各种事件,如 Web 应用的启动和停止、用户请求到达等。 Servlet容器提供了一些默认的监听器来监听这些事件,当事件发生时,Servlet 容器会负责调用监 听器的方法。当然,你可以定义自己的监听器去监听你感兴趣的事件,将监听器配置在 web.xml 中。比如 Spring 就实现了自己的监听器,来监听 ServletContext 的启动事件, 目的是当 Servlet 容器启动时,创建并初始化全局的 Spring 容器。

1
2
3
4
5
6
7
Filter.doFilter(); 
HandlerInterceptor.preHandle();
Controller
HandlerInterceptor.postHandle();
DispatcherServlet 渲染视图
HandlerInterceptor.afterCompletion();
Filter.doFilter(); Servlet方法返回

通过tomcat部署servlet

1.部署在tomcat中

  1. servlet代码
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    import java.io.IOException;
    import java.io.PrintWriter;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;

    public class MyServlet extends HttpServlet{

    @Override
    protected void doGet(HttpServletRequest request,HttpServletResponse response)
    throws ServletException,IOException{
    System.out.println("MyServlet 在处理 get()请求...");
    PrintWriter out = response.getWriter();
    response.setContentType("text/html;charset=utf-8");
    out.println("<strong>My Servlet!</strong><br>");
    }

    @Override
    protected void doPost(HttpServletRequest request,HttpServletResponse response)
    throws ServletException,IOException{
    System.out.println("MyServlet 在处理 post()请求...");
    PrintWriter out = response.getWriter();
    response.setContentType("text/html;charset=utf-8");
    out.println("<strong>My Servlet!</strong><br>");
    }
    }

步骤2:代码编译

1
javac -cp ./servlet-api.jar MyServlet.java

步骤3.项目层级

1
2
MyWebApp/WEB-INF/web.xml
MyWebApp/WEB-INF/classes/MyServlet.class

步骤四 web.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?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"
metadata-complete="true">
<servlet>
<servlet-name>myServlet</servlet-name>
<servlet-class>MyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>myServlet</servlet-name>
<url-pattern>/myservlet</url-pattern>
</servlet-mapping>
</web-app>

2.其他参考地址https://github.com/feifa168/mytomcat