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
displayTime_jsp.java和displayTime_jsp.class文件目录:%tomcat%\work\Catalina\localhost\myweb\org\apache\jsp
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就是一个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示例的文件结构:
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页面显示效果:
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标签)中会讲到。