JSP总结(一):概述,真身,语法

什么是jsp

直觉上,jsp就是Java版本的HTML,加入了一些语法,以便于结合Java代码。
实际上,jsp是一个Servlet类,由服务器自动转化。

JSP = html + Java脚本(代码片段) + JSP动态标签

jsp原理

这篇文章讲的非常详细:jsp原理

源码解析

简单概括一下:
我们编写的index.jsp文件长这样:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'index.jsp' starting page</title>
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->
  </head>
  
  <body>
    <%
    	int a = 5;
    %>
    <%=
    	5 + 5
    %>
  </body>
</html>

在Tomcat/work/Catalina/localhost里可以找到index.jsp对应的真身:index_jsp.java:

...
public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent {
...
  public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
        throws java.io.IOException, javax.servlet.ServletException {

...
}

真实index_jsp类继承了HttpJspBase抽象类:

...
public abstract class HttpJspBase extends HttpServlet implements HttpJspPage {
... 
    @Override
    public final void service(HttpServletRequest request, HttpServletResponse response) 
        throws ServletException, IOException 
    {
        _jspService(request, response);
    }
...
    @Override
    public abstract void _jspService(HttpServletRequest request, 
                                     HttpServletResponse response) 
        throws ServletException, IOException;
}

而抽象类HttpJspBase继承了我们最熟悉的HttpServlet,从service方法的调用也可以看出,真身的_jspService就是其生命周期方法中的service()。

运行过程

第一次执行:

  • 客户端通过电脑连接服务器,因为是请求是动态的,所以所有的请求交给WEB容器来处理
  • 在容器中找到需要执行的*.jsp文件
  • 之后*.jsp文件通过转换变为*.java文件
  • *.java文件经过编译后,形成*.class文件
  • 最终服务器要执行形成的*.class文件

第二次执行:

因为已经存在了*.class文件,所以不在需要转换和编译的过程

修改后执行:

1.源文件已经被修改过了,所以需要重新转换,重新编译

JSP总结(一):概述,真身,语法

jsp语法:

3种Java脚本

<%! java代码 %>
这一部分的代码用于声明成员变量和成员方法,真身中的位置是类之下,方法之上。

<% Java代码 %>
这一部分的内容都在真身的_jspService()方法中。

<%= Java代码 %>
这一部分也在_jspService()中,只不过这里的Java代码在真身中都在方法中的out.print()括号中。

Java代码和真身对比

JSP总结(一):概述,真身,语法

;