今天动车票都买好了,感觉离厦工越来越近了捏????,亚达哟????????????????????
1、jsp的全换是java server pages,Java 的服务器页面
2、jsp的主要作用是代替Servlet程序回传html 页面的数据
3、因为Servlet程序回传html页面数据是一件非常繁锁的事情。开发成本和维护成本都极高
下图为同样是写html,内容为hello 。
servlet写hello
jsp写hello
jsp页面和html页面-样,都是存放在web目录下。访问也跟访问html页面一样。
比如在web目录下有如下的文件:
web目录
a.html页面 访问地址是=====>>>>>> http://ip:port/工程 路径/a.html
b.jsp页面 访问地址是=====>>>>>>> http://ip:port/工程路径/b.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程序
<%@ 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默认继承谁 |
<%@ page contentType="text/html;charset=UTF-8" language="C++" %>
表示jsp翻译后是什么语言文件,暂时只支持java
这里我们改成C++试试看????
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
表示jsp返回的数据类型是什么。也是源码response.setContentType()参数值
<%@ page pageEncoding="GBK" %>
表示当前jsp页面文件本身的字符集
一般字符集都统一下,让我们改回UTF-8
<%@ page import="java.util.*" %> <%-- 导包 --%> <%@ page import="java.util.Map" %> <%-- 导类 --%>
和java代码一样,用于导包,导类????
<%@ 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>
我们可以看到缓冲区溢出了
<%@ 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
<%@ page isErrorPage="false" %>
设置当前jsp页面,是否时错误页面。默认是false,如果是true可以获取异常信息
<%@ page contentType="text/html;charset=UTF-8" isErrorPage="true" language="java" %>
isErrorPage设置完true后,源代码才会出现这行
<%@ page session ="true" %>
设置访问当前jsp页面,是否会创建HttpSession对象。默认是true
如果设置为false,下图将不会出现这行代码
<%@ page extends ="类的详细路径" %>
设置jsp翻译出来的java默认继承谁,这里我们改成继承HttpServlet
<%@ page contentType="text/html;charset=UTF-8" extends="javax.servlet.http.HttpServlet" language="java" %>
效果理想(确信,一般别乱改
脚本写在HTML标签外还是里都是可以用滴
格式 : <%! 声明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>
之前
之后
格式 : <%= 表达式 %>
作用 : 在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、表达式脚本中的表达式不能以分号结束。
不然会这样????????????,翻译成源码
格式 : <% 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)]
<!-- 这是html注释 -->
html注释会被翻译到java源代码中。在_ jspService 方法里,以out.writer输出到客户端。
<% // 这是java单行注释 /* * 这是java多行注释 * */ %>
java注释会被翻译到java源代码中
<%-- <!-- 这是html注释 --> <% // 这是java单行注释 /* * 这是java多行注释 * */ %> --%>
jsp注释可以注掉,jsp页面中所有代码。,所以自然java源码里是没有出现的,因此浏览器也不会出现
jsp中的内置对象,是指Tomcat在翻译jsp页面成为Servlet源代码后,内部提供的九大对象,叫内置对象。
对象 | 解释 |
---|---|
request | 请求对象 |
response | 响应对象 |
pageContext | jsp的上下文对象 |
session | 会话对象 |
application | ServletContext对象 |
config | ServletConfig对象 |
out | jsp输出流对象 |
page | 指向当前jsp的对象 |
exception | 异常对象(需要isErrorPage=“true”) |
域对象 | 有效期 |
---|---|
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域的值也消失
我们一般用,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()方法输出)
格式
<%@ 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.页面的代码拷贝到包含的位置执行输出
格式
<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")%>
从scope1.jsp 跳转到scope2.jsp
<jsp:forward page="/scope2.jsp"></jsp:forward>
这代码写的可读性极差
<%@ 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>
效果图
1、Listener 监听器它是JavaWeb的三三大组件之一。 JavaWeb 的三大组件分别是: Servlet 程序、Filter 过滤器、Listener 监听器
2、Listener 它是JavaEE的规范,就是接口
3、监听器的作用是,监听某种事物的变化。然后通过回调函数,反馈给客户(程序)去做一些相应的处理
ServletContextListener它可以监听ServletContext对象的创建和销毁。
ServletContext对象在web工程启动的时候创建,在web工程停止的时候销毁。
监听到创建和销毁之后都会分别调用ServletContextListener监听器的方法反馈。
contextInitialized
在ServletContext对象创建之后马上调用,初始化
default void contextInitialized(ServletContextEvent sce) { }
contextDestroyed
在ServletContext对象销毁后调用
default void contextDestroyed(ServletContextEvent sce) { }
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