JavaWeb——Servlet
Servlet概述
简介:Java Servlet 是运行在 Web 服务器或应用服务器上的小程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。
Servlet 是JavaEE 规范(接口)之一。
Servlet 就JavaWeb 三大组件之一。三大组件分别是:Servlet 程序、Filter 过滤器、Listener 监听器。
使用 Servlet,您可以收集来自网页表单的用户输入,呈现来自数据库或者其他源的记录,还可以动态创建网页。
Java Servlet 通常情况下与使用 CGI(Common Gateway Interface,公共网关接口)实现的程序可以达到异曲同工的效果。但是相比于 CGI,Servlet 有以下几点优势:
- 性能明显更好。
- Servlet 在 Web 服务器的地址空间内执行。这样它就没有必要再创建一个单独的进程来处理每个客户端请求。
- Servlet 是独立于平台的,因为它们是用 Java 编写的。
- 服务器上的 Java 安全管理器执行了一系列限制,以保护服务器计算机上的资源。因此,Servlet 是可信的。
- Java 类库的全部功能对 Servlet 来说都是可用的。它可以通过 sockets 和 RMI 机制与 applets、数据库或其他软件进行交互。
Servlet程序的实现
- 编写一个类去实现Servlet 接口
- 实现service 方法,处理请求,并响应数据
- 到web.xml 中去配置servlet 程序的访问地址
Servlet的生命周期
-
执行Servlet 构造器方法
-
执行init 初始化方法
当用户调用一个 Servlet 时,就会创建一个 Servlet 实例,每一个用户请求都会产生一个新的线程,适当的时候移交给 doGet 或 doPost 方法。init() 方法简单地创建或加载一些数据,这些数据将被用于 Servlet 的整个生命周期。 -
执行service() 方法
service() 方法是执行实际任务的主要方法。Servlet 容器(即 Web 服务器)调用 service() 方法来处理来自客户端(浏览器)的请求,并把格式化的响应写回给客户端。
每次服务器接收到一个 Servlet 请求时,服务器会产生一个新的线程并调用服务。service() 方法检查 HTTP 请求类型(GET、POST、PUT、DELETE 等),并在适当的时候调用 doGet、doPost、doPut,doDelete 等方法。 -
执行destroy 销毁方法
destroy() 方法只会被调用一次,在 Servlet 生命周期结束时被调用。destroy() 方法可以让您的 Servlet 关闭数据库连接、停止后台线程、把 Cookie 列表或点击计数器写入到磁盘,并执行其他类似的清理活动。
- 第一个到达服务器的 HTTP 请求被委派到 Servlet 容器。
- Servlet 容器在调用 service() 方法之前加载 Servlet。
- 然后 Servlet 容器处理由多个线程产生的多个请求,每个线程执行一个单一的 Servlet 实例的 service() 方法。
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* @version 1.0
* @Description Servlet程序的实现
*/
public class HelloServlet implements Servlet {
public HelloServlet() {
System.out.println("1.构造器方法");
}
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("2.init初始化方法");
}
@Override
public ServletConfig getServletConfig() {
return null;
}
/**
* @return void
* service方法是专门用来处理请求和响应的
* @Param [servletRequest, servletResponse]
*/
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("3.Service方法Hello Servlet 被访问了");
//类型转换(因为HttpServletRequest才有getMethod()方法)
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
//获取请求信息
String method = httpServletRequest.getMethod();
if ("GET".equals(method)) {
doGet();
} else if ("POST".equals(method)) {
doPost();
}
}
/**
* get请求的方法//TODO
* @Param []
* @return void
*/
public void doGet(){
System.out.println("get请求");
System.out.println("get请求");
}
/**
*
* post请求的方法//TODO
* @Param []
* @return void
*/
public void doPost(){
System.out.println("post请求");
System.out.println("post请求");
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
System.out.println("4.destroy销毁方法");
}
}
Web.xml的配置信息
<!-- servlet标签给Tomcat配置Servlet程序-->
<servlet>
<!--servlet-name标签 给 Servlet程序起一个别名(一般是类型)-->
<servlet-name>HelloServlet</servlet-name>
<!--servlet-class是Servlet程序的全类名-->
<servlet-class>pers.hwyee.servlet.HelloServlet</servlet-class>
</servlet>
<!--servlet-mapping标签给servlet程序配置访问地址-->
<servlet-mapping>
<!--servlet-name标签的作用是告诉服务器,我当前配置的地址给哪个Servlet程序使用-->
<servlet-name>HelloServlet</servlet-name>
<!--url-pattern标签配置访问地址
/ 斜杠在服务器解析的时候,表示地址为http://ip:port/工程路径
/hello 表示地址为:http://ip:port/工程路径/hello
-->
<url-pattern>/hello</url-pattern>
</servlet-mapping>
HttpServlet类
通过继承HttpServlet类创建Servlet程序:
- 编写一个类去继承HttpServlet 类
- 根据业务需要重写doGet 或doPost 方法
- 到web.xml 中的配置Servlet 程序的访问地址
public class HelloServlet2 extends HttpServlet {
/**
* @Description doGet()在get请求时调用
* @Param [req, resp]
* @return void
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("HelloServlet2 的doGet()方法");
ServletConfig servletConfig = getServletConfig();
System.out.println(servletConfig);
//2.获取初始化参数init-param
System.out.println("初始化参数username的值是:" + servletConfig.getInitParameter("username"));//null
System.out.println("初始化参数url的值是:" + servletConfig.getInitParameter("url"));//null
}
/**
* @Description doPost()在post请求时调用
* @Param [req, resp]
* @return void
*/
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("HelloServlet2 的doPost()方法");
}
}
Servlet类的继承体系
Servlet接口:
只负责定义Servlet程序的访问规范
GenericServlet:
实现了Servlet接口,做了很多空的实现方法。
并持有一个ServletConfig的类的引用,对ServletConfig做了一些方法。
HttpServlet:
继承GenericServlet,实现了service()方法,并作了请求的分发处理:
doGet()方法和doPost()方法,并处理了其中的异常。
用户自定义Servlet类:
一般继承HttpServlet重写doGet、doPost方法来实现需求。
ServletConfig类
Servlet 程序的配置信息类(接口)。
Servlet 程序和ServletConfig 对象都是由Tomcat 负责创建,我们负责使用。
ServletConfig 是每个Servlet 程序创建时,就创建一个对应的ServletConfig 对象。
ServletConfig 的作用
- 可以获取Servlet 程序的别名servlet-name 的值(在web.xml配置的信息)
- 获取初始化参数init-param
- 获取ServletContext 对象
@Override
public void init(ServletConfig servletConfig) throws ServletException {
//1.可以获取Servlet程序的别名servlet-name的值
System.out.println("HelloServlet程序的别名是:" + servletConfig.getServletName());
//2.获取初始化参数init-param
System.out.println("初始化参数username的值是:" + servletConfig.getInitParameter("username"));
System.out.println("初始化参数url的值是:" + servletConfig.getInitParameter("url"));
//3.获取ServletContext对象
System.out.println("ServletContext对象:" + servletConfig.getServletContext());
}
初始化参数在web.xml配置信息示例:
<!--init-param是初始化参数-->
<init-param>
<!-- 参数名-->
<param-name>username</param-name>
<!-- 参数值-->
<param-value>root</param-value>
</init-param>
<init-param>
<param-name>url</param-name>
<param-value>jdbc:mysql:/test</param-value>
</init-param>
重写init()方法一定要调用父类的init(config)
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);//使用ServletConfig这个不能丢
System.out.println("重写了init初始化方法,做了一些工作");
}
ServletContext类
- ServletContext 是一个接口,它表示Servlet 上下文对象
- 一个web 工程,只有一个ServletContext 对象实例。
- ServletContext 对象是一个域对象。
- ServletContext 是在web 工程部署启动的时候创建。在web 工程停止的时候销毁。
域对象,是可以像Map 一样存取数据的对象,叫域对象。
这里的域指的是存取数据的操作范围(整个web 工程)。
存储数据 | 获取数据 | 删除数据 | |
---|---|---|---|
Map | put() | get() | remove() |
域对象 | setAttribute() | getAttribute() | removeAttribute(); |
ServletContext 的作用
1、获取web.xml 中配置的上下文参数context-param
2、获取当前的工程路径,格式: /工程路径
3、获取工程部署后在服务器硬盘上的绝对路径
4、像Map 一样存取数据
public class ContextServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1、获取web.xml 中配置的上下文参数context-param
ServletContext servletContext = getServletConfig().getServletContext();
String username = servletContext.getInitParameter("username");
System.out.println("context-param参数username值:" + username);
System.out.println("context-param参数password值:" + getServletContext().getInitParameter("password"));
//2、获取当前的工程路径,格式: /工程路径
System.out.println("当前工程路径是:" + servletContext.getContextPath());
//3、获取工程部署后在服务器硬盘上的绝对路径
// 斜杠表示服务器解析地址为:http://ip:port/工程名/ 映射到IDEA代码的Web目录
System.out.println("工程部署的路径是:" + servletContext.getRealPath("/"));
System.out.println("工程下css目录的绝对路径是:" + servletContext.getRealPath("/css"));
System.out.println("工程下imgs目录下的6.jpg的绝对路径是:" + servletContext.getRealPath("/imgs/6.jpg"));
//获取servletContext对象
ServletContext servletContext = getServletContext();
System.out.println(servletContext);
System.out.println("保存之前: context1 中获取与数据key1的值是:" + servletContext.getAttribute("key1"));
servletContext.setAttribute("key1","value1");
System.out.println("context1 中获取与数据key1的值是:" + servletContext.getAttribute("key1"));
System.out.println("context1 中获取与数据key1的值是:" + servletContext.getAttribute("key1"));
}
}
上下文参数在web.xml 中的配置:
<!-- context-param是上下文参数(它属于整个web工程)-->
<context-param>
<param-name>username</param-name>
<param-value>context</param-value>
</context-param>
<context-param>
<param-name>password</param-name>
<param-value>root</param-value>
</context-param>
HTTP 协议
协议是指双方,或多方,相互约定好,大家都需要遵守的规则,叫协议。
所谓HTTP 协议,就是指,客户端和服务器之间通信时,发送的数据,需要遵守的规则,叫HTTP 协议。HTTP 协议中的数据又叫报文。
请求的HTTP 协议格式:
客户端给服务器发送数据叫请求。
服务器给客户端回传数据叫响应。
请求又分为GET 请求,和POST 请求两种
GET 请求
- 请求行
(1) 请求的方式GET
(2) 请求的资源路径[+?+请求参数]
(3) 请求的协议的版本号HTTP/1.1 - 请求头
key : value 组成不同的键值对,表示不同的含义。
GET请求没有请求体
POST 请求
- 请求行
(1) 请求的方式POST
(2) 请求的资源路径[+?+请求参数]
(3) 请求的协议的版本号HTTP/1.1 - 请求头
- key : value 不同的请求头,有不同的含义
- 空行
- 请求体===>>> 就是发送给服务器的数据
常用请求头的说明
Accept: 表示客户端可以接收的数据类型
Accpet-Languege: 表示客户端可以接收的语言类型
User-Agent: 表示客户端浏览器的信息
Host: 表示请求时的服务器ip 和端口号
哪些操作是GET请求与POST 请求
GET 请求有哪些:
1、form 标签method=get
2、a 标签
3、link 标签引入css
4、Script 标签引入js 文件
5、img 标签引入图片
6、iframe 引入html 页面
7、在浏览器地址栏中输入地址后敲回车
8、Ajax:type:“GET”
POST 请求有哪些:
1、form 标签method=post
2、Ajax:type:“POST”
响应的HTTP 协议格式
- 响应行
(1) 响应的协议和版本号
(2) 响应状态码
(3) 响应状态描述符 - 响应头
(1) key : value 不同的响应头,有其不同含义 - 空行
- 响应体---->>> 就是回传给客户端的数据