什么是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语法:
3种Java脚本
<%! java代码 %>
这一部分的代码用于声明成员变量和成员方法,真身中的位置是类之下,方法之上。
<% Java代码 %>
这一部分的内容都在真身的_jspService()方法中。
<%= Java代码 %>
这一部分也在_jspService()中,只不过这里的Java代码在真身中都在方法中的out.print()括号中。