javaweb(07) Servlet详解
javaweb(07) Servlet详解
什么是Servlet
简介
- 从广义上来讲,Servlet规范是Sun公司制定的一套技术标准,包含与web应用相关的一系列接口,是web应用实现方式的宏观解决方案。而具体的Servlet容器负责提供标准的实现。
- 从狭义上讲,Servlet指的是javax.servlet.Servlet接口及其子接口,也可以值实现了Servlet接口的实现类。
- Servlet作为服务端的一个组件,它的本意是“服务端的小程序”。Servlet的实例对象由Servlet容器负责创建;Servlet的方法由容器在特定情况下调用;Servlet容器会在web应用卸载时销毁Servlet对象的实例
- servlet 是运行在 Web 服务器中的小型 Java 程序。servlet 通常通过 HTTP(超文本传输协议)接收和响应来自 Web 客户端的请求。
Servlet作用
- 接受请求
- 处理请求
- 完成响应
第一个Servlet程序
步骤
1、编写一个类去实现 Servlet 接口
2、实现 service 方法,处理请求,并响应数据
3、到 web.xml 中去配置 servlet 程序的访问地址
具体实现及注释
1、编写一个类去实现 Servlet 接口
2、实现 service 方法,处理请求,并响应数据
3、到 web.xml 中去配置 servlet 程序的访问地址
完成前面步骤后,启动服务器,在浏览器上输入 http://localhost:8080/05_servlet/hello即可发出请求,服务器会响应。
实现流程图解
Servlet的生命周期
- servlet是跑在tomcat服务器上的,而servlet对象通过servlet容器在服务器上创建。
- servlet的生命周期是指servlet从创建到销毁的过程
测试Servlet各个方法的运行时机
测试类代码:
package com.deserts.servlet1;
import javax.servlet.*;
import java.io.IOException;
/**
* @ClassName TestServlet
* @Description 测试servlet的生命周期
* @Author deserts
* @Date 2020/8/9 17:38
*/
public class TestServlet implements Servlet {
public TestServlet(){
System.out.println("我是构造器...\n");
}
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("init...\n");
}
@Override
public ServletConfig getServletConfig() {
System.out.println("getServletConfig...\n");
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("service...\n");
}
@Override
public String getServletInfo() {
System.out.println("getServletInfo...\n");
return null;
}
@Override
public void destroy() {
System.out.println("destroy...");
}
}
配置文件:
启动服务器,发现没有方法被调用:
访问test资源时,发现先调用构造方法创建对象,再调用初始化方法,再调用service方法:
再次访问test资源时,发现只调用了service方法,并没有再次调用构造器创建对象:
当我们断开与服务器的连接时,发现在断开前调用了destroy方法,销毁对象:
servlet生命周期的总结
当我们第一次请求访问test资源时:
- 创建一个servlet对象
- 调用init方法,初始化servlet
- 调用service方法处理请求
以后再次请求:
- 只调用service方法处理请求
项目从服务器卸载时:
- 服务器会调用destroy方法销毁对象
servlet是一个单例,多线程运行。
ServletConfig
ServletConfig类的三大作用
-
可以获取 Servlet 程序的别名 servlet-name 的值
-
获取初始化参数 init-param
-
获取 ServletContext 对象
代码实现
配置文件主要内容:
servlet主要代码(也可以在方法外声明servletConfig变量,在init方法初始化,在service中使用):
控制台输出结果:
ServletContext
什么是ServletContext
-
ServletContext 是一个接口,它表示 Servlet 上下文对象
-
一个 web 工程,只有一个 ServletContext 对象实例。
-
ServletContext 对象是一个域对象。(application)
-
ServletContext 是在 web 工程部署启动的时候创建。在 web 工程停止的时候销毁。
什么是域对象?
域对象,是可以像 Map 一样存取数据的对象,叫域对象。 这里的域指的是存取数据的操作范围,整个 web 工程。
ServletContext的四个作用
-
获取 web.xml 中配置的上下文参数 context-param
-
获取当前的工程路径,格式: /工程路径
-
获取工程部署后在服务器硬盘上的绝对路径 (资源的真实路径)
-
像 Map 一样存取数据
代码实现
配置文件主要内容:
前三个功能的验证:
运行结果:
第四个作用在四大域对象学完一起总结。
HttpServlet
实际开发中我们继承HttpServlet抽象类去实现Servlet程序。
HttpServlet源码解析
继承体系
HttpServlet继承GenericServlet,而GenericServlet继承了Servlet:
服务器运行Servlet,那为什么实现HttpServlet就可以了呢?可以从Servlet接口和GenericServlet中找到答案
Servlet接口
Servlet接口有几个抽象方法,其中service是处理请求的核心方法,接下来看看GenericServlet!
GenericServlet抽象类
GenericServlet抽象类没有太大的特别之处,大boss是HttpServlet。
public abstract void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
HttpServlet抽象类
查看HttpServlet的类结构,发现该类重载了service方法,两个方法参数类型不同:
接下来可以看看参数类型未ServletRequest和ServletResponse的方法:
可以知道,该方法将两个参数进行强转,并调用了另一个重载的service方法,接下来可以看看这个方法:
第一部分,获取http请求的类型,如果为GET类型,调用doGet方法,处理请求:
第二部分,如果为其它类型的,根据类型处理请求,若请求类型不是http类型的,抛异常:
总结
至此可知,继承HttpServlet的类处理请求,服务器会调用原始的service方法,在该方法中对两个参数进行强转,再调用与强转后类型匹配的service重载方法,在该重载方法中,会获取客户端发出的HTTP请求的类型,再根据请求类型调用相应的方法处理请求,因此,我们在继承HttpServlet抽象类后,只需要重写doXXX方法,服务器会自动调用,我们一般重写doGet方法和doPost方法。
过程图解
HttpServletResponse类的作用
作用
- 给浏览器响应字符串
- 可以重定向到一个页面或其它资源,重定向就是告诉浏览器重新请求别的资源
示例
HttpServletRequest类的作用
作用
- 获取请求数据。当键值是一对一时(如文本框),使用getParameter()获取;当键值是多对一时(如多选框),使用getParameterValues()获取多选框的内容。
- 获取请求头信息
- 转发一个页面或资源
- 作为域对象共享数据(request)
示例
核心代码:
index.html表单代码:
服务器开启后的页面:
提交后的页面:
控制台输出:
转发和重定向的区别
转发和重定向过程图解
转发:
重定向:
区别
转发 | 重定向 | |
---|---|---|
浏览器地址 | 不会变化 | 会变化 |
Request | 同一个请求 | 两次请求 |
API | Request对象 | Response对象 |
位置 | 服务器内部完成 | 浏览器完成 |
WEB-INF文件夹 | 可以访问 | 不能访问 |
共享请求域数据 | 可以共享 | 不可以共享 |
目标资源 | 必须是当前web应用中的资源 | 不局限于当前web应用 |
乱码问题
- 编码:将字符转换为二进制数
- 解码:将二进制数转换为字符
- 乱码:一段文本,使用A字符集编码,使用B字符集解码,就会产生乱码。所以解决乱码问题的根本办法就是统一编码和解码的字符集。
响应乱码
产生原因:服务器响应时,浏览器不知道服务器传输的数据的内容类型和编码集
解决方案:告诉浏览器传输的数据的内容类型和编码集
post乱码
产生原因:浏览器将数据编码并提交上来,但是服务器不知道编码规则
解决方法:让服务器知道编码规则即可,重新设置请求的编码格式
get乱码
出现原因:浏览器将地址栏也编码,服务器不知道,而且8080接收到url后,已经按默认解码规则解码了
解决方法:修改tomcat服务器server.xml配置文件,在8080端口号处增加URIEncoding=“UTF-8”
路径问题
相对路径与绝对路径
转发和重定向绝对路径的注意点
1.转发中使用绝对路径写时,/表示从项目的根路径开始,即http://localhost:8080/项目名/如:
request.getRequestDispatcher("/index.html").forword(request,response);
表示的地址是:http://localhost:8080/05_servlet/index.html
2.重定向用绝对路径表示,/表示从Tomcat的根目录开始,即http://localhost:8080/如:
response.sendRedirect("/05_servlet/pages/a.html");
表示的路径是:http://localhost:8080/05_servlet/pages/a.html
重定向时我们动态获取项目的路径,不写死使移植性更高:
response.sendRedirect(request.getContextPath() + "/page/a.html");
base标签的使用
使用base标签,作用就是指定页面上的路径的基础路径,所有路径都是以base标签中指定的基础路径开始。只有相对路径的写法,会按照base标签指定的基础路径来拼接新的路径。如:
<base href="htto://localhost:8080/05_servlet/" />
<a href = "path.html"/>
上一篇: 用php来刷新浪博客访问量
下一篇: Ubuntu系统下搭建MediaWiki