1、什么是Servlet
-
Servlet是JaveEE规范之一,规范就是接口
-
Servlet是JavaWeb三大组件之一。三大组件分别是:Servlet程序、Filter过滤器、Listener监听器
-
Servlet是运行在服务器上的一个java小程序,它可以接收客户端发送来的请求,并响应数据给客户端
2、手动实现Servlet程序
-
编写一个类去实现Servlet接口
-
实现service方法,处理请求,并响应数据
-
到web.xml中去配置程序的访问地址
package com.first.cyh;
import jakarta.servlet.*;
import java.io.IOException;
public class HelloServlet implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println(“Hello Servlet!”);
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
<?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”>
HelloServlet
com.first.cyh.HelloServlet
HelloServlet
/hello
3、url地址到Servlet程序的访问
4、Servlet的生命周期
-
执行Servlet构造器方法
-
执行init初始化方法
- 第一、二步是在第一次访问的时候创建Servlet程序时才调用
- 执行service方法
- 每次访问都会调用
- 执行destroy销毁方法
- 在web工程停止的时候调用
5、GET和POST请求的分发处理
package com.first.cyh;
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import java.io.IOException;
public class HelloServlet implements Servlet {
public HelloServlet() {
System.out.println(“你好鸭”);
}
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println(“初始化成功咯!”);
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
//ServletRequest和HttpServletRequest是两个接口,HttpServletRequest继承自ServletRequest
//此处的形式参数其实是HttpServletRequest接口的实现类,因为接口不能实例化,所以传进来的是实现类
//因为需要实现ServletRequest到HttpServletRequest的强制类型转换(父类到子类)
//只有父类对象是用子类构造方法生成的才能实现强制转换,所以传进来的参数应该是HttpServletRequest接口的实现类
//强制类型转换,因为HTTPServletRequest接口才有getMethod方法来判断请求的类型
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
String method = httpServletRequest.getMethod();
if(method.equals(“GET”)){
doGet();
}
else if(“POST”.equals(method)){
doPost();
}
}
private void doGet() {
System.out.println(“我是GET请求”);
}
private void doPost() {
System.out.println(“我是POST请求”);
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
System.out.println(“拜拜QAQ”);
}
}
6、通过继承HttpServlet实现Servlet程序
一般在实际项目开发中,都是使用继承HttpServlet类的方式去实现Servlet程序
-
编写一个类去继承HttpServlet类(Servlet是接口,HttpServlet是类)
-
根据业务需要重写doGet()或doPost()方法
-
到web.xml中配置Servlet程序的访问地址
package com.first.cyh;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
public class HelloServlet2 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println(“hello doPost”);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println(“hello doGet”);
}
}
<?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”>
HelloServlet
com.first.cyh.HelloServlet
HelloServlet
/hello
HelloServlet2
com.first.cyh.HelloServlet2
HelloServlet2
/hello2
7、使用IDEA创建Servlet程序
-
项目结构->Facets->点开Web工程->在底部“根源”处把选项勾上
-
在需要创建Servlet程序的软件包处右键新建->Servlet->为程序命名->去掉创建注解类选项的勾
-
配置文件自动生成改Servlet程序的配置->手动配置该Servlet程序访问路径
-
重写Servlet程序的doGet()和doPost()方法
8、Servlet的继承体系
Servlet接口
Servlet继承体系
ServletConfig类是Servlet程序的配置信息类
二者都是由Tomcat负责创建,我们负责使用
Servlet程序默认是第一次访问时创建对象,而ServletConfig是每个Servlet程序创建时就创建一个对应的ServletConfig对象
1、ServletConfig类的三大作用
-
可以获取Servlet程序的别名servlet-name的值
-
获取初始化参数init-param
-
获取ServletContext对象
HelloServlet
com.first.cyh.HelloServlet
username
root
url
jdbc:mysql//localhost/test
public class HelloServlet implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println(“初始化成功咯!”);
//获取配置文件中servlet-name的值
System.out.println(“servlet程序的别名是” + servletConfig.getServletName());
//获取配置文件中的初始化参数init-param
System.out.println(“初始化参数username的值是” + servletConfig.getInitParameter(“username”));
System.out.println(“初始化参数url的值是” + servletConfig.getInitParameter(“url”));
//获取ServletContext对象
System.out.println(servletConfig.getServletContext());
}
//其他方法省略
}
//输出结果
/*
初始化成功咯!
servlet程序的别名是HelloServlet
初始化参数username的值是root
初始化参数url的值是jdbc:mysql//localhost/test
org.apache.catalina.core.ApplicationContextFacade@5cd687b4
*/
2、注意事项
如果Servlet程序继承HttpServlet类时重写了init(ServletConfig config) throws ServletException方法,需要加上super.init(config)
//这是GenericServlet类(HttpServlet类的父类)中的方法
public void init(ServletConfig config) throws ServletException {
this.config = config;
this.init();
}
public void init() throws ServletException {
}
public ServletConfig getServletConfig() {
return this.config;
}
public class HelloServlet2 extends HttpServlet {
@Override
//Tomcat生成ServletConfig对象并调用init程序
public void init(ServletConfig config) throws ServletException {
//super.init(config);
//如果没有调用父类的init(config)方法,则Tomcat创建的ServletConfig值丢失
//即config属性(定义在GenericServlet类中)没有保存值
System.out.println(“doSth”);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println(“hello doPost”);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println(“hello doGet”);
//由于GenericServlet类中的config没有保存值,所以getServletConfig()方法出现空指针异常
ServletConfig servletConfig = getServletConfig();
System.out.println(“Servlet程序的别名为” + servletConfig.getServletName());
}
}
1、什么是ServletContext
-
ServletContext是一个接口,它表示Servlet上下文对象
-
一个web工程,只有一个ServletContext对象实例
-
ServletConfig对象取决于有多少个Servlet程序(一一对应,只能访问到配置文件中属于自己的配置信息)
-
但ServletContext对象还能访问配置文件中上下文参数
-
ServletContext对象是一个域对象
-
ServletContext对象是在web工程部署启动的时候创建,在web工程停止的时候销毁
什么是域对象
域对象指的是可以像Map一样存取数据的对象
这里的域指的是存取数据的操作范围——整个web工程
| | 存数据 | 取数据 | 删除数据 |
| :-: | :-: | :-: | :-: |
| Map | put() | get() | remove() |
| 域对象 | setAttribute() | getAttribute() | removeAttribute() |
2、ServletContext类的四大作用
-
获取web.xml中配置的上下文参数context-param
-
获取当前工程路径,格式:/工程路径
-
获取工程部署在服务器硬盘上的绝对路径
-
像Map一样存取数据
1)获取信息
<?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”>
username
context
password
root
HelloServlet
com.first.cyh.HelloServlet
username
root
url
jdbc:mysql//localhost/test
HelloServlet
/hello
public class ContextServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取配置文件中的上下文参数
ServletContext context = getServletConfig().getServletContext();
System.out.println(context.getInitParameter(“username”));
System.out.println(context.getInitParameter(“password”));
//获取当前的工程路径,格式:/工程路径
System.out.println(context.getContextPath());
//获取工程部署后在服务器硬盘的绝对路径
/*
getRealPath()返回一个给定虚拟路径的真实路径
这个斜杆表示站点的根,也就是获取网站的根目录,即工程部署路径
而/css就是表示该路径下的css文件夹
*/
System.out.println(context.getRealPath(“/”));
System.out.println(context.getRealPath(“/css”));
System.out.println(context.getRealPath(“/jpg”));
}
}
上述程序执行后会返回
context
root
/myfirst
E:\eclipse-workspace\Javaweb-servlet\out\artifacts\Javaweb_servlet_war_exploded
E:\eclipse-workspace\Javaweb-servlet\out\artifacts\Javaweb_servlet_war_exploded\css
E:\eclipse-workspace\Javaweb-servlet\out\artifacts\Javaweb_servlet_war_exploded\jpg
而为什么获得的路径为什么和我们项目创建的路径不一样,在我的另一篇博文web工程部署路径与getServletConfig().getRealPath()中详细讲解了
为什么需要获取工程存放路径呢?
因为项目在本地开发后,项目中的文件路径写的是本地的路径。然而当项目部署到其他设备后,物理地址发生改变,就会导致文件找不到而报错。
2)存取数据
public class ContextServlet1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//GenericServlet获取获取ServletContext对象的方式,等同于getServletConfig().getServletContext()
ServletContext servletContext = getServletContext();
System.out.println(“保存之前Context1中获取域数据key1的值是:” + servletContext.getAttribute(“key1”));
//存数据
servletContext.setAttribute(“key1”,“value1”);
//取数据
System.out.println(“Context1中获取域数据key1的值是:” + servletContext.getAttribute(“key1”));
}
}
public class ContextServlet2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext servletContext = getServletContext();
System.out.println(“Context2中获取域数据key1的值是:” + servletContext.getAttribute(“key1”));
}
}
以下为两次访问ContextServlet1输出的结果(没有重新部署)
保存之前Context1中获取域数据key1的值是:null
Context1中获取域数据key1的值是:value1
保存之前Context1中获取域数据key1的值是:value1
Context1中获取域数据key1的值是:value1
重新部署后再次访问ContextServlet1输出的结果
保存之前Context1中获取域数据key1的值是:null
Context1中获取域数据key1的值是:value1
这是因为ServletContext对象是在web工程部署启动的时候创建,在web工程停止的时候销毁,所以没有重新部署的话key1在set之后就一直存在,所以第二次及以后访问时都会有保存之前Context1中获取域数据key1的值是:value1
,而重新部署之后第一次访问就又是null
而前文中的getInitParameter()获取的数据是保存在xml文件中的,故一直存在
总结
setAttribute方式存参数相当于把数据存在内存中,工程停止时消失,而xml方式存参数则是持久化到硬盘中
getInitParameter获得的是xml方式存储的参数
getAttribute获得的是setAttribute方式存储的参数
而当我们已经访问完ContextServlet1后再访问ContextServlet2,会输出
Context2中获取域数据key1的值是:value1
这是因为一个web工程,只有一个ServletContext对象实例,两个Servlet程序中的servletContext其实是相同的,如果我们在两个程序中都输出servletContext这个对象,值是相同的
所以当第一个Servlet程序设置完key1参数后,第二个自然也可以使用它
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
tParameter()获取的数据是保存在xml文件中的,故一直存在
总结
setAttribute方式存参数相当于把数据存在内存中,工程停止时消失,而xml方式存参数则是持久化到硬盘中
getInitParameter获得的是xml方式存储的参数
getAttribute获得的是setAttribute方式存储的参数
而当我们已经访问完ContextServlet1后再访问ContextServlet2,会输出
Context2中获取域数据key1的值是:value1
这是因为一个web工程,只有一个ServletContext对象实例,两个Servlet程序中的servletContext其实是相同的,如果我们在两个程序中都输出servletContext这个对象,值是相同的
所以当第一个Servlet程序设置完key1参数后,第二个自然也可以使用它
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-RFzS3Lw3-1715572894054)]
[外链图片转存中…(img-t2pAnmDP-1715572894054)]
[外链图片转存中…(img-vU8iNofn-1715572894055)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!