1、JSP基础



1.1、引入


Servlet的作用: 用java语言开发动态资源的技术!!!

Jsp的作用:用java语言(+html语言)开发动态资源的技术!!!

Jsp就是servlet!!!


1.2、Jsp的特点


1)jsp的运行必须交给tomcat服务器!!!!

tomcat的work目录: tomcat服务器存放jsp运行时的临时文件

2)jsp页面既可以写html代码,也可以写java代码。

(html页面不能写java代码 。而jsp页面可以写java代码)


1.3、体验jsp页面作用


需求:显示当前时间到浏览器上

可以把jsp页面当做html页面在tomcat中访问!!!

示例代码:displayTime.jsp

<%@ page language="java" import="java.util.*,java.text.*" pageEncoding="utf-8"%>



  
    显示当前时间
  
  
	<%
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
		String curTime = sdf.format(new Date());
		// response对象和out对象都是JSP的内置对象
		//response.getWrite()得到的对象是PrintWriter类型,不带有缓冲区
		//out对象是JspWriter类型,带有缓冲区
		response.getWriter().write("当前时间是:" + curTime + "
");//第一种输出方式 out.write("当前时间是:" + curTime + "
");//第二种输出方式  %>       

显示结果:


1.4、Jsp的执行过程


问题: 访问http://localhost:8080/myweb/displayTime.jsp  如何显示效果?

(1)访问到displayTime.jsp,tomcat扫描到jsp文件,    在%tomcat%/work把jsp文件翻译成java源文件

翻译:displayTime.jsp   ->   displayTime_jsp.java

(2)tomcat服务器把java源文件编译成class字节码文件

编译:displayTime_jsp.java  ->  displayTime_jsp.class

(3)tomcat服务器构造displayTime_jsp类对象

(4)tomcat服务器调用displayTime_jsp类里面方法,返回内容显示到浏览器。

 

第一次访问jsp:走(1)(2)(3)(4)

第n次访问jsp:走(4)

注意:jsp文件修改了或jsp的临时文件被删除了,要重新走翻译(1)和编译(2)的过程


displayTime.jsp文件的部署目录:%tomcat%\webapps\myweb\displayTime.jsp

JSP系列:(1)JSP基础_第1张图片


displayTime_jsp.java和displayTime_jsp.class文件目录:%tomcat%\work\Catalina\localhost\myweb\org\apache\jsp

JSP系列:(1)JSP基础_第2张图片




1.5、问题:为什么Jsp是Servlet?


在%tomcat%\work\Catalina\localhost\myweb(项目名称)\org\apache\jsp目录下

jsp翻译成的java文件displayTime_jsp.java:

package org.apache.jsp;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import java.util.*;
import java.text.*;

public final class displayTime_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent {

  private static final JspFactory _jspxFactory = JspFactory.getDefaultFactory();

  private static java.util.List _jspx_dependants;

  private javax.el.ExpressionFactory _el_expressionfactory;
  private org.apache.AnnotationProcessor _jsp_annotationprocessor;

  public Object getDependants() {
    return _jspx_dependants;
  }

  //2. _jspInit初始化方法
  public void _jspInit() {
    _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
    _jsp_annotationprocessor = (org.apache.AnnotationProcessor) getServletConfig().getServletContext().getAttribute(org.apache.AnnotationProcessor.class.getName());
  }
  //4._jspDestroy销毁方法
  public void _jspDestroy() {
  }
  //3. _jspService提供服务的方法
  public void _jspService(HttpServletRequest request, HttpServletResponse response)
        throws java.io.IOException, ServletException {
	//下面是JSP的九大内置对象中的6个	
    PageContext pageContext = null;
    HttpSession session = null;
    ServletContext application = null;
    ServletConfig config = null;
    JspWriter out = null;
    Object page = this;//只有page对象得到赋值
    //再加上由参数传入的request和response对象,还有exception对象,一共是9个
    
	JspWriter _jspx_out = null;
    PageContext _jspx_page_context = null;


    try {
      response.setContentType("text/html;charset=utf-8");

	  //下面是分别为pageContext、application、config、session和out对象赋值。
      pageContext = _jspxFactory.getPageContext(this, request, response,null, true, 8192, true);
      application = pageContext.getServletContext();
      config = pageContext.getServletConfig();
      session = pageContext.getSession();
      out = pageContext.getOut();

      _jspx_out = out;
	  _jspx_page_context = pageContext;

	  //下面的这部分内容,则是由displayTime.jsp文件翻译成的java代码。
      out.write("\r\n");
      out.write("\r\n");
      out.write("\r\n");
      out.write("\r\n");
      out.write("  \r\n");
      out.write("    显示当前时间\r\n");
      out.write("  \r\n");
      out.write("  \r\n");
      out.write("\t");

		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
		String curTime = sdf.format(new Date());
		// response对象和out对象都是JSP的内置对象
		//	response.getWrite()得到的对象是PrintWriter类型,不带有缓冲区
		//out对象是JspWriter类型,带有缓冲区
		response.getWriter().write("当前时间是:" + curTime + "
");//第一种输出方式 out.write("当前时间是:" + curTime + "
");//第二种输出方式         out.write("    \r\n");       out.write("  \r\n");       out.write("\r\n");     } catch (Throwable t) {       if (!(t instanceof SkipPageException)){         out = _jspx_out;         if (out != null && out.getBufferSize() != 0)           try { out.clearBuffer(); } catch (java.io.IOException e) {}         if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);         else log(t.getMessage(), t);       }     } finally {       _jspxFactory.releasePageContext(_jspx_page_context);     }   } }

在上面这段代码中,我们可以看到:displayTime_jsp类继承自org.apache.jasper.runtime.HttpJspBase类。

public final class displayTime_jsp extends org.apache.jasper.runtime.HttpJspBase

关于org.apache.jasper.runtime.HttpJspBase类,我们可以在%tomcat%\lib\jasper.jar包中找到它,如果要查看它的源码,在下载tomcat的地方,也提供了tomcat源码的下载。

通过查看org.apache.jasper.runtime.HttpJspBase源码,我们可以知道:HttpJspBase类继承自javax.servlet.http.HttpServlet类。HttpJspBase源码如下:

package org.apache.jasper.runtime;

import java.io.IOException;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.HttpJspPage;
import javax.servlet.jsp.JspFactory;

import org.apache.jasper.compiler.Localizer;

/**
 * This is the super class of all JSP-generated servlets.
 *
 * @author Anil K. Vijendran
 */
public abstract class HttpJspBase 
    extends HttpServlet 
    implements HttpJspPage 
{
    //1.构造方法
    protected HttpJspBase() {
    }
	//2.init方法
    public final void init(ServletConfig config) 
	throws ServletException 
    {
        super.init(config);
		jspInit();
        _jspInit();
    }
	//2.1 jspInit方法
	public void jspInit() {
    }
	//2.2 _jspInit方法
    public void _jspInit() {
    }
    
    /**
	 * 3. service方法
	 * 注意这个方法声明为final,子类不能对此service方法进行修改
     * Entry point into service.
     */
    public final void service(HttpServletRequest request, HttpServletResponse response) 
	throws ServletException, IOException 
    {
        _jspService(request, response);
    }
	//3.1 _jspService方法,这是一个abstract修饰的方法,由子类实现其代码
    public abstract void _jspService(HttpServletRequest request, 
				     HttpServletResponse response) 
	throws ServletException, IOException;
    
	//4. destory方法
    public final void destroy() {
		jspDestroy();
		_jspDestroy();
    }
	//4.1 jspDestroy方法
    public void jspDestroy() {
    }
	//4.2 _jspDestroy方法
    protected void _jspDestroy() {
    }
}

对于Servlet接口、HttpServlet类和HttpJspBase之间的关系可以用以下简图表示:

JSP系列:(1)JSP基础_第3张图片

更详细的看一下各个接口和类的方法,可以看下图

JSP系列:(1)JSP基础_第4张图片




结论:

Jsp就是一个servlet程序!!!

servlet的技术可以用在jsp程序中

jsp的技术并不是全部适用于servlet程序!


Servlet的生命周期:

1)构造方法(第1次访问)

2)init方法(第1次访问)

3)service方法

4)destroy方法

Jsp的生命周期

1)翻译: jsp->java文件

2)编译: java文件->class文件(servlet程序)

3)构造方法(第1次访问)

4)init方法(第1次访问):_jspInit()

5)service方法:_jspService()

6)destroy方法:_jspDestroy()


2、Jsp语法



2.1、Jsp模板


jsp页面中的html代码就是jsp的模板



2.2、Jsp表达式


语法:<%=变量或表达式%>

作用: 向浏览器输出变量的值或表达式计算的结果

注意:

1)表达式的原理就是翻译成out.print(“变量” );通过该方法向浏览器写出内容

2)表达式后面不需要带分号结束。



2.3、Jsp的脚本


语法:<% java代码 %>

作用: 执行java代码

注意:

1)原理:把脚本中java代码原封不动拷贝到_jspService方法中执行。


2.4、Jsp的声明


语法:<%! 变量或方法 %>

作用: 声明jsp的变量或方法

注意:

1)“变量”翻译成“成员变量”,“方法”翻译成“成员方法”。


2.5、Jsp的注释


语法: <%-- 注释内容 -->

注意:

1)html的注释会被翻译和执行。而jsp的注释不能被翻译和执行。


示例JspDemo.jsp:

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>



  
    Jsp语法
  
  
    
    <%
    	String name = "lsieun";
    	int a = 2;
    	int b = 3;
     %>
     
     
     <%="abc" %> 
     <%=name %>
     <%=(a-b) %>
     <%=add(a,b) %>
                 <%!       private boolean flag = false;//定义成员变量       private int add(int a, int b){       return a + b;       }       %>                     <%--this is a JSP comment.it will only be seen in jsp code--%>          

转换成的JspDemo_jsp.java代码:

package org.apache.jsp;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import java.util.*;

public final class JspDemo_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent {


     	private boolean flag = false;//定义成员变量
     	private int add(int a, int b){
     		return a + b;
     	}
      
  private static final JspFactory _jspxFactory = JspFactory.getDefaultFactory();

  private static java.util.List _jspx_dependants;

  private javax.el.ExpressionFactory _el_expressionfactory;
  private org.apache.AnnotationProcessor _jsp_annotationprocessor;

  public Object getDependants() {
    return _jspx_dependants;
  }

  public void _jspInit() {
    _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
    _jsp_annotationprocessor = (org.apache.AnnotationProcessor) getServletConfig().getServletContext().getAttribute(org.apache.AnnotationProcessor.class.getName());
  }

  public void _jspDestroy() {
  }

  public void _jspService(HttpServletRequest request, HttpServletResponse response)
        throws java.io.IOException, ServletException {

    PageContext pageContext = null;
    HttpSession session = null;
    ServletContext application = null;
    ServletConfig config = null;
    JspWriter out = null;
    Object page = this;
    JspWriter _jspx_out = null;
    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("\r\n");
      out.write("\r\n");
      out.write("\r\n");
      out.write("  \r\n");
      out.write("    Jsp语法\r\n");
      out.write("  \r\n");
      out.write("  \r\n");
      out.write("    \r\n");
      out.write("    ");

    	String name = "lsieun";
    	int a = 2;
    	int b = 3;
     
      out.write("\r\n");
      out.write("     \r\n");
      out.write("     \r\n");
      out.write("     ");
      out.print("abc" );
      out.write(" 
\r\n");       out.write("     ");       out.print(name );       out.write("
\r\n");       out.write("     ");       out.print((a-b) );       out.write("
\r\n");       out.write("     ");       out.print(add(a,b) );       out.write("
\r\n");       out.write("     \r\n");       out.write("     \r\n");       out.write("     ");       out.write("\r\n");       out.write("      \r\n");       out.write("      \r\n");       out.write("      ");       out.write("\r\n");       out.write("      \r\n");       out.write("  \r\n");       out.write("\r\n");     } catch (Throwable t) {       if (!(t instanceof SkipPageException)){         out = _jspx_out;         if (out != null && out.getBufferSize() != 0)           try { out.clearBuffer(); } catch (java.io.IOException e) {}         if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);         else log(t.getMessage(), t);       }     } finally {       _jspxFactory.releasePageContext(_jspx_page_context);     }   } }

在浏览器访问到的JspDemo.jsp的HTML代码如下:



  
    Jsp语法
  
  
    
    
     
     
     abc 
     lsieun
     -1
     5
                                                

3、Jsp的三大指令



3.1、include指令


作用: 在当前页面用于包含其他页面

语法: <%@include file="common/header.jsp">

注意:

1)原理是把被包含的页面(header.jsp)的内容翻译到包含页面(index.jsp)中,合并成翻译成一个java源文件,再编译运行!!,这种包含叫静态包含(源码包含)

2)如果使用静态包含,被包含页面中不需要出现全局的html标签了!!!(如html、head、body)

include示例的文件结构:

JSP系列:(1)JSP基础_第5张图片

header.jsp的内容:

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
/p_w_picpaths/bg.gif"/>

index.jsp的内容:

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>



  
    首页
  
  
    <%@include file="common/header.jsp" %>
    
    主体部分   

index.jsp页面显示效果:

JSP系列:(1)JSP基础_第6张图片


3.2、page指令


作用: 告诉tomcat服务器如何翻译jsp文件

<%@ page

language="java"   --告诉服务器使用什么动态语言来翻译jsp文件

import="java.util.*" --告诉服务器java文件使用什么包(导入包),多个包之间用逗号分割

pageEncoding="utf-8"  --告诉服务器使用什么编码翻译jsp文件(成java文件)

contentType="text/html; charset=utf-8" 服务器发送浏览器的数据类型和内容编码。

                注意:在开发工具中,以后只需要设置pageEncoding即可

                解决中文乱码问题

errorPage="error.jsp"  指定当前jsp页面的错误处理页面。

isErrorPage="false"   指定当前页面是否为错误处理页面。

                false,不是错误处理页面,则不能使用exception内置对象;

                true,是错误处理页面,可以使用exception内置对象。

buffer="8kb"        --jsp页面的缓存区大小。

session="true"      --是否开启session功能。false,不能用session内置对象;

                true,可以使用session内置对象。

isELIgnored="false"   --是否忽略EL表达式。

%>


3.3、taglib指令


语法:<%@taglib uri="tld文件的uri名称" prefix="简写">

taglib指令的作用是导入外部标签库,在后续的文章(JSP标签)中会讲到。