JSP的运行原理,基本语法,指令和隐式对象的使用,掌握JSP动作元素的使用
先说下怎样编写一个JSP文件
点开你的web项目,点开WebContent-----new-----JSP File
把编码格式都改为utf-8
在body标签里可以写内容,比如My First JSP HelloWorld
运行结果
这说明HTML中的元素可以被JSP容器所解析,实际上,JSP只是在原有的HTML文件中加入了一些具有Java特点的代码。
JSP运行原理
执行JSPservice()方法来处理客户端的请求,对于每一个请求,JSP容器都会创建一个新的线程来处理它。
如果多个客户端同时请求JSP文件,则JSP容器也会创建多个线程,使得每一个客户端请求都对应一个线程。
这种多线程的执行方式可以极大的降低对系统资源的要求,提高系统的并发量并缩短时间。
JSP的基本语法
JSP脚本元素
JSP脚本元素是指嵌套在<%和%>之中的一条或多条Java程序代码,通过JSP脚本元素可以将Java代码嵌入HTML页面中,所有可执行的Java代码,都可以通过JSP脚本来执行。
JSP脚本元素主要包含:
(1)JSP Scriptlets。JSP Scriptlets是一段代码段,当需要使用Java实现一些复杂的操作或控制时,可以使用它。
JSP Scriptlets语法格式如下:
<% java 代码(变量、方法、表达式)%>
在JSP Scriptlets中声明的变量是JSP页面的局部变量,调用JSP Scriptlets时,会为局部变量分配内存空间,调用结束后,释放局部变量占有的内存空间。
(2)JSP声明语句
JSP声明语句用于声明变量和方法,它以“<%!”开始,以“%>”结束,其语法格式如下
<%!
定义的变量或方法等
%>
在JSP声明语句中的都是成员方法、成员变量、静态方法、静态变量、静态代码块等。
在JSP声明语句中声明的方法在整个JSP页面内有效,但是在方法内定义的变量只在该方法内有效。
在一个JSP页面中可以有多个JSP声明语句,单个声明中的Java语句可以是不完整的,但是多个声明组合后的结果必须是完整的Java语句。
直接上代码,看效果
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JSP声明语句</title>
</head>
<%!
int a = 1,b=2;//定义两个变量a,b
%>
<%!
public String print(){
String str = "itcast";
return str;
}
%>
<body>
<%
out.println(a+b);//输出两个变量的和
%>
<br />
<%
out.print(print());//调用print()方法,输出其返回值
%>
</body>
</html>
执行结果如下
3.JSP表达式
JSP表达式用于将程序数据输出到客户端格式<%= expression %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP声明语句</title>
</head>
<%!
int a = 1, b = 2; //定义两个变量a,b
%>
<%!
public String print() { //定义print方法
String str = "itcast"; //方法内定义的变量str
return str;
}
%>
<body>
<%=a+b %><br />
<%=print() %>
</body>
</html>
JSP注释
<!-- 这个是HTML注释 -->
<%--这个是JSP注释 --%>
JSP指令
1.page指令
<%@ page 属性名1=“属性值1” 属性名2=“属性值2”。。。。%>
language指明解释该JSP文件时采用的语言,默认为Java
import 指定JSP页面翻译成的Servlet源文件中导入的包或类
session指明该JSP页面是否内置Session对象,如果为true,则说明内置Session对象,可以直接使用,否则没有内置Session对象,默认情况下,session属性为true.需要注意的是,JSP引擎自动导入以下四个包:
java.lang.*
javax.servlet.*
javax.servlet.jsp.*
javax.servlet.http.*
isErrorPage指定该页面是否为错误处理页面,如果为true,则该JSP内置有一个Exception对象的exception,可直接使用。默认情况下为false
errorPage,某个JSP页面的相对路径,指定一个错误页面,如果该JSP程序抛出一个未捕捉的异常,则转到errorPage指定的页面。errorPage指定页面的isErrorPage属性为true,且内置的exception对象为未捕捉的异常。
contentType 有效的文档类型,客户端浏览器根据该属性判断文档类型,
例如:HTML格式为text/html
纯文本格式为text/plain
JPG图像为image/jpeg
GIF图像为image/gif
Word文档为application/msword
pageEcCoding当前页面,指定页面编码格式
2.include指令
在开发过程中,需要在JSP页面静态包含一个或多个文件,可以通过include指令完成
<%@ include file = "被包含的文件地址"%>
举个例子感受下
date.jsp
include.jsp
结果如下
JSP隐式对象
9个
out 用于页面输出
request 得到用户请求信息
response 服务器向客户端的回应信息
config 服务器配置,可以取得初始化参数
session 用来保存用户的信息
application 所有用户的共享信息
page 指定当前页面转换后的Servlet类的实例
pageContext JSP的页面容器
exception 表示JSP页面所发生的异常,在错误页中才起作用
在JSP页面中,经常需要向客户端发送文本内容,这时可以使用out对象来实现,它相当于具有缓存功能的PrintWriter
直接上代码
<%@ 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>
<%
out.println("first line<br />");
response.getWriter().println("second line<br />");
%>
</body>
</html>
结果如下
发现了吗,second line先输出了,这说明out.print()是等到整个JSP页面结束后才将缓冲区的数据写入Servlet引擎提供的缓冲区。
而response.getWriter().println("second line<br />"),则是直接把内容写入Servlet引擎提供的缓冲区,Servlet引擎按照缓冲区中的数据存放顺序输出内容。
有时候你可能想让out直接输出,这时,你可以使用,buffer = "0kb"
直接上代码,看效果
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8" buffer="0kb"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Insert title here</title>
</head>
<body>
<%
out.println("first line<br />");
response.getWriter().println("second line<br />");
%>
</body>
</html>
结果
pageContext对象
void setAttribute(String name,Object value,int scope)用于设置pageContext对象的属性
Object getAttribute(String name,int scope)用于获取pageContext对象的属性
void removeAttribute(String name,int scope)删除指定范围内名称为name的属性
void removeAttribute(String name)删除所有范围内名称为name的属性
Object findAttribute(String name)从4个域对象中查找名称为name的属性
其中参数name指定的是属性名称,参数scope指定的是属性的作用范围。pageContent对象的作用范围有4个值
pageContent.PAGE_SCOPE:表示页面范围
pageContent.REQUEST_SCOPE:表示请求范围
pageContent.SESSION_SCOPE:表示会话范围
pageContent.APPLICATION_SCOPE:表示Web应用程序范围
直接上代码,看效果
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>pageContext</title>
</head>
<body>
<%
//获取request对象
HttpServletRequest req = (HttpServletRequest) pageContext.getRequest();
//设置page范围内属性
pageContext.setAttribute("str", "Java",pageContext.PAGE_SCOPE);
//设置request范围内属性
req.setAttribute("str", "Java Web");
//设置page范围内属性
String str1=(String) pageContext.getAttribute("str", pageContext.PAGE_SCOPE);
//获得的request范围属性
String str2=(String) pageContext.getAttribute("str", pageContext.REQUEST_SCOPE);
%>
<%="page范围:"+str1%><br />
<%="request范围:"+str2%>
</body>
</html>
结果如下
exception对象
在JSP页面中,经常要做一些异常信息的处理,exception对象是java.lang.Exception类的实例对象,它用于封装JSP中抛出的异常信息,exception对象只有在错误处理页面才可使用,即page指令中指定了属性<%@ page isErrorPage = "true" %>
直接上代码,看效果
exception.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8" errorPage="error.jsp"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Insert title here</title>
</head>
<body>
<%
int a=3;
int b=0;
%>
输出结果为:<%=(a/b) %><%--此处会产生异常 --%>
</body>
</html>
error.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8" isErrorPage="true"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>error page</title>
</head>
<body>
<!-- 显示异常信息 -->
<%=exception.getMessage() %><br />
</body>
</html>
这时报出错误500,没有达到我们预期的除0错误。
我们需要点击浏览器菜单栏中的工具,---Internet选项,---高级----将“显示友好错误HTTP错误信息”复选框中的√去掉,然后点击窗口的确认按钮,并刷新页面即可。
JSP动作元素
JSP动作元素用来控制JSP的行为,执行一些常用的JSP页面动作,通过动作元素可以实现使用多行Java代码能够实现的效果,
如包含页面文件,实现请求转发等。
在JSP页面中,为了把其他资源的输出内容插入到当前JSP页面的输出内容中,JSP技术提供了<jsp:include>动作元素,
<jsp:include page="relativeURL" flush="true|false" />
page属性用于指定被引入资源的相对路径;
flush属性用于指定是否将当前页面的输出内容刷新到客户端,默认情况下为false
直接上代码看效果
included.jsp
<%@ 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>
<%--让线程睡5s --%>
<%Thread.sleep(5000);%>
这是included.jsp<br />
</body>
</html>
dynamicInclude.jsp
<%@ 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>
这是dynamicInclude.jsp内的中文
<br />
<jsp:include page="included.jsp" flush="ture"></jsp:include>
</body>
</html>
他会先输出dynamicInclude.jsp
停5s才显示included.jsp,因为被调用的资源included.jsp在当前JSP页面输出内容后才被调用,其最后显示结果
<jsp:forward>动作元素将当前请求转发到其他Web资源(HTML页面,JSP页面,Servlet等),在执行请求转发之后的当前页面将不再执行,而是执行该元素指定的目标页面。格式:<jsp:forward page="relativeURL" />
page属性用于指定被引入资源的相对路径;
直接上代码感受下
jspforward.jsp
<%@ 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>
<jsp:forward page="welcome.jsp"></jsp:forward>
</body>
</html>
welcome.jsp
<%@ 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>
你好,欢迎进入首页,当前访问时间是:
<%
out.print(new java.util.Date());
%>
</body>
</html>
运行结果
虽然地址栏中访问的是jspforward.jsp,但是浏览器显示出了welcome.jsp。这就是请求转发。