JSP的工作原理
我们编写一个简单的HTML文件----form.html,这个HTML中包含一个表单,这个表单可以接受用户输入的数字,然后把这个数字发送到Web服务器,服务器根据接受的参数决定显示内容重复的次数。
form.html
<html>
<head>
<title>JSP原理</title>
</head>
<body>
<p>请输入显示的次数</p>
<form method=get action="showData.jsp">
<input type="text" name=times>
<input type=submit value="提交">
</form>
</body>
</html>
因为这里说原理,且说显示图片麻烦,固将图片省略。反正页面显示一个text文本框和一个提交按钮。
当用户在文本框中输入数字后点击提交,浏览器会把用户的数据和请求发送到showData.jsp。由于showData.jsp是新编写的,故还没有经过编译,Servlet容器会在第一次调用这个JSP时候自动编译它。编译完成后,就好调用这个JSP。JSP从服务器获得请求中表单的数据,根据这个数据执行Scriptlet并产生一些输出。这些输出包含的就是HTML文件,然后由Servlet容器把这些输出发送到客户端。
下面给出showData.jsp页面代码
< %@ page language="java" contentType="text/html;charset=gb2312"% >
<%@ page info="a hello world example"%>
<html>
<head>
<title>jsp原理</title>
</head>
<body>
<center>
<h1>
<%
int times=Integer.parseInt(request.getParameter("times"));
for(int i=0;i<times;i++){
out.println("Hello, World");
out.println("<br>")
}
%>
</h1>
</center>
</body>
</html>
这个页面显示你在form.html中提及数字个Hello World!。例如你在form.html中提及的数字是5,那么在showData.jsp页面就显示6行Hello World!
那看看在showData.jsp页面的Scriptlets吧!
<%
int times=Integer.parseInt(request.getParameter("times"));
for(int i=0;i<times;i++){
out.println("Hello, World");
out.println("<br>")
}
%>
。那么被解析成HTML代码是什么呢?看下面
Hello WorldI
<br>
Hello WorldI
<br>
Hello WorldI
<br>
Hello WorldI
<br>
.....
为了进一步了解JSP的工作原理,我们还得看JSP编译后的结果。
Servlet容器在第一次调用JSP时,会自动编译,然后这个JSP就驻留内存了。所以我们在调用JSP时,第一次总是会有一定的延时,在接下来的调用中就不会再有延时了。
下面看看JSP引擎上得到的java文件的源代码:
package org.apache.jsp;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
public final class helloworld_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent{
public String getServeltInfo(){
return "a Hello world example";
}
public static java.util.Vector_jspx_dependants;
public java.util.List getDependants(){
return _jspx-dependents;
}
public void _jspService(HttpServletRequest request,HttpServeltResponse response)
throws java.io.IOException,ServeltException{
JSPFactory _jspxFactory=null;
PageContext pageContext=null;
HttpSession session=null;
ServletContext application=null;
ServletConfig config=null;
JspWriter out=null;
Object page=this;
JspWriter _jspx_out=null;
try
_jspxFactory=JspFactory.getDefaultFactory();
response.setContentType("text/html;charset=gb2312");
pageContext=_jspxFactory.getPageContext(this,request,response,null,true,8192,true);
application=pageContext.getServeltContext();
config=pageContext.getServeltConfig();
session=pageContext.getSession();
out=pageContext.getOut();
_jspx_out=out;
out.write(" \r\n");
out.write(" \r\n");
out.write("<html>\r\n\t");
out.write("<head>\r\n\t\t");
out.write("<title>JSP原理 ");
out.write("<title>\r\n\t");
out.write(" </head>\r\n\t");
out.write("<body> \r\n\t\t");
out.write("<center> \r\n\t\t");
out.write("<h1> \r\n\t\t");
int times=Integer.parseInt(request.getParameter("times"));
for(int i=0;i<times;i++)
{
out.println("Hello,World!");
out.println("<br>");
}
out.write(" \r\n\t\t");
out.write("</h1> \r\n\t\t");
out.write("</center> \r\n\t\t");
out.write("</body> \r\n");
out.write(" </html>\r\n");
catch(Throwable){
if(!(instanceof javax.servlet.jsp.SkipPageException)){
out=_jspx_out;
if(out!=null && out.getBufferSize()!=0)
out.clearBuffer();
if(pageContent!=null) pageContext.handlePageException();
}
}finally{
if(_jspFactory!=null) _jspxFactory.releasePageContext(pageContext);
}
}
}
看完上面的代码,请留意黑体字是生成客户端响应的代码片段。可以看出,通过一个循环把动态的内容输入到客户端输出流上。 JSP源文件是安装在Web服务器上的JSP引擎编译执行的。JSP引擎把来自客户端的请求传递给JSP源文件,然后JSP引擎再把对它的响应从JSP源文件传递给客户端。
所有的JSP引擎都必须支持的请求和响应协议时HTTP,但是同一个引擎也可以支持其他的一些请求和响应协议。默认的request对象对应的协议是HttpServletRequest,而response对象对应的协议则是HttpServletResponse。
一个JSP引擎需要在传递request和response对象之前,在JSP源代码中创建一个类,而Servlet则定义了在JSP引擎与JSP源文件之间实现类的约定。例如,当使用HTTP协议时,HttpServlet类就描述了JSP引擎和JSP源文件实现类之间的约定。
JSP规范中还定义了JSP引擎与JSP页面作者之间的约定,这个约定实际上就是页面作者对JSP源文件中描述的动作所进行的假设。例如
public final void _jspx_init() throws JasperException :该方法可以在JSP页面中随意定义JSP页面初始化时调用该方法当该方法调用时,在Servlet中的所有方法都可以使用。
public final void _jspx_destory()throws JasperException :该方法可以再JSP页面中随意定义JSP页面结束之前调用该方法
public void _jspService(HttpServeltRequest request,HttpServeltResponse response)throws IOException,ServeltException: 该方法不能在JSP页面中定义JSP引擎自动按照JSP页面的内容产生这个方法每次客户请求时,都要调用该方法
这个约定描述了一个JSP作者如何说明当源文件实现init()和destory()方法时必须执行的一些动作。在这个约定中,最重要的是 _jspService()方法,这个方法是通过一个JSP引擎从JSP源文件自动产生的。
上述就是JSP的技术原理。如果有什么不对请大家不要浪费砖头,给我狠狠的拍。呵呵