一、ServletContext对象
ServletContext代表一个web应用环境对象,即一个web环境。也就是说ServletContext对象内部封装了该web应用的信息。因此一个web应用只有一个ServletContext对象。所有用户都可以获取及使用,可以实现不同用户请求的数据共享。
1、特点
- ServletContext对象由Tomcat服务器在启动加载项目的时候完成创建,存储在服务器。
- ServletContext对象一个项目中只有一个,以任意方式获取到的都是同一个。
- ServletContext对象中保存的数据是所有用户共享的。
2、使用
获取对象 |
|
存储数据 | 往ServletContext对象中存数据,键值对的方式: servletContext.setAttribute("name", "root"); |
取出数据 | 从ServletContext对象中获取数据: (ServletContext中取出的原始数据位为Object类型) |
3、获取web.xml中配置的上下文参数
可以在web.xml中配置一些参数,可以通过ServletContext对象获取。经常出现在框架的底层。
<!--配置上下文参数(全局参数)-->
<context-param>
<param-name>name</param-name>
<param-value>admin</param-value>
</context-param>
<context-param>
<param-name>age</param-name>
<param-value>18</param-value>
</context-param>
String name1 = servletContext.getInitParameter("name");
String age = servletContext.getInitParameter("age");
System.out.println("name:" + name1 + ", age:" + age);
4、ServletContext对象的生命周期
当服务器启动时会创建ServletContext对象。服务器关闭后该对象销毁。
ServletContext对象的生命周期很长,仅存放所有用户共享的数据。
二、域对象
1、认识域对象
域对象类似于之前学习的map集合,可以存放键值对的数据。不同的是域对象中数据的使用有一定的区域范围限制。
三大域对象 :
域 | 对象 | 名称 |
---|---|---|
request域 | HttpServeltRequest对象 | 请求域 |
session域 | HttpSession对象 | 会话域 |
application域 | ServletContext对象 | 应用域 |
常用方法:
方法 | 作用 |
---|---|
setAttribute(key, value) | 向域中添加或修改数据,无则添加,有则修改 |
getAttribute(key) | 获取域中的数据 |
removeAttribute(key) | 从域中移除指定key的数据 |
2、不同域对象的介绍
域对象 | 有效范围 | 作用 | 生命周期 |
---|---|---|---|
request域 (请求对象) | 一次请求有效 | 流转业务数据 | 创建:浏览器每次请求,服务器都会重新创建。 使用:在请求的Servlet中或者请求转发后的Servlet中使用。 销毁:请求响应结束后,该请求对象就会被销毁。 |
Session域 (HttpServlet对象) | 单次会话内有效,多次请求 | 一般用来存储用户状态数据。 | 创建:从第一次发出请求,会话开始 使用:一次会话内,浏览器和服务器之间发生多次请求都有效 销毁:会话结束,比如:达到最大不活动时间、手动销毁 |
Application域 (ServletContext对象) | 当前web项目内都有效,可以跨请求,跨会话访问。 | 一般放一些全局的和项目本身相关所有用户共享的数据,如在线人数,不建议存放业务数据。 | 创建:服务器启动 使用:服务器运行期间都有效 销毁:服务器关闭 |
三、文件上传和下载
在Servlet3.0之前的版本中如果实现文件上传需要依赖apache的Fileupload组件,在Servlet3.0以及之后的版本中提供了Part对象处理文件上传,所以不在需要额外的添加Fileupload组件。
1. 配置
在Servlet3.0以及之后的版本中实现文件上传时必须要在Servlet中开启多参数配置:
方式一:web.xml 配置
<multipart-config>
<file-size-threshold></file-size-threshold>
<location></location>
<max-file-size></max-file-size>
<max-request-size></max-request-size>
</multipart-config>
元素名 | 类型 | 描述 |
---|---|---|
<file-size-threshold> | int | 当数据量大于该值时,内容将被写入临时文件。 |
<location> | String | 存放生成的临时文件地址。 |
<max-file-size> | long | 允许上传的文件最大值(byte)。默认值为 -1,表示没有限制 |
<max-request-size> | long | 一个 multipart/form-data请求能携带的最大字节数(byte),默认值为 -1,表示没有限制。 |
方式二:@MultipartConfig 配置
属性名 | 类型 | 描述 |
---|---|---|
fileSizeThreshold | int | 当数据量大于该值时,内容将被写入临时文件。 |
location | String | 存放生临时成的文件地址 |
maxFileSize | long | 允许上传的文件最大值(byte)。默认值为 -1,表示没有限制 |
maxRequestSize | long | 一个 multipart/form-data请求能携带的最大字节数(byte),默认值为 -1,表示没有限制。 |
2. Part对象中常用的方法
方法 | 说明 |
---|---|
long getSize() | 上传文件的大小 |
String getSubmittedFileName() | 上传文件的原始文件名 |
String getName() | 获取<input name="upload" ...>标签中name属性值 |
InputStream getInputStream() | 获取上传文件的输入流 |
void write(String path) | 保存文件至指定位置 |
实现上传:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--
文件上传:
1.请求方式必须为post
2.enctype="multipart/form-data"
post请求:
默认的传递数据内容类型:enctype="application/x-www-form-urlencoded" 普通数据格式。
手动指定:enctype="multipart/form-data" 除了有普通的数据还有文件
-->
<form action="uploadServlet" enctype="multipart/form-data" method="post">
头像:<input type="file" name="photo"> <br>
<input type="submit">
</form>
</body>
</html>
Servlet
@MultipartConfig
@WebServlet("/uploadServlet")
public class UploadServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Part photo = req.getPart("photo");
String name = photo.getSubmittedFileName();
String upload = getServletContext().getRealPath("upload");
File file = new File(upload);
if (!file.exists()) {
file.mkdirs();
}
photo.write(upload + "/" + name);
}
}
实现下载:
获取文件的输入流,通过输出流响应到浏览器。
@WebServlet("/downloadServlet")
public class DownloadServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
String filename = req.getParameter("filename");
//设置响应头,文件定位为附件(以附件形式下载)
resp.setHeader("Content-Disposition", "attachment; filename=" + new String(filename.getBytes(),"ISO8859-1"));
//1.通过响应对象获取输出流
ServletOutputStream outputStream = resp.getOutputStream();
//2.通过字节输入流读取文件
String realPath = req.getServletContext().getRealPath("upload");
FileInputStream fis = new FileInputStream(realPath + "/" + filename);
System.out.println(fis);
int val = 0;
while ((val=fis.read()) != -1) {
outputStream.write(val);
}
}
}
四、监听器(Listener)
1. 需求
目前我们在web项目中,可以使用三大域对象request、session、application作为数据流转的载体。而这三个域对象都不是我们创建的,也不是我们销毁的。
我们可以给三大域对象添加监听,监听三大域对象的创建及销毁,监听到他们有动态的时候,执行对应的方法。这就是监听器。
2.介绍
作用:
- 监听三大域对象的创建、销毁及数据的变更。
特点:
- 监听方法由tomcat根据监听结果来调用执行。
- 监听方法中的逻辑代码由我们根据需要编写。
3. 使用
监听器的使用步骤:
-
创建一个类,实现监听器接口(Listener)。
-
实现里面的方法。
-
在web.xml中配置监听器。
监听器接口:
ServletRequestListenter | 监听request对象的创建销毁 |
ServletRequestAttributeListener | 监听request域中数据的变更 |
HttpSessionListener | 监听Session对象的创建销毁 |
HttpSessionAttributeListener | 监听Session对象中数据的变更 |
ServletContextListener | 监听ServletContext对象的创建销毁 |
ServletContextAttributeListener | 监听ServletContext对象中数据的变更 |
代码演示:
public class MyListener implements ServletRequestListener, ServletRequestAttributeListener,
HttpSessionListener, HttpSessionAttributeListener, ServletContextListener, ServletContextAttributeListener {
//监听ServletContext对象中数据的添加
@Override
public void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) {
}
//监听ServletContext对象中数据的删除
@Override
public void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) {
}
//监听ServletContext对象中数据的修改
@Override
public void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) {
}
//监听ServletContext对象的初始化
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
}
//监听ServletContext对象的销毁
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
}
//监听ServletRequest对象中数据的添加
@Override
public void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) {
System.out.println("request对象中添加的数据!");
}
//监听ServletRequest对象中数据的删除
@Override
public void attributeRemoved(ServletRequestAttributeEvent servletRequestAttributeEvent) {
System.out.println("request对象中删除了数据!");
}
//监听ServletRequest对象中数据的修改
@Override
public void attributeReplaced(ServletRequestAttributeEvent servletRequestAttributeEvent) {
System.out.println("request对象中修改了数据!");
}
//监听ServletRequest对象中数据的销毁
@Override
public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
System.out.println("request对象被销毁!");
}
//监听ServletRequest对象的初始化
@Override
public void requestInitialized(ServletRequestEvent servletRequestEvent) {
System.out.println("request对象被初始化!");
}
//监听HttpSession对象中数据的添加
@Override
public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {
}
//监听HttpSession对象中数据的删除
@Override
public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {
}
//监听HttpSession对象中数据的修改
@Override
public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {
}
//监听HttpSession对象的创建
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
}
//监听HttpSession对象的销毁
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
}
}
<!--
配置监听器,在服务器启动的时候就会创建监听器对象,监听器生效,一旦符合监听要求,
tomcat底层会通过反射调用监听器中的方法完成处理
-->
<listener>
<listener-class>com.bjsxt.listener.MyListener</listener-class>
</listener>
五、过滤器(Filter)
1. 过滤器的介绍
Tomcat服务器一直是在被动的接收请求,而且Tomcat服务器收到请求后需要调用Servlet的service方法进行处理。
过滤器作用:Tomcat收到客户端请求后, 调用资源前会对请求进行拦截, 完成相关的处理。
2. 过滤器的使用
过滤器的编写步骤:
创建一个类,实现过滤器接口(Filter)。
实现接口中的方法,编写自己的代码。
在web.xml中配置过滤器或通过注解配置。
代码编写:
public class CharacterFilter implements Filter {
public CharacterFilter() {
System.out.println("过滤器被创建!");
}
/**
* 处理化方法,执行一些初始化的操作,一般不用
* @param filterConfig
* @throws ServletException
*/
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("过滤器被初始化!");
}
/**
* 过滤器的核心方法,过滤器拦截到请求后,就是在该方法中对请求进行判断,看是否让其继续访问我们的资源
* @param servletRequest 封装的请求信息
* @param servletResponse 封装的响应对象
* @param filterChain 过滤器链,用来放行的
* @throws IOException
* @throws ServletException
*/
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("开始对请求进行判断处理!");
filterChain.doFilter(servletRequest, servletResponse);//放行
}
/**
* 销毁方法,用来做一些释放资源的操作,一般不用
*/
@Override
public void destroy() {
System.out.println("过滤器被销毁!");
}
}
配置:
<!--配置过滤器-->
<filter>
<filter-name>CharacterFilter</filter-name>
<!--
配置过滤器所在的全路径,由Tomcat在启动的时候,通过放射创建该过滤器对象
-->
<filter-class>com.bjsxt.filter.CharacterFilter</filter-class>
</filter>
<!--配置过滤器的拦截路径,也就是对哪些请求进行拦截-->
<filter-mapping>
<filter-name>CharacterFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
3. 过滤器链
注意:
- 在web.xml中配置多个过滤器,过滤器执行顺序 为配置的先后顺序。
- 使用注解配置多个过滤器,过滤器执行顺序为 根据字符串的比较规则,进行排序的配置的过滤器名称。