一、JSP中的隐藏对象
由于JSP是嵌入式的语言,不能显式的把一些必须的参数传递进来,比如Request对象,Response对象等,所以在JSP规范中提供了几个隐含的对象来实现折椅功能。所谓隐含的对象,就是大家约定好使用一个名字来指代某个特定的对象,在编写JSP的时候不用显式的声明就能使用,由JSP引擎负责在解释的时候把隐含对象加入到解释完的.java文件中。常用的隐含对象有application, session, request, response, out, page, exception, pageContext
1.session对象
2.application对象
3.request对象
4.respose对象
5.out对象
6.page对象
7.exception对象
8.pageContext对象
1.session对象
前面在Servlet部分已经提到,过当客户第一次访问Web服务器发布目录(一个Web服务器有一个或多个"发布目录")下的网页文件时,Web服务器会自动创建一个session对象,并为其分配唯一的ID号,客户可以将其需要的一些信息保存到该session对象,以便需要时使用。session对象就是指通过getSession法办法得到的对象,在JSP中是隐含对象,关于session对象的使用读者可以参见Servlet API
2.application对象
当Web服务器启动时,Web服务器会自动创建application对象。Application对象一旦创建,它将一直存在,直到Web服务器关闭。因此,application对象可以实现多客户间的数据共享。
一个Web服务器常常有多个发布目录,当Web服务器启动时,它自动为每个发布目录都创建一个application对象,这些application对象各自独立,而且和发布目录一一对应。
application的生命周期:从Web服务器启动到Web服务器关闭。
application在生命周期内的作用范围:在同一个发布目录A下的所有网页文件中,都可以对"和发布目录A对应"的application对象进行操作,而且访问发布目录A的所有客户都共用一个application对象。因此,当在该application中存放数据信息时,所有访问该发布目录A的客户都能够对其进行访问,实现了多客户之间的数据共享。
application对象的基类是:javax.servlet.ServletContext类。可以用该类中的getServletContext()方法取得application。具体的使用方法参见Servlet API。
3.request对象
request对象主要用于取得客户在表单中提交的数据信息及多个网页之间数据信息传递等。同时通过它也可以取得Web服务器的参数。跟Servlet参数中的Request对象是相对应的。
request对象的基类为:javax.servlet.ServletRequest
如果传输协议是http,则是javax.servlet.HttpServletRequest
具体的使用方法参见Servlet API。
4. respose对象
respose对象主要用于向客户端输出信息,响应客户端的请求。跟Servlet参数中的Response对象是相对应的。
respose对象的基类是:javax.servlet.ServletResponse
如果传输协议是http.则为javax.servlet.HttpServletResponse.
具体的使用方法参见Servlet API。
5.out对象
out对象用于向客户端输出数据。
out对象基类是:javax.servlet.JspWriter类,跟Servlet中由HttpServletResponse得到的PrintWriter略有不同,但是都是从
Writer继承而来,所以基本上还是一样的。
具体的使用方法参见Servlet API。
6.page对象
page对象是当前JSP页面本身的一个实例。它的类型是:java.lang.Object。
其方法就是Object类中的方法。如:Class getClass()返回一个对象在运行时所对应的类的表示,从而可以得到相应的信息。String toString()返回当前对象的字符串表示。page对象在当前页面中可以用this代替。
具体的使用方法参见Java 2 API。
7.exception对象
当JSP页面在执行过程中发生例外或错误时,会自动产生exception对象。
在当前页面用设置后,就可以使用该exception对象,来查找页面出错信息。
exception对象的类型是:java.lang.Exception类.
exception对象的常用方法为:
String getMessage()
返回页面的出错信息,如果没有则返回null
void printStackTrace()
以标准错误输出流的形式,打印并显示当前exception对象及其执行轨迹.
具体的使用方法参见Java 2 API。
8.pageContext对象
pageContext对象相当于当前页面的容器,可以访问当前页面的所有对象。
pageContext对象的基类是:javax.servlet.jsp.PageContext类。
pageContext对象的常用方法:
HttpSession getSession() 取得当前页面的session对象。
ServletRequest getRequest() 取得当前页面的request对象。
ServletResponse getResponse() 取得当前页面的response对象。
ServletContext getServletContext() 取得当前页面的application对象。
ServletConfig getServletConfig() 取得当前页面的config对象。
Object getPage() 取得当前页面的page对象。
JspWriter getOut() 取得当前页面的out对象。
Exception getException() 取得当前页面的exception对象。
void setAttribute(String variabelName, Object objectName)
将对象objectName保存到pageContext中。
Object getAttribute(String variableName)
取得pageContext对象中保存的数据。如果参数variableName在当前session中不存在,则返回null.
void removeAttribute(String variableName)
删除pageContext中指定名字variableName的对象。如果该对象名不存在,则不执行任何操作。
具体的使用方法参见Servlet API。
二、JSP中的隐藏对象
下面举一个简单例子来说明JSP的基本的编写方法,具体的应用技巧还需要读者到实践中去体会。这个例子就是用JSP来实现我们在讲解Servlet的时候给出的从表单获取数据并打印到客户客户端的例子,原来的例子中用到的静态HTML文件,只需把form的action改成我们新的响应文件JSPtest.jsp即可,读者主要查看JSP文件和原来的Java文件的区别。
1.静态HTML文件ourform..html
2.JSP文件:JSPtest.jsp
1.静态HTML文件ourform.html
Our Form
你的姓名:
你的性别:男
2.JSP文件:JSPtest.jsp
Data You Posted
你的姓名:
你的性别: 男
这个例子的执行结果和前面是一摸一样的。在以前Servlet分析的基础上,读者看懂这个例子应该没什么问题,这里就不对语法做过多分析了。下面我们来分析一下这个例子的几个特点。
首先最明显的一点就是,使用JSP之后文件变得更短,格式更清晰了,这也是要使用JSP的一个最主要的原因,使用Servlet来打印大量的HTML语句是很费事的,而JSP的主体是HTML,嵌入的Java语句只负责动态效果,所以使用比Servlet方便的多。在下面我们会分析如何使Servlet和JSP互相配合,取长补短,获得更好的应用效果。
另外一个就是JSP使用的时候不需要单独配置每一个文件,只要是扩展名为jsp,JSP引擎会自动识别。而Servlet是必须进行配置后才能投入使用的,这也是处于安全性的考虑,直接访问.class文件是不允许的,因为不能保证它是一个合法的Servlet。而JSP是没有经过编译的文本,即使是编译成了Servlet,也肯定是符合Servlet规范的,尽管可能不符合HTML语法,所以它是安全的。
还有就是中文问题在这里的到了简化,本地的中文字符串不需要编码转换就能够正常在客户端显示。这里关键的一点是在头部设置页属性,其中charset=gb2312就是告诉JSP引擎本地编码是gb2312,然后JSP引擎就会自动进行转换,不需要手工转了。但是,并不是说就这么一劳永逸了,中文问题在JSP页面之间传参的时候还是存在的,读者只要掌握了编码的转换方式,应付任何中文问题就是转来转去的问题,因此读者应该从根本上理解中文问题,这才是一劳永逸的办法。
这时候如果我们把静态页面的GET改成POST会是什么后果呢?我们会发现,不象HttpServlet,这个JSP还是能够正常工作的,这是因为JSP的实现在最低层是Servlet,但跟HttpServlet又是有所区别的,所以它不存在客户端请求的分类问题,它只有一个_jspService(HttpServletRequest request, HttpServletResponse response)方法由JSP引擎实现,所以写JSP不必象Servlet那样关心那么多杂碎的事情。
下面是Resin生成的临时Java文件,是上面的例子转换成Servlet之后的样子,有兴趣的读者可以读一下,如果真正读通懂了,一定会受益匪浅的。
// Resin(tm) generated JSP
package _jsp;
import java.io.*;
import javax.servlet.*;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
import javax.servlet.http.*;
public class _JSPtest__jsp extends com.caucho.jsp.JavaPage{
public void
_jspService(javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response)
throws IOException, javax.servlet.ServletException
{
javax.servlet.jsp.PageContext pageContext = com.caucho.jsp.QJspFactory.create().getPageContext(this, request, response, null, true, 8192, true);
javax.servlet.jsp.JspWriter out = (javax.servlet.jsp.JspWriter) pageContext.getOut();
com.caucho.jsp.ByteWriteStream _jsp_raw_out;
_jsp_raw_out = (com.caucho.jsp.ByteWriteStream) out;
javax.servlet.ServletConfig config = getServletConfig();
javax.servlet.Servlet page = this;
javax.servlet.http.HttpSession session = pageContext.getSession();
javax.servlet.ServletContext application = pageContext.getServletContext();
try {
_jsp_raw_out.write(_jsp_string0, 0, _jsp_string0.length);
String name = request.getParameter("Name");
String sex = request.getParameter("Sex");
_jsp_raw_out.write(_jsp_string1, 0, _jsp_string1.length);
out.print((name));
_jsp_raw_out.write(_jsp_string2, 0, _jsp_string2.length);
if(sex.equals("1")) out.print("男");
else out.print("女");_jsp_raw_out.write(_jsp_string3, 0, _jsp_string3.length);
} catch (Exception e) {
pageContext.handlePageException(e);
} finally {
JspFactory.getDefaultFactory().releasePageContext(pageContext);
}
}
private java.util.ArrayList _caucho_depends;
private java.util.ArrayList _caucho_cache;
private com.caucho.java.LineMap _caucho_line_map;
public boolean _caucho_isModified()
{
if (com.caucho.util.CauchoSystem.getVersionId() != -1983231406)
return true;
for (int i = 0; i < _caucho_depends.size(); i++) {
com.caucho.jsp.Depend depend;
depend = (com.caucho.jsp.Depend) _caucho_depends.get(i);
if (depend.isModified())
return true;
}
return false;
}
public long _caucho_lastModified()
{
return 0;
}
public com.caucho.java.LineMap _caucho_getLineMap()
{
return _caucho_line_map;
}
public void _caucho_init(HttpServletRequest req, HttpServletResponse res)
{
res.setContentType("text/html; charset=GB2312");
}
public void init(ServletConfig config,
com.caucho.java.LineMap lineMap,
com.caucho.vfs.Path pwd)
throws ServletException
{
super.init(config);
_caucho_line_map = new com.caucho.java.LineMap("_JSPtest__jsp.java", "/JSPtest.jsp");
_caucho_line_map.add(1, 1);
_caucho_line_map.add(1, 28);
_caucho_line_map.add(9, 29);
_caucho_line_map.add(16, 33);
_caucho_line_map.add(20, 35);
_caucho_depends = new java.util.ArrayList();
_caucho_depends.add(new com.caucho.jsp.Depend(pwd.lookup("/D:/gzf@WeiHai/Resin/doc/JSPtest.jsp"),
996991110000L));
}
private static byte []_jsp_string0;
private static byte []_jsp_string1;
private static byte []_jsp_string2;
private static byte []_jsp_string3;
static {
try {
_jsp_string0 = "\r\n\r\n\r\n \r\n\r\n\r\n\r\n
Data You Posted
\r\n".getBytes("GB2312");
_jsp_string1 = "\r\n \r\n \r\n 你的姓名: \r\n ".getBytes("GB2312");
_jsp_string2 = " \r\n
\r\n \r\n 你的性别: \r\n ".getBytes("GB2312");
_jsp_string3 = " \r\n
\r\n \r\n\r\n\r\n".getBytes("GB2312");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
注意:JSP文件实际上是先被服务器转化成Servlet文件后才执行的。