文章目录
Jsp
jsp 的全换是 java server pages。Java 的服务器页面。 jsp 的主要作用是代替 Servlet 程序回传 html 页面的数据。 因为 Servlet 程序回传 html 页面数据是一件非常繁锁的事情。开发成本和维护成本都极高。
通过Servlet实现一个HTML回传
PrintHtml.java
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
* @BelongsProject: JavaWeb
* @BelongsPackage: PrintHtml
* @Author: HeXin
* @CreateTime: 2023/1/31 22:13
* @Description:
* @Version: 1.0
*/
public class PrintHtml extends HttpServlet {
@Override
protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html; charset=UTF-8");
//通过响应的回传流回html页面数据
PrintWriter writer = resp.getWriter();
writer.write("<!DOCTYPE html>\r\n");
writer.write("<html lang=\"en\">\r\n");
writer.write("<head>\r\n");
writer.write(" <meta charset=\"UTF-8\">\r\n");
writer.write(" <title>Title</title>\r\n");
writer.write("</head>\r\n");
writer.write("<body>\r\n");
writer.write(" 这是HTML页面数据\r\n");
writer.write("</body>\r\n");
writer.write("</html>\r\n");
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>PrintHtml</servlet-name>
<servlet-class>PrintHtml</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>PrintHtml</servlet-name>
<url-pattern>/print</url-pattern>
</servlet-mapping>
</web-app>
通过jsp回传一个HTML
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
这是Html页面数据
</body>
</html>
明显可以看出,Jsp处理回传数据的方式快很多,并且代码量很少
创建jsp文件
首先准备一个已经添加好web应用程序的框架支持的模块
第一步
第二步
其访问地址与html类似,都是http://ip:port/工程路径/xxx.jsp
jsp的本质
jsp 页面本质上是一个Servlet 程序
。
当我们第一次访问 jsp 页面的时候。Tomcat 服务器会帮我们把 jsp 页面翻译成为一个 java 源文件。并且对它进行编译成为.class 字节码程序。我们打开 java 源文件不难发现其里面的内容是:
跟踪原代码发现,HttpJspBase 类。它直接地继承了 HttpServlet 类。也就是说 jsp 翻译出来的 java 类,它间接的继承了 HttpServlet 类。也就是说,翻译出来的是一个 Servlet 程序
总结:通过翻译的 java 源代码我们就可以得到结果:jsp 就是 Servlet 程序。
jsp的语法
jsp有三种语法,分别是头部page指令
、常用脚本
、注释
头部的page指令
jsp 的 page 指令可以修改 jsp 页面中一些重要的属性或者行为。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
属性名 | 含义 |
---|---|
language | 表示jsp翻译后是什么语言文件(暂时只支持java) |
contentType | 表示jsp返回的数据类型是什么 |
pageEncoding | 表示当前 jsp 页面文件本身的字符集 |
import | 跟 java 源代码中一样。用于导包,导类 |
autoFlush | 设置当 out 输出流缓冲区满了之后,是否自动刷新冲级区。默认值是 true。 |
buffer | 设置 out 缓冲区的大小。默认是 8kb |
errorPage | 设置当 jsp 页面运行时出错,自动跳转去的错误页面路径。 |
isErrorPage | 设置当前 jsp 页面是否是错误信息页面。默认是 false。如果是 true 可以获取异常信息 |
session | 设置访问当前 jsp 页面,是否会创建 HttpSession 对象。默认是 true。 |
extends | 设置 jsp 翻译出来的 java 类默认继承的父类。 |
常见错误
常用脚本
常用脚本又分为三种:声明脚本
、表达式脚本
、代码脚本
。
声明脚本(极少使用)
格式:
<%! 声明 java 代码 %>
作用:可以给 jsp 翻译出来的 java 类定义属性和方法甚至是静态代码块。内部类等。
代码演示
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<!--
Created by IntelliJ IDEA.
User: He
Date: 2023/1/31
Time: 22:36
To change this template use File | Settings | File Templates.
-->
<%@ page contentType="text/html;charset=UTF-8" language="java" autoFlush="false" buffer="1kb" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<!-- 声明类属性-->
<%!
private Integer id;
private String name;
private static List<String> list;
%>
<!--声明static静态代码块-->
<%!
static{
list = new ArrayList<String>();
list.add("Hello");
list.add("World");
}
%>
<!--声明类方法-->
<%!
public int sum(int num1,int num2) {
return num1 + num2;
}
%>
<!--声明内部类-->
<%!
public static class user{
private String username;
private String password;
}
%>
</body>
</html>
表达式脚本(常用)
格式:
<%=表达式%>
作用:在jsp页面上输出数据
代码演示
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.List" %>
<!--
Created by IntelliJ IDEA.
User: He
Date: 2023/2/1
Time: 10:16
To change this template use File | Settings | File Templates.
-->
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<!--输出整形-->
<%=506 %><br/>
<!--输出浮点型-->
<%=13.14 %><br/>
<!--输出字符串-->
<%="WLM" %><br/>
<!--输出对象-->
<%! private static List<String> list;
static{
list = new ArrayList<String>();
list.add("Hello");
list.add("World");
}
%>
<%= list %>
</body>
</html>
表达式脚本的特点:
- 所有的表达式脚本都会被翻译到_jspService() 方法中
- 表达式脚本都会被翻译成为 out.print()输出到页面上
- 由于表达式脚本翻译的内容都在_jspService() 方法中,所以_jspService()方法中的对象都可以直接使用。
表达式脚本中的表达式不能以分号结束
。
代码脚本
格式:
<% Java语句 %>
作用:可以在 jsp 页面中,编写自己需要的功能(写的是 java 语句)。
代码脚本的特点是:
- 代码脚本翻译之后都在_jspService 方法中 _
- _代码脚本由于翻译到_jspService()方法中,所以在_jspService()方法中的现有对象都可以直接使用。
- 可以由多个代码脚本块组合完成一个完整的 java 语句。
- 代码脚本还可以和表达式脚本一起组合使用,在 jsp 页面上输出数据
代码演示
<!--
Created by IntelliJ IDEA.
User: He
Date: 2023/2/1
Time: 10:33
To change this template use File | Settings | File Templates.
-->
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<!--if语句-->
<%
if(3>4){
%>
<%="You like me"%>
<%
}else{
%>
<%="I like you"%>
<%
}
%><br/>
<!--for循环-->
<%
for(int i = 0;i<=10;i++){
%>
<%=i%>
<%
}
%><br/>
<!--翻译后 java 文件中_jspService 方法内的代码-->
<%!
public static class user{
private String username;
private String password;
}
%>
<%
String username = request.getParameter("username");
%>
<%=username%>
</body>
</html>
注释
jsp注释又分为三种:html注释
、java注释
、jsp注释
。
Html注释
格式:
<!--这是html注释-->
html 注释会被翻译到 java 源代码中。在_jspService 方法里,以 out.writer 输出到客户端。
Java注释
格式:
<%
//单行Java注释
/*多行Java注释*/
%>
java 注释会被翻译到 java 源代码中。
Jsp注释
<%-- 这是 jsp 注释 --%>
jsp 注释可以注掉,jsp 页面中所有代码。
Jsp内置对象
jsp 中的内置对象,是指 Tomcat 在翻译 jsp 页面成为 Servlet 源代码后,内部提供的九大对象,叫内置对象。
对象名 | 含义 |
---|---|
request | 请求对象 |
response | 响应对象 |
pageContext | Jsp上下文对象 |
session | 会话对象 |
application | ServletContext对象 |
config | ServletConfig对象 |
out | Jsp输出流对象 |
page | 指向当前Jsp对象 |
exception | 异常对象 |
Jsp域对象
对象名 | 所属类 | 生命周期(有效范围) |
---|---|---|
pageContext | PageContextImpl类 | 当前jsp页面内有效 |
request | HttpServletRequest类 | 一次请求内有效 |
session | HttpSession类 | 一次会话范围(打开浏览器访问服务器,直到关闭浏览器)内有效 |
application | ServletContext类 | 整个web工程范围内都有效(只要web工程不停止,数据就一直在) |
域对象是可以像 Map 一样存取数据的对象。四个域对象功能一样。不同的是它们对数据的存取范围。
虽然四个域对象都可以存取数据。在使用上它们是有优先顺序的。
四个域在使用的时候,优先顺序分别是,他们从小到大的范围的顺序。
pageContext - -> request - -> session - -> application
代码实现
<%--
Created by IntelliJ IDEA.
User: He
Date: 2023/2/1
Time: 11:58
To change this template use File | Settings | File Templates.
--%>
<%@ page import="javax.servlet.jsp.PageContext"%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>e.jsp</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>
Jsp中的out输出和response.getWriter输出的区别
response 中表示响应,我们经常用于设置返回给客户端的内容(输出)
out 也是给用户做输出使用的。
由于 jsp 翻译之后,底层源代码都是使用 out 来进行输出,所以一般情况下。我们在 jsp 页面中统一使用 out 来进行输出。避
免打乱页面输出内容的顺序。
out.write() 输出字符串没有问题
out.print() 输出任意数据都没有问题(都转换成为字符串后调用的 write 输出)
Jsp常用标签
包含三个标签:Jsp静态包含
、Jsp动态包含
、Jsp标签-转发
Jsp静态包含
静态包含的特点:
1、静态包含不会翻译被包含的 jsp 页面。
2、静态包含其实是把被包含的 jsp 页面的代码拷贝到包含的位置执行输出。
代码实现
main.jsp
<%--
Created by IntelliJ IDEA.
User: He
Date: 2023/2/1
Time: 13:52
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
头部内容<br/>
主要内容<br/>
<%-- 静态包含
file属性指定要包含的jsp页面路径
地址中的第一个斜杠/ 表示 http://ip:port/工程路径/映射到代码的web目录
--%>
<%@include file="footer.jsp"%>
</body>
</html>
footer.jsp
<%--
Created by IntelliJ IDEA.
User: He
Date: 2023/2/1
Time: 13:52
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
脚页信息<br/>
</body>
</html>
Jsp动态包含
动态包含的特点:
1、动态包含会把包含的 jsp 页面也翻译成为 java 代码
2、动态包含底层代码使用如下代码去调用被包含的 jsp 页面执行输出。
JspRuntimeLibrary.include(request, response, "/include/footer.jsp", out, false);
3、动态包含,还可以传递参数
代码实现
main.jsp
<%--
Created by IntelliJ IDEA.
User: He
Date: 2023/2/1
Time: 13:52
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
头部内容<br/>
主要内容<br/>
<%-- 动态包含
page属性是指定包含jsp页面的路径
动态包含也可以像静态包含一样。把被包含的内容执行输出到包含位置
--%>
<jsp:include page="/include/footer.jsp">
<jsp:param name="username" value="WLM"/>
<jsp:param name="password" value="123456"/>
</jsp:include>
</body>
</html>
footer.jsp
<%--
Created by IntelliJ IDEA.
User: He
Date: 2023/2/1
Time: 13:52
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
脚页内容<br/>
<%=request.getParameter("username")%>
</body>
</html>
动态包含的底层原理:
Jsp标签-转发
作用:本质为请求转发标签,功能就是请求转发
<jsp:forward page=""></jsp:forward>
page属性设置请求转发路径(前面要加一个斜杠)
练习1:用Jsp在页面上输出九九乘法表
<%--
Created by IntelliJ IDEA.
User: He
Date: 2023/2/1
Time: 14:35
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>九九乘法表</title>
<style type="text/css">
table{
font-size:20px;
width: 1000px;
border-collapse: collapse;
}
</style>
</head>
<body>
<h1 align="center">九九乘法表</h1>
<table align="center">
<% for(int i=1;i<=9;i++){ %>
<tr>
<% for(int j=1;j<=i;j++){ %>
<td style="border:3px solid black"><%=j+" x "+ i +" = "+(i*j)%></td>
<% } %>
</tr>
<% } %>
</table>
</body>
</html>
练习2:用Jsp查询并显示10条学生信息
SearchStudentServlet.java
package code;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* @BelongsProject: JavaWeb
* @BelongsPackage: SearchStudentServlet
* @Author: HeXin
* @CreateTime: 2023/2/1 15:50
* @Description:
* @Version: 1.0
*/
public class SearchStudentServlet extends HttpServlet {
@Override
protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
List<Student> list = new ArrayList<Student>();
for(int i = 0;i<10;i++){
list.add(new Student(i,"name"+i,"1816739263"+i,"123456@qq.com"));
}
//保存查询到的结果到request
req.setAttribute("studentInformation",list);
//请求转发到showStudent.jsp页面
req.getRequestDispatcher("/test/showStudent.jsp").forward(req, resp);
}
}
showStudent.jsp
<%@ page import="java.util.List" %>
<%@ page import="code.Student" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="code.Student" %><%--
Created by IntelliJ IDEA.
User: He
Date: 2023/2/1
Time: 15:09
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>学生信息表</title>
<style type="text/css">
table{
border:1px solid black;
width: 1000px;
border-collapse: collapse;
}
td{
border: 1px solid black;
text-align: center;
}
</style>
</head>
<body>
<%
List<Student> list = (List<Student>) request.getAttribute("studentInformation");
%>
<table>
<tr>
<td>编号</td>
<td>姓名</td>
<td>电话</td>
<td>邮箱</td>
<td>操作</td>
<td>操作</td>
</tr>
<%for(Student student:list){%>
<tr>
<td><%=student.getId()%></td>
<td><%=student.getName()%></td>
<td><%=student.getPhone()%></td>
<td><%=student.getEmail()%></td>
<td>修改</td>
<td>删除</td>
</tr>
<%}%>
</table>
</body>
</html>
web.xml
<servlet>
<servlet-name>SearchStudentServlet</servlet-name>
<servlet-class>code.SearchStudentServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SearchStudentServlet</servlet-name>
<url-pattern>/search</url-pattern>
</servlet-mapping>
Listener监听器
Listener监听器是JavaWeb的三大组件之一 ( 三大组件分别是:Servlet程序、Filter过滤器、Listener监听器)。Listener是JavaEE的规范,其为接口。
监听器的作用是,监听某种事物的变化。然后通过回调函数,反馈给客户(程序)去做一些响应的处理。
ServletContextListener监听器
ServletContextListener可以监听ServletContext对象的创建和销毁。
ServletContext对象在Web工程启动的时候创建,在web工程停止的时候销毁。
需要实现的两个方法分别是:
public interface ServletContextListener extends EventListener {
/**
* 在 ServletContext 对象创建之后马上调用,做初始化
*/
public void contextInitialized(ServletContextEvent sce);
/**
* 在 ServletContext 对象销毁之后调用
*/
public void contextDestroyed(ServletContextEvent sce);
}
代码演示
MyServletContextListenerImpl.java
package code;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
/**
* @BelongsProject: JavaWeb
* @BelongsPackage: MyServletContextListenerImpl
* @Author: HeXin
* @CreateTime: 2023/2/1 16:14
* @Description:
* @Version: 1.0
*/
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对象被销毁");
}
}
web.xml
<!--配置监听器-->
<listener>
<listener-class>code.MyServletContextListenerImpl</listener-class>
</listener>