距离上一篇博文的时间相差近一个月,这期间由于自己的一些问题,没有坚持发文章,这里要做个自我批评,以后一定要给自己一些计划,坚持一周至少两篇。
好了,言归正传,前两篇遗留下了两个问题,第一个是九大内置对象中还有session和pageContext没有做介绍,第二个就是为什么这些对象可以不用声明直接使用呢?接下来我们一一来解决吧。
一、session对象
1、作用范围:会话期间,也就是session scope。
2、说明:
(1)session对象用于存储一个用户的会话状态,也就是说,session对象是对某个用户的会话过程中的信息存储;
(2)例如:购物车常使用session 的概念来实现,当用户把物品放入购物车时,他不须重复做身份确认的动作(如:Login),就能把物品放入用户的购物车。但服务器利用session 对象,就能确认用户是谁,把它的物品放在属于用户的购物车,而不会将物品放错到别人的购物车。
3、实例
(1)获取会话消息
<%@ page contentType="text/html;charset=GB2312" import="java.util.*" %> <html> <head> <title>session对象方法</title> </head> <body><b> 会话ID : <%= session.getId() %><br/> 是否新会话: <%= session.isNew() %><br/> 设置和获取属性对象:用户名= <% session.setAttribute("用户名","Bill56");%> <%=session.getAttribute("用户名")%><br/> <% Date creationTime = new Date(session.getCreationTime()); Date accessedTime = new Date(session.getLastAccessedTime()); %> 会话创建时间:<%= creationTime%><br/> 上次访问时间:<%= accessedTime%><br/> 会话持续时间(s):<%= session.getMaxInactiveInterval()%><br/> </body> </html>
演示时可以使用不同的浏览器,例如IE,FireFox,证明不同的用户使用的不同的session。
用谷歌浏览器打开:
用IE浏览器打开:
可以发现,不同的浏览器对应的会话ID不一样,SessionID是服务器用来标识是否是同一个会话的信息。
(2)模拟一个自动登录效果
index.jsp:
<%@ page language="java" import="java.util.*" pageEncoding="GB2312"%> <html> <head><title>MyJsp.jsp</title></head> <body> <form action="treat.jsp" method="post" > 用户名:<input type="text" name="name" /> 密 码:<input type="password" name="password" /> <input type=“submit” value=“登陆” /> <a href="1.jsp">需要登录的页面</a> <a href="2.jsp">不需要登录的页面</a> </form> </table> </body> </html>
treat.jsp
treat.jsp <%@ page contentType="text/html;charset=GB2312" %> <html> <head> <title></title> </head> <body> <% String name = request.getParameter("name"); String password = request.getParameter("password"); if(name.equals("wgw")&&password.equals("123")){ session.setAttribute("userName", name ); %> 您好,已经登录!<br /> <a href="http://localhost:8080/try/index.jsp">点击返回主页</a> <% } else { %> 用户名和秘密不正确<br /> <%} %> </body> </html>
1.jsp:需要登录访问的网页
1.jsp <%@ page language="java" import="java.util.*" pageEncoding="GB2312"%> <html> <head> <title>response应用</title> </head> <body> <% String userName= (String)session.getAttribute("userName"); if(userName == null ){ %> 请先登录 <% }else{%> 您好<%= userName%> <%}%> </body> </html>
2.jsp:无需登录即可访问的网页
2.jsp <%@page import="java.util.*"%> <%@ page language="java" import="java.util.*" pageEncoding="GB2312"%> <html> <head> <title>无须登陆便可访问</title> </head> <body> 您好! </body> </html>
二、pageContext对象
1、作用范围:page scope,即本页面有效
2、说明:pageContext对象能够存取其他隐含对象。
3、注意:
当隐含对象本身也支持属性时,pageContext对象也提供存取那些属性的方法。不过在使用下列方法时,需要指定范围的参数:
void setAttribute(String name, Object value, int scope)
Object getAttribute(String name, int scope)
void removeAttribute(String name, int scope)
Enumeration getAttributeNamesInScope(int scope)
范围参数有四个常数,分别代表四种范围:PAGE_SCOPE 代表Page范围,REQUEST_SCOPE代表Request范围,SESSION_SCOPE 代表Session 范围,最后APPLICATION_SCOPE 代表Application 范围。分别对应整数“1”、“2”、“3”、“4”表示。
4、例子
<html> <head><title>pagecontext应用</title> <meta http-equiv="Content-Type" content="text/html; charset=gb2312"> </head> <body > <p>设置4个对象的username属性!</p> <p> <% pageContext.setAttribute("username","L.Q.Y"); request.setAttribute("username","Bill56"); session.setAttribute("username","Liuqingyong"); application.setAttribute("username","newjohn"); %> </p> <p>“1”page scope范围内的username是: <%=pageContext.getAttribute("username",1)%> </p> <p>“2”request scope范围内的username是: <%=pageContext.getAttribute("username",2)%> </p> <p>“3”session scope范围内的username是: <%=pageContext.getAttribute("username",3)%> </p> <p>“4”application scope范围内的username是: <%=pageContext.getAttribute("username",4)%> </p> </body> </html>
三、JSP运行原理
1、原理:首先由浏览器向Web服务器提出访问JSP页面的请求(Request),然后由JSP容器负责将JSP转换成Servlet,产生的Servlet经过编译后生成类文件,然后再把类文件加载到内存进行执行。最后由Web服务器将执行结果响应(Response)给客户端浏览器。 如下图所示:
从图中,我们可以得到一个很重要的线索,就是jsp文件最终会变成一个Java类文件,进而编译生成可执行的字节码文件,那么JSP转换成的java文件在哪呢?
2、JSP.Java文件的位置
如果你使用的是Tomcat作为开发的服务器环境,那么可以在Tomcat的主目录下的 “Tomcat存放路径\work\Catalina\localhost”下发现,有我们之前创建的Web网站项目,打开刚刚例子下的Demo,一直点可以看到两个文件:index_jsp.java和index_jsp.class,打开.java文件,可以看到如下代码,这就是JSP经过服务器处理后形成的对应的Java文件。
/*
* Generated by the Jasper component of Apache Tomcat
* Version: Apache Tomcat/8.0.27
* Generated at: 2016-03-26 07:40:41 UTC
* Note: The last modified time of this file was set to
* the last modified time of the source file after
* generation to assist with modification tracking.
*/
package org.apache.jsp;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import java.util.*;
public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent,
org.apache.jasper.runtime.JspSourceImports {
private static final javax.servlet.jsp.JspFactory _jspxFactory =
javax.servlet.jsp.JspFactory.getDefaultFactory();
private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;
private static final java.util.Set<java.lang.String> _jspx_imports_packages;
private static final java.util.Set<java.lang.String> _jspx_imports_classes;
static {
_jspx_imports_packages = new java.util.HashSet<>();
_jspx_imports_packages.add("javax.servlet");
_jspx_imports_packages.add("java.util");
_jspx_imports_packages.add("javax.servlet.http");
_jspx_imports_packages.add("javax.servlet.jsp");
_jspx_imports_classes = null;
}
private volatile javax.el.ExpressionFactory _el_expressionfactory;
private volatile org.apache.tomcat.InstanceManager _jsp_instancemanager;
public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
return _jspx_dependants;
}
public java.util.Set<java.lang.String> getPackageImports() {
return _jspx_imports_packages;
}
public java.util.Set<java.lang.String> getClassImports() {
return _jspx_imports_classes;
}
public javax.el.ExpressionFactory _jsp_getExpressionFactory() {
if (_el_expressionfactory == null) {
synchronized (this) {
if (_el_expressionfactory == null) {
_el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
}
}
}
return _el_expressionfactory;
}
public org.apache.tomcat.InstanceManager _jsp_getInstanceManager() {
if (_jsp_instancemanager == null) {
synchronized (this) {
if (_jsp_instancemanager == null) {
_jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
}
}
}
return _jsp_instancemanager;
}
public void _jspInit() {
}
public void _jspDestroy() {
}
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException {
final java.lang.String _jspx_method = request.getMethod();
if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method) && !javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSPs only permit GET POST or HEAD");
return;
}
final javax.servlet.jsp.PageContext pageContext;
javax.servlet.http.HttpSession session = null;
final javax.servlet.ServletContext application;
final javax.servlet.ServletConfig config;
javax.servlet.jsp.JspWriter out = null;
final java.lang.Object page = this;
javax.servlet.jsp.JspWriter _jspx_out = null;
javax.servlet.jsp.PageContext _jspx_page_context = null;
try {
response.setContentType("text/html;charset=utf-8");
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
out.write("\r\n");
out.write("<html>\r\n");
out.write("<head>\r\n");
out.write("<title>session对象方法</title>\r\n");
out.write("</head>\r\n");
out.write("<body><b>\r\n");
out.write("会话ID : ");
out.print( session.getId() );
out.write("<br/>\r\n");
out.write("是否新会话: ");
out.print( session.isNew() );
out.write("<br/>\r\n");
out.write("设置和获取属性对象:用户名=\r\n");
session.setAttribute("用户名","Bill56");
out.write('\r');
out.write('\n');
out.print(session.getAttribute("用户名"));
out.write("<br/>\r\n");
Date creationTime = new Date(session.getCreationTime());
Date accessedTime = new Date(session.getLastAccessedTime());
out.write("\r\n");
out.write("会话创建时间:");
out.print( creationTime);
out.write("<br/>\r\n");
out.write("上次访问时间:");
out.print( accessedTime);
out.write("<br/>\r\n");
out.write("\r\n");
out.write("会话持续时间(s):");
out.print( session.getMaxInactiveInterval());
out.write("<br/>\r\n");
out.write("</body>\r\n");
out.write("</html>\r\n");
out.write("\r\n");
} catch (java.lang.Throwable t) {
if (!(t instanceof javax.servlet.jsp.SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
try {
if (response.isCommitted()) {
out.flush();
} else {
out.clearBuffer();
}
} catch (java.io.IOException e) {}
if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
else throw new ServletException(t);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
}
3、分析代码
阅读上述代码,可以发现index_jsp.java这个类中有如下成员变量的定义:
final javax.servlet.jsp.PageContext pageContext;
javax.servlet.http.HttpSession session = null;
final javax.servlet.ServletContext application;
final javax.servlet.ServletConfig config;
javax.servlet.jsp.JspWriter out = null;
final java.lang.Object page = this;
javax.servlet.jsp.JspWriter _jspx_out = null;
javax.servlet.jsp.PageContext _jspx_page_context = null;
是不是发现刚好有熟悉的东西呢?没错,pageContext,session,application,config,out,page这6个JSP的内置对象的定义都在这里,并且还可以知道它们所属的类,那么问题来了?还有三个内置对象呢?request,response和exception去哪了呢?
仔细阅读代码,会发现,有一个这样的方法:
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException;
这个方法的参数中又有了熟悉的request和response了,并且可以知道它们分别属于HttpServletRequest类和HttpServletResponse类,至于exception这个对象,因为,前面说过,必须把jsp文件的page中指定isErrorPage为true时,才可以使用,也就意味着没有指定这个属性的jsp页面在转换成java文件时不会自动为我们定义exception这个对象,大家可以自定义个jsp文件,将其errorPage指定为true,再找到对应的java文件,便可以发现exception这个对象了。
好了,关于JSP内置对象的介绍就到这了,让我想想下个礼拜要更新点什么呢,嘻嘻~~~
谢谢您的关注和阅读,文章不当之处还请您不吝赐教~~~