在JavaWeb中,Servlet中三大域对象分别是request,session,ServletContext
request:一个请求链,每一个请求都会创建一个request,作用域为当前的请求链,一般用于同一请求链之间不同页面的参数传递,如表单中的值传递。
session:Tomcat(服务器)会为每个会话创建一个session对象,作用域:session的数据只能在当前会话中的所有servlet共享(会话范围:如某个用户从首次访问服务器开始,到用户关闭浏览器结束),HttpSession底层依赖Cookie。
application(ServletContext): 服务器会为每个web应用创建一个ServletContext对象,而ServletContext对象的创建时在服务器启动时完成的,在服务器关闭时销毁的, 作用:在整个web应用的动态资源之间共享数据。
在Servlet中获取ServletContext对象,下面示例常用方法
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext context = this.getServletContext();
/*调用setAttribute方法完成保存数据,可在其他servlet中使用ServletContext来获取保存的值
如 String param = (String) this.getServletContext().getAttribute("name"); */
context.setAttribute("name", "小明");
String param1= context.getInitParameter("param1");
System.out.println(param1);
//获取所有的初始化参数名称
Enumeration
while(params.hasMoreElements()) {
String initParam = params.nextElement();
String initValue = context.getInitParameter(initParam);
System.out.println(initParam+":"+initValue);
}}
控制台输出结果
ServletContext获取资源相关方法
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//得到的是有盘符的路径 如F:\Tomcat\apache-tomcat-7.0.94\webapps\Dmeo\index.jsp
String path = this.getServletContext().getRealPath("/index.jsp");
System.out.println(path);
System.out.println("输出获取到文件");
//获取资源路径,创建输入流对象
InputStream in = this.getServletContext().getResourceAsStream("/index.jsp");
byte[] by =new byte[1024];
while(in.read(by)!=-1) {
System.out.println(new String(by));
}
//获取当前路径下所有的资源的路径
Set
System.out.println(paths);
}
输出结果如下
使用ServletContext完成网站访问量统计简单案例
想要网站所有资源被访问时都要给访问量进行累加,可以使用ServletContext对象来完成这一功能,首先创建一个用来报存访问量的Integer类型的变量,使用ServletContext对象的SetAttribute方法将它保存到域中,这样所有的Servlet都可以访问到。资源被第一次访问时,创建一个变量,设置值为1,保存到ServletContext域中,从第二次访问之后,可以从ServletContext域中获取这个变量进行累加。
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext application = this.getServletContext();
Integer count = (Integer) application.getAttribute("count");
if(count==null) { //判断是否空,为空的话创建变量赋值并保存到域中
application.setAttribute("count", 1);
}else { //不为空则在原有的基础上加一
application.setAttribute("count", count+1);
}
//设置编码
response.setContentType("text/html;charset=utf-8");
//使用response对象(响应对象)向浏览器输出
PrintWriter out = response.getWriter();
out.print("当前访问量:"+""+count+"");
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
效果:(每访问一次加一)
session:(会话)如一个用户对服务器的多次连贯性的请求(就是多次请求中没有关闭浏览器),在jsp中,session是jsp中的内置对象,所以session无须创建即可使用
演示将用户信息保存到session中
先从jsp页面获取到用户信息,通过验证后将用户信息保存到session域中
如果用户没有登录就访问其他页面的话,就保存信息,转发到登录页面
<body>
<h1>index.jsph1>
<%String name= (String)session.getAttribute("username");
if(name==null){
request.setAttribute("msg", "你还没有登录,请登录");
request.getRequestDispatcher("/jsp/Login.jsp").forward(request, response);
return;
}%>
body>
效果
request(请求对象):可以获取客户端ip、请求参数、请求头、请求URL等
getHeader(String name)获取请求头(单头)
getIntHeader(String name)获取单值int类型的请求头
getContextPath();获取项目名
getParamter(String name)获取指定名称的请示参数值
请求转发、包含和重定向
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setAttribute("name", ".xiaoming");
//请求转发
request.getRequestDispatcher("/index.jsp").forward(request, response);
//请求包含
//request.getRequestDispatcher("/index.jsp").include(request, response);
//重定向
//response.sendRedirect("/index.jsp");
}
区别
有时候一个请求链需要多个servlet完成,所以需要在一个servlet转发到另一个servlet。
请求转发:有下一个Servlet完成响应体,当前Servlet可以设置响应头。如response.setHeader("pragma", "no-cache");
请求包含:由两个Servlet共同完成没有完成的响应体。
请求转发和重定向的区别:
请求次数:请求转发是一个请求一个响应,而重定向是两次请求两次响应
地址栏:请求转发和请求包含都是地址栏不会发生变化,而重定向地址栏会发生变化,显示后一个请求的地址。
范围:请求转发只能转发到本项目其他的Servlet,重定向不但能定向到本项目,还能定向到其他项目
路径:因为请求转发和请求包含都是服务端行为,所以转发时只需要给出转发的Servlet路径,而重定向需要给出requestURL(请求路径),也就是需要包括项目名。
效率:请求转发和重定向比较是请求转发的效率高,因为请求转发是一个请求。
根据需求选择,如果需要地址栏发生变化,使用重定向,而需要在下一个Servlet中获取request域中的数据时,使用请求转发或包含。
总结:使用作用域传递或存储数据需要根据项目需要来选择不同的域获取数据或保存数据,只有掌握它们的生命周期、作用范围才能正确选择作用域。