WEB核心之JSP

JSP服务器端页面技术

1 JSP概述

1.1 什么是JSP

  JSP全名是Java Server Pages,它是建立在Servlet规范之上的动态网页开发技术。在JSP文件中, HTML代码与Java代码共同存在,其中,HTML代码用来实现网页中静态内容的显示,Java代码用来实现网页中动态内容的显示。

1.2 JSP的运行过程

  JSP的工作模式是请求/响应模式,客户端首先发出HTTP请求,JSP程序收到请求后进行处理并返回处理结果。**在一个JSP文件第一次被请求时,JSP引擎(容器)把该JSP文件转换成为一个 Servlet,而这个引擎本身也是一个Servlet。**如下图所示:

JSP的具体运行过程如下:

  ①客户端发出请求,请求访问JSP文件
  ② JSP容器先将JSP文件转换成一个Java源文件(Java Servlet源程序),在转换过程中,如果发现JSP文件中存在任何语法错误,则中断转换过程,并向服务端和客户端返回出错信息。
  ③如果转换成功,则JSP容器将生成的Java源文件编译成相应的字节码文件* class。该class文件就是一个Servlet,Servlet容器会像处理其他Servlet—样来处理它。

  以HelloWorld.jsp为例,当用户第一次访问HelloWorld.jsp页面时,该页面会先被JSP容器转换为一个名称为HelloWorld_Jsp.java的源文件,然后将源文件编译为一个名称为HelloWorld_Jsp.class字节码文件。如果项目发布在Tomcat的webapps目录中,源文件和.class文件可以在Tomcat安装目录/work/Catalina/localhost/项目名/org/apache/jsp 下找到。HelloWorld.jsp文件转换后的java源文件没有实现Servlet接口,但继承了 org.apache.jasper runtime.HttpJspBase 类。而HttpJspBase类是HttpServlet的一个子类,由此可见, HelloWorld_jsp 类就是一个 Servlet。
  结论:JSP 就是 Servlet。

  问题:我们访问服务器的jsp文件时,服务器时如何处理的呢?

  下面是Tomcat的Web.xml的全局配置文件的部分代码。我们可以看到,当我们访问服务器的后缀名为jsp或jspx文件时,会创建org.apache.jasper.servlet.JspServlet处理请求的页面,将动态页面转换为静态页面输入到客户端。

<servlet>
        <servlet-name>jsp</servlet-name>
        <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
        <init-param>
            <param-name>fork</param-name>
            <param-value>false</param-value>
        </init-param>
        <init-param>
            <param-name>xpoweredBy</param-name>
            <param-value>false</param-value>
        </init-param>
        <load-on-startup>3</load-on-startup>
    </servlet> 

<!-- The mappings for the JSP servlet -->
    <servlet-mapping>
        <servlet-name>jsp</servlet-name>
        <url-pattern>*.jsp</url-pattern>
        <url-pattern>*.jspx</url-pattern>
    </servlet-mapping>

2 JSP基本语法

2.1 JSP脚本元素

JSP脚本元素主要包含如下三种类型:JSP Scriptlets、JSP声明语句、JSP表达式

  • JSP Scriptlets
<% java代码(变虽、方法、语句等)%>

  在JSP Scriptlets中声明的变量是JSP页面的局部变量,在调用的时候会为局部变量分配内存空间,调用结束后,释放局部变量占有的内存空间。

  • JSP声明语句
<%! 定义的变里或方法等 %>

  JSP的声明语句用于声明成员变量和方法被声明的Java代码将被编译到Servlet的JspService()方法之外,即在JSP声明语句中定义的都是成员方法、成员变量、静态方法、静态变量、静态代码块等。

在一个JSP页面中可以有多个JSP声明语句,单个声明中的Java语句可以是不完整的,但是多个声明组合后的结果必须是完整的Java语句。

接下来,通过一个案例来演示JSPScriptlets和声明语句的使用。

JSP代码

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>你好JSP!!</title>
</head>
<body>
	<h1>HelloWorld!!!</h1>
	<h1>Hello JSP!!!</h1>	
	<%--此处写的代码都会放在转换后的java文件中的service()方法中 --%>
	<% 
		//在此处写方法会报错
		int a = 1;
		int b = 1;
		//调用run方法
		out.print(run());
	%>
	
	<%--此处写的代码都会放在转换后的java文件中的service()方法外,即成员位置 --%>
	<%!
		//定义成员变量和静态变量
		int a = 3;
		static int c = 3;
		//定义成员方法
		public int run(){
			return  a + c;
		}
	%>	
</body>
</html>

上面jsp代码转换后的部分Servlet代码

public final class HelloWorld_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent,
                 org.apache.jasper.runtime.JspSourceImports {


		//定义成员变量和静态变量
		int a = 3;
		static int c = 3;
		//定义成员方法
		public int run(){
			return  a + c;
		}
	
       ......省略一些代码......
  
  public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
      throws java.io.IOException, javax.servlet.ServletException {
           
 		......省略一些代码......
    
		//在此处写方法会报错
		int a = 1;
		int b = 1;
		//调用run方法
		out.print(run());
           
		......省略一些代码......    
  }
}
  • JSP表达式
<%=java变量或表达式>
	会被翻译成service方法内部out.print()

例如:

<%="休斯顿火箭的莫雷真的是猪队友" %>
	转换为
out.print("休斯顿火箭的莫雷真的是猪队友" );

2.2 JSP注释

<%-- jsp的注释格式 --%>

JSP注释、java的注释和html的注释对比:

注释名称注释格式jsp源码翻译后的Servlet源码页面显示HTML源码
html注释< !--注释内容-->可见可见可见
java注释//单行注释
/**/ 多行注释
可见可见不可见
jsp注释<%--注释内容--%>可见不可见不可见

3 JSP指令

  为了设置JSP页面中的一些信息,Sun公司提供了 JSP指令。JSP 2.0中共定义了 page、include 和taglib三种指令,每种指令都定义了各自的属性。接下来,本节将针对page和mclude指令进行详细的讲解。

3.1 page指令

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

page指令一些常用的属性

属性名称取值/范围描述
contentType有效的文档类型客户端浏览器根据该属性判断文档类型
pageEncoding当前页面指定页面的编码格式。(内部包含contentType可以只设置此属性)
buffer8kbjsp缓存大小,即out的缓存大小
errorPage某个JSP页面的相对路径指定一个错误页面,如果该JSP程序抛出一个未捕捉的异常,则转到errorPage指定的页面。errorPage指 定页面的isErrorPage属性力true,一旦内置的exception 对象为未捕捉的异常
isErrorPagetrue/false指定该页面是否为错误处理页面,如果为true,则该 JSP内置有一个Exception对象的exception,可直接使用。默认情况下,isErrorPage的值为false
import任何包名、类名指定在JSP页面翻译成的Servlet源文件中导入的包或类。import是唯一可以声明多次的page指令属性。 一个import属性可以引用多个类,中间用英文逗号隔开。
languagejava指明解释该JSP文件时采用的语言,默认是Java
sessiontrue/false指明该JSP内是否内置Session对象,如果为true,则说明内置Session对象,可以直接使用,否则没有内置Session对象。默认情况下,session属性的值为 true。

注意:表中列举了page指令的常见属性,其中,除了 import属性外,其他的属性都只能出现一次, 否则会编译失败。需要注意的是,page指令的属性名称都是区分大小写的。

3.2 include指令

静态包含

<%@ include file="被包含的文件地址" %>

3.3 taglib指令

在jsp页面中引入标签库(jstl标签库、struts2标签库)

 <%@ taglib uri="标签库地址" prefix="前缀"%>

4 JSP内置/隐式对象

4.1 内置对象概述

​ 在JSP页面中,有一些对象需要频繁使用,如果每次都獻新创建这些对象则会非常麻烦。为了 简化Web应用程序的开发,JSP2.0规范中提供了 9个隐式(内置)对象,它们是JSP默认创建的, 可以直接在JSP页面中使用。

名称类型描述
requestHttpServletRequest得到用户请求信息
responseHttpServletResponse服务器向客户的响应信息
outJspWriter用于页面输出
applicationServletContext所有用户的共享信息
configServletConfig服务器配置,可以获得初始化参数
pageObject当前页面转换后得Servlet类的实例
pageContextPageContextJSP页面容器
sessionSession保存用户的信息
exceptionThrowable表示JSP页面所发生的异常,在错误页面才起作用

4.2 out对象

  在JSP页面中,经常需要向客户端发送文本内容,这时,可以使用out对象来实现。out对象是 javax.servlet jsp.JspWriter 类的实例对象,它的作用与 ServletResponse.getWriter()方法返回的 PrintWriter对象非常相似,都是用来向客户端发送文本形式的实体内容。不同的是,out对象的类型 为JspWriter,它相当于一种带缓存功能的PrintWriter。

  使用out对象写数据到客户端的时候,会先将数据写到out缓冲区(默认8kb)。再把out缓冲区中的数据写到response缓冲区,再输出给客户端。

小案例:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	aaaa
	<%
		out.write("bbbb");
		response.getWriter().write("cccc");
	%>
	<%="dddd" %>
</body>
</html>

页面输出效果:

cccc aaaa bbbb dddd

  上面的效果表明,尽管a和b在c之前输出,但是a、b、d都是先写到out缓冲区,再写到response缓冲区的。而c是直接写在response缓冲区的。

  我们也可以在指令中将out的缓冲区设置为0kb,代表关闭out缓冲区,内容直接写到response缓冲区。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" buffer="0kb"%>

页面输出效果:

aaaa bbbb cccc dddd

4.3 pageContext对象

  在JSP页面中,使用pageContext对象可以获取JSP的其他8个隐式对象。pageContext对象是javax.servlet.jsp.PageContext类的实例对象,它代表当前JSP页面的运行环境,并提供了一系列用于 获取其他隐式对象的方法。

获取其他对象的方式都是get方法,例如:
JspWriter getOut()
ServletRequest getRequest()
    ......

  pageContext除了能获取其他8大隐式对象,还是一个域对象,可以存储数据

方法名称功能描述
void setAttribute(String name,Object value)给page域中存数据
Object getAttribute(String name)获取page域的数据
void removeAttribute(String name)删除page域的数据
void setAttribute(String name,Object value,int scope)给指定的域对象设置属性
Object getAttribute(String name,int scope)获得指定域对象的属性值
void removeAttribute(String name,int scope)移除指定域对象的属性
Object findAttribute(String name)从4个域对象中查找名称name属性

pageContext对象的作用范围有四个值:

  • PageContext.PAGE_SCOPE:表示页面范围
  • PageContext.REQUEST_SCOPE:表示请求范围
  • PageContext.SESSION_SCOPE:表示会话范围
  • PageContext.APPLICATION_SCOPE:表示 Web 应用程序范围

注意:需要注意的是,当使用findAttribute()方法查找名称为name的属性时,会按照pageContext、request、 session和application的顺序依次进行査找,如果找到,则返回属性的名称,否则返回null。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<% 
		pageContext.setAttribute("name", "wangba", PageContext.PAGE_SCOPE); 
		pageContext.setAttribute("name", "zhangsan", PageContext.REQUEST_SCOPE); 
		pageContext.setAttribute("name", "lisi", PageContext.SESSION_SCOPE); 
		pageContext.setAttribute("name", "zhaoliu", PageContext.APPLICATION_SCOPE); 
	%>
	
	<%
		String name1 = (String)pageContext.getAttribute("name", PageContext.PAGE_SCOPE);
		String name2 = (String)pageContext.getAttribute("name", PageContext.REQUEST_SCOPE);
		String name3 = (String)pageContext.getAttribute("name", PageContext.SESSION_SCOPE);
		String name4 = (String)pageContext.getAttribute("name", PageContext.APPLICATION_SCOPE);
	%>
	
	<%=name1 %>		<%--wangba--%>
	<%=name2 %>		<%--zhangsan--%>
	<%=name3 %>		<%--lisi--%>
	<%=name4 %>		<%--zhaoliu--%>

</body>
</html>

4.4 JSP的四个域的范围

PageContext 常量名描述作用域名称域对象类型
PAGE_SCOPE当前页面中有效pageContextPageContext
REQUEST_SCOPE一次请求范围requestHttpServletRequest
SESSION_SCOPE一次会话范围sessionHttpSession
APPLICATION_SCOPE应用范围applicationServletContext

5 JSP动作元素/标签

  JSP动作元素用来控制JSP的行为,执行一些常用的JSP页面动作。通过动作元素可以实现使用多行Java代码能够实现的效果,如包含页面文件,实现请求转发等。

5.1 页面包含

动态包含格式:

<jsp:include page="要包含的文件的路径" />

5.2 请求转发

<jsp:forword page="要转发的文件的路径"/>

5.3 动态包含和静态包含的区别

  • 动态包含要引入的资源和当前JSP页面是两个彼此独立的执行实体。而静态包含只能引入遵循JSP格式的文件,被引入文件与当前JSP文件需要共同合并才能被翻译成一个Servlet文件。
  • 动态包含中引入的资源是在运行时才包含的,而且只包含运行结果。而静态包含引入的资源是在编译时期包含的,包含的是源代码。
  • 动态包含产生两个独立的Servlet。静态包含产生一个Servlet。
  • 静态包含在两个文件中不能有相同的变量,而动态包含允许,因为静态包含相当于将包含文件内容直接赋值到主体文件中,如果出现相同的变量,就会出现覆盖等问题,导致文件出错。而动态包含相当于调用不同的jsp,变量所在的空间不同。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值