JSP
问题
目前使用Servlet返回前端页面代码编写较为复杂,并且维护与修改成本较高
简介
JSP(Java Server Pages)基于Servlet技术的、运行在服务器之上、支持Java语言的动态网页技术.
本质上来说JSP就是一个Servlet.
当客户端请求一个JSP文件时,JSP文件会在服务器中转换成Servlet来执行.
作用
替换显示页面部分的Servlet
创建
选择web文件夹右键选择jsp,填写文件名称
访问地址
http://ip:端口/项目路径/文件名.jsp
Page指令
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
属性:
contentType:当前响应数据类型与编码格式
language:jsp文件翻译后是什么语言,目前只支持java
pageEncoding:当前页面编码格式
import:导包
autoFlush:输出流缓冲区,满了以后是否自动刷新,默认是true,如果改为false,当缓冲区满了以后会报错
buffer:缓冲区大小,默认8kb
errorPage:当前页面出现异常时跳转的页面
isErrorPage:当前页面是否为错误页面,默认值为false,如果为true表示捕获异常信息
session:当前页面是否会创建session对象,默认是true
extends:指定父类
常用脚本
声明脚本
作用:声明
语法:<%! 声明的java代码 %>
示例
<%@ page import="java.util.List" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <%! private int a; private List<String> list; private static double d; static { //声明静态代码块 } public void test(){ System.out.println("声明方法"); } public class Test{ //声明内部类 } %> </body> </html>
表达式脚本
作用:在jsp页面输出内容
语法:<%= xxx %>
实际调用方法:out.print(xxx);
示例
<%@ page import="java.util.List" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <%=10 %> <%=10.1 %> <%="xxx" %> <%=new String("xxx") %> </body> </html>
代码脚本
作用:在jsp页面中编写java代码
语法:<% java代码 %>
示例:
<%@ page import="java.util.List" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <% System.out.println("你好,我是jsp中的代码脚本输出的内容"); %> <% int a = 10; if (a > 100){ System.out.println(a); }else{ System.out.println(100); } %> <% String contextPath = request.getContextPath(); %> <%=contextPath %> <% for (int i = 0; i < 10; i++) { %> <%=i%><br/> <% } %> </body> </html>
注释
语法:<%-- 注释内容 --%>
九大内置对象
jsp中的内置对象,是指Tomcat在翻译jsp页面成为Servlet源代码后,提供的九个对象.
分别是:
request:请求对象
response:响应对象
pageContext:jsp的上下文对象,可以获取当前JSP的任何信息
session:会话对象
application:ServletContext对象
config:ServletConfig对象
out:输出流对象
page:指向当前jsp的对象,相当于this
exception:异常对象,注意需要在page指令中设置isErrorPage="true",才可使用
四大域对象
就是九大内置对象中用来存储数据的四个对象
域对象:可以用来存取数据的对象
pageContext:当前jsp页面中有效
request:一次请求中使用
session:一次会话中使用,从浏览器第一次访问该项目到浏览器关闭
application:当前Tomcat中,从服务器打开到服务器关闭
区别在于其使用范围
示例:
a.jsp <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>a页面</title> </head> <body> <% pageContext.setAttribute("key","pageContext"); request.setAttribute("key","request"); session.setAttribute("key","session"); application.setAttribute("key","application"); %> <%=pageContext.getAttribute("key")%> <hr /> <%=request.getAttribute("key")%> <hr /> <%=session.getAttribute("key")%> <hr /> <%=application.getAttribute("key")%> <hr /> <% request.getRequestDispatcher("/b.jsp").forward(request,response); %> </body> </html> b.jsp <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>b页面</title> </head> <body> <%=pageContext.getAttribute("key")%> <hr /> <%=request.getAttribute("key")%> <hr /> <%=session.getAttribute("key")%> <hr /> <%=application.getAttribute("key")%> <hr /> </body> </html> </body> </html>
out与response
相同点:都是给页面输出内容
不同点:response先于out执行
原因:out输出时会先执行flush方法将输出的内容追加到response尾部导致的
示例1:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <% out.println("out输出"); response.getWriter().println("response输出"); %> </body> </html>
示例2
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <% out.println("out输出"); out.flush(); response.getWriter().println("response输出"); %> </body> </html>
示例3:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <% //注意write输出其他类型没有问题,但是输出整型时会将数字转换为字符输出 //所以此时显示的是a out.write(97); //println或print,先将类型转换为字符串,在调用write输出 //所以此时显示的97 out.println(97); %> </body> </html>
经验:在jsp页面中统一使用out.print()输出,既可以防止数据输出顺序错乱又可以保证数字不会转换为字符输出
JSP常用标签
作用
一个网页可以大致分为三个模块
顶部导航栏,轮播图等
中部页面主体
底部信息展示
但是底部信息展示可能在当前网站的项目中都有使用,所以我们可以将其单独提出作为一个jsp页面
静态引入
语法<%@ include file=“/引入的jsp文件” %>
动态引入
语法:<jsp:include page=“/引入的jsp页面”>
动态传值(get请求方式)
<jsp:include page="/b.jsp">
<jsp:param name="name" value="Tom"/>
<jsp:param name="age" value="18"/>
</jsp:include>
转发
<jsp:forward page="/b.jsp"></jsp:forward>
EL表达式
问题
JSP相较于Servlet来说,在动态网页的数据渲染方面要便捷很多,但是能不能继续简化呢?
我们可以使用EL表达式
简介
英文全称:Expression Language
作用:应用于JSP页面,可以更简单、便捷的获取pageContext、request、session、application等作用域的值,进行渲染。
EL表达式就是替代以下代码的作用:
pageContext.getAttribute(“key”);
request.getAttribute(“key”);
session.getAttribute(“key”);
application.getAttribute(“key”);
语法
${key}
举例
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <% request.setAttribute("str","啦啦啦"); %> Java脚本获取的数据:<%=request.getAttribute("str") %> EL表达式获取的数据:${str} </body> </html>
取值顺序
问题:当四个域key相同时的取值
从小到大
示例
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <% request.setAttribute("k","请求"); pageContext.setAttribute("k","当前jsp"); session.setAttribute("k","会话"); application.setAttribute("k","项目"); %> ${k} </body> </html>
如何指定域获取参数
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <% request.setAttribute("k","请求"); pageContext.setAttribute("k","当前jsp"); session.setAttribute("k","会话"); application.setAttribute("k","项目"); %> <!-- pageScope对应pageContext requestScope对应request sessionScope对应session applicationScope对应application --> ${applicationScope.k} </body> </html>
输出指定对象的数据
<%@ page import="test.User" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.HashMap" %>
<%@ page import="java.util.Map" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
//简单类型
request.setAttribute("key1",123);
//字符串
request.setAttribute("key2","Hello EL!");
//对象
request.setAttribute("key3",new User("张三",18,"男"));
//数组
String[] arr = {"aaa","bbb","ccc"};
request.setAttribute("key4",arr);
//集合
List<User> list = new ArrayList<>();
list.add(new User("小明",18,"男"));
list.add(new User("李四",28,"男"));
list.add(new User("小红",20,"女"));
request.setAttribute("key5",list);
//Map
Map<String,User> map = new HashMap<>();
map.put("z",new User("小周",18,"男"));
map.put("l",new User("小李",28,"男"));
map.put("x",new User("小许",20,"女"));
request.setAttribute("key6",map);
%>
${key1}
<hr />
${key2}
<hr />
${key3.name}
<hr />
${key4[2]}
<hr />
${key5[1].name}
<hr />
${key6["z"].name}
<hr />
${key6.z.name}
<hr />
</body>
</html>
运算符
算数运算
运算符 | 描述/示例 |
---|---|
+ | ${key1+key2} 表示根据key1获取的值然后加上key2获取的值,显示到网页 |
- | 减法 |
* | 乘法 |
/ or div | 除法, ${key/4} 等价于 ${key div 4} |
% or mod | 取模 |
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> ${5+5} <hr /> ${5-5} <hr /> ${5*5} <hr /> ${5/5} <hr /> ${5 div 5} <hr /> ${5 % 5} <hr /> ${5 mod 5} <hr /> </body> </html>
关系比较
运算符 | 描述/示例 |
---|---|
== or eq | ${key == v} 表示比较根据key获取的值是否等于v,返回结果为true/false等价于 ${key eq v} |
!= or ne | 不等于 |
> or gt | 大于 |
< or lt | 小于 |
>= or ge | 大于等于 |
<= or le | 小于等于 |
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> ${5==5} <hr /> ${5!=5} <hr /> ${5 > 5} <hr /> ${5 < 5} <hr /> ${5 >= 5} <hr /> ${5 <= 5} <hr /> </body> </html>
逻辑运算
运算符 | 描述/示例 |
---|---|
&& or and | 逻辑与,用于连接两个条件 |
` | |
! or not | 逻辑非 |
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> ${true && true} <hr /> ${true||true} <hr /> ${!true} <hr /> </body> </html>
判空
运算符 | 描述/示例 |
---|---|
empty | ${empty key}如果key对应取出的值为空,则返回true |
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> ${empty key} <hr /> </body> </html>
隐式对象
除了四个域对象pageScope、requestScope、sessionScope、applicationScope之外,EL中还提供了另外的7个对象,分别用于获取不同的数据
注意:有11个隐式对象
隐式对象 | 说明 |
---|---|
param | 获取Rquest对象的参数,返回String,${param.key} 等价于request.getParameter("key") |
paramValues | 获取Rquest对象传递的所有的参数的Map集合,返回值类型Map<String, String[]>,${paramValues} 等价于request.getParameterMap() |
header | 获取HTTP请求头,返回值类型Map<String, String>, ${header.contentPosition} |
headerValues | 获取HTTP请求头中所有的值,返回值类型Map<String, String[]> |
initParam | 获取上下文初始化参数(在web.xml中配置的context-param中的数据) |
pageContext | 一般用于获取协议、服务器端口、获取工程路径(重点)、获取请求方式等 获取jsp其他八个内置对象 |
cookie | 获取cookie中的值,返回值类型Map<String, Cookie>,${cookie.username} |
示例
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> 获取name参数的值:${param.name} <hr /> 获取所有参数的值:${paramValues} <hr /> 获取name参数的值:${paramValues.name[0]} <hr /> 获取请求头中所有的值:${header} <hr /> 获取请求头中sec-fetch-mode的值:${header["sec-fetch-mode"]} <hr /> 获取请求头中所有数据的值:${headerValues} <hr /> 获取上下文参数test的值:${initParam.test} <hr /> 获取协议:${pageContext.request.scheme} <hr /> 获取工程路径:${pageContext.request.contextPath} <hr /> 获取SessionId:${pageContext.session.id} <hr /> <!-- 使用别的Servlet先对cookie存值 --> 获取cookie中key为name的值:${cookie.name.value} <hr /> </body> </html>