大家好,欢迎来到IT知识分享网。
5.2 Servlet
Servlet 是Java提供的一门动态web资源开发技术
5.2.1 快速入门
需求分析:编写一个Servlet类,并使用IDEA中Tomcat插件进行部署,最终通过浏览器访问所编写的Servlet程序
- 导入 Servlet 依赖坐标
- <dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
provided 指在编译和测试过程这种有效,最后生成的war包时不会加入
因为Tomcat的lib目录中已经有servlet-api这个jar包,如果在生成war包的时候生效就会和Tomcat中的jar包冲突,导致报错
–>
<scope>provided</scope>
</dependency> - 定义类,实现 Servlet 接口,并重写接口中所有方法,并在 service 方法中打印一句话
- import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;
* @Author 晨默
* @Date 2022/8/30 21:44
*/
@WebServlet(“/demo1”)
public class ServletDemo1 implements Servlet {
public void init(ServletConfig servletConfig) throws ServletException {}
public ServletConfig getServletConfig() {
return null;
}
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println(“servlet hello world~”);
}
public String getServletInfo() {
return null;
}
public void destroy() {}
} - 配置:在 ServletDemo 类上使用 @WebServlet 注解,配置该 Servlet 的访问路径
- @WebServlet(“/demo1”)
- 访问:启动Tomcat,浏览器输入 URL 地址访问该 Servlet
- http://localhost:5050/tomcat-demo-war/demo1
- 访问后,在控制台就会打印 servlet hello world~。程序运行成功
5.2.2 执行流程
- 浏览器发出 http://localhost:5050/tomcat-demo-war/demo1 的请求
- localhost:5050 :找到要访问的Tomcat Web服务器
- tomcat-demo:找到部署在Tomcat服务器上的tomcat-demo项目
- demo1:找到要访问的是项目中的哪个Servlet类,根据@WebServlet后面的值进行匹配
- 找到ServletDemo1这个类后,Tomcat Web服务器就会为ServletDemo1这个类创建一个对象,然后调用对象的service方法
- service方法中有 ServletRequest 和 ServletResponse 两个参数。
- ServletRequest:请求数据;
- ServletResponse:响应数据
- 5.2.3 生命周期1. 生命周期对象的生命周期指一个对象从被创建到被销毁的整个过程2. Servlet 生命周期Servlet运行在Servlet容器(web服务器)中,其生命周期由容器来管理,分为4个阶段
- 加载和实例化:默认情况下,当 Servlet 第一次被访问时,有容器创建 Servlet 对象
- 默认情况,Servlet会在第一次访问被容器创建,但是如果创建Servlet比较耗时的话,那么第一个访问的人等待的时间就比较长,用户的体验就比较差,那么我们能不能把Servlet的创建放到服务器启动的时候来创建,具体如何来配置?
@WebServlet(urlPatterns = “/demo1”, loaOnStartup = 1)
loadOnStartup的取值有两类情况
(1)负整数:第一次访问时创建 Servlet 对象
(2)0或正整数:服务器启动时创建 Servlet 对象,数字越小优先级越高 - 初始化:在 Servlet 实例化之后,容器将调用 Servlet 的 init() 初始化对象,完成一些如加载配置文件、创建连接等初始化的工作。该方法只调用一次
- 请求处理:每次请求Servlet时,Servlet容器都会调用Servlet的service()方法对请求进行处理
- 服务终止:当需要释放内存或者容器关闭时,容器就会调用Servlet实例的destroy()方法完成资源的释放。在destroy()方法调用之后,容器会释放这个Servlet实例,该实例随后会被Java的垃圾收集器所回收
- Terminal命令行中,用 mvn tomcat7:run 启动tomcat后,用 Ctrl+C 关闭tomcat,即可调用 destroy 方法
- import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;
* @Author 晨默
* @Date 2022/8/31 8:33
*/
@WebServlet(urlPatterns = “/demo2”, loadOnStartup = 1)
public class ServletDemo2 implements Servlet {
* 初始化方法
* 1.调用时机:默认情况下,Servlet被第一次访问时,调用
* * loadOnStartup: 默认为-1,修改为0或者正整数,则会在服务器启动的时候,调用
* 2.调用次数: 1次
* @param servletConfig
* @throws ServletException
*/
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println(“init….”);
}
public ServletConfig getServletConfig() {
return null;
}
* 提供服务
* 1.调用时机:每一次Servlet被访问时,调用
* 2.调用次数: 多次
* @param servletRequest
* @param servletResponse
* @throws ServletException
* @throws IOException
*/
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println(“Servlet, Hello World!”);
}
public String getServletInfo() {
return null;
}
* 销毁方法
* 1.调用时机:内存释放或者服务器关闭的时候,Servlet对象会被销毁,调用
* 2.调用次数: 1次
*/
@Override
public void destroy() {
System.out.println(“destroy….”);
}
}
5.2.4 Servlet 方法介绍- 获取 Servlet 信息
- String getServletInfo() // 该方法用来返回 Servlet 的相关信息,没什么打印出,一般返回一个空字符串即可
public String getServletInfo(){
return “”;
} - 获取 ServletConfig 对象
- ServletConfig getServletConfig()
- 5.2.5 体系结构Servlet 的体系结构
1. Servlet 简化编写自定义Servlet继承自HttpServlet,只实现 service 方法 import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
* @Author 晨默
* @Date 2022/8/31 9:04
*/
@WebServlet(“/demo4”)
public class ServletDemo4 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO GET
System.out.println(“get….”);
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO POST
System.out.println(“post…”);
}
}2. GET、POST 判断优化 —— HttpServlet类提供 protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
String method = req.getMethod();
long lastModified = getLastModified(req);
if (lastModified == –1) {
// servlet doesn’t support if-modified-since, no reason
// to go through further expensive logic
doGet(req, resp);
} else {
long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
if (ifModifiedSince < lastModified) {
// If the servlet mod time is later, call doGet()
// Round down to the nearest second for a proper compare
// A ifModifiedSince of -1 will always be less
maybeSetLastModified(resp, lastModified);
doGet(req, resp);
} else {
resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
}
}}
else if (method.equals(METHOD_HEAD)) {
long lastModified = getLastModified(req);
maybeSetLastModified(resp, lastModified);
doHead(req, resp);}
else if (method.equals(METHOD_POST)) {
doPost(req, resp);}
else if (method.equals(METHOD_PUT)) {
doPut(req, resp);}
else if (method.equals(METHOD_DELETE)) {
doDelete(req, resp);}
else if (method.equals(METHOD_OPTIONS)) {
doOptions(req,resp);}
else if (method.equals(METHOD_TRACE)) {
doTrace(req,resp);}
else {
//
// Note that this means NO servlet supports whatever
// method was requested, anywhere on this server.
//
Object[] errArgs = new Object[1];
errArgs[0] = method;
errMsg = MessageFormat.format(errMsg, errArgs);
}
}5.2.6 urlPattern 配置Servlet类编写好后,要想被访问到,就需要配置其访问路径(urlPattern)- 一个Servlet可以配置多个urlPattern
- 如:@WebServlet(urlPatterns = {“/demo1”,”demo2})
- localhost:8080/demo71,localhost:8080/demo1`这两个地址都能访问到
- urlPattern配置规则
- 如果路径配置的不是扩展名,那么在路径的前面就必须要加/,否则会报错
- 如果路径配置的是*.do,那么在*.do的前面不能加/,否则会报错
- 精确匹配
- 目录匹配
- 访问路径localhost:8080/user/任意
- 思考:
- 答案是: 能、能、demo8,进而我们可以得到的结论是/user/*中的/*代表的是零或多个层级访问目录,同时精确匹配优先级要高于目录匹配。
- 扩展名匹配
- 注意:
- 任意匹配
- 注意:/和/*的区别?
- 当我们的项目中的Servlet配置了 “/”,会覆盖掉tomcat中的DefaultServlet,当其他的url-pattern都匹配不上时都会走这个Servlet
- 当我们的项目中配置了”/*”,意味着匹配任意访问路径
- DefaultServlet是用来处理静态资源,如果配置了”/”会把默认的覆盖掉,就会引发请求静态资源的时候没有走默认的而是走了自定义的Servlet类,最终导致静态资源不能被访问
- 访问路径http://localhost:8080/web-demo/user是否能访问到demo9的doGet方法?
- 访问路径http://localhost:8080/web-demo/user/a/b是否能访问到demo9的doGet方法?
- 访问路径http://localhost:8080/web-demo/user/select是否能访问到demo9还是demo8的doGet方法?
- 5.2.7 XML配置前面对应Servlet的配置,我们都使用的是@WebServlet,这个是Servlet从3.0版本后开始支持注解配置,3.0版本前只支持XML配置文件的配置方法。对于XML的配置步骤有两步:
- 编写Servlet类
- 在web.xml中配置该Servlet
- <?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”>
Servlet 全类名
–>
<servlet>
<!– servlet的名称,名字任意–>
<servlet-name>demo13</servlet-name>
<!–servlet的类全名–>
<servlet-class>com.itheima.web.ServletDemo13</servlet-class>
</servlet>
Servlet 访问路径
–>
<servlet-mapping>
<!– servlet的名称,要和上面的名称一致–>
<servlet-name>demo13</servlet-name>
<!– servlet的访问路径–>
<url-pattern>/demo13</url-pattern>
</servlet-mapping>
</web-app>
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/7041.html