1、编写一个类去实现 Servlet 接口
2、实现 service 方法,处理请求,并响应数据
3、到 web.xml 中去配置 servlet 程序的访问地址
1、编写一个类去实现 Servlet 接口
2、实现 service 方法,处理请求,并响应数据
3、到 web.xml 中去配置 servlet 程序的访问地址
完成前面步骤后,启动服务器,在浏览器上输入 http://localhost:8080/05_servlet/hello即可发出请求,服务器会响应。
测试类代码:
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是一个单例,多线程运行。
可以获取 Servlet 程序的别名 servlet-name 的值
获取初始化参数 init-param
获取 ServletContext 对象
配置文件主要内容:
servlet主要代码(也可以在方法外声明servletConfig变量,在init方法初始化,在service中使用):
控制台输出结果:
ServletContext 是一个接口,它表示 Servlet 上下文对象
一个 web 工程,只有一个 ServletContext 对象实例。
ServletContext 对象是一个域对象。(application)
ServletContext 是在 web 工程部署启动的时候创建。在 web 工程停止的时候销毁。
域对象,是可以像 Map 一样存取数据的对象,叫域对象。 这里的域指的是存取数据的操作范围,整个 web 工程。
获取 web.xml 中配置的上下文参数 context-param
获取当前的工程路径,格式: /工程路径
获取工程部署后在服务器硬盘上的绝对路径 (资源的真实路径)
像 Map 一样存取数据
配置文件主要内容:
运行结果:
第四个作用在四大域对象学完一起总结。
实际开发中我们继承HttpServlet抽象类去实现Servlet程序。
HttpServlet继承GenericServlet,而GenericServlet继承了Servlet:
服务器运行Servlet,那为什么实现HttpServlet就可以了呢?可以从Servlet接口和GenericServlet中找到答案
Servlet接口有几个抽象方法,其中service是处理请求的核心方法,接下来看看GenericServlet!
GenericServlet抽象类没有太大的特别之处,大boss是HttpServlet。
public abstract void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
查看HttpServlet的类结构,发现该类重载了service方法,两个方法参数类型不同:
接下来可以看看参数类型未ServletRequest和ServletResponse的方法:
可以知道,该方法将两个参数进行强转,并调用了另一个重载的service方法,接下来可以看看这个方法:
第一部分,获取http请求的类型,如果为GET类型,调用doGet方法,处理请求:
第二部分,如果为其它类型的,根据类型处理请求,若请求类型不是http类型的,抛异常:
至此可知,继承HttpServlet的类处理请求,服务器会调用原始的service方法,在该方法中对两个参数进行强转,再调用与强转后类型匹配的service重载方法,在该重载方法中,会获取客户端发出的HTTP请求的类型,再根据请求类型调用相应的方法处理请求,因此,我们在继承HttpServlet抽象类后,只需要重写doXXX方法,服务器会自动调用,我们一般重写doGet方法和doPost方法。
核心代码:
index.html表单代码:
服务器开启后的页面:
提交后的页面:
控制台输出:
转发:
重定向:
转发 | 重定向 | |
---|---|---|
浏览器地址 | 不会变化 | 会变化 |
Request | 同一个请求 | 两次请求 |
API | Request对象 | Response对象 |
位置 | 服务器内部完成 | 浏览器完成 |
WEB-INF文件夹 | 可以访问 | 不能访问 |
共享请求域数据 | 可以共享 | 不可以共享 |
目标资源 | 必须是当前web应用中的资源 | 不局限于当前web应用 |
产生原因:服务器响应时,浏览器不知道服务器传输的数据的内容类型和编码集
解决方案:告诉浏览器传输的数据的内容类型和编码集
产生原因:浏览器将数据编码并提交上来,但是服务器不知道编码规则
解决方法:让服务器知道编码规则即可,重新设置请求的编码格式
出现原因:浏览器将地址栏也编码,服务器不知道,而且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 href="htto://localhost:8080/05_servlet/" />