1.ServletContext
ServletContext是Java Web应用程序中的一个接口,它提供了与Web应用程序相关的信息和方法。
ServletContext是在Web应用程序启动时由Web服务器创建的,它代表整个Web应用程序。
在Servlet中,可以通过getServletContext()方法获取ServletContext对象,从而访问与Web应用程序相关的信息和方法。
2.ServletContext用于共享数据
一个Web应用程序中的多个Servlet都可以读写ServletContext,所以ServletContext可以用于共享数据。相当于是一个ServletContext对应多个Servlet,第一个Servlet在ServletContext中保存了数据,第二个Servlet可以从ServletContext中读取。
第一个Servlet在ServletContext中保存了数据:
package com.study.servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = getServletContext();
String username = "一棵树";
context.setAttribute("username", username);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
第二个Servlet可以从ServletContext中读取:
package com.study.servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class GetServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = getServletContext();
String username = (String)context.getAttribute("username");
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html");
PrintWriter writer = resp.getWriter();
writer.print("I am " + username);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
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_4_0.xsd"
version="4.0"
metadata-complete="true">
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.study.servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>getname</servlet-name>
<servlet-class>com.study.servlet.GetServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>getname</servlet-name>
<url-pattern>/getname</url-pattern>
</servlet-mapping>
</web-app>
先访问/hello, 在访问/getname,这样可以读取到属性的值:
3.ServletContext用于获得初始化参数
可以在web.xml里配置context的参数
<context-param> <param-name>url</param-name> <param-value>http://localhost</param-value> </context-param>
然后用ServletContext获取这些初始化参数
package com.study.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class ParamServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String param = getServletContext().getInitParameter("url");
resp.getWriter().print(param);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
}
4.ServletContext用于请求转发
请求转发就是当前Servlet将请求转发给另一个Servlet,体现在浏览器中就是会显示另一个Servlet的内容,但是浏览器的地址栏显示的路径不变,还是原先的Servlet的路径。
这意味着用户并没有直接访问第二个Servlet,一直访问的是第一个Servlet。
package com.study.servlet;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class DispatcherServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = getServletContext();
RequestDispatcher dispatcher = context.getRequestDispatcher("/print");
dispatcher.forward(req,resp);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
}
结果:
5.ServletContext用于读取资源文件
读取recource下的资源文件,例如*.properties。
运行项目后会被打包到classes下。
因为读取文件时要写相对路径,很容易写成/classes/web.properties。
但用这个路径是读不到的,要用:
/WEB-INF/classes/web.properties
至于IDEA为什么把显示项目结构时把WEB-INF省略了,我也不是很理解
package com.study.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class ReadServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
InputStream inputStream = getServletContext().getResourceAsStream(
"/WEB-INF/classes/web.properties"
);
Properties properties = new Properties();
properties.load(inputStream);
String name = properties.getProperty("name");
String gender = properties.getProperty("gender");
resp.getWriter().print(name + " is " + gender);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
}