从零开始的Servlet(1)

Servlet基础

Servlet是JSP的前身。Servlet是在服务端上运行的小程序,一个Servlet就是一个Java类,并且可以通过“请求–响应”编程模型来访问的这个驻留在服务器内存里的Servlet程序。

Tomcat容器等级

Tomcat的容器分为四个等级:
Servlet的容器管理Context容器,一个Context对应于一个web工程

创建Servlet

Servelet的继承体系如下:
自定义Servlet –> Abstract class HttpServlet –> Abstract class GenericServlet –> interface Servlet

写个小例子

  1. 继承HttpServlet
  2. 重写doGet()和doPost()方法
  3. 在web.xml中注册Servlet

这个方式和Django里的View.py里处理request和response的方式有点像。

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
28
package com.servlet.ackerman;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class HelloServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// super.doGet(request, response);
System.out.println("处理Get()请求");
PrintWriter out = response.getWriter();
response.setContentType("text/html;charset=utf-8");
out.println("<Strong>Hello World</Strong>");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// super.doPost(req, resp);
System.out.println("处理Post()请求");
PrintWriter out = response.getWriter();
response.setContentType("text/html;charset=utf-8");
out.println("<Strong>Hello MyBaby</Strong>");
}
}

接着在web.xml注册HelloServlet类,就像在Django的admin.py里注册一样

1
2
3
4
5
6
7
8
<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>com.servlet.ackerman.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/HelloServlet</url-pattern>
</servlet-mapping>

在页面上使用Servlet,注意这里的href和action的链接与上面的url-pattern要匹配

1
2
3
4
5
<h1>第一个Servlet例子</h1>
<a href="HelloServlet">Get方式请求HelloServlet</a>
<form action="HelloServlet" method="POST">
<input type="submit" value="Post方式提交HelloServlet"/>
</form>

Servlet的执行流程

Get方式请求HelloServlet –> <\a href=”appNames/HelloServlet”> –> 在web.xml寻找对应的url-pattern –> 在web.xml寻找对应的servlet-class –> 寻找HelloServlet类中的doGet()请求方法

HttpServlet类扩展了GenericServlet类,实现了GenericServlet类的抽象方法。
HttpServlet类有两个service()方法。
我们自己编写的Servlet继承了HttpServlet类,一般只需覆盖doPost或者doGet方法,不必覆盖service方法,因为service()会调用doPost或者doGet方法。

Servlet生命周期

三个阶段:

  1. 初始化阶段,Servlet类先被创建,然后调用init()方法(如果Servlet已经被加载,直接进行第二步)。
  2. 响应客户请求阶段,调用service()方法。由service()方法根据提交方式选择执行doGet()或者doPost()方法。
  3. 终止阶段,调用destroy方法。

servlet加载的三种情况

首先要记得Servlet实例化对象是长期存放在内存中的。
在下列时刻Servlet容器装载Servlet:

  1. Servlet容器启动时自动装载某些Servlet,实现它只需要在web.xml文件中Servlet标签中添加如下代码,数字越小表示优先级越高。

    1
    <loadon-startup>1</loadon-startup>

    这样启动Tomcat容器后Servlet类会被创建并调用init()方法。

  2. 在Servlet容器启动后,客户首次向Servlet发送请求。
  3. Servlet类文件被更新后,重新加载Servlet。

Servlet被加载后,Servlet容器创建一个Servlet实例并且调用Servlet的init()方法进行初始化。在整个Servlet的整个生命周期内,init()方法只被调用一次。

Servlet和JSP内置对象

下面展示的是JSP九大内置对象怎么在Servlet中获得

1
2
3
4
5
6
7
8
9
out resp.getWriter
request service()方法中的req参数
response service()方法中的resp参数
session req.getSession函数
application getServletContext()函数
exception Throwable
page this
pageContext PageContext
Config getServletConfig()函数

Servlet 路径跳转

Servlet 获取初始化参数

第一步:
写JSP页面

1
2
<h1>获取初始化参数</h1>
<a href="GetInitParameterServlet">点我点我</a>

第二步:
写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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
package com.servlet;
import com.sun.deploy.net.HttpResponse;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.ws.http.HTTPException;
import java.io.IOException;
import java.io.PrintWriter;
public class GetInitParameterServlet extends HttpServlet {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
//在初始化Servlet类的时候会调用该函数
//获取在web.xml中的参数
public void init() throws ServletException{
this.setUsername(this.getInitParameter("username"));
this.setPassword(this.getInitParameter("password"));
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws HTTPException, IOException{
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws HTTPException, IOException{
//将获得的初始化参数返回在页面
response.setContentType("text/html;charset=utf-8");
PrintWriter outer = response.getWriter();
outer.println(this.getUsername() + "<br/>");
outer.println(this.getPassword() );
}
}

第三步:
在web.xml中注册Servlet类并设置初始参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<servlet>
<servlet-name>InitParameter</servlet-name>
<servlet-class>com.servlet.GetInitParameterServlet</servlet-class>
<init-param>
<param-name>username</param-name>
<param-value>ackerman</param-value>
</init-param>
<init-param>
<param-name>password</param-name>
<param-value>javaweb</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>InitParameter</servlet-name>
<url-pattern>/GetInitParameterServlet</url-pattern>
</servlet-mapping>