JSP工作原理
1)Web容器根据客户端访问的资源类别(Web容器会根据资源的第一行代码确定),如果你访问的是JSP资源,就交由JSP引擎处理
如果你访问的是Servlet资源,就交由Servlet引擎处理
2)如果是JSP资源,JSP引擎会将其翻译成Servlet资源,传入相关的对象,如果是静态资源,以out.write()形式输出,如果是动态 资源,以out.print()形式输出
3)此时JSP引擎在翻译正确后,将其输出给Servlet引擎,当作Servlet处理。
4)如果再次访问同一个date.jsp文件,翻译工作依然进行,Servlet引擎工作可以减化,所以这是为会么第N次较第1次快的原因
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<body>
<font size="44" color="red">
当前时间:<%= new Date().toLocaleString()%>
</font>
</body>
</html>
翻译
// Decompiled by Jad v1.5.8e2. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://kpdus.tripod.com/jad.html
// Decompiler options: packimports(3) fieldsfirst ansi space
// Source File Name: date_jsp.java
package org.apache.jsp;
import java.io.IOException;
import java.util.Date;
import java.util.Map;
import javax.el.ExpressionFactory;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.*;
import org.apache.jasper.runtime.*;
import org.apache.tomcat.InstanceManager;
public final class date_jsp extends HttpJspBase
implements JspSourceDependent
{
private static final JspFactory _jspxFactory = JspFactory.getDefaultFactory();
private static Map _jspx_dependants;
private ExpressionFactory _el_expressionfactory;
private InstanceManager _jsp_instancemanager;
public date_jsp()
{
}
public Map getDependants()
{
return _jspx_dependants;
}
public void _jspInit()
{
_el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
_jsp_instancemanager = InstanceManagerFactory.getInstanceManager(getServletConfig());
}
public void _jspDestroy()
{
}
public void _jspService(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException
{
JspWriter _jspx_out;
PageContext _jspx_page_context;
JspWriter out = null;
_jspx_out = null;
_jspx_page_context = null;
try
{
response.setContentType("text/html;charset=UTF-8");
PageContext pageContext = _jspxFactory.getPageContext(this, request, response, null, true, 8192, true);
_jspx_page_context = pageContext;
pageContext.getServletContext();
pageContext.getServletConfig();
pageContext.getSession();
JspWriter out = pageContext.getOut();
_jspx_out = out;
out.write("\r\n");
out.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\r\n");
out.write("<html>\r\n");
out.write(" <body>\r\n");
out.write(" \t<font size=\"44\" color=\"red\">\r\n");
out.write(" \t\t当前时间:");
out.print((new Date()).toLocaleString());
out.write("\r\n");
out.write(" \t</font>\r\n");
out.write(" </body>\r\n");
out.write("</html>\r\n");
break MISSING_BLOCK_LABEL_251;
}
catch (Throwable t)
{
if (!(t instanceof SkipPageException))
{
JspWriter out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
try
{
if (response.isCommitted())
out.flush();
else
out.clearBuffer();
}
catch (IOException ) { }
if (_jspx_page_context != null)
_jspx_page_context.handlePageException(t);
else
throw new ServletException(t);
}
}
_jspxFactory.releasePageContext(_jspx_page_context);
break MISSING_BLOCK_LABEL_259;
Exception exception;
exception;
_jspxFactory.releasePageContext(_jspx_page_context);
throw exception;
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
JSP语法
1)JSP模版元素
模版元素就是HTML中的静态内容,即<body>,<table>,<form>标签。。。
2)JSP表达式
a)语法:<%="字符串变量或表达式"%>
c)默认输出到浏览器
<font size="44" color="red">
当前时间:<%= new Date().toLocaleString()%>
</font>
3)JSP脚本片断
a)语法:<% ...java代码; %>
b)脚本片断中的注释符号与java代码一致
注意:JSP修改后,无需重新部署,直接刷新,Web容器会自动比较新旧二个版本的JSP
c)多个JSP脚本片断中定义的变量,本质是_jspService()方法中的局部变量
4)JSP声明
a)语法:<%! ...java代码 %>
b)JSP声明的变量或方法,会成为Servlet的实例变量或实例方法或普通方法
c)JSP脚本片断中不能定义局部方法,方法只能定义在JSP声明中
3,4点看如下代码
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ page import="java.io.*"%>
<%@ page import="java.net.*"%>
<%@ page buffer="8kb" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<body>
<%!
属性
String name = "呵呵";
%>
<%!
方法
public String getName(){
return name;
}
%>
<%
String name = "局部变量";
%>
该实例变量为:<%=getName()%>
</body>
</html>
输出:该实例变量为:呵呵
// Decompiled by Jad v1.5.8e2. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://kpdus.tripod.com/jad.html
// Decompiler options: packimports(3) fieldsfirst ansi space
// Source File Name: declare_jsp.java
package org.apache.jsp;
import java.io.IOException;
import java.util.Map;
import javax.el.ExpressionFactory;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.*;
import org.apache.jasper.runtime.*;
import org.apache.tomcat.InstanceManager;
public final class declare_jsp extends HttpJspBase
implements JspSourceDependent
{
String name;
private static final JspFactory _jspxFactory = JspFactory.getDefaultFactory();
private static Map _jspx_dependants;
private ExpressionFactory _el_expressionfactory;
private InstanceManager _jsp_instancemanager;
public declare_jsp()
{
name = "呵呵";
}
public String getName()
{
return name;
}
public Map getDependants()
{
return _jspx_dependants;
}
public void _jspInit()
{
_el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
_jsp_instancemanager = InstanceManagerFactory.getInstanceManager(getServletConfig());
}
public void _jspDestroy()
{
}
public void _jspService(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException
{
JspWriter _jspx_out;
PageContext _jspx_page_context;
JspWriter out = null;
_jspx_out = null;
_jspx_page_context = null;
try
{
response.setContentType("text/html;charset=UTF-8");
PageContext pageContext = _jspxFactory.getPageContext(this, request, response, null, true, 8192, true);
_jspx_page_context = pageContext;
pageContext.getServletContext();
pageContext.getServletConfig();
pageContext.getSession();
JspWriter out = pageContext.getOut();
_jspx_out = out;
out.write("\r\n");
out.write("\r\n");
out.write("\r\n");
out.write("\r\n");
out.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\r\n");
out.write("<html>\r\n");
out.write(" <body>\r\n");
out.write(" \r\n");
out.write(" \r\n");
out.write("\t");
out.write(" \r\n");
out.write("\t");
out.write(13);
out.write(10);
out.write(9);
out.write("\r\n");
out.write("\t\r\n");
out.write("\t该实例变量为:");
out.print(getName());
out.write("\r\n");
out.write(" </body>\r\n");
out.write("</html>\r\n");
break MISSING_BLOCK_LABEL_322;
}
catch (Throwable t)
{
if (!(t instanceof SkipPageException))
{
JspWriter out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
try
{
if (response.isCommitted())
out.flush();
else
out.clearBuffer();
}
catch (IOException ) { }
if (_jspx_page_context != null)
_jspx_page_context.handlePageException(t);
else
throw new ServletException(t);
}
}
_jspxFactory.releasePageContext(_jspx_page_context);
break MISSING_BLOCK_LABEL_330;
Exception exception;
exception;
_jspxFactory.releasePageContext(_jspx_page_context);
throw exception;
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
5)JSP指令
1)指令是程序员控制JSP引擎做什么的依据
2)有三类:
a)page
b)include
c)tablib
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
page指令的属性有
- language="指明JSP支持的语言,默认为java语言"
- import="当前JSP页面中,需要导入的包,其中import可以写多次"
- session="true表示需要服务器创建session/false不需要服务器创建session",默认true
- buffer="none|8kb|sizekb"JSP输出使用的缓存大小,默认8kb
- autoFlush="true表示当缓存满时,web容器是自动刷新到客户端/false需要手工刷新到客户端",默认true
- isThreadSafe="true表示web服务器确保线程安全/false不确保线程安全",默认true
- info="text"表示jsp的相关描述信息,可以通过getServletInfo()取得该jsp的信息
- errorPage="当前jsp页面出错后,转发到的目标页面,用于局部异常处理
- isErrorPage="true"(当某个jsp页面有该属性时,web容器会自动创建exception对象 ,该页面是是异常处理页面,用于局部异常处理。
- isELIgnored="false":false:JSP引擎不忽略EL表达式语言;true:JSP引擎忽略EL表达式语言"
- pageEncoding="UTF-8"
- jSP页面的中文采用UTF-8方式编码
- JSP保存时采用UTF-8方式编码
- 指示浏览器以UTF-8方式查看
<%@ page import="java.io.*"%>
<%@ page import="java.net.*"%>
<%@ page buffer="8kb" %>
<%@ page isErrorPage="true" %>
<%@ page errorPage="error.jsp" %>
全局异常处理
在web.xml文件:
<error-page>
<error-code>500</error-code>
<location>/s_500.jsp</location>
</error-page>
<error-page>
<exception-type>java.lang.NumberFormatException</exception-type>
<location>/s1_500.jsp</location>
</error-page>
如果全局中有code又有type,此时二者同时显示
当全局和局部异常同时出现时,局部异常优先
6 @include指令[静态包含]
1)include指令包含多个JSP页面,最后JSP引擎只翻译主JSP页面,即index.jsp页面
2)include指令包含n个JSP页面,那么被包含的JSP页面原封不动的进入主JSP页面,即index.jsp页面,造成HTML结构非常混乱
3)include指令包含多个JSP页面,多个JSP最终会翻译成一个Servlet,即index_jsp.java页面
细节
被引入的文件必须遵循JSP语法。 被引入的文件可以使用任意的扩展名,即使其扩展名是html,JSP引擎也会按照处理jsp页面的方式处理它里面的内容,为了见明知意,JSP规范建议使用.jspf(JSP fragments)作为静态引入文件的扩展名。
由于使用include指令将会涉及到2个JSP页面,并会把2个JSP翻译成一个servlet,所以这2个JSP页面的指令不能冲突(除了pageEncoding和导包除外)。
<%-- 包含head.jsp和foot.jsp --%>
<%@ include file="common/head.jsp"%>
<hr/>
include指令的用法
<hr/>
<%@ include file="common/foot.jsp"%>
</body>
// Decompiled by Jad v1.5.8e2. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://kpdus.tripod.com/jad.html
// Decompiler options: packimports(3) fieldsfirst ansi space
// Source File Name: index_jsp.java
package org.apache.jsp;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.el.ExpressionFactory;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.*;
import org.apache.jasper.runtime.*;
import org.apache.tomcat.InstanceManager;
public final class index_jsp extends HttpJspBase
implements JspSourceDependent
{
private static final JspFactory _jspxFactory = JspFactory.getDefaultFactory();
private static Map _jspx_dependants;
private ExpressionFactory _el_expressionfactory;
private InstanceManager _jsp_instancemanager;
public index_jsp()
{
}
public Map getDependants()
{
return _jspx_dependants;
}
public void _jspInit()
{
_el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
_jsp_instancemanager = InstanceManagerFactory.getInstanceManager(getServletConfig());
}
public void _jspDestroy()
{
}
public void _jspService(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException
{
JspWriter _jspx_out;
PageContext _jspx_page_context;
JspWriter out = null;
_jspx_out = null;
_jspx_page_context = null;
try
{
response.setContentType("text/html;charset=UTF-8");
PageContext pageContext = _jspxFactory.getPageContext(this, request, response, "error.jsp", true, 8192, true);
_jspx_page_context = pageContext;
pageContext.getServletContext();
pageContext.getServletConfig();
pageContext.getSession();
JspWriter out = pageContext.getOut();
_jspx_out = out;
out.write("\r\n");
out.write("\r\n");
out.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\r\n");
out.write("<html>\r\n");
out.write(" <body>\r\n");
out.write(" ");
out.write("\t\r\n");
out.write("\t");
out.write("\r\n");
out.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\r\n");
out.write("<html>\r\n");
out.write(" <body>\r\n");
out.write(" \thead.jsp\r\n");
out.write(" </body>\r\n");
out.write("</html>\r\n");
out.write("\r\n");
out.write("\t\t<hr/>\r\n");
out.write("\t\tinclude指令的用法\r\n");
out.write("\t\t<hr/>\r\n");
out.write("\t");
out.write("\r\n");
out.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\r\n");
out.write("<html>\r\n");
out.write(" <body>\r\n");
out.write(" \tfoot.jsp\r\n");
out.write(" </body>\r\n");
out.write("</html>\r\n");
out.write("\r\n");
out.write(" \r\n");
out.write(" </body>\r\n");
out.write("</html>\r\n");
break MISSING_BLOCK_LABEL_384;
}
catch (Throwable t)
{
if (!(t instanceof SkipPageException))
{
JspWriter out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
try
{
if (response.isCommitted())
out.flush();
else
out.clearBuffer();
}
catch (IOException ) { }
if (_jspx_page_context != null)
_jspx_page_context.handlePageException(t);
else
throw new ServletException(t);
}
}
_jspxFactory.releasePageContext(_jspx_page_context);
break MISSING_BLOCK_LABEL_392;
Exception exception;
exception;
_jspxFactory.releasePageContext(_jspx_page_context);
throw exception;
_jspxFactory.releasePageContext(_jspx_page_context);
}
static
{
_jspx_dependants = new HashMap(2);
_jspx_dependants.put("/common/head.jsp", Long.valueOf(0x13731484f4fL));
_jspx_dependants.put("/common/foot.jsp", Long.valueOf(0x13731484f4fL));
}
}
7 jsp九大隐式/内置对象
1)request
2)response
3)session
访问jsp页面时,默认web服务器创建session
访问servlet时,必须通过request.getSession()才能创建session
在转发和重定向情况下,session域不会销毁
4)application=ServletContext对象
5)config:取得jsp在web.xml文件中的映射信息
6)exception:该对象只能在<%@isErroPage="true"%>的情况下,容器才会创建,否则容器不予创建
<body>
出错了:原因如下<br/>
<%=exception.getMessage()%>
</body>
7)out:out的类型是JspWriter,它是具体缓存功能的PrintWriter对象
<%
//out内置对象的类型是JspWriter,它是一个带有缓冲的PrintWriter对象
out.write("先");
//response内置对象输出
response.getWriter().write("后");
%>
8)pageContext: 表示Jsp行运过程中的环境对象
a)能够取得其它8个内置对象
b)具有转发和包含的功能
c)域对象
[pageContext/request/session/application]
9)page
获取对象
- getException方法返回exception隐式对象
- getPage方法返回page隐式对象
- getRequest方法返回request隐式对象
- getResponse方法返回response隐式对象
- getServletConfig方法返回config隐式对象
- getServletContext方法返回application隐式对象
- getSession方法返回session隐式对象
- getOut方法返回out隐式对象
pageContext对象的方法
public void setAttribute(java.lang.String name,java.lang.Object value)
public java.lang.Object getAttribute(java.lang.String name)
public void removeAttribute(java.lang.String name)
pageContext对象中还封装了访问其它域的方法
public java.lang.Object getAttribute(java.lang.String name,int scope)
public void setAttribute(java.lang.String name, java.lang.Object value,int scope)
public void removeAttribute(java.lang.String name,int scope)
代表各个域的常量
PageContext.APPLICATION_SCOPE
PageContext.SESSION_SCOPE
PageContext.REQUEST_SCOPE
PageContext.PAGE_SCOPE
findAttribute方法 :先后查找各个域中的属性
四个域对象的生命周期
1、pageContext jsp执行时创建pageContext,jsp页面结束时pageContext销毁
2、request 客户请求服务器时创建,请求结束request销毁
3、session 客户机请求服务器时,第一次getSession时,服务器创建session,session过xx多长时间没用了(或调用了 session.invalidate方法),服务器销毁session
4、application(servletContext) web应用启动时就创建,web应用停止就销毁