概念:Java Server Pages:Java 服务器端页面
可以理解为:一个特殊的页面,其中既可以指定定义 HTML 标签,又可以定义 Java 代码
用于简化书写
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
JSP - Hello World
<%
System.out.println("Hello JSP!");
%>
<%= "Hello JSP!" %>
Hello JSP!
客户端浏览器通过
http://localhost:8080/虚拟目录/index.jsp
访问服务器中的index.jsp
资源:
index.jsp
资源。index.jsp
转换为 .java
文件。(由 JSP 引擎自动生成的一个类,该类继承了 HttpJspBase
,而 HttpJspBase
又继承了 HttpServlet
类并实现了 HttpJspPage
接口 ).java
文件,生成 .class
字节码文件。由于该文件可以被浏览器访问到,所以该类(字节码文件)是 Servlet ,因为一个 Java 类只有是 Servlet 才可以被外界访问到。
所以 JSP 本质上就是一个 Servlet
JSP 定义 Java 代码的方式
<% 代码 %>
:定义的 Java 代码,在 service 方法中,service 方法中可以定义什么,该脚本中就可以定义什么。<%! 代码 %>
:定义的 Java 代码,在 JSP 转换后的 Java 类的成员位置(使用较少,因为在 Servlet 中尽量不要定义成员变量,可能引发线程安全问题)<%= 代码 %>
:定义的 Java 代码,会输出到页面中,输出代码中可以定义什么,该脚本中就可以定义什么。在 JSP 页面中不需要获取和创建,可以直接使用的对象
response.getWriter()
类似
response.getWriter()
和 out.writer()
的区别: out.writer()
写在哪,就在哪输出,但不论 response.getWriter()
写在哪,都会先 out.writer()
一步输出显示(response 和 out 对象都有字符输出流都有缓冲区,之后做出响应的时候,Tomcat 服务器会先找 response 对象的缓冲区数据,后找 out 对象的缓冲区数据),所以一般尽量少用 response.getWriter()
输出数据,因为会打乱页面布局变量名 | 真实类型 | 作用 |
---|---|---|
pageContext | PageContext | 当前页面共享数据,还可以获取其他八个对象 |
request | HttpServletRequest | 一次请求访问的多个资源(转发)共享资源 |
session | HttpSession | 一次会话的多个请求间共享数据 |
application | ServletContext | 所有用户间共享数据 |
response | HttpServletResponse | 响应对象 |
page | Object | 当前页面(Servlet)的对象(this) |
out | JspWriter | 输出对象,将数据输出到页面上 |
config | ServletConfig | Servlet 的配置对象 |
exception | Throwable | 异常对象 |
作用:用于配置 JSP 页面,导入资源配置文件
格式:
<%@ 指令名称 属性名1=属性值1 属性名2=属性值2 ...... %>
分类:
response.setContentType()
<%@ include file="top.jsp" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
导入标签库使用标签库需要导入 jar 包,使用 Maven 导入所需要的 jar 包
<dependency>
<groupId>javax.servletgroupId>
<artifactId>jstlartifactId>
<version>1.2version>
dependency>
<dependency>
<groupId>javax.servlet.jsp.jstlgroupId>
<artifactId>jstl-apiartifactId>
<version>1.2version>
dependency>
<dependency>
<groupId>taglibsgroupId>
<artifactId>standardartifactId>
<version>1.1.2version>
dependency>
:只能注释 HTML 代码片段<%-- --%>
:可以注释全部内容(推荐使用)利用 JSP 写法,虽然其中方便插入 HTML 标签和 Java 代码,但是可读性较差,不推荐使用,仅作了解
<%@ page import="java.util.Date" %>
<%@ page import="java.text.SimpleDateFormat" %>
<%@ page import="java.net.URLEncoder" %>
<%@ page import="java.net.URLDecoder" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
首页
<%
// 获取所有 Cookie
Cookie[] cookies = request.getCookies();
boolean flag=false; // 没有 Cookie 为 lastTime
// 遍历 Cookie 数组
if (cookies!=null&&cookies.length>0){
for (Cookie cookie : cookies) {
// 获取 Cookie 的名称
String name = cookie.getName();
// 判断名称是否是:lastTime
if ("lastTime".equals(name)){
// 有该 Cookie,不是第一次访问
flag=true; // 有 lastTime 的 Cookie
// 设置 Cookie 的 value
// 获取当前时间的字符串,重新设置 Cookie 的值,重新发送 Cookie
Date date = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String str_date = simpleDateFormat.format(date);
System.out.println("编码前:"+str_date);
// URL 编码
str_date = URLEncoder.encode(str_date, "utf-8");
System.out.println("编码后:"+str_date);
cookie.setValue(str_date);
// 设置 Cookie 的存活时间
cookie.setMaxAge(60*60*24); // 一天
response.addCookie(cookie);
// 响应数据
// 获取 Cookie 的 value、时间
String value = cookie.getValue();
System.out.println("解码前:"+value);
// URL 解码
value= URLDecoder.decode(value,"utf-8");
System.out.println("解码后:"+value);
%>
欢迎回来,您上次访问时间为:<%=value%>
<%
break;
}
}
}
if (cookies==null||cookies.length==0||flag==false){
// 没有,第一次访问
// 设置 Cookie 的 value
// 获取当前时间的字符串,重新设置 Cookie 的值,重新发送 Cookie
Date date = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String str_date = simpleDateFormat.format(date);
System.out.println("编码前:"+str_date);
// URL 编码
str_date = URLEncoder.encode(str_date, "utf-8");
System.out.println("编码后:"+str_date);
Cookie cookie = new Cookie("lastTime",str_date);
// 设置 Cookie 的存活时间
cookie.setMaxAge(60*60*24); // 一天
response.addCookie(cookie);
%>
您好,欢迎您首次访问!
<%
}
%>
${表达式}
,例如:${3>4}
结果为 falseisELIgnored="true"
表示忽略当前 JSP 页面中的所有的 EL 表达式\${表达式}
:表示忽略当前这个 EL 表达式运算符:
${empty list}
如果 list 集合为 null 且长度为0,则返回 true)<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
算数运算符
${3 + 4}
${3 / 4}
${3 div 4}
${3 % 4}
${3 mod 4}
${3 * 4}
比较运算符
${3 == 4}
${3 < 4}
逻辑运算符
${3 > 4 && 3 < 4}
${3 > 4 and 3 < 4}
${empty str}
:判断字符串、集合、数组对象是否为 null 或者长度为0${not empty str}
:表示判断字符串、集合、数组对象是否不为 null 并且长度大于0<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
空运算符
<%
String str="abc";
request.setAttribute("str",str);
List list=new ArrayList();
request.setAttribute("list",list);
%>
${empty str}
${not empty list}
EL 表达式只能从域对象中获取值
${域名称.键名}
:从指定域中获取指定键的值域名称 | 指定的域 |
---|---|
pageScope | pageContext |
requestScope | request |
sessionScope | session |
applicationScope | application(ServletContext) |
举例:在 request 域中存储了 name=张三
,获取:${requestScope.name}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
EL 表达式获取域中的数据
<%
// 在域中存储数据
request.setAttribute("name","张三");
request.setAttribute("age","22");
%>
获取域中的数据
${requestScope.name}
${requestScope.age}
${requestScope.gender}
<%-- 没有该数据,就是空字符串,在页面上什么也不显示 --%>
${键名}
:表示依次从最小的域中查找是否有该键对应的值,直到找到为止<%@ page contentType="text/html;charset=UTF-8" language="java" %>
EL 表达式获取域中的数据
<%
// 在域中存储数据
session.setAttribute("name","李四");
request.setAttribute("name","张三");
%>
获取域中的数据
${name}
<%-- 获取的结果为张三 --%>
${域名称.键名.属性名}
:本质上会去调用对象的 getter 方法public class User {
private String name;
private int age;
private Date birthday;
/**
* 逻辑视图
* @return
*/
public String getBirStr() {
if (birthday != null) {
// 格式化日期对象
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// 返回字符串
return simpleDateFormat.format(birthday);
} else {
return "";
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}
<%@ page import="com.example.jsp_test.User" %>
<%@ page import="java.util.Date" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
EL 表达式获取对象的数据
<%
User user = new User();
user.setName("张三");
user.setAge(22);
user.setBirthday(new Date());
request.setAttribute("user",user);
%>
获取对象中的值
${requestScope.user}
<%-- 如果 JavaBean 类中不进行重写 toString 方法,它返回的就是地址值 --%>
<%-- 获取属性值
通过对象的属性来获取
setter 或 getter 方法,去掉 set 或 get,再将剩余的部分将首字母变为小写
setName → Name → name
--%>
${requestScope.user.name}
${requestScope.user.age}
${requestScope.user.birthday}
${requestScope.user.birthday.month}
<%-- month 要加1才是实际月份--%>
<%-- 可以继续获取日期对象的属性值 --%>
${user.birStr}
${域名称.键名[索引]}
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.List" %>
<%@ page import="com.example.jsp_test.User" %>
<%@ page import="java.util.Date" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
EL 表达式获取 List 集合的数据
<%
User user = new User();
user.setName("张三");
user.setAge(22);
user.setBirthday(new Date());
List list = new ArrayList();
list.add("aaa");
list.add("bbb");
list.add(user);
request.setAttribute("list",list);
%>
获取 List 集合的数据
${list}
${list[0]}
${list[1]}
${list[10]}
<%-- 如果角标越界就是空字符串,页面什么也不显示 --%>
${list[2].name}
${域名称.键名.key名称}
或 ${域名称.键名["key名称"]}
<%@ page import="com.example.jsp_test.User" %>
<%@ page import="java.util.*" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
EL 表达式获取 Map 集合的数据
<%
User user = new User();
user.setName("张三");
user.setAge(22);
user.setBirthday(new Date());
Map map=new HashMap();
map.put("name","李四");
map.put("gender","男");
map.put("user",user);
request.setAttribute("map",map);
%>
获取 Map 集合的数据
${map.gender}
${map["gender"]}
${map.user.name}
EL 表达式中有11个隐式对象
${pageContext.request.contextPath}
:动态获取虚拟目录)<%@ page contentType="text/html;charset=UTF-8" language="java" %>
隐式对象
${pageContext.request}
在 JSP 页面动态获取虚拟目录
${pageContext.request.contextPath}
使用步骤:
<%@ taglib %>
c:if
标签没有 else 情况,想要 else 情况,则可以再定义一个 c:if
标签<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
if 标签
显示
<%
// 判断 Request 域中的一个 List 集合是否为空,如果不为空则显示遍历集合
List list=new ArrayList();
list.add("123");
request.setAttribute("list",list);
request.setAttribute("number",3);
%>
遍历集合
${number}为奇数
${number}为偶数
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
choose 标签
<%-- 完成数字编号对应星期几的案例
1. 域中存储数字
2. 使用 choose 标签取出数字 相当于 switch 声明
3. 使用 when 标签做数字判断 相当于 case
4. otherwise 标签做其他事情的声明 相当于 default--%>
<%
request.setAttribute("number",3);
%>
星期一
星期二
星期三
星期四
星期五
星期六
星期日
数字输入有误!
for(int i=0;i<10;i++){}
List list; for(User user : list){}
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
foreach 标签
${i}${s.index}
${s.count}
<%
List list=new ArrayList();
list.add("aaa");
list.add("bbb");
list.add("ccc");
request.setAttribute("list",list);
%>
${s.index} ${s.count} ${str}
public class User {
private String name;
private int age;
private Date birthday;
public User(){}
public User(String name, int age, Date birthday) {
this.name = name;
this.age = age;
this.birthday = birthday;
}
/**
* 逻辑视图
* @return
*/
public String getBirStr() {
if (birthday != null) {
// 格式化日期对象
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// 返回字符串
return simpleDateFormat.format(birthday);
} else {
return "";
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="com.example.jsp_test.User" %>
<%@ page import="java.util.Date" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
练习
<%
List list=new ArrayList();
list.add(new User("张三",23,new Date()));
list.add(new User("李四",24,new Date()));
list.add(new User("王五",25,new Date()));
request.setAttribute("list",list);
%>
编号
姓名
年龄
生日
<%-- 数据行 --%>
${s.count}
${user.name}
${user.age}
${user.birStr}
${s.count}
${user.name}
${user.age}
${user.birStr}