什么是ServletContext
- Web容器在启动时,会为其上部署的每个Web应用创建一个ServletContext对象。
- ServletContext对象凌驾于该应用的所有Servlet之上,使用范围,整个Web应用。
- Web容器启动时创建,关闭时销毁。
ServletContext的作用
1. 共享数据
一个Web应用当中的不同Servlet之间可能会用到相同的数据,可以将其保存到ServletContext对象之中(key-value形式),其他Servlet可以根据key获取到。相当于一种通信方式,相比于将数据持久化到IO文件中,更加高效。注意:保存之后才能获取。
- HelloServlet:保存数据到ServletContext对象中。先于获取数据的Web资源被访问
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取ServletContext对象
ServletContext context = this.getServletContext();
// 创建数据
String username = "YuJing";
// 保存数据到ServletContext对象,名字为username,值为YuJing
context.setAttribute("username", username);
resp.setContentType("text/html");
resp.setCharacterEncoding("utf-8");
resp.getWriter().print("保存username数据到ServletContext对象");
}
}
- GetFromContext:获取数据
public class GetFromContext extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取ServletContext对象
ServletContext context = this.getServletContext();
// 根据键值取数据,前提是数据已经被保存到context中
String username = (String) context.getAttribute("username");
System.out.println("从ServletContext对象中获取数据: " + username);
// 做出响应
resp.setContentType("text/html");
resp.setCharacterEncoding("utf-8");
resp.getWriter().print("名字:" + username);
}
}
- web.xml
<?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_3_1.xsd"
version="3.1"
metadata-complete="true">
<servlet>
<servlet-name>helloServlet</servlet-name>
<servlet-class>com.jing.servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>helloServlet</servlet-name>
<url-pattern>/helloServlet</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>getFromContext</servlet-name>
<servlet-class>com.jing.servlet.GetFromContext</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>getFromContext</servlet-name>
<url-pattern>/GFC</url-pattern>
</servlet-mapping>
</web-app>
- 启动Tomcat,访问资源
- 先访问http://localhost:8080/servlet02/GFC
- 先访问http://localhost:8080/servlet02/helloServlet,再访问http://localhost:8080/servlet02/GFC
2. 获取初始化参数
在web.xml中可以配置两类初始化参数,<context-param>和<init-param>。初始化参数的作用是提前存放一些公用的数据,然后在程序中按需获取。
<?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_3_1.xsd"
version="3.1"
metadata-complete="true">
<!--作用域:整个Web应用,所有Servlet都可以获取使用-->
<context-param>
<param-name>db-url</param-name>
<param-value>jdbc:mysql://localhost:3306/test01</param-value>
</context-param>
<servlet>
<servlet-name>helloServlet</servlet-name>
<servlet-class>com.jing.servlet.HelloServlet</servlet-class>
<!--作用域:HelloServlet-->
<init-param>
<param-name>param1</param-name>
<param-value>avalible in servlet init()</param-value>
</init-param>
</web-app>
- 获取<context-param>:ServletContext.getInitParameter(param-key);
public class GetParamServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取ServletContext对象
ServletContext context = this.getServletContext();
// 获取全局参数
String initParameter = context.getInitParameter("db-url");
// 前端展示
resp.getWriter().print(initParameter);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req, resp);
}
}
- 获取<init-param>:this.getInitParameter(key-param);
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String param1 = this.getInitParameter("param1");
resp.getWriter().print(param1);
}
}
注:在Web.xml中注册并映射servlet
3. 请求转发
请求转发:A访问B,B无法处理,B去访问C,B获取响应之后再返回给A
请求重定向:A访问B,B无法处理,B告诉A去访问C,A去访问C,C响应A,地址栏的地址会发生改变
- 目标Servlet:Error.java
public class Error extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().print("<h1>404</h1>");
}
}
- 源Servlet:RequestDispatcherServlet
public class RequestDispatcherServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取ServletContext对象
ServletContext context = this.getServletContext();
// 这行代码的作用是,获取请求转发器并设置目标资源访问路径
RequestDispatcher requestDispatcher = context.getRequestDispatcher("/error");
// 将请求转发给新的路径
requestDispatcher.forward(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req, resp);
}
}
- web.xml
<?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_3_1.xsd"
version="3.1"
metadata-complete="true">
<servlet>
<servlet-name>error</servlet-name>
<servlet-class>com.jing.servlet.Error</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>error</servlet-name>
<url-pattern>/error</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>requestDispatcher</servlet-name>
<servlet-class>com.jing.servlet.RequestDispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>requestDispatcher</servlet-name>
<url-pattern>/RDS</url-pattern>
</servlet-mapping>
</web-app>
- 请求结果
4. 获取资源文件
资源文件一般是指.properties或者.xml这些配置文件。
- 资源文件所在目录:
- /WEB-INF/classes/db.properties
- 文件内容:
- 资源访问
-
public class PropertiesServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 获取资源文件的额输入流 InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties"); // Properties类 里面维护一个HashTable,用于存储key-value Properties properties = new Properties(); // 将属性文件的内容加载进properties properties.load(is); // 获取属性值 String username = properties.getProperty("username"); String password = properties.getProperty("password"); resp.getWriter().print(username + ": " + password); } }
- /WEB-INF/classes/com/jing/servlet/aa.properties
- 文件内容:
- 资源访问