我们知道当客户端发出请求的时候,可以将请求参数通过HttpServletRequest传递给doGet()或doPost()。其实,在servlet初始化的时候,也可以有初始化参数。如下,在web.xml中设者某一servlet的初始化参数:
Chapter3 servlet
com.wyf.servlet.Ch3.BeerSelect
adminEmail
[email protected]
在servlet代码中,可以通过getServletConfig().getInitParameter("adminEmail")获取到该参数,如下为servlet代码。
/**
* Servlet,负责接收请求并响应
*/
public class BeerSelect extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
String color = request.getParameter("color"); //从客户的Post请求中获取到参数
BeerExpert be = new BeerExpert();
List result = be.getBrands(color);
String adEmail = getServletConfig().getInitParameter("adminEmail");
//将模型(专家)返回的结果附加到请求中,
request.setAttribute("styles",result);
request.setAttribute("adminEmail",adEmail);
//利用RequestDispatcher对象,将请求转发给另外一个Servlet或JSP页面
RequestDispatcher view = request.getRequestDispatcher("result.jsp"); //为JSP实例化一个请求分派器
//使用请求分派器,要求容器准备好JSP,并向JSP发送请求和响应
view.forward(request,response);
}
}
在servlet初始化之前,不能使用servlet初始化参数。
容器初始化一个servlet时,会为这个servlet建一个唯一的ServletConfig。容器从web.xml文件中读到servlet初始化参数,并把这些参数交给ServletConfig,然后将ServletConfig传递给servlet的init()方法。
如上图,servlet初始化参数只能读一次,就是在容器初始化servlet的时候。
上下文初始化参数和servlet初始化参数很类似,只是上下文参数对整个web应用可用,而不是针对某一个servlet。因此,web应用中所有的servlet以及JSP都自动地能够访问上下文初始化参数。
mainEmail
[email protected]
在servlet代码中,可以通过方法getServletContext().getInitParameter("adminEmail")获取到上下文初始化参数。
每个servlet有一个ServletConfig,每个Web应用有一个ServletContext,Web应用中地所有部分都能访问到ServletContext。
采用ServletConfig(servlet初始化参数)和ServletContext(上下文参数)能够得到初始化的一些参数,但是,这些初始化参数必须是string类型。如果我们想要一个对象,比如数据库DataSource来初始化应用,让所有的servlet都能够使用。应该怎么办呢?我们不能把一个对象放到XML部署描述文件中。
可以创建一个单独的类,这个类不是servlet或Jsp,他能监听ServletContext一生中的两个关键事件,初始化(创建)和撤销。该类实现了javax.servlet.ServletContextListener。该类具有以下功能:
示例如下:
首先我们在web.xml中设置上下文初始化参数ServletContext。
breed
Great Dane
创建一个上下文初始化参数监听者,并在web.xml文件中注册该监听者。
/**
* 监听者
*/
public class MyServletContextListener implements ServletContextListener {
/**
* 初始化
* @param servletContextEvent
*/
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
//由事件得到ServletContext
ServletContext sc = servletContextEvent.getServletContext();
String dogBreed = sc.getInitParameter("breed"); //获取ServletContext初始参数
Dog dog = new Dog(dogBreed);
//使用上下文设置一个属性(名/对象)
sc.setAttribute("dog",dog);
}
/**
* 撤销
* @param servletContextEvent
*/
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
//
}
}
com.wyf.ServletContextListern.MyServletContextListener
创建一个普通的Java类,我们的监听者会在上下文参数初始化的时候,利用参数创建对象,并将对象存储为属性,以供web应用的其他部分使用。
public class Dog{
private String breed;
public Dog(String breed){
this.breed = breed;
}
public String getBreed() {
return breed;
}
/**
* 重写toString方法
* @return
*/
@Override
public String toString() {
return "Dog{" +
"breed='" + breed + '\'' +
'}';
}
}
测试类如下:
/**
* Servlet
*/
public class ListernerTest extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("test ServletContext attributes set by listener");
out.println("
");
Dog dog = (Dog) getServletContext().getAttribute("dog");
out.println("dog breed is "+dog.getBreed());
}
}
前文中,我们通过监听者,创建Dog对象,并将其作为一个属性存储(设置)到ServletContext,这样应用的其他部分就能够得到他。属性是用于在Web应用程序中共享信息的对象。属性允许Servlet之间共享信息,属性具有三个作用域,上下文、请求、会话。
属性 | 参数 | |
类型 | 应用/上下文属性 请求属性 会话属性 |
应用/上下文初始化参数 请求参数 Servlet初始化参数 |
设置方法 | setAttribute(String name,Object value) |
上下文初始化参数和Servlet初始化参数在Web.xml中进行设置; 请求参数由容器生成HttpServletRequest对象并设置参数 |
返回类型 | Object | String |
获取方法 | getAttribute(String name) |
getInitParameter(String name) |
上下文属性web应用中每一部分都能够访问。
需要注意,上下文作用域不是线程安全的。 如下图所示:
会话属性,只有能访问特定HttpSession的部分才能访问到。
请求属性,只有能访问特定ServletRequest的部分才能访问到。