首页 > 代码库 > Web开发中的域问题:PageContext,Request,Session,ServletContext(Application)
Web开发中的域问题:PageContext,Request,Session,ServletContext(Application)
Web开发中的四个域对象(范围由小到大):
page(jsp有效) request(一次请求) session(一次会话) application(当前web应用)
page域指的是pageContext.
request域指的是HttpServletRequest
session 域指的是HTTPSession
application 域指的是ServletContext
之所以他们是域对象,原因就是他们都内置了map集合,都有setAttribute getAttribute方法。而且他们的name都是String类型,而value都是Object类型。
他们都有自己固定的生命周期和作用域。
这四个对象的生命周期(生命周期就是值对象的创建到销毁的期间):
page:jsp页面被执行,生命周期开始,jsp页面执行完毕,声明周期结束。
request:用户发送一个请求,开始,服务器返回响应,请求结束,生命周期结束。
session:用户打开浏览器访问,创建session(开始),session超时或被声明失效,该对象生命周期结束。
application:web应用加载的时候创建。Web应用被移除或服务器关闭,对象销毁。[结束]。
-------------------------------------------------------------------------------------------------------------------------------------------------------------
注意:
1.Page只在当前jsp有效,每次请求分别对应不同的request.
2.Request,只在当前请求有效,每次请求分别对应不同的request域
【Request域】可以调用request这个隐含对象的getAttribute()方法来访问具有这种范围类型的对象。也可以使用getParameter(String name) return String来获取XML里传递给它的参数。
String data = "http://www.mamicode.com/XBY request";
request.setAttribute("data4",data);
request.getRequestDispatcher("/1.jsp").forward(request, response);
Request可以用于Forward
String data = http://www.mamicode.com/(String)request.getAttribute("data");
out.write(data);
【如果在forward前将在Servlet程序中写入的部分内容已经被真正地传送到客户端,forward方法将抛出IllegalStateException异常。】关键在跳转后要return.
如果在调用Forward方法前向servlet引擎的缓冲区(response)中写入内容,只要写入到缓冲区的内容还没有真正输出到客户端,forward方法将可以被正常执行,原来写入到缓冲区的内容 会被清空,但是,已经写入到HttpServletResponse对象的响应字段信息保持有效。
Forward请求转发特点:
1.客户端只发出了一次请求,而服务器端有多个资源调用
2.客户端浏览器端RUL不会变化。
-------------------------------------------------------------------------------------------------------------------------------------------------------------
3.Session只在一次会话中有效,会话结束就无法取到数据了。getAttribute(String name) return Object
HttpSession session = request.getSession();
session.setAttribute("name", "电视");
response.setCharacterEncoding("UTF-8");//处理中文乱码问题
response.setContentType("text/html;charset=UTF-8");//处理中文乱码问题
PrintWriter out = response.getWriter();//处理中文乱码问题
HttpSession session = request.getSession();
String product = (String)session.getAttribute("name");
out.write(product);
只有当getSession()时,服务器才会为该浏览器创建session,他的生命周期默认为30min。
<session-config>
<session-timeout>10</session-timeout>
</session-config>
当使用request.getSession(false);时,就是查看session,不生成session.例如在查看已购买东西时,会使用。//ie8的话,开2个浏览器还是共享一个session,ie7是服务器把sessionid写进了浏览器的进程中,而ie8是服务器实现了多个同一款浏览器的session共享。
【cookie】如果没有指定Cookies对象的有效期,则Cookies对象只存在于客户端的内存。当浏览器关闭时,Cookies就会失效。
HttpSession session = request.getSession();
String sessionid = session.getId();
Cookie cookie = new Cookie("JSESSIONID", sessionid);
cookie.setPath("/servlet");
cookie.setMaxAge(30*60);
response.addCookie(cookie);
session.setAttribute("name", "电视");//重新写cookie。设置时间。
如果禁用cookie,就是使用利用URL重写技术让浏览器的URL带上SESSIONID。
--------------------------------------------------------------------------------------------------------------------------------------------------------------
4.application:在JSP自动生成的Servlet文件中,是这样定义的:final javax.servlet.ServletContext application;
ServletContext域:
1.这是一个容器
2.说明这个容器的作用范围是整个应用程序范围
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String data="http://www.mamicode.com/xby ok";
this.getServletContext().setAttribute("data", data);
System.out.println("write ok!");
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String value = http://www.mamicode.com/(String)this.getServletContext().getAttribute("data");
System.out.println(value);
}
【补】ServletContext可以转发Servlet,但是Servlet不方便显示。
forward:
String data="http://www.mamicode.com/xby yes!";
this.getServletContext().setAttribute("data", data);
RequestDispatcher rd = this.getServletContext().getRequestDispatcher("/1.jsp");
rd.forward(request, response);
这样不好,因为涉及到多线程问题,ServletContext会被同一应用中的所有Servlet所共享】
通过ServletContext读取web资源:
InputStream in= this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
Properties props = new Properties();
props.load(in);
String username = props.getProperty("username");
String passwd = props.getProperty("passwd");
获得资源文件路径(用于上传下载):
String path= this.getServletContext().getRealPath("/WEB-INF/classes/db.properties");
FileInputStream in = new FileInputStream(path);】
使用ServletContext管理相关的资源。webapp都是在jvm下执行的,所以绝对路径就是在jvm的路径。
ServletContext会在服务器启动时创建,目录在webapps中;服务器停止时会销毁这个ServletContext.------------------------------------------------------------------------------------------------------------------------------------------------------------- -
四个域对象在选择的时候,能用范围小的绝不用范围大的:
page:数据只是暂时存在集合,在jsp页面的其他地方要用,用page(页面中自定义的map)
(什么时候需要用map了,就用page)
Request:【程序产生数据,数据显示完后就没有用了】
数据只是做显示的,看完了就没用了。就存request域,请求转发,Servlet产生的处理结果(数据)交给jsp显示。数据转发可以带数据。
Session:【程序产生数据,显示后等会还需要使用】
数据给用户看完了,一定还要用,会话结束了就没用了
用户登录,用户信息发给客户端看,看完了,一会访问别的页面还要看用户信息。
购物车,购物车成功了,给用户看购物车,待会随时间可以查看购物车
请求重定向,因为是两次请求,每一次请求的数据,第二次请求还要看。
application:【ServletContext在jsp中另一个名字就是application,数据显示后,等会还需要用,还需要给别人用,例如聊天室】
数据给一个用户用完了,别人还要用;
聊天室,聊天记录,需要给所有的用户看;统计网站在线人数,所有看到的应该是一个数
【总结】:四个域对象在选择的时候,能用范围小的绝不用范围大的。
1.需要定义Map时不如用page,
2.请求Servlet,转发给jsp的数据存request,
3.请求重定向带过去的数据存Session,
4.全局的数据存application。
4.ServletContext:WEB容器在启动时,他会为每一个【WEB应用程序】都创建一个对应的ServletContext对象,它代表【当前WEB应用】,驻留在服务器的内存里。
在一个contex中的数据都是共享的,它是web应用的配置信息和配置参数。
Web开发中的域问题:PageContext,Request,Session,ServletContext(Application)