zl程序教程

您现在的位置是:首页 >  后端

当前栏目

javaweb学习总结(十四)——JSP原理详解编程语言

JSP学习原理编程语言 详解 总结 javaweb 十四
2023-06-13 09:20:31 时间
一、什么是JSP?

JSP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术。
JSP这门技术的最大的特点在于,写jsp就像在写html,但它相比html而言,html只能为用户提供静态数据,而Jsp技术允许在页面中嵌套java代码,为用户提供动态数据。

二、JSP原理 2.1、Web服务器是如何调用并执行一个jsp页面的?

浏览器向服务器发请求,不管访问的是什么资源,其实都是在访问Servlet,所以当访问一个jsp页面时,其实也是在访问一个Servlet,服务器在执行jsp的时候,首先把jsp翻译成一个Servlet,所以我们访问jsp时,其实不是在访问jsp,而是在访问jsp翻译过后的那个Servlet,例如下面的代码:

index.jsp

 1 %@ page language="java" import="java.util.*" pageEncoding="UTF-8"% 

 2 % 

 3 String path = request.getContextPath(); 

 4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 

 5 % 

 7 !DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 

 8 html 

 9 head 

10 base href=" %=basePath% " 

12 title First Jsp /title 

14 /head 

16 body 

17 % 

18 out.print("Hello Jsp"); 

19 % 

20 /body 

21 /html 

当我们通过浏览器访问index.jsp时,服务器首先将index.jsp翻译成一个index_jsp.class,在Tomcat服务器的work/Catalina/localhost/项目名/org/apache/jsp目录下可以看到index_jsp.class的源代码文件index_jsp.java,index_jsp.java的代码如下:

 1 package org.apache.jsp; 

 3 import javax.servlet.*; 

 4 import javax.servlet.http.*; 

 5 import javax.servlet.jsp.*; 

 6 import java.util.*; 

 8 public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase 

 9 implements org.apache.jasper.runtime.JspSourceDependent { 

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

13 private static java.util.List _jspx_dependants; 

15 private javax.el.ExpressionFactory _el_expressionfactory; 

16 private org.apache.AnnotationProcessor _jsp_annotationprocessor; 

18 public Object getDependants() { 

19 return _jspx_dependants; 

20 } 

22 public void _jspInit() { 

23 _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory(); 

24 _jsp_annotationprocessor = (org.apache.AnnotationProcessor) getServletConfig().getServletContext().getAttribute(org.apache.AnnotationProcessor.class.getName()); 

25 } 

27 public void _jspDestroy() { 

28 } 

30 public void _jspService(HttpServletRequest request, HttpServletResponse response) 

31 throws java.io.IOException, ServletException { 

33 PageContext pageContext = null; 

34 HttpSession session = null; 

35 ServletContext application = null; 

36 ServletConfig config = null; 

37 JspWriter out = null; 

38 Object page = this; 

39 JspWriter _jspx_out = null; 

40 PageContext _jspx_page_context = null; 

43 try { 

44 response.setContentType("text/html;charset=UTF-8"); 

45 pageContext = _jspxFactory.getPageContext(this, request, response, 

46 null, true, 8192, true); 

47 _jspx_page_context = pageContext; 

48 application = pageContext.getServletContext(); 

49 config = pageContext.getServletConfig(); 

50 session = pageContext.getSession(); 

51 out = pageContext.getOut(); 

52 _jspx_out = out; 

54 out.write(/r); 

55 out.write(/n); 

57 String path = request.getContextPath(); 

58 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 

60 out.write("/r/n"); 

61 out.write("/r/n"); 

62 out.write(" !DOCTYPE HTML PUBLIC /"-//W3C//DTD HTML 4.01 Transitional//EN/" /r/n"); 

63 out.write(" html /r/n"); 

64 out.write(" head /r/n"); 

65 out.write(" base href=/""); 

66 out.print(basePath); 

67 out.write("/" /r/n"); 

68 out.write(" /r/n"); 

69 out.write(" title First Jsp /title /r/n"); 

70 out.write("/t/r/n"); 

71 out.write(" /head /r/n"); 

72 out.write(" /r/n"); 

73 out.write(" body /r/n"); 

74 out.write(" "); 

76 out.print("Hello Jsp"); 

78 out.write("/r/n"); 

79 out.write(" /body /r/n"); 

80 out.write(" /html /r/n"); 

81 } catch (Throwable t) { 

82 if (!(t instanceof SkipPageException)){ 

83 out = _jspx_out; 

84 if (out != null out.getBufferSize() != 0) 

85 try { out.clearBuffer(); } catch (java.io.IOException e) {} 

86 if (_jspx_page_context != null) _jspx_page_context.handlePageException(t); 

87 } 

88 } finally { 

89 _jspxFactory.releasePageContext(_jspx_page_context); 

90 } 

91 } 

92 }

我们可以看到,index_jsp这个类是继承 org.apache.jasper.runtime.HttpJspBase这个类的,通过查看Tomcat服务器的源代码,可以知道在apache-tomcat-6.0.20-src/java/org/apache/jasper/runtime目录下存HttpJspBase这个类的源代码文件,如下图所示:

javaweb学习总结(十四)——JSP原理详解编程语言

我们可以看看HttpJsBase这个类的源代码,如下所示:

 1 /* 

 2 * Licensed to the Apache Software Foundation (ASF) under one or more 

 3 * contributor license agreements. See the NOTICE file distributed with 

 4 * this work for additional information regarding copyright ownership. 

 5 * The ASF licenses this file to You under the Apache License, Version 2.0 

 6 * (the "License"); you may not use this file except in compliance with 

 7 * the License. You may obtain a copy of the License at 

 8 * 

 9 * http://www.apache.org/licenses/LICENSE-2.0 

10 * 

11 * Unless required by applicable law or agreed to in writing, software 

12 * distributed under the License is distributed on an "AS IS" BASIS, 

13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

14 * See the License for the specific language governing permissions and 

15 * limitations under the License. 

16 */ 

18 package org.apache.jasper.runtime; 

20 import java.io.IOException; 

22 import javax.servlet.ServletConfig; 

23 import javax.servlet.ServletException; 

24 import javax.servlet.http.HttpServlet; 

25 import javax.servlet.http.HttpServletRequest; 

26 import javax.servlet.http.HttpServletResponse; 

27 import javax.servlet.jsp.HttpJspPage; 

28 import javax.servlet.jsp.JspFactory; 

30 import org.apache.jasper.compiler.Localizer; 

32 /** 

33 * This is the super class of all JSP-generated servlets. 

34 * 

35 * @author Anil K. Vijendran 

36 */ 

37 public abstract class HttpJspBase 

38 extends HttpServlet 

39 implements HttpJspPage 

42 { 

44 protected HttpJspBase() { 

45 } 

47 public final void init(ServletConfig config) 

48 throws ServletException 

49 { 

50 super.init(config); 

51 jspInit(); 

52 _jspInit(); 

53 } 

55 public String getServletInfo() { 

56 return Localizer.getMessage("jsp.engine.info"); 

57 } 

59 public final void destroy() { 

60 jspDestroy(); 

61 _jspDestroy(); 

62 } 

64 /** 

65 * Entry point into service. 

66 */ 

67 public final void service(HttpServletRequest request, HttpServletResponse response) 

68 throws ServletException, IOException 

69 { 

70 _jspService(request, response); 

71 } 

73 public void jspInit() { 

74 } 

76 public void _jspInit() { 

77 } 

79 public void jspDestroy() { 

80 } 

82 protected void _jspDestroy() { 

83 } 

85 public abstract void _jspService(HttpServletRequest request, 

86 HttpServletResponse response) 

87 throws ServletException, IOException; 

88 }

HttpJspBase类是继承HttpServlet的,所以HttpJspBase类是一个Servlet,而index_jsp又是继承HttpJspBase类的,所以index_jsp类也是一个Servlet,所以当浏览器访问服务器上的index.jsp页面时,其实就是在访问index_jsp这个Servlet,index_jsp这个Servlet使用_jspService这个方法处理请求。

2.2、Jsp页面中的html排版标签是如何被发送到客户端的?

浏览器接收到的这些数据

 1 !DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 

 2 html 

 3 head 

 4 base href="http://localhost:8080/JavaWeb_Jsp_Study_20140603/" 

 6 title First Jsp /title 

 8 /head 

10 body 

11 Hello Jsp 

12 /body 

13 /html 

都是在_jspService方法中使用如下的代码输出给浏览器的:

 1 out.write(/r); 

 2 out.write(/n); 

 4 String path = request.getContextPath(); 

 5 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 

 7 out.write("/r/n"); 

 8 out.write("/r/n"); 

 9 out.write(" !DOCTYPE HTML PUBLIC /"-//W3C//DTD HTML 4.01 Transitional//EN/" /r/n"); 

10 out.write(" html /r/n"); 

11 out.write(" head /r/n"); 

12 out.write(" base href=/""); 

13 out.print(basePath); 

14 out.write("/" /r/n"); 

15 out.write(" /r/n"); 

16 out.write(" title First Jsp /title /r/n"); 

17 out.write("/t/r/n"); 

18 out.write(" /head /r/n"); 

19 out.write(" /r/n"); 

20 out.write(" body /r/n"); 

21 out.write(" "); 

23 out.print("Hello Jsp"); 

25 out.write("/r/n"); 

26 out.write(" /body /r/n"); 

27 out.write(" /html /r/n");

在jsp中编写的java代码和html代码都会被翻译到_jspService方法中去,在jsp中编写的java代码会原封不动地翻译成java代码,如 %out.print( Hello Jsp );% 直接翻译成out.print( Hello Jsp );,而HTML代码则会翻译成使用out.write( html标签 /r/n );的形式输出到浏览器。在jsp页面中编写的html排版标签都是以out.write( html标签 /r/n );的形式输出到浏览器,浏览器拿到html代码后才能够解析执行html代码。

2.3、Jsp页面中的java代码服务器是如何执行的?

在jsp中编写的java代码会被翻译到_jspService方法中去,当执行_jspService方法处理请求时,就会执行在jsp编写的java代码了,所以Jsp页面中的java代码服务器是通过调用_jspService方法处理请求时执行的。

2.4、Web服务器在调用jsp时,会给jsp提供一些什么java对象?

查看_jspService方法可以看到,Web服务器在调用jsp时,会给Jsp提供如下的8个java对象

1 PageContext pageContext; 

2 HttpSession session; 

3 ServletContext application; 

4 ServletConfig config; 

5 JspWriter out; 

6 Object page = this; 

7 HttpServletRequest request, 

8 HttpServletResponse response

其中page对象,request和response已经完成了实例化,而其它5个没有实例化的对象通过下面的方式实例化

1 pageContext = _jspxFactory.getPageContext(this, request, response,null, true, 8192, true); 

2 application = pageContext.getServletContext(); 

3 config = pageContext.getServletConfig(); 

4 session = pageContext.getSession(); 

5 out = pageContext.getOut();

 这8个java对象在Jsp页面中是可以直接使用的,如下所示:

 1 % 

 2 session.setAttribute("name", "session对象");//使用session对象,设置session对象的属性 

 3 out.print(session.getAttribute("name")+" br/ ");//获取session对象的属性 

 4 pageContext.setAttribute("name", "pageContext对象");//使用pageContext对象,设置pageContext对象的属性 

 5 out.print(pageContext.getAttribute("name")+" br/ ");//获取pageContext对象的属性 

 6 application.setAttribute("name", "application对象");//使用application对象,设置application对象的属性 

 7 out.print(application.getAttribute("name")+" br/ ");//获取application对象的属性 

 8 out.print("Hello Jsp"+" br/ ");//使用out对象 

 9 out.print("服务器调用index.jsp页面时翻译成的类的名字是:"+page.getClass()+" br/ ");//使用page对象 

10 out.print("处理请求的Servlet的名字是:"+config.getServletName()+" br/ ");//使用config对象 

11 out.print(response.getContentType()+" br/ ");//使用response对象 

12 out.print(request.getContextPath()+" br/ ");//使用request对象 

13 % 

运行结果如下:

javaweb学习总结(十四)——JSP原理详解编程语言

2.5、Jsp最佳实践

Jsp最佳实践就是jsp技术在开发中该怎么去用。

不管是JSP还是Servlet,虽然都可以用于开发动态web资源。但由于这2门技术各自的特点,在长期的软件实践中,人们逐渐把servlet作为web应用中的控制器组件来使用,而把JSP技术作为数据显示模板来使用。其原因为,程序的数据通常要美化后再输出:让jsp既用java代码产生动态数据,又做美化会导致页面难以维护。让servlet既产生数据,又在里面嵌套html代码美化数据,同样也会导致程序可读性差,难以维护。因此最好的办法就是根据这两门技术的特点,让它们各自负责各的,servlet只负责响应请求产生数据,并把数据通过转发技术带给jsp,数据的显示jsp来做。

2.6、Tomcat服务器的执行流程

javaweb学习总结(十四)——JSP原理详解编程语言

第一次执行:

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

第二次执行:

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

修改后执行:

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

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/11393.html

cgojavamacphpxml