Servlet之JSP_02初探

一、被编译后的JSP

1、写一个JSP文件:index.jsp
<html>
<head>
<title>Hello World</title>
</head>
<body>
	<h1>Hello World!</h1>
	<%
		out.println("Your IP address is " + request.getRemoteAddr());

		java.io.File f = new java.io.File(this.getClass()
				.getProtectionDomain().getCodeSource().getLocation()
				.getPath());
	%>

	<h4>Compiled Servlet file location:</h4>
	<%=f.getAbsolutePath()%>

</body>
</html>

      注意:在jsp中使用了两种嵌入代码的格式:<% %>、<%= %>


2、输出效果:
引用

Hello World!

Your IP address is 127.0.0.1

Compiled Servlet file location:
C:\Users\eclipse\eworkspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\work\Catalina\localhost\webApp



3、被编译后的文件:
根据被编译后的 servlet 的输出路径,可以找到其对应的 .class 文件存放的位置。
上面的路径只是根路径,要找到具体的文件,还需要继续展开。我们会发现在 org/apache/jsp 目录下存放着两个文件:
      index_jsp.java
      index_jsp.class

原来 web 容器把 JSP 都编译成了以 org.apache.jsp 包名开头的文件。
打开 index_jsp.java,可以看到这就是 web 容器为我们做的:
/*
 * Generated by the Jasper component of Apache Tomcat
 * Version: Apache Tomcat/7.0.68
 * Generated at: 2016-09-16 03:17:38 UTC
 * Note: The last modified time of this file was set to
 *       the last modified time of the source file after
 *       generation to assist with modification tracking.
 */
package org.apache.jsp;

import javax.servlet. * ;
import javax.servlet.http. * ;
import javax.servlet.jsp. * ;

public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase
                             implements org.apache.jasper.runtime.JspSourceDependent {

	private static final javax.servlet.jsp.JspFactory _jspxFactory = javax.servlet.jsp.JspFactory.getDefaultFactory();
	private static java.util.Map<java.lang.String, java.lang.Long> _jspx_dependants;
	private volatile javax.el.ExpressionFactory _el_expressionfactory;
	private volatile org.apache.tomcat.InstanceManager _jsp_instancemanager;

	public java.util.Map<java.lang.String, java.lang.Long> getDependants() {
		return _jspx_dependants;
	}

	public javax.el.ExpressionFactory _jsp_getExpressionFactory() {
		if (_el_expressionfactory == null) {
			synchronized(this) {
				if (_el_expressionfactory == null) {
					_el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
				}
			}
		}
		return _el_expressionfactory;
	}

	public org.apache.tomcat.InstanceManager _jsp_getInstanceManager() {
		if (_jsp_instancemanager == null) {
			synchronized(this) {
				if (_jsp_instancemanager == null) {
					_jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
				}
			}
		}
		return _jsp_instancemanager;
	}

	public void _jspInit() {}

	public void _jspDestroy() {}

	public void _jspService(final javax.servlet.http.HttpServletRequest request, 
                            final javax.servlet.http.HttpServletResponse response)
                            throws java.io.IOException,javax.servlet.ServletException {

		final javax.servlet.jsp.PageContext pageContext;
		      javax.servlet.http.HttpSession session = null;
		final javax.servlet.ServletContext application;
		final javax.servlet.ServletConfig config;
		      javax.servlet.jsp.JspWriter out = null;
		final java.lang.Object page = this;
		      javax.servlet.jsp.JspWriter _jspx_out = null;
		      javax.servlet.jsp.PageContext _jspx_page_context = null;

		try {
			response.setContentType("text/html");
			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("<html>\n");
			out.write("<head><title>Hello World</title></head>\n");
			out.write("<body>\n");
			out.write("<h1>Hello World!</h1>\n");

			out.println("Your IP address is " + request.getRemoteAddr());

			java.io.File f = new java.io.File(
		    this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath());

			out.write("\n");
			out.write("<h4>Compiled Servlet file location:</h4> \n");
			out.print(f.getAbsolutePath());
			out.write("\n");
			out.write("</body>\n");
			out.write("</html>");
		} catch (java.lang.Throwable t) {
			if (!(t instanceof javax.servlet.jsp.SkipPageException)) {
				out = _jspx_out;
				if (out != null && out.getBufferSize() != 0)
					try {
						if (response.isCommitted()) {
							out.flush();
						} else {
							out.clearBuffer();
						}
					} catch (java.io.IOException e) {}
				if (_jspx_page_context != null)
					_jspx_page_context.handlePageException(t);
				else
					throw new ServletException(t);
			}
		}
		finally {
			_jspxFactory.releasePageContext(_jspx_page_context);
		}
	}
}

      写在JSP文件中的内容,都被放在了 _jspService() 方法的 try-catch 语句块中。


二、当请求到来时,发生了什么?

当浏览器向 web 容器发送一个请求时,在web容器内部发生了什么?例如:在浏览器的地址栏中输入:http://localhost:8080/myApp/index.jsp

1、
      web 容器首先查看有没有与请求路径 "/index.jsp" 相对应的 servlet 的注册。

2、
      如果有,则调用这个servlet;
      如果无,则到部署目录下查找与该请求路径对应的jsp文件。

3、
      如果无,对应的jsp文件,则报404(没有找到资源);
      如果有,对应的jsp文件,则对其进行编译,并为其注册访问路径:"/index.jsp" ,
      javax.servlet.ServletContext.addServlet(servletName, servletClass)。
      最后调用该 servlet 的 service() 方法。

由此我们可以看出:
      JSP 是动态编译,动态加载的。而且是懒加载。




三、附

1、可以在 JSP 代码块<% %>中使用的 9 个内置对象:

通过上述对 JSP 翻译后的 .java 文件的查看: 这 9 个变量在 _jspService() 方法的前面部分已声明,因此可以在 JSP 代码块<% %>中直接使用。

注意:变量名称不可写错。

Object Description
request This is the HttpServletRequest object associated with the request.
response This is the HttpServletResponse object associated with the response to the client.
out This is the PrintWriter object used to send output to the client.
session This is the HttpSession object associated with the request.
application This is the ServletContext object associated with application context.
config This is the ServletConfig object associated with the page.
pageContext This represents the environment for the page, containing useful information like page-scope attributes, access to the request, response and session objects, as well as the JspWriter referenced by out. This object also has methods for including another URL's contents, and for forwarding or redirecting to another URL. E.G. pageContext.forward ("other.jsp"); 
page This represents the generated servlet instance itself, i.e., it is same as the "this" keyword used in a Java file. As a result, you do not typically know who the super class is, and consequently do not normally make use of this object or its methods.
Exception The Exception object allows the exception data to be accessed by designated JSP.



2、pageContext vs page in Detail


page 指的是 this 对象,就是当前的 jsp 实例。

pageContent 则提供了许多对于当前 page 操作的方法和对其它环境变量的引用。
例如:
pageContent.setAttribute(); // 给本 jsp 实例设置属性。
pageContent.getRequest(); // 获取到 request 对象。


说明:
在实际应用中往往一个页面是由多个jsp组成的,它们各自代表不同的模块。
如何保证各jsp之间变量的名称互不冲突,不会被覆盖,变量的范围就显得格外重要。
在这种情况下,选择默认的 page 范围。

pageContent.setAttribute(); 就是用来设置本 jsp 中的变量的。

参阅:<c:set> 标签的使用。
http://lixh1986.iteye.com/blog/2324611




Implicit Object: pageContex     
Class or Interface: javax.servlet.jsp.PageContext     
Purpose, Function, or Uses:
      Used for storing and retrieving page-related information and sharing objects within the same translation unit and same request.
      Also used as a convenience class that maintains a table of all the other implicit objects. For example:
public void _jspService(HttpServletRequest request,
	                    HttpServletResponse response)
                        throws java.io.IOException, ServletException{
	...
	try {

		...
		application = pageContext.getServletContext();
		config      = pageContext.getServletConfig();
		session     = pageContext.getSession();
		out         = pageContext.getOut();
		...

	} catch (Throwable t) {
		...
	}
	finally {
		...
	}
}


Implicit Object: page     
Class or Interface: java.lang.Object
Purpose, Function, or Uses:
      Refers to the generated Servlet class. Since page refers to the generated class and the class implements the Servlet interface, it is a valid cast it to Servlet. And the page variable could also be cast to JspPage or HttpJspPage since these two interfaces are derived from the Servlet interface and are implemented by the generated servlet class. For example:

<%= ((Servlet)page).getServletInfo() %>

<%= ((JspPage)page).xxx() %>

<%= ((HttpJspPage)page).xxx() %>








引用:
https://www.tutorialspoint.com/jsp/jsp_implicit_objects.htm

What is difference between page and pageContext in JSP pages?
- http://www.xyzws.com/jspfaq/what-is-difference-between-page-and-pagecontext-in-jsp-pages/4







-
转载请注明
原文出处:http://lixh1986.iteye.com/blog/2324570















-

猜你喜欢

转载自lixh1986.iteye.com/blog/2324570