JavaWeb之Web资源与Servlet详解
Web资源与Servlet详解
一、Web资源基础
1. Web资源介绍
Web资源是运行在服务端的资源,主要包括:
- html、jsp、css、js等页面相关资源
- Servlet程序
Web资源分类
- 静态Web资源:不会根据用户、时间、操作变化的资源,无需查询数据库(如html、css、js等)
- 动态Web资源:会根据不同条件展示不同数据,需要程序处理或查询数据库(如servlet、jsp、thymeleaf等)
二、Servlet详解
1. Servlet介绍
Servlet是运行在服务端的小程序,从代码角度看,它是一个接口,我们需要实现该接口来完成一个Servlet程序。
2. Servlet入门
需求:访问一个Servlet,响应"helloservlet"
实现步骤
- 创建一个类
- 实现Servlet接口
- 重写Servlet接口中所有的抽象方法(其中service方法非常重要)
- 在service方法中编写处理请求和响应的代码
- 在web.xml中配置servlet或使用注解配置
- 启动tomcat,运行web项目,通过浏览器访问servlet
直接访问Servlet
public class Servlet1 implements Servlet {@Overridepublic void init(ServletConfig servletConfig) throws ServletException {}@Overridepublic ServletConfig getServletConfig() {return null;}/*** 处理请求和响应的核心方法* @param servletRequest 请求对象* @param servletResponse 响应对象* @throws ServletException* @throws IOException*/@Overridepublic void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {servletResponse.getWriter().write("helloservlet");}@Overridepublic String getServletInfo() {return "";}@Overridepublic void destroy() {}
}
<servlet><!-- servlet-name:自定义的Servlet名称 --><servlet-name>servlet1</servlet-name><!-- servlet-class:Servlet的全限定名 --><servlet-class>com.atguigu.a_servlet.Servlet1</servlet-class>
</servlet><servlet-mapping><!-- 与上方servlet-name保持一致 --><servlet-name>servlet1</servlet-name><!-- url-pattern:浏览器访问路径 --><url-pattern>/servlet1</url-pattern>
</servlet-mapping>
访问路径格式:localhost:8080/web应用名称/urlpattern配置的路径
通过页面访问Servlet
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>首页</title>
</head>
<body><form action="/web应用名称/url-pattern配置的路径" method="get">用户名:<input type="text" name="username"/><br/>密 码:<input type="password" name="password"/><br/><input type="submit" value="登录"></form>
</body>
</html>
Servlet小结
- 在当前project下集成tomcat
- 创建web项目
- 引入tomcat依赖
- 编写servlet并配置(web.xml或注解)
- 部署web项目,修改application context名称
- 启动tomcat,通过配置的url-pattern访问servlet
- 页面访问路径格式:
/web应用程序名称/url-pattern
Web概念汇总
- 原生Tomcat:安装在电脑上的Tomcat软件
- IDEA中的Tomcat实例:通过idea配置的Tomcat,使用原生Tomcat软件
- IDEA中的Web工程:程序员编写的动态Web工程
- war包:根据Web工程生成,实际部署在Tomcat中的文件
- 访问静态资源:
/Web应用名称/静态资源路径
(如:localhost:8080/day06_servlet/index.html)- 访问动态资源:
/Web应用名称/映射路径
(如:localhost:8080/day06_servlet/servlet1)- Web应用名称:部署时设置的ApplicationContext名称,非工程名
3. 注解方式使用Servlet
当Servlet程序较多时,使用web.xml配置会很繁琐,可采用注解方式替代配置文件。
// 注解格式:@WebServlet("/url-pattern的配置")
@WebServlet("/servlet2")
public class Servlet2 implements Servlet {@Overridepublic void init(ServletConfig servletConfig) throws ServletException {}@Overridepublic ServletConfig getServletConfig() {return null;}@Overridepublic void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {servletResponse.getWriter().write("helloservlet2");}@Overridepublic String getServletInfo() {return "";}@Overridepublic void destroy() {}
}
注意:不要同时使用注解和web.xml两种方式配置同一个servlet
4. Servlet的三种映射路径配置
Servlet的映射路径指的是在web.xml中配置的url-pattern或注解中的路径,通过该路径访问对应的servlet。
分类 | 格式 | 说明 |
---|---|---|
精准匹配(完全匹配) | /servlet1 | 访问时必须完整匹配路径才能访问对应的servlet |
目录匹配 | /目录名/* | 访问路径中必须包含指定目录名 |
后缀名匹配 | *.action | 访问路径以指定后缀结尾即可访问 |
public class Servlet3 implements Servlet {@Overridepublic void init(ServletConfig servletConfig) throws ServletException {}@Overridepublic ServletConfig getServletConfig() {return null;}@Overridepublic void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {servletResponse.getWriter().write("servlet3");}@Overridepublic String getServletInfo() {return "";}@Overridepublic void destroy() {}
}
<servlet-mapping><servlet-name>servlet3</servlet-name><!-- 精准匹配 --><!--<url-pattern>/servlet3</url-pattern>--><!-- 目录匹配 --><!--<url-pattern>/cart/*</url-pattern>--> //路径中必须带cart<!-- 后缀名匹配 --><url-pattern>*.action</url-pattern>
</servlet-mapping>
5. Servlet生命周期
生命周期介绍
Servlet的生命周期是指从对象产生到运行再到结束的整个过程,涉及三个关键方法:
public class Servlet4 implements Servlet {// 初始化:第一次访问servlet时,tomcat创建servlet对象并调用init方法@Overridepublic void init(ServletConfig servletConfig) throws ServletException {System.out.println("Servlet4 init");}@Overridepublic ServletConfig getServletConfig() {return null;}// 处理请求:每次访问servlet都会调用@Overridepublic void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {System.out.println("Servlet4 service");}@Overridepublic String getServletInfo() {return "";}// 销毁:tomcat停止或项目从tomcat移除时调用@Overridepublic void destroy() {System.out.println("Servlet4 destroy");}
}
<servlet><servlet-name>servlet4</servlet-name><servlet-class>com.atguigu.a_servlet.Servlet4</servlet-class>
</servlet><servlet-mapping><servlet-name>servlet4</servlet-name><url-pattern>/servlet4</url-pattern>
</servlet-mapping>
Servlet对象提前创建
默认情况下,第一次访问servlet时tomcat才会创建servlet对象。高并发场景下可配置项目启动时就创建servlet对象:
<servlet><servlet-name>servlet5</servlet-name><servlet-class>com.atguigu.a_servlet.Servlet5</servlet-class><!-- 配置提前创建,数字越小优先级越高 --><load-on-startup>2</load-on-startup>
</servlet><servlet-mapping><servlet-name>servlet5</servlet-name><url-pattern>/servlet5</url-pattern>
</servlet-mapping>
6. ServletConfig配置对象(了解)
ServletConfig用于操作web.xml中的参数,主要方法如下:
方法名 | 作用 |
---|---|
getServletContext() | 获取ServletContext对象(代表整个web应用程序) |
getServletName() | 获取中定义的servlet名称 |
getInitParameter(String key) | 根据名字获取初始化参数值 |
getInitParameterNames() | 获取所有初始化参数名组成的Enumeration对象 |
public class Servlet7 implements Servlet {@Overridepublic void init(ServletConfig servletConfig) throws ServletException {// 获取ServletContext对象ServletContext servletContext = servletConfig.getServletContext();System.out.println("servletContext = " + servletContext);// 获取servlet-name参数String servletName = servletConfig.getServletName();System.out.println("servletName = " + servletName);// 获取初始化参数String value1 = servletConfig.getInitParameter("key1");System.out.println("value1 = " + value1);// 获取所有初始化参数Enumeration<String> enumeration = servletConfig.getInitParameterNames();while (enumeration.hasMoreElements()) {String key = enumeration.nextElement();System.out.println(key + " = " + servletConfig.getInitParameter(key));}}// 其他方法省略...
}
<servlet><servlet-name>servlet7</servlet-name><servlet-class>com.atguigu.a_servlet.Servlet7</servlet-class><init-param><param-name>key1</param-name><param-value>zhangsan</param-value></init-param><init-param><param-name>key2</param-name><param-value>lisi</param-value></init-param>
</servlet><servlet-mapping><servlet-name>servlet7</servlet-name><url-pattern>/servlet7</url-pattern>
</servlet-mapping>
7. 继承HttpServlet方式实现Servlet(最常用)
基本说明
- Servlet接口有一个实现类:GenericServlet
- GenericServlet有一个子类:HttpServlet
- HttpServlet提供了处理HTTP请求的方法:
- doGet():处理GET请求
- doPost():处理POST请求
实现示例
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>首页</title>
</head>
<body><form action="/day04_servlet/httpservlet1" method="post">用户名:<input type="text" name="username"/><br/>密 码:<input type="password" name="password"/><br/><input type="submit" value="登录"></form>
</body>
</html>
@WebServlet("/httpservlet1")
public class Servlet1 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("i am get");}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("i am post");}
}
注意:
- 地址栏直接请求是GET请求
- 超链接请求是GET请求
- 表单提交方式由method属性指定
统一处理GET和POST请求
当需要对GET和POST请求进行相同处理时,可以在一个方法中调用另一个方法:
@WebServlet("/httpservlet2")
public class Servlet2 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("处理请求逻辑...");}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 调用doGet方法,统一处理逻辑doGet(req,resp);}
}
Servlet模板配置
为提高开发效率,可以配置Servlet模板:
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
#parse("File Header.java")import java.io.*;
import jakarta.servlet.*;
import jakarta.servlet.http.*;
import jakarta.servlet.annotation.WebServlet;
import java.io.IOException;@WebServlet("/${Class_Name}")
public class ${Class_Name} extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request,response);}
}
8. 路径说明
URL(统一资源定位符)
- 概述:互联网资源的唯一访问地址,客户端通过URL访问具体资源
- 格式:
http://localhost:8080/Web应用名称/项目下的资源
- 用途:客户端访问服务器资源,或服务器之间的资源访问
URI(统一资源标识符)
- 概述:服务器中某个资源的唯一标识,用于同项目内资源访问
- 格式:
/项目部署名/资源路径
- 用途:同一项目中某个资源访问另一个资源
三、ServletContext对象
1. 基本概念
- ServletContext是代表整个web应用的对象,每个web应用只有一个
- 作为域对象使用,是作用范围最大的域对象
- 作用范围:在ServletContext中存储的数据可在当前项目中共享
2. ServletContext对象的获取
@WebServlet(name = "Servlet1", urlPatterns = "/context1")
public class Servlet1 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 获取ServletContext对象ServletContext servletContext = getServletContext();System.out.println("servletContext = " + servletContext);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}
}
说明:
- 我们的类继承了HttpServlet
- HttpServlet继承了GenericServlet
- getServletContext()是GenericServlet中的方法
3. ServletContext常用方法
方法名 | 说明 |
---|---|
String getInitParameter(String key) | 根据获取 |
String getRealPath(“相对路径”) | 获取web应用中资源的绝对路径 |
String getContextPath() | 获取web应用程序的名称 |
String getMimeType(“文件后缀”) | 获取文件的MIME类型 |
@WebServlet("/servlet11")
public class Servlet11 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {ServletContext servletContext = getServletContext();// 获取全局初始化参数String key1 = servletContext.getInitParameter("key1");System.out.println("key1:" + key1);// 获取资源绝对路径String path1 = servletContext.getRealPath("1.txt");System.out.println("path1:" + path1);// 获取web应用名称String contextPath = servletContext.getContextPath();System.out.println(contextPath);// 获取MIME类型String mimeType = servletContext.getMimeType("1.jpg");System.out.println("mimeType:" + mimeType);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}
}
<!-- 全局初始化参数配置 -->
<context-param><param-name>key1</param-name><param-value>我是全局参数</param-value>
</context-param>
4. ServletContext作为域对象
ServletContext作为域对象可以实现数据共享,主要方法:
方法名 | 说明 |
---|---|
setAttribute(String key, Object o) | 往域中存数据 |
getAttribute(String key) | 从域中取数据 |
removeAttribute(String key) | 从域中删除数据 |
// 存储数据
@WebServlet("/servlet12")
public class Servlet12 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {ServletContext servletContext = getServletContext();servletContext.setAttribute("username", "tom");// servletContext.removeAttribute("username");}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}
}// 获取数据
@WebServlet("/servlet13")
public class Servlet13 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {ServletContext servletContext = getServletContext();Object username = servletContext.getAttribute("username");System.out.println("username:" + username);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}
}