快速入门
**servlet2.5 的方式:**必须有 web.xml 配置文件
三个步骤创建一个 servlet:
1.创建一个类实现 servlet 接口
2.重写 service 方法
3.在 web.xml 文件中配置创建的类(将请求路径和 java 程序的对应关系建立起来)
tomcat 只要一启动,就会去加载 web.xml 文件,只加载一次
只要这个 web.xml 配置文件修改了任何一处,都要重新 tomcat 重新加载
servlet 的创建和服务方法、service 的执行都是由 tomcat 自动完成
servlet3.0 的方式:没有web.xml配置文件
步骤:
- 创建 JavaEE6(含6) 以上的工程
2.创建一个类实现 servlet 接口,并在实现类上标注 @WebServle 注解
@WebServlet 注解的属性:
name 属性:servlet名称,相当于web.xml中的<servlet‐name>
urlPatterns 属性:请求路径
示例:@WebServlet(name = “HelloServlet”, urlPatterns = “/hello”)
servlet 的生命周期
一个对象从创建到消亡的过程,就是生命周期。
和 servlet 的生命周期相关的 3 个方法:
// Servlet对象只要一创建出来就会调用的方法 void init(ServletConfig var1) // 处理浏览器交互的方法 void service(ServletRequest var1, ServletResponse var2) // 销毁的方法 void destroy()
Servlet 的生命周期:
浏览器第一次访问该 servlet 的时候,创建该 servlet 的对象,执行 init 初始化方法,只创建一次,请求使用的都是同一个 servlet 对象(单例对象),线程是不安全的
浏览器每次访问的时候都会执行 service 服务方法,访问一次执行一次
当服务器关闭的时候,会销毁该 servlet,执行 destory 方法
servlet 的体系结构
servlet 的继承体系:HttpServlet(功能最多)extends GenericServlet implements Servlet接口
在 servlet 中,真正执行程序逻辑的是 service 方法时,对于 servlet 的初始化和销毁,一般由服务器调用执行,开发者本身不需要关心。
企业开发中:继承 HttpServlet,只需要复写 doget 和 dopost 方法,而开发工具已经提供好了模板,直接用即可
Servlet 的配置
url-pattern(路径规则)配置
在创建 servlet 后,如果想要这个 servlet 可以被访问到,必须在 web.xml 文件中对其进行配置。
url-pattern 标签就是用于确定访问一个 servlet 的路径
示例:
<servlet> <servlet-name>ServletDemo1</servlet-name> <servlet-class>cn.itcast.web.ServletDemo1</servlet-class> </servlet> <servlet-mapping> <servlet-name>ServletDemo1</servlet-name> <url-pattern>/sd1</url-pattern> <url-pattern>/sd2</url-pattern> <url-pattern>/sd3</url-pattern> <url-pattern>/sd</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>ServletDemo2</servlet-name> <!-- 完全匹配 --> <url-pattern>/aaa</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>ServletDemo3</servlet-name> <!-- 扩展名匹配 --> <url-pattern>*.do</url-pattern> </servlet-mapping>
注:
- 一个servlet也可以被不同的路径映射,但一般在开发中,只需要配置一个有效路径即可
- 路径映射的配置方式:
完全匹配:必须以 / 开始
例如: /ms1、 /aaa/ms1、/aaa/bb/cc/ms1
目录匹配:必须以 / 开始,以 * 结束
例如: /*、/aaa/*
扩展名(后缀名)匹配:以 *.xx 结束(xx 代表的是后缀名)。注意:不能以 / 开始
例如:*.action、*.do
多种匹配的优先级:完全匹配 > 目录匹配 > 扩展名匹配
只有一个 servlet 会执行,执行的结果是按照优先级去执行的
load-on-startup(优先级)配置
load-on-startup 标签可以设置 servlet 的加载优先级别和容器是否在启动时加载该 servlet
- 当值为 0 或者大于 0 时,代表容器启动时加载该 servlet。正数的值越小,启动时加载该 servlet 的优先级越高。
- 如果为负数,则容器启动时不会加载该 servlet,只有该 servlet 被选择时才会加载。
servlet 的默认创建是在第一次访问的时候
示例:
<servlet> <servlet-name>ServletDemo1</servlet-name> <servlet-class>cn.itcast.web.ServletDemo1</servlet-class> <load-on-startup>2</load-on-startup> </servlet> <servlet-mapping> <servlet-name>ServletDemo1</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>
注:
数字 1 被 tomcat 默认的 servlet 给占用了,在 tomcat 的 web.xml 中可以看到也使用了一个 servlet
tomcat 一启动会加载 2 个 web.xml 文件,一个是项目自定义的 web.xml,一个 tomcat 的 web.xml
<servlet> <servlet-name>default</servlet-name> <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
该 servlet 是 tomcat 创建的,主要用来处理其它的 servlet 处理不了的请求
比如在当前下访问不到的资源都会走该 servlet,该 servlet 底层默认走写好的页面(404 500…)
Servlet 的路径
servlet 的访问路径分为 2 种:
- 绝对路径
带协议的绝对路径
地址栏的地址方式,一般用于外部资源的访问,例如:http://localhost:8080/web02/ms5
不带协议的绝对路径
把协议和端口名省略,永远只能访问到本机的资源,一般用于内部资源的访问, 例如:/web02/ms5,
特点:以/开头 以资源名结尾
相对路径:相对比较的是地址栏的地址
特点:同级目录及以下 以 ./ 开头、以资源名结尾(也可省略 ./ )
父级目录 以 …/ 开头,返回父级目录
Servlet 相关对象
HttpServletRequest 请求对象
概述
HttpServletRequest 对象代表浏览器端的请求,当浏览器端通过 HTTP 协议访问服务器时,HTTP 请求中的所有信息都封装在这个对象中,开发人员通过这个对象的 api,可以获得客户通过浏览器传递过来的数据。
HttpServletRequest 对象的作用:封装浏览器的请求数据(请求行、请求头 、请求体)
API
HttpServletRequest extends ServletRequest
获取请求行数据(请求方式、访问的资源、协议版本)
// 获取请求方式 String getMethod() // 获取请求行中的资源名部分 String getRequestURI() // 获取客户端请求完整URL StringBuffer getRequestURL() // 获取请求协议和版本 String getProtocol() // 获取端口 int getLocalPort() // 获取请求者的ip地址 String getRemoteAddr() // 获取当前的项目名路径 String getContextPath()
获取请求头数据(键值对 key/value 的数据)
// 根据请求头的key获取value String getHeader(String key) // 例如:Referer可以获取到来源地址(没有来源为null:直接访问) --防盗链 // 例如:User-Agent可以获取用户的浏览器版本信息 --下载必备、处理下载乱码的 // 返回此请求包含的所有头名称 Enumeration getHeaderNames()
获取请求体数据(所有浏览器提交的表单数据)
// 获取单一name对应的value值 String getParameter(String name) // 获取多个name对应的多个value值 String[] getParameterValues(String name) // 获取页面所有的value值 Map<String,String[]> getParameterMap() // 注意:key:对应的是表单中name属性名,value对应的的是表单的name属性的value值 // 设置编码。一般设置为 utf-8,否则请求中中文可能会乱码 void setCharacterEncoding(String var1)
作为容器数据存取删(request 也被称为域对象)
// 存储数据 void setAttribute(String name, Object o) // 获取数据 Object getAttribute(String name) // 移除数据 void removeAttribute(String name)
注意:若想要在多个 servlet 之间的使用 request 传递数据,则需要保证多个 servlet 之间使用的是同一个 request 对象,可以使用请求转发。
request.getRequestDispatcher("/servlet的地址").forward(request, response);
HttpServletResponse 对象
概述
HttpServletResponse 对象:服务器用来给浏览器写内容的一个对象
服务器有数据如果想给浏览器:只能按照 http 协议的规定通过3个方向给:响应行、响应头、响应体
API
- 操作响应行
格式:协议/版本 状态码
示例:HTTP/1.1 200
状态码含义
200 请求响应已成功 302 重定向 304 去找缓存数据 403 服务器拒绝执行 (文件或文件夹加了权限) 404 请求的资源没找到 405 请求的方法不存在 500 服务器错误 (代码写的有问题)
操作响应头
格式:key:valu
API 方法:
// 设置键值对形式的响应头 setHeader(String key,String value)
常用响应头:
// content-type:通知浏览器响应的内容是什么类型的,并且用什么编码解析内容。解决响应回去的中文乱码问题 response.setHeader("content-type","文件的类型;charset=utf-8"); // 简写 response.setContentType("文件的类型;charset=utf-8"); // location:重定向 response.setHeader("location", "/day31/sd4"); response.setStatus(302); // 简写 response.sendRedirect("url"); // refresh:定时刷新 response.setHeader("refresh","秒数;url=跳转的路径"); // content-disposition:通知浏览器写回去的东西要以附件形式打开 (只用于下载)。默认情况下都是页面直接展示写回去的数据 response.setHeader("content-disposition","attachment;filename=" + aaa.jpg);
操作响应体
页面上要展示的内容
API 方法:
// 字符流 PrintWriter getWriter() // 字节流 (二进制) ServletOutputStream getOutputStream()
特点:
- 若是能写的出来的内容用字符流,其他全用字节流(下载专用)
- 不能同时出现
- 服务器会自动关闭这2个流
ServletContext 对象
概述
ServletContext:servlet 的上下文对象(全局管理者对象),是一个全局的储存信息的空间。
一个 web 项目只有一个全局管理者(SevletContext对象)
生命周期:
当 web 应用被加载时,ServletContext 生命周期开始(创建)
当 web 应用被移除容器时,ServletContext 生命周期结束(销毁)
作用范围:整个 web 应用
作用:
可以在整个 web 应用(多个 servlet 之间)共享数据
可以获取项目的地址和项目资源流(路径和流)
API
原生获取 ServletContext 对象
在继承 HttpServlet 或 GenericServlet 的自定义类中,直接通过父类方法 getServletContext() 获取 ServletContext 对象
public ServletContext getServletContext()
Spring 项目获取 ServletContext 对象
- 通过 spring 注入自动注入(推荐)
@Autowired private ServletContext servletContext;
通过 HttpServletRequest 对象
@GetMapping("/test") public String test(HttpServletRequest request) { ServletContext servletContext = request.getServletContext(); return "success"; }
实现 WebApplicationInitializer 接口,重写 onStartup() 方法
import javax.servlet.ServletContext; import javax.servlet.ServletException; import org.springframework.web.WebApplicationInitializer; public class ApplicationInitializer implements WebApplicationInitializer { @Override public void onStartup(ServletContext servletContext) throws ServletException { System.out.println(servletContext); } }
创建一个实现 ServletContextListener 的监听器
// 必不可少,声明为监听器,注册到web容器中 @WebListener public class InitContextListener implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent servletContextEvent) { ServletContext servletContext = servletContextEvent.getServletContext(); System.out.println(servletContext); } @Override public void contextDestroyed(ServletContextEvent servletContextEvent) { } }
通过 ContextLoader 类
ServletContext servletContext = ContextLoader.getCurrentWebApplicationContext().getServletContext();
注意:使用这种方式需要 webApplicationContext 完成初始化后才能获取到 servletContext 对象,否则获取的是空值导致空指针异常
操作 ServletContext 对象
数据存取操作:保存在 ServletContext 中的数据是项目全局共享的数据,可以用来在多个 servlet 之间传递信息数据
// 存。特点:可以存多对 但是存在key值覆盖 void setAttribute(String name, Object value) // 取。特点: \没取到返回null Object getAttribute(String name) // 删 void removeAttribute(String name)
读取项目资源的方法
// 获取WEB项目的磁盘路径。场景:上传 String getRealPath(String path) // 根据WEB项目的磁盘资源获取流。场景:下载 InputStream getResourceAsStream(String path) // 获取web.xml中<context>标签的参数内容 String getInitParameter(String name)