JavaWeb——一文带你入门Servlet(生命周期、注解配置方法、IDEA与tomcat的相关配置)
Servlet在JavaWeb中非常重要,在JavaWeb的核心知识体系都是围绕Servlet来转的。
1、Servlet快速入门
Servlet:Server applet,是运行在服务器端的小程序,Servlet就是一个接口,定义了Java类被浏览器访问到(tomcat识别)的规则。需要我们自定义一个类,实现Servlet接口,覆写方法。
快速入门步骤:
- 1)创建JavaEE项目;
- 2)定义一个类,实现Servlet的接口; public class ServletDemo1 implements Servlet
- 3)覆写接口中的抽象方法;
//提供服务的方法
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("Hello Servlet");
}
- 4)配置Servlet(web.xml中 根标签内)
<!-- 配置Servlet -->
<servlet>
<servlet-name>demo1</servlet-name>
<servlet-class>cn.test.web.servlet.ServletDemo1</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>demo1</servlet-name>
<url-pattern>/demo1</url-pattern>
</servlet-mapping>
【实现效果】:运行程序,在浏览器中输入:http://localhost:8080/demo1,在IDEA后台可见输出信息
补充下,如果我们的项目比较多时,为了便于管理,最好是加上虚拟目录,以项目名称命名,在IEDA:RUN-》Edit Configurations中设置:
此时浏览器访问为:
以上就是Servlet的快速入门实践,那么Servlet的执行原理是怎样的呢?
- 1)当服务器接收到浏览器的请求后,会解析请求URL路径,获取访问的Servlet的资源路径;
- 2)查找web.xml文件,是否有对应得<url-pattern>标签体内容;
- 3)若有,则在找到对应的<servlet-class>全类名;
- 4)tomcat会将字节码文件加载进内存,并且创建其对象;
- 5)调用其方法。
2、Servlet中的生命周期
1)被创建:执行init方法,只执行一次
Servlet什么时候被创建?默认情况下,第一次被访问时被创建,我们可以在web.xml文档中<servlet>标签下配置Servlet的创建时机:
- 第一次被访问时创建,<load-on-startup>值为负数(默认为-1)
- 在服务器启动时创建,<load-on-startup>值为0或正整数
Servlet的init方法只执行一次,说明一个Servlet在内存中只存在一个对象,Servlet是单例的。多个用户同时访问时可能存在线程安全问题,为此解决方法是尽量不要在Servlet中定义成员变量,即使定义了成员变量,也不要对其修改值。
2)提供服务:执行service方法,执行多次
每次访问Servlet时,service方法都会被调用一次。
3)被销毁:执行destroy方法,只执行一次
服务器关闭时,Servlet被销毁,注意,是需要服务器正常关闭时,才会执行destroy方法,该方法在Servlet被销毁之前之前,一般用于释放资源。
3、Servlet3.0注解配置
上面我们都是使用web.xml进行Servlet的配置,若一个项目中有很多个Servlet,我们就要在web.xml中针对每一个进行配置,很繁琐。那么有没有更好的配置方法呢?使用Servlet3.0,其好处是支持注解配置,可以不使用web.xml了。步骤:
- 1)创建JavaEE项目,选择Servlet的版本为3.0以上,可以不创建web.xml;
- 2)定义一个类,实现Servlet接口;
- 3)覆写方法;
- 4)在类上使用@WebServlet注解,进行配置; @WebServlet("/资源路径")
public @interface WebServlet {
java.lang.String name() default "";
java.lang.String[] value() default {};
java.lang.String[] urlPatterns() default {};
int loadOnStartup() default -1;
javax.servlet.annotation.WebInitParam[] initParams() default {};
boolean asyncSupported() default false;
java.lang.String smallIcon() default "";
java.lang.String largeIcon() default "";
java.lang.String description() default "";
java.lang.String displayName() default "";
}
【注意】urlparttrn定义Servlet的访问路径:
- 一个Servlet可以定义多个访问路径:@WebServlet({"/d4","/demo4"})
- 路径定义规则: /xxx: /xxx/xxx:多层路径,目录结构,eg:@WebServlet("/user/demo4")、@WebServlet("/user/*") *.do:@WebServlet("*.do")
4、IDEA与tomcat的相关配置
1)IDEA会为每一个tomcat部署的项目单独建立一份配置文件;
查看控制台的log:
Using CATALINA_BASE: "C:UsersthinkAppDataLocalJetBrainsIntelliJIdea2020.1tomcatTomcat_8_5_31_4_servlet"
2)工作空间项目和tomcat部署的web项目
- tomcat真正访问的是“tomcat部署的web项目”,“tomcat部署的web项目”对应着“工作空间项目”的web目录下的所有资源;
- WEB-INF目录下的资源不能被浏览器直接访问;
- 断电调试:使用“小虫子”debug启动。
5、Servlet的体系结构
Servlet——接口 | GenericServlet——抽象类 | HttpServlet——抽象类
以上就是Servlet的继承结构,在前几节中,我们都是实现Servlet接口,不得不覆写Servlet接口的所有抽象方法,实际我们需要用的方法可能只有Service(),那么如何才能简化这种写法呢?
1)GenericServlet:将Servlet接口中的其他方法做了默认空实现,只将service()方法作为抽象,所以,定义Servlet类时,可以继承GenericServlet,实现service()方法即可。
@WebServlet("/demo2")
public class ServletDemo2 extends GenericServlet {
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("demo2....");
}
}
2)HttpServlet:对http协议的封装,可以简化操作,使用步骤如下,我们一般处理http请求时都是使用此方法:
- 定义类继承HttpServlet;
- 覆写doGet或doPost方法;
@WebServlet("/demo3")
public class ServletDemo3 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doGet....");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doPost....");
}
}
本文为博主原创文章,转载请注明出处!
- 使用 React 和 GraphQL 做一个todo list
- 徒手撸框架---实现 Aop
- 基于 Token 的 WEB 后台认证机制
- TiDB 源码阅读系列文章(二)初识 TiDB 源码
- Java 异常处理的 9 个最佳实践
- JavaScript 深拷贝性能分析
- Git 的使用
- Linux 基础:文件查找 find
- PHP 闭包(Closure)初探
- linux服务器apache服务配置wordpress伪静态
- 用 Python 实现一个大数据搜索引擎
- 关于 Java 你不知道的 10 件事
- 如何在一周之内获得GitHub stars 3500+ —为什么对于程序员这是如此的重要
- 程序员做完整性检查的命令行工具
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 事务并发调度的可串行性及两段锁协议
- 面试不易,控场情况下,感觉少要了1万!
- Java 操作 ElasticSearch
- Docker部署常见应用
- Spring 中实现自动注入的几种方式
- Spring 容器的创建过程
- 04 Spring Boot 整合MyBatis
- OpenFeign服务调用
- Windows10安装JDK14
- IDEA 配置 maven 完美解决方案
- 06 Spring Boot 整合Shrio
- List集合转化为数组
- 小心,99%的面试者,都倒在了这里。一文带你了解spring全家桶
- 阿里P9整理Java 高频面试题聊一聊 JUC 下的 LinkedBlockingQueue
- Java环境配置