概述
jsp:20年; vbs, asp, asp.net
- Java Server Pages:运行在服务器端的网页
- 简单理解:在html中嵌入java语言
本质:使用通过response对象获取打印流将页面信息打印至客户端进行网页的书写
但是由于在java书写页面必须使用打印流字符串的形式,所以很繁琐,所以开发出了可以书写java代码的页面jsp
使用servlet打印流的形式打印动态页面
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
String username = request.getParameter("username");
//通过打印流返回动态页面
PrintWriter writer = response.getWriter();
writer.print("<html>");
writer.print("<head><title>登录成功</title></head>");
writer.print("<body>欢迎用户:"+username+"登录!</body>");
writer.print("</html>");
}
}
使用jsp的形式书写动态页面
<%@ 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>Insert title here</title>
</head>
<body>
<%
获取请求,请求参数:username
String username = request.getParameter("username");
%>
<!-- out就相当去打印流对象 -->
欢迎用户:<% out.print(username); %>登录!
</body>
</html>
一.页面元素
- 静态HTML标签
- 指令:<%@ 指令%>
- 脚本(代码块)
- <%JAVA代码%> 局部代码
- <%=java表达式%>
- <%! 声明 %> 声明方法
- 注释
- HTML注释:
- JAVA注释 :<% // /**/ %>
- JSP:<%-- --%>
<!-- jsp脚本-->
<!-- jsp本质还是servlet 只不过是特殊的servlet 可以直接书写html -->
<!-- 为了将java代码与html静态标签区分 需要使用脚本包裹java代码 -->
<!-- 这样在解析jsp时 会忽略静态html标签 执行java代码 -->
<!-- java小脚本 代码块 用于包裹java代码 可以在< % 中书写任意java代码 % > -->
<%
//在这里可以使用任意的java代码
System.out.println("hello world!");
%>
<!-- java打印脚本 用于将其结果打印至页面 < %= 内容%>-->
<!-- 要书写在页面的内容 注意 虽然是java代码 但是无需书写; -->
<!-- 通常与小脚本一起使用 用于输出结果 -->
<%
int a = 1;
int b = 2;
%>
<%=a + b%>
<%="输出汉字也可以"%>等价于write.print("") 一般常用方式为为页面标签动态赋值
<br>
<input type="text" value="<%=a%>">
<!-- java声明脚本 -->
<!-- 在普通的脚本中书写的代码本质就是在对应的doget dopost中 -->
<!-- 因为java中方法中不允许声明方法 所以需要使用特殊的方法声明方法 -->
<%!//声明脚本可以声明方法 由其他脚本调用
public void aaa() {
System.out.println("aaa方法执行");
}%>
<%
aaa();
%>
<!-- jsp注释 -->
<!-- 因为jsp是java提供的书写html的服务 -->
<!-- 对于注释的使用拥有三种注释 -->
<!-- 1.html注释 -->
<!-- 书写在html中 会发送至客户端 客户端可以查看 -->
<!-- 2.java注释 -->
<% //书写在java小脚本中 与java中一样 需要书写注释符号
// 在读取jsp后 解析java代码 编译时忽略 %>
<!-- 3.jsp注释 -->
<%-- 无需添加其他特殊语法 直接书写注释内容即可
在读取jsp时会自动忽略
--%>
案例
计算两个变量的和并显示在页面
<%@ 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>Insert title here</title>
</head>
<body>
<%
//定义局部变量
int a = 2;
int b = 3;
//求和
int sum = a+b;
%>
<h2><%=sum %></h2>
</body>
</html>
定义求和方法
<%@ 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>Insert title here</title>
</head>
<body>
<%!
//成员变量
int a=10;
int b =60;
//声明方法
public int sum(int c,int d){
return c+d;
}
%>
<%=sum(4,6) %>
</body>
</html>
二.运行原理
- 客户端发送请求请求对应jsp时
- 服务器获取jsp翻译成java文件
- java文件编译生成class文件
- 运行class文件,向客户端响应内容
jsp本质就是一个servlet
注意:jsp只在第一次访问或修改的时候重新翻译和编译。
第一次请求jsp导致加载jsp响应过慢的情况称之为第一人惩罚策略
执行流程:
当客户端请求对应的jsp时,服务器首先判断的是是否编译过,如果编译过继续判断,判断是否修改,如果修改重新编译,如果没有修改 ,则直接将之前编译的servlet对象(jsp在执行时会翻译成servlet)返回并进行服务处理
三.JSP指令
page指令
作用
- 设置当前JSP页面属性,定义怎样运行JSP页面(一般不会自己特殊书写 而是通过创建自动定义)
写法
-
<%@ page 属性名="值" 属性名="值"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
在页面创建时自动生成的常用属性以及值
属性
-
import
-
导入java的包,可以出现多次,也可以写一个,包之间使用逗号隔开,一般直接在<%%>中书写对应类使用快捷键提示可以直接生成
<%@page import="java.util.Date,java.text.DateFormat,java.text.SimpleDateFormat"%>
-
-
pageEncoding
- 代表的是当前页面的编码,JSP翻译成java文件,服务器需要知道JSP文件的编码方式,一般设置为UTF-8
-
contentType
-
charset:设置响应内容的页面采用的编码
-
contentType="text/html; charset=UTF-8
-
-
isElIgnored
- 决定jsp页面是否忽略el表达式(默认为不忽略,如果页面无法使用EL表达式建议添加isELIgnored=“false”)
include指令
作用
- 将JSP页面包含在一起,引入其他的jsp页面
语法
- <%@ include file=“要包含的JSP页面”%>
原理
- 静态包含:把包含文件的代码复制到当前文件,一起翻译为java文件,一起编译。
该指令可以理解为将指定的jsp页面内容复制至当前指定位置
这个指令,经常用于重复功能的书写,将多个页面重复的功能书写在一个jsp中,其他页面通过引用的方式进行使用.
例如:网站的导航栏以及尾部信息
taglib指令
作用
- 导入其他标签库,在使用jsp之后使用<%%>书写java代码这种方式并不完善,容易混淆,所以提供通过指定标签的形式替代jsp中java代码的书写,而是变为使用指定的标签的形式完成java功能的实现
<table>
<tbody>
<%
for (int i = 1; i <= 10; i++) {
%>
<tr>
<td><%=i%></td>
<td><%=i%></td>
<td><%=i%></td>
</tr>
<%
}
%>
</tbody>
</table>
写法
- <%@ taglib uri=“标签库地址” prefix=“前缀”%>
- prefix:标签的前缀
四.九大内置对象以及四大作用域
概念
- jsp本质是servlet,在书写servlet对应方法时自己创建的对象,例如 请求对象 响应对象 会话对象 上下文对象等,由srervlet方法参数直接创建 ,我们使用时无需创建可以直接使用的对象,称之为内置对象,我们只需要使用内置对象名.方法即可,无需创建
分类
- request:一次请求
- HttpServletRequest
- session:一次会话
- HttpSession
- application:整个应用
- ServletContext
- pageContext:当前页面
- PageContext
- response:保存请求页面响应信息
- HttpServletResponse
- config:保存当前servlet对应的配置文件
- ServletConfig
- page:代码当前的jsp对应的servlet对象
- this
- out:可以直接在页面输出内容,内容会直接答应在页面中
- PrintWriter
- exception:用于存储当前页面异常信息,当页面发送异常时将异常信息存储至当前对象
- Throwable
九大内置对象分别代码对应数据的存储,其中最常用的四大作用域pageContext.request.session.application
page.jsp
<body>
page.jsp
<!-- 四大作用域 -->
<!-- 方法通用 都是为指定作用域中添加数据 获取数据 删除数据 -->
<br>pageContext作用域范围为当前页面<br>
<% pageContext.setAttribute("pageContext", "只有当前页面生效"); %>
<%=pageContext.getAttribute("pageContext") %>
<br>request作用域范围为本次请求,如果通过转发其他页面也可以访问<br>
<% request.setAttribute("request", "本次请求生效"); %>
<%=request.getAttribute("request") %>
<br>session作用域范围为当前会话,浏览器不关闭其他分页打开不同页面也可以访问<br>
<% session.setAttribute("session","本次会话生效"); %>
<%=session.getAttribute("session") %>
<br>application作用域为当前服务器,只要服务器不关闭都可以后期<br>
<% application.setAttribute("applicaton", "当前服务器生效"); %>
<%=application.getAttribute("applicaton") %>
<!-- 将请求转发 这样look.jsp与当前jsp使用相同的请求对象 -->
<% request.getRequestDispatcher("look.jsp").forward(request, response); %>
</body>
look.jsp
<body>
look.jsp
<!-- 四大作用域 -->
<!-- 方法通用 都是为指定作用域中添加数据 获取数据 删除数据 -->
<br>pageContext作用域范围为当前页面<br>
<%=pageContext.getAttribute("pageContext") %>
<br>request作用域范围为本次请求,如果通过转发其他页面也可以访问<br>
<%=request.getAttribute("request") %>
<br>session作用域范围为当前会话,浏览器不关闭其他分页打开不同页面也可以访问<br>
<%=session.getAttribute("session") %>
<br>application作用域为当前服务器,只要服务器不关闭都可以后期<br>
<%=application.getAttribute("applicaton") %>
</body>
域对象范围案例演示
-
A.jsp
<%@ 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>Insert title here</title> </head> <body> <h2>A页面</h2> <!-- 在pageContext域对象存入值--> <% pageContext.setAttribute("msg", "hello"); %> <!-- 获取pageContext域对象中的属性值 --> <%=pageContext.getAttribute("msg") %> <!-- 在request域对象中存入值 --> <%request.setAttribute("info", "world"); %> <!-- 在session域对象中存入值 --> <%session.setAttribute("test", "111"); %> <!-- 在application中存入值 --> <%application.setAttribute("music", "简单爱"); %> <a href="/JSPTest/a">跳转到Servlet</a> </body> </html>
-
MyServlet
//重定向到B.jsp(分别演示重定向和转发到B页面) resp.sendRedirect("/JSPTest/scope/B.jsp");
-
B.jsp
<%@ 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>Insert title here</title> </head> <body> <h2>B页面</h2> <!-- 获取pageContext域对象中的属性值 --> <%=pageContext.getAttribute("msg") %> <!-- 获取request域对象中的属性值 --> <%=request.getAttribute("info") %> <!-- 获取session 域对象中的属性值 --> <%=session.getAttribute("test") %> <!-- 获取application 域对象中的属性值 --> <%=application.getAttribute("music") %> </body> </html>
PageContext
概念
- 代表的是当前页面上下文对象,也是一个域对象,代表范围是当前页面
作用
-
域对象,代表范围是当前页面
-
可以获取其他八个内置对象
ServletRequest sr = pageContext.getRequest();//获取request对象 HttpSession se = pageContext.getSession();//获取session对象
-
可以向其他域对象存取值
pageContext.setAttribute("test", "11", PageContext.SESSION_SCOPE);//通过pageContext向session域对象存入值 pageContext.getAttribute("test", PageContext.SESSION_SCOPE);//通过pageContext从session域对象获取值 pageContext.findAttribute("test")//从小的范围向大的范围依次查找,直到找到为止
五.动作标签
概念
- JSP标签,但是需要放在服务器端运行,才能访问
作用
- JSP动作标签代替Java代码方式,通过标签的使用减少java代码的书写
分类
页面转发
- 写法
- <jsp:forward page=“”>:代表请求的转发;page代表的是转发的页面
<!-- 将请求转发 这样look.jsp与当前jsp使用相同的请求对象 -->
<%-- <% request.getRequestDispatcher("look.jsp").forward(request, response); %>
--%>
<!-- jsp提供了相应的标签 替换java代码的书写 -->
<jsp:forward page="look.jsp"/>
虽然该方法可以转发页面,但是实际开发过程中我们通常使用servlet转发jsp显示数据的形式进行操作,不会使用jsp转发到jsp,因为在书写代码时尽量减少jsp页面中java代码的书写,防止混淆
页面引入
- 写法
- jsp:include:代表页面的包含(动态包含,不管动态包含,静态包含,产生效果一样,但是原理不同)
<%@ include file="page.jsp"%>
<hr>
<jsp:include page="page.jsp" />
page.jsp
<%-- page.getclass获取输出的是当前页面对应的class
动作标签jsp:includ 是将当前页面解析为servelt执行后的结果引入
指令 include 是将当前页面代码复制到指定页面一起编译servlet执行
所以根据页面打印的信息就知道哪个是先运行后引入 哪个是直接复制引入执行
--%>
<%=
page.getClass()
%>
与include指令一样都可以将指定页面引入到当前页面,效果也是相同,但是原理不同
includle动作标签是动态引入
是将指定的jsp翻译成servelt执行后将结果引入到当前servlet中(会将所有涉及的servlet全部翻译执行)
include指令是静态引入
是在将jsp翻译成servlet时 将指定页面代码复制至当前页面,之后翻译成一个servlet之后编译执行(只翻译执行一个servlet)
使用场景:如果使用的jsp中没有书写java,只是静态页面内容 可以直接使用include指令引入,如果相应的jsp中需要执行代码建议使用includle标签,如果考虑到执行效率问题,也可以使用include指令