Serlet
:server applet
概念:运行在服务器端的小程序
servlet
就是一个接口,定义了java
类被浏览器访问到tomcat
识别的规则【其实就是接口】- 定义的类实现
Servlet
接口,重写方法
可以理解为:用户通过url
访问服务器,在服务器中有编写的java
类【该类没有main
方法】需要依赖于web
服务器才能运行,这种的java
类必须遵守一定的规则 【在java
中规则就是接口】,其实就是实现接口,web
服务器才能识别。
Serlet
快速入门
步骤:
-
创建一个
javaee
项目 -
定义一个类,并实现
Servlet
接口 -
实现接口中所有抽象方法
-
配置
Servlet
- 配置定义类的全路径
- 映射路径
<!--1.配置定义类的全路径--> <servlet> <servlet-name>servlet1</servlet-name> <servlet-class>com.example.web.Servlet01</servlet-class> <!-- 修改创建Servlet对象的时机 1.默认情况下是第一次访问时,创建Servlet, 值是一个正负数 2.可以修改为服务器启动时,创建Servlet, 值是一个0或正数 --> <load-on-startup>1</load-on-startup> </servlet> <!--配置映射--> <servlet-mapping> <servlet-name>servlet1</servlet-name> <url-pattern>/servlet1</url-pattern> </servlet-mapping>
在IDEA
中设置项目的虚拟目录:
执行原理
- 当服务器接受到客户端浏览器的请求后,会解析请求
url
路径,获取访问的servlet
资源路径 - 查找
web.xml
,在映射配置中的<url-pattern>
中是否有对应的资源名称 - 如果有,则继承查找相应的
<servlet-class>
全类名 tomcat
服务器会将该类的字节码加载进行内存,并且创建该的对象- 调用该的方法
Servlet
生命周期
1.被创建:执行一次init
方法,只执行一次
Servlet
什么时候创建?
《1》默认情况下,第一次访问时,Servlet
被创建
《2》可以配置执行Servlet
标签下配置
在<servlet>
标签下配置
<!-- 修改创建Servlet对象的时机
1.默认情况下是第一次访问时,创建Servlet, 值是一个正负数
2.可以修改为服务器启动时,创建Servlet, 值是一个0或正数
-->
<load-on-startup>1</load-on-startup>
2.Servlet
的init
方法,只执行一次,说明只有一个Servlet
对象在内存中,因为Servlet
是单例的
- 当多个用户访问时,可能存在线程安全问题
- 解决线程安全问题:尽量不要在
Servlet
中定义在成员变量,即使定义了成员变量,也不要对成员变量修改值
2.提供服务:执行servlce
方法
- 每次访问
Servlet
时,Servlet
方法都会被调用一次
3.被销毁:执行destroy
方法,前提是正常关闭服务器,只执行一次
Servlet
被销毁时执行,服务器关闭时,Servlet
被销毁- 只有服务器正常关闭时,才会执行
destroy
方法 - 在
Servlet
销毁前先执行destroy
方法后销毁,一般用于释放资源
/**
* @author: 海康
* @version: 1.0
*
* Servlet快速入门步骤:
* 创建一个javaee项目
* 定义一个类实现Servlet接口
* 实现接口中所有方法
* 配置web.xml文件,指定定义的类名和映射路径
*/
public class Servlet01 implements Servlet {
/**
* 初始化方法
* 在Servlet创建时,执行,只会执行一次
* @param servletConfig
* @throws ServletException
*/
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
/**
*获取ServletConfig对象
* ServletConfig:Servlet的配置对象
*/
@Override
public ServletConfig getServletConfig() {
return null;
}
/**
* 服务访问一次执行一次
*/
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("您好:湛江,我的家!");
}
/**
* 获取Servlet的一些信息,版本,作用等等
*/
@Override
public String getServletInfo() {
return null;
}
/**
* 销毁方法
* 在服务器正常关闭时,执行一次
*/
@Override
public void destroy() {
}
}
使用注解开发javaweb
项目
好处:支持注解配置,可以不需要web.xml
文件
@WebServlet(urlPatterns = {"/httpSer"})
,注意是一定不能漏掉/
,否则会报下以的错误
Artifact javaweb01:war exploded: Error during artifact deployment. See server log for details.
使用步骤:
-
创建
javaee
项目,选择Servlet
的版本是3.0
以上,可以不创建web.xml
-
定义一个类,实现
Servlet
接口 -
实现
Servlet
接口中所有方法 -
在类上使用
@WebServlet
注解,进行配置@WebServlet(urlPatterns="资源路径")
http://localhost:8080/javaweb02_annotation_war_exploded/demo1
/javaweb02_annotation_war_exploded
表示项目的虚拟路径
/demo1
表示是资源路径
@WebServlet(urlPatterns = "demo1")
public class Servlet_ann 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("您好javaweb注解开发...");
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
IDEA
与tomcat
相关配置
-
IDEA
会为每一个tomcat
部署的项目单独建立一份配置文件可以查看控制台的
log
uSING CATALINA_BASE:
-
工作空间的项目 和
tomcat
部署的web
项目tomcat
真正访问的是tomcat
部署的web
项目,tomcat
部署的web
项目对应着 “工作空间项目” 的web
目录下的所有资源WEB-INF
目录下的资源不能被浏览器直接访问
断点调试:使用"小虫子"启动dubug
启动
Serlvet
的体系结构
Serlvet
接口中有一个抽象类GenericServlet
而GenericServlet
又有一个抽象类HttpServlet
抽象
GenericServlet
:将Servlet
接口中其他的方法做了默认空实现,只将service()
方法作为为抽象
在继承GenericServlet
类时,只需要实现service()
方法即可
HttpServlet
:对http
协议的一种封装,简化操作
使用的步骤是:
- 定义一个类继承
HttpServlet
抽象类 - 一般重写
doGet()
方法和doPost()
方法
HttpServlet
抽象类出现的本质是:由于每个service()
方法都需要对请求进行判断是get
请求还pout
请求等等,所以sun
提供了HttpServlet
抽象,帮助我们判断
HttpServlet
抽象类的继承关系
相关的方法和字段
HttpServlet
中service
源码
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
HttpServletRequest request;
HttpServletResponse response;
try {
request = (HttpServletRequest)req;
response = (HttpServletResponse)res;
} catch (ClassCastException var6) {
throw new ServletException("non-HTTP request or response");
}
this.service(request, response);
}
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String method = req.getMethod();
long lastModified;
if (method.equals("GET")) {
lastModified = this.getLastModified(req);
if (lastModified == -1L) {
this.doGet(req, resp);
} else {
long ifModifiedSince = req.getDateHeader("If-Modified-Since");
if (ifModifiedSince < lastModified) {
this.maybeSetLastModified(resp, lastModified);
this.doGet(req, resp);
} else {
resp.setStatus(304);
}
}
} else if (method.equals("HEAD")) {
lastModified = this.getLastModified(req);
this.maybeSetLastModified(resp, lastModified);
this.doHead(req, resp);
} else if (method.equals("POST")) {
this.doPost(req, resp);
} else if (method.equals("PUT")) {
this.doPut(req, resp);
} else if (method.equals("DELETE")) {
this.doDelete(req, resp);
} else if (method.equals("OPTIONS")) {
this.doOptions(req, resp);
} else if (method.equals("TRACE")) {
this.doTrace(req, resp);
} else {
String errMsg = lStrings.getString("http.method_not_implemented");
Object[] errArgs = new Object[]{method};
errMsg = MessageFormat.format(errMsg, errArgs);
resp.sendError(501, errMsg);
}
}
案例:
public class HttpServlet1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("是get请求...");
// 在浏览器中默认是get请求
}
@Override
protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("是put请求...");
}
}
Servlet
相关注解路径配置
urlpartten
:Servlet
访问路径的配置
1.路径定义规则
- 方式一:
/xxx
:路径匹配一定不能漏掉/
,否则报错 - 方式二:
/xxx/xxx
:多层路径,目录结构 一定不能漏掉/
,否则报错 - 方式三:
*.xx
:扩展名匹配一定不能加在星号的前/
,否则报错
2.一个Servlet
可以定义多个访问路径:例如:@WebServlet(urlPatterns = {"/httpSer1","/httpSer2","/httpSer3"})
如果路径格式书写不正确,一般会报错,错误形式为:Artifact javaweb01:war exploded: Error during artifact deployment. See server log for details.
案例:
//@WebServlet({"/d4","/dd4","/ddd4"})
//@WebServlet("/user/demo4")
//@WebServlet("/user/*")
//@WebServlet("/*")