今天动车票都买好了,感觉离厦工越来越近了捏🤗,亚达哟😭😭😭😭😭
1、jsp初入
1.1、什么是jsp
1、jsp的全换是java server pages,Java 的服务器页面
2、jsp的主要作用是代替Servlet程序回传html 页面的数据
3、因为Servlet程序回传html页面数据是一件非常繁锁的事情。开发成本和维护成本都极高
下图为同样是写html,内容为hello 。
servlet写hello
jsp写hello
1.2、jsp 如何访问
jsp页面和html页面-样,都是存放在web目录下。访问也跟访问html页面一样。
比如在web目录下有如下的文件:
web目录
a.html页面 访问地址是=====>>>>>> http://ip:port/工程 路径/a.html
b.jsp页面 访问地址是=====>>>>>>> http://ip:port/工程路径/b.jsp
1.3、jsp本质是什么
本质上是servlet
当我们第一次访问jsp页面的时候。Tomcat 服务器会帮我们把jsp页面翻译成为一个java源文件。并且对它进行编译成为.class字节码程序。
证明
我们根据CATALINA_BASE 找到 work\Catalina\localhost 下会发现,第一次启动tomcat会自动生成,我们的工程_jsp
我们一直点到jsp里面去,当我们第一次通过浏览器访问b.jsp,这里会自动生成,.java和.class文件
🔍我们打开java源文件✋不难发现其里面的内容是:
然后会发现🤓
org.apache.jasper.runtime.HttpJspBase这个类继承了HttpServlet这个类
也就是说,jsp翻译出来的java类,它间接继承了HttpServlet类。那么,也就是说,翻译出来的就是一个Servlet程序
2、jsp的三种语法
2.1、page指令
<%@ page 属性 %>
属性 | 作用 |
---|---|
language | 表示jsp翻译后是什么语言文件,暂时只支持java |
contentType | 表示jsp返回的数据类型是什么。也是源码response.setContentType()参数值 |
pageEncoding | 表示当前jsp页面文件本身的字符集 |
import | 和java代码一样,用于导包,导类🤤 |
autoFlush | 设置当前out输出流缓冲区满了之后,是否自动刷新缓冲区,默认是true |
buffer | 设置out缓冲区的大小。默认是8kb |
errorPage | 设置当前jsp页面运行时出错,自动跳转去的错误页面路径 |
isErrorPage | 设置当前jsp页面,是否时错误页面。默认是false,如果是true可以获取异常信息 |
session | 设置访问当前jsp页面,是否会创建HttpSession对象。默认是true |
extends | 设置jsp翻译出来的java默认继承谁 |
2.1.1、language
<%@ page contentType="text/html;charset=UTF-8" language="C++" %>
表示jsp翻译后是什么语言文件,暂时只支持java
这里我们改成C++试试看😁
2.1.2、contentType
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
表示jsp返回的数据类型是什么。也是源码response.setContentType()参数值
2.1.3、pageEncoding
<%@ page pageEncoding="GBK" %>
表示当前jsp页面文件本身的字符集
一般字符集都统一下,让我们改回UTF-8
2.1.4、import
<%@ page import="java.util.*" %> <%-- 导包 --%>
<%@ page import="java.util.Map" %> <%-- 导类 --%>
和java代码一样,用于导包,导类🤤
2.1.5、autoFlush 和 buffer
<%@ page
autoFlush="true"
buffer="8kb" %>
都是给out输出流使用
autoFlush : 设置当前out输出流缓冲区满了之后,是否自动刷新缓冲区,默认是true
buffer : 设置out缓冲区的大小。默认是8kb(这个8kb是经过许多实验得出的适合值)
我们这里把,自动刷新缓存关闭,缓冲区数值改小一点,再让jsp里面内容多1点,看看效果
<%@ page contentType="text/html;charset=UTF-8"
autoFlush="false"
buffer="1kb"
language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
b.jsp页面
<div>flzj</div> <%-- 我们让这div 数量来个100个 --%>
</body>
</html>
我们可以看到缓冲区溢出了
2.1.6、errorPage
<%@ page errorPage="路径" %>
设置当前jsp页面运行时出错,自动跳转去的错误页面路径
我们在b.jsp这里故意写个12 / 0 的错误嗷😁
<%@ page contentType="text/html;charset=UTF-8"
errorPage="/errro500.jsp"
language="java" %>
<!--
errorPage表示错误后自动跳转去的路径
这个路径一般都是以斜杠打头,不以/打头也行,它表示请求地址 为
http://ip:port/工程路径/
映射到代码的webapp目录
-->
<html>
<head>
<title>Title</title>
</head>
<body>
b.jsp页面
<%
int a = 12 / 0;
%>
</body>
</html>
然后我们再写errro500.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>错误!</title>
</head>
<body>
你访问的b.jsp 出现程序错误!!! 我们正在大力维护...
</body>
</html>
此时,当我们访问b.jsp会跳转到errro500.jsp
2.1.7、isErrorPage
<%@ page isErrorPage="false" %>
设置当前jsp页面,是否时错误页面。默认是false,如果是true可以获取异常信息
<%@ page contentType="text/html;charset=UTF-8"
isErrorPage="true"
language="java" %>
isErrorPage设置完true后,源代码才会出现这行
2.1.8、session
<%@ page session ="true" %>
设置访问当前jsp页面,是否会创建HttpSession对象。默认是true
如果设置为false,下图将不会出现这行代码
2.1.9、extends
<%@ page extends ="类的详细路径" %>
设置jsp翻译出来的java默认继承谁,这里我们改成继承HttpServlet
<%@ page contentType="text/html;charset=UTF-8"
extends="javax.servlet.http.HttpServlet"
language="java" %>
效果理想(确信,一般别乱改
2.2、jsp中常用的脚本
脚本写在HTML标签外还是里都是可以用滴
2.2.1、声明脚本
格式 : <%! 声明java代码 %>
作用 :可以给jsp翻译出来的java类定义属性和方法甚至是静态代码块。内部类等。
声明类属性
<%!
private Integer age;
private String name;
private static Map<String,Object> map;
%>
声明static静态代码块
<%!
static{
map = new HashMap<String,Object>();
map.put("k1","v1");
map.put("k2","v2");
map.put("k3","v3");
}
%>
声明类方法
<%!
public void helloTest(){
System.out.println("HELLO!");
}
%>
声明内部类
<%!
private static class a{
private int age = 10;
String name = "flzjsTest";
}
%>
写好这些后,我们运行tomcat,进入到b.jsp,这时候我们看看b.java 会有什么变化
<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %>
<%@ page contentType="text/html;charset=UTF-8"
language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%!
// 声明类属性
private Integer age;
private String name;
private static Map<String,Object> map;
//声明static静态代码块
static{
map = new HashMap<String,Object>();
map.put("k1","v1");
map.put("k2","v2");
map.put("k3","v3");
}
//声明类方法
public void helloTest(){
System.out.println("HELLO!");
}
//声明内部类
private static class a{
private int age = 10;
String name = "flzjsTest";
}
%>
</body>
</html>
之前
之后
2.2.2、表达式脚本
格式 : <%= 表达式 %>
作用 : 在jsp页面上输出数据
我们赶快写一点,准备开溜咯
<%--
1.输出整型
2.输出浮点型
3.输出字符串
4.输出对象
--%>
<%= 12 %> <br/>
<%= 12.12%> <br/>
<%= "hahaha"%> <br/>
<%= map%> <br/>
<%= request.getParameter("username")%>
表达式脚本的特点
1、所有的表达式脚本都会被翻译到jspService() 方法中
2、表达式脚本都会被翻译成为out.print( )输出到页面上
3、由于表达式脚本翻译的内容都在_ jspService() 方法中所以_jspService()方法中的对象都可以直接使用。
比如下图的,request、response、pageContext、session…都可用
这里我们使用了里面的request对象
<%= request.getParameter("username")%>
4、表达式脚本中的表达式不能以分号结束。
不然会这样😱😱😱,翻译成源码
2.2.3、代码脚本
格式 : <% java代码 %>
作用 : 可以在jsp中编写我们自己需要的功能
<%--
1、if语句
2、for循环语句
3、翻译后java文件中_jspService方法内的代码都可以写
--%>
<%
int a = 10;
if(a == 10) System.out.println("a等于10");
else System.out.println("a不等于10");
%>
<%
for(int i = 0 ; i < 10 ; i++)
System.out.println(i);
%>
<%
System.out.println(request.getParameter("username"));
%>
特点
1、代码脚本翻译之后都在_jspService()方法中
2、代码脚本由于翻译到_ jspService()方法中 ,所以在_jspService()方法中的现有对象都可以直接使用
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VWzQu3y2-1644745690037)(D:\java\javaweb\picture\jsp\代码脚本也在_jspService方法中.png)]
3、还可以由多个代码脚本块组合完成一个完成的java语句
你甚至可以这样写一个for循环
<%
for(int i = 0 ; i < 10 ; i++){
%>
<%
System.out.println(i);
}
%>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iI9yFhXu-1644745690037)(D:\java\javaweb\picture\jsp\代码脚本特点3.png)]
4、代码脚本还可以和表达式脚本一起组合使用。在jsp页面.上输出数据
你可以这样输出0~9
<%
for(int i = 0 ; i < 10 ; i++){
%>
<%= i %> <br/>
<%
}
%>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3DjTnodQ-1644745690037)(D:\java\javaweb\picture\jsp\代码脚本特点4.png)]
2.3、jsp的三种注释
2.3.1、html注释
<!-- 这是html注释 -->
html注释会被翻译到java源代码中。在_ jspService 方法里,以out.writer输出到客户端。
2.3.2、java注释
<%
// 这是java单行注释
/*
* 这是java多行注释
* */
%>
java注释会被翻译到java源代码中
2.3.3、jsp注释
<%--
<!-- 这是html注释 -->
<%
// 这是java单行注释
/*
* 这是java多行注释
* */
%>
--%>
jsp注释可以注掉,jsp页面中所有代码。,所以自然java源码里是没有出现的,因此浏览器也不会出现
3、jsp九大内置对象
jsp中的内置对象,是指Tomcat在翻译jsp页面成为Servlet源代码后,内部提供的九大对象,叫内置对象。
对象 | 解释 |
---|---|
request | 请求对象 |
response | 响应对象 |
pageContext | jsp的上下文对象 |
session | 会话对象 |
application | ServletContext对象 |
config | ServletConfig对象 |
out | jsp输出流对象 |
page | 指向当前jsp的对象 |
exception | 异常对象(需要isErrorPage=“true”) |
4、jsp四个域对象
域对象 | 有效期 |
---|---|
pageContext(PageContextmpl类) | 当前jsp页面范围内有效 |
request(HttpServletRequest类) | 一次请求内有效 |
session(HttpSession类) | 一个会话范围内有效(打开浏览器访问服务器,直到关闭浏览器) |
application(ServletContext类) | 整个web工程范围内都有效(只要web工程不停止,数据都在) |
域对象是可以像Map一样存取数据的对象。四个域对象功能一样。不同的是它们对数据的存取范围。
虽然四个域对象都可以存取数据。在使用上它们是有优先顺序的。四个域在使用的时候,优先顺序分别是,他们从小到大的范围的顺序:
pageContext ===>>> request ====>>>session ====>>> application
效果演示
我们首先先一个scope1.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>这里是scope1页面</title>
</head>
<body>
<h1>这里是scope1页面</h1>
<%
pageContext.setAttribute("key","pageContext");
request.setAttribute("key","request");
session.setAttribute("key","session");
application.setAttribute("key","application");
%>
pageContext 的值是: <%= pageContext.getAttribute("key")%> <br/>
request 的值是: <%= request.getAttribute("key")%> <br/>
session 的值是: <%= session.getAttribute("key")%> <br/>
application 的值是: <%= application.getAttribute("key")%> <br/>
</body>
</html>
这里,👴突然发现👴的 pageContext.setAttribute()用不了,需要,我们自己去导入jsp.jar。。
现在,我们需要在上面的代码后面加上跳转到scope2.jsp 和 写下scope2.jsp就开始测试把
<%
//跳转到scope2.jsp
request.getRequestDispatcher("/scope2.jsp").forward(request,response);
%>
<html>
<head>
<title>这是是scope2.jsp</title>
</head>
<body>
<h1>这里是从scope1跳转来的scope2</h1>
pageContext 的值是: <%= pageContext.getAttribute("key")%> <br/>
request 的值是: <%= request.getAttribute("key")%> <br/>
session 的值是: <%= session.getAttribute("key")%> <br/>
application 的值是: <%= application.getAttribute("key")%> <br/>
</body>
</html>
这时候,我们访问scope1.jsp就会发现,pageContex域的值已经消失了
现在,我们直接访问scope2.jsp,request 域的值也消失了
现在我们重新打开浏览器,访问scope2.jsp ,我们会发现session域的值也消失
然后,我们重启服务器,或者重新部署服务器,再去访问scope2.jsp,会发现application域的值也消失
5、jsp输出
我们一般用,out输出和response.getWriter输出
这里,大家一定疑惑为什么out先写,居然后输出
原来是out.flush()操作,会把out缓冲区的数据写入response缓冲区的末尾,如下图所示
这时候,肯定会有人不信嗷,那我们就在out.flush()方法试试看
结论
1、用out.write()来输出
(因为翻译后的源码也是用out来输出,用response.getWriter输出可能会乱序)
2、out.write() 只能用来输出字符串或者字符。可以试试writ.print()。
(out.write()会把传入的参数强转为char[]。源码中out.print()方法会把内容转为字符串再调用out.write()方法输出)
6、jsp的常用标签
6.1、静态包含
格式
<%@ include file = "/" %>
file属性 指定你要包含的jsp路径
路径中第一个斜杆,表示http://ip:port/工程路径/
图解
静态包含就是,可以灵活更新一块内容,比如下图,你可以灵活更新页脚
代码实现
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>这是一个网页</title>
</head>
<body>
头部信息<br/>
主题信息<br/>
<%@ include file="/include/foot.jsp"%>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>这里是底部信息</title>
</head>
<body>
底部信息<br/>
</body>
</html>
特点
1.静态包含不会翻译被包含的jsp.页面
2.静态包含其实是把被包含的jsp.页面的代码拷贝到包含的位置执行输出
6.2、动态包含
格式
<jsp:include page="/"></jsp:include>
page属性 是指定你要包含的jsp页面路径
动态包含也可以像静态包含一样,把包含的内容执行输出到包含位置
代码实现
和上面的静态包含差不多 😁😁😁
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>这是一个网页</title>
</head>
<body>
头部信息<br/>
主体信息<br/>
<jsp:include page="/include/footer.jsp"></jsp:include>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>这里是底部信息</title>
</head>
<body>
底部信息<br/>
</body>
</html>
图解
特点
1,动态包合会把包含的jsp页面也翻译成为java代码
2.动态包含底层代码使用如下代码去调用被包含的jsp页面执行输出。JspRuntimeLibrary.include(request, response, “/include/footer.jsp”, out, false);
3,动态包含,还可以传递参数
在main里这样写
<jsp:include page="/include/footer.jsp">
<jsp:param name="username" value="abc"/>
<jsp:param name="password" value="123456"/>
</jsp:include>
footer这样写,来接收
<%= request.getParameter("username")%>
<%= request.getParameter("password")%>
6.3、请求转发
从scope1.jsp 跳转到scope2.jsp
<jsp:forward page="/scope2.jsp"></jsp:forward>
jsp练习
九九乘法表
这代码写的可读性极差
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>九九乘法表</title>
<style type="text/css">
table{
width: 650px;
}
</style>
</head>
<h1>九九乘法表</h1>
<table align="center">
<%for(int i = 1 ; i <= 9 ; i++){%>
<tr>
<%for(int j = 1 ; j <= i ; j++){ %>
<td> <%= j + "x" + i + "=" + (j * i) %> </td>
<% } %>
</tr>
<% } %>
</table>
<body>
</body>
</html>
把学生信息输入到表格
学生类
public class Student {
private Integer id;
private String name;
private Integer age;
private String phone;
}
//construct、get and set 省略
jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>把学生信息输入到表格</title>
<style>
table{
border: 1px black solid;
width: 600px;
}
td,th{
border: 1px blue solid;
}
</style>
</head>
<body>
<%
List<Student> studentList = new ArrayList<Student>();
for(int i = 1 ; i <= 10 ; i++){
studentList.add(new Student(i,"student" + i,i,"phone" + i));
}
%>
<table>
<tr>
<td>编号</td>
<td>姓名</td>
<td>年龄</td>
<td>手机</td>
</tr>
<% for(Student s : studentList){ %>
<tr>
<td><%= s.getId() %></td>
<td><%= s.getName() %></td>
<td><%= s.getAge() %></td>
<td><%= s.getPhone() %></td>
</tr>
<% } %>
</table>
</body>
</html>
请求转发实战
1、2已经学过了,这不是重点,我们需要完成3
SearchStudentServlet
public class SearchStudentServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<Student> studentList = new ArrayList<Student>();
for(int i = 1 ; i <= 10 ; i++){
studentList.add(new Student(i,"student" + i,i,"phone" + i));
}
request.setAttribute("stuList",studentList);
request.getRequestDispatcher("/test/showStudent.jsp").forward(request,response);
}
}
showStudent.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>这里展示学生信息</title>
<style>
table{
border: 1px black solid;
width: 600px;
}
td,th{
border: 1px blue solid;
}
</style>
</head>
<body>
<table>
<tr>
<td>编号</td>
<td>姓名</td>
<td>年龄</td>
<td>手机</td>
</tr>
<% List<Student> studentList = (List<Student>)request.getAttribute("stuList"); %>
<% for(Student s : studentList){ %>
<tr>
<td><%= s.getId() %></td>
<td><%= s.getName() %></td>
<td><%= s.getAge() %></td>
<td><%= s.getPhone() %></td>
</tr>
<% } %>
</table>
</body>
</html>
效果图
7、Listener监听器
7.1、监听器介绍
1、Listener 监听器它是JavaWeb的三三大组件之一。 JavaWeb 的三大组件分别是: Servlet 程序、Filter 过滤器、Listener 监听器
2、Listener 它是JavaEE的规范,就是接口
3、监听器的作用是,监听某种事物的变化。然后通过回调函数,反馈给客户(程序)去做一些相应的处理
7.2、ServletContextListener监听器
ServletContextListener它可以监听ServletContext对象的创建和销毁。
ServletContext对象在web工程启动的时候创建,在web工程停止的时候销毁。
监听到创建和销毁之后都会分别调用ServletContextListener监听器的方法反馈。
contextInitialized
在ServletContext对象创建之后马上调用,初始化
default void contextInitialized(ServletContextEvent sce) {
}
contextDestroyed
在ServletContext对象销毁后调用
default void contextDestroyed(ServletContextEvent sce) {
}
7.3、如何使用ServletContextListener监听器
1、编写一个类去实现ServletContextListener
2、实现其两个回调方法
public class MyServletContextListenerImpl implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("ServletContext对象被创建了");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("ServletContext对象被销毁了");
}
}
3、到web.xml中去配置监听器
<listener>
<listener-class>com.flzj.listener.MyServletContextListenerImpl</listener-class>
</listener>
到这里就结束🌶,加油加油(ง •_•)ง,距离寒假结束还剩13day