web基础3-servlet入门2(session、cookie、JSP和bean概念)
web基础3-servlet入门2(session、cookie、JSP和bean概念)
一、Cookie 、Session
7.1 会话
会话:用户打开一个浏览器,点击了很多超链接,访问多个web资源,关闭浏览器,这个过程可以称之为会话
有状态会话:
一个客户来过商店,下次再来这个商店,我们需要知道这个客户曾经来过,这个过程可以称之为会话;
你能怎么证明你是商店的客户?
你 商店
1.发票 商店给你发票
2.商店登记 商店标记你来过了(会员)
一个网站,怎么证明你来过?
客户端 服务端
1.服务端给客户端一个信件,客户端下次访问服务端带上信件就可以了=》cookie
2.服务器登记你来过了,下次你来的时候我来匹配你=》session
7.2 常见应用场景
网站登陆之后,你下次不用登陆了,第二次访问直接就上去了
7.3 保存会话的两种技术
7.3.1 cookie
- 客户端技术
服务端怎么发给客户端:响应
客户端怎么把东西带到服务端:请求
<servlet>
<servlet-name>CookieServlet</servlet-name>
<servlet-class>com.happy.servlet.CookieServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CookieServlet</servlet-name>
<url-pattern>/cookie</url-pattern>
</servlet-mapping>
package com.happy.servlet;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
public class CookieServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//服务器,告诉你,你来的时间,把这个时间封装成为一个信件,你下次来,我就知道你来了
//解决中文乱码
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html");
PrintWriter out = response.getWriter();
// cookie,服务器从客户端获取cookie
// 从这里返回数组,说明cookie可能存在多个
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
String name = cookie.getName();
if (name.equals("time")) {
System.out.println("==============");
String value = cookie.getValue();
long ltime = Long.parseLong(value);
Date date = new Date(ltime);
System.out.println("上次访问时间是=>" + date.toLocaleString());
out.write("您上次访问时间=>" + date.toLocaleString() + "\n");
continue;
}
if (name.equals("name")) {
System.out.println("==============");
String value = cookie.getValue();
System.out.println(name + ":" + value);
out.write("您的姓名是=>" + value + "\n");
continue;
}
}
} else {
out.write("这是您第一次访问本站");
}
// 服务器给客户端响应一个cookie
// Date date = new Date();
// SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
// System.out.println(formatter.format(date));
// String time = formatter.format(date);
long ltime = System.currentTimeMillis();
// cookie只能存string不能存对象,有局限性
Cookie cookie1 = new Cookie("time", String.valueOf(ltime));
// 设置时间的有效期为1天
cookie1.setMaxAge(24*60*60);
Cookie cookie2 = new Cookie("name2", "happy");
Cookie cookie3 = new Cookie("name2", "happy3");
response.addCookie(cookie1);
response.addCookie(cookie2);
response.addCookie(cookie3);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}


7.3.1.1 cookie的有效期
cookie默认有效期为:打开访问地址到关闭浏览器的一次会话
改变cookie有效期
// 设置时间的有效期为1天
cookie1.setMaxAge(24*60*60);

7.3.1.2 cookie操作步骤和API
-
从请求中拿到cookie信息
-
服务器响应客户端cookie
Cookie[] cookies=req.getCookies(); //获得Cookie数组 cookie.getName(); //获得cookie的key cookie.getValue(); //获得cookie的value //创建一个cookie new Cookie("name","happy"); //设置cookie的有效期 cookie.setMaxAge(24*60*60); //响应给客户端一个cookie resp.addCookie(cookie1) resp.addCookie(cookie2)注意:new Cookie("name","happy")中的key是全局唯一,如果有重复以最后一次为准,既覆盖
7.3.1.3 cookie的保存地址
cookie:一般会保存在本地用户目录下appdata
7.3.1.4 cookie的特性
一个网站cookie是否存在上限!细节问题
一个cookie只能保存一个信息
一个web站点可以给浏览器发送多个cookie,最多存放20个cookie
cookie大小有限制4kb
300个cookie浏览器上限。
cookie只能存字符串数据(因为在客户端),而session可以存对象
new cookie(String st1,String str2); session.setAttribute(String var1, Object var2);
7.3.1.5 删除cookie
核心代码:修改cookie的有效期并立即返回
Cookie cookie1 = new Cookie(cookieName,"");
cookie1.setMaxAge(0);
response.addCookie(cookie1);
详细代码如下
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>删除cookie</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/cookiedel">
您要删除的cookie的name:<input type="text" name="name"/><br/>
<input type="submit">
</form>
</body>
</html>
<servlet>
<servlet-name>CookieDelServlet</servlet-name>
<servlet-class>com.happy.servlet.CookieDelServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CookieDelServlet</servlet-name>
<url-pattern>/cookiedel</url-pattern>
</servlet-mapping>
package com.happy.servlet;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
import java.io.PrintWriter;
public class CookieDelServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html");
// 获取前端传来的参数cookie名字
String cookieName=request.getParameter("name");
PrintWriter out = response.getWriter();
Cookie[] cookies = request.getCookies();
for (Cookie cookie : cookies) {
if(cookie.getName().equals(cookieName)) {
Cookie cookie1 = new Cookie(cookieName,"");
cookie1.setMaxAge(0);
response.addCookie(cookie1);
break;
}
}
out.println("您删除了cookie:"+cookieName);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
7.3.1.6 Urlencode编码解码
如果遇到cookie值中文出现乱码,可以编码解码。
URLEncoder.encode("高兴","utf-8")
URLEncoder.Decode(cookie.getValue(),"utf-8")
7.3.2 session
- 服务端技术(也依赖于cookie)
主要服务器登记你来过,利用这个技术,可以保存用户的会话信息。我们可以把信息和数据放在session中。
-
可以在服务器,给每一个用户创建一个session对象(建议)
-
一个session独占一个浏览器,只要浏览器没有关闭,这个session就存在。注意是一个浏览器一个session,不同浏览器不同session
-
用户登陆之后,整个网站它都可以访问了
-
session的应用:保存用户或者购物车的信息
7.3.2.1 session和cookie的关系
session的唯一标志SessionId存在一个cookie当中。cookie的name为JSESSIONID


7.3.2.2 session的操作步骤和API
package com.happy.servlet;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
import java.io.PrintWriter;
public class SessionServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 解决乱码问题
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
// 得到session
HttpSession session = request.getSession();
session.setAttribute("name","高兴");
Object id = session.getAttribute("id");
String sessionId = session.getId();
System.out.println(sessionId);
boolean aNew = session.isNew();
if(aNew){
out.write("session创建成功,sessionID为:"+sessionId);
}else{
out.write("session已经存在了,sessionID为:"+sessionId);
}
// 尝试从cookie里拿sessionId
for (Cookie cookie : request.getCookies()) {
if(cookie.getName().equals("JSESSIONID")){
System.out.println("cookie里的JSESSIONID值为:"+cookie.getValue());
}
}
// 给session中增加东西
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
结果如下:可见一样

删除session的cookie,session也消失


删除前查看session情况

删除后查看session情况:原来sessionId被删除了

7.3.3.3 删除session
除了上面删除session所依赖的name为JSESSIONID的cookie以外,一般不用这种方式,还有两种方式:
手动删除
在代码中显示的手动注销,使用session.invalidate()
package com.happy.servlet;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
public class InvalidateSessionServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
session.invalidate();
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
web.xml配置删除
也可以在web.xml中通过配置,全局设置session的有效期。
<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"
metadata-complete="true">
<servlet>
<servlet-name>CookieServlet</servlet-name>
<servlet-class>com.happy.servlet.CookieServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CookieServlet</servlet-name>
<url-pattern>/cookie</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>CookieDelServlet</servlet-name>
<servlet-class>com.happy.servlet.CookieDelServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CookieDelServlet</servlet-name>
<url-pattern>/cookiedel</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>ChineseCookieServlet</servlet-name>
<servlet-class>com.happy.servlet.ChineseCookieServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ChineseCookieServlet</servlet-name>
<url-pattern>/chinese</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>SessionServlet</servlet-name>
<servlet-class>com.happy.servlet.SessionServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SessionServlet</servlet-name>
<url-pattern>/session</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>GetSessionServlet</servlet-name>
<servlet-class>com.happy.servlet.GetSessionServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>GetSessionServlet</servlet-name>
<url-pattern>/getsession</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>InvalidateSessionServlet</servlet-name>
<servlet-class>com.happy.servlet.InvalidateSessionServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>InvalidateSessionServlet</servlet-name>
<url-pattern>/invalidate</url-pattern>
</servlet-mapping>
<!--设置session的时间-->
<session-config>
<!-- 1分钟后session自动失效,以分钟为单位-->
<session-timeout>1</session-timeout>
</session-config>
</web-app>
7.3.3 cookie和session的区别
| cookie | session | |
|---|---|---|
| 技术分类 | 客户端技术 | 主要是服务端技术 |
| 使用cookie保存信息程度 | 保存所有信息在cookie里 | 只保存sessionId在一个name为JESESSIONID的cookie里 |
| 保存信息位置 | 都保存在客户端 | 除了一个存JESESSIONID的cookie,其余保存在服务器的一个用户(一个浏览器的)独占session对象中 |
| 保存信息类型 | 只能保存字符串类数据 | 可以保存object类型 |
| 数量 | 可以有多个cookie | 一个浏览器只有一个session |
| 创建方法 | 通过new一个cookie对象存放一个键值对 | 通过getSession后,再用session.setAttribute |
| 销毁方法 | new一个同名cookie,并设置cookie.setMaxAge(0); | 1. session.invalidate,销毁所有session里的数据, 2. web.xml配置全局session timeout |
7.3.2 session和ServletContext域(ApplicationContext)的区别
| session | ServletContext | |
|---|---|---|
| 域范围 | 一个浏览器内共享数据(不论这个浏览器内多少窗口) | 所有Servelet共享数据,多个浏览器甚至不同用户共享数据。 |
| 应用场景 | 保存用户专属数据,如:1. 登陆(保存登陆信息)等;2.购物车信息 | 可用于计数,如某页面访问量 |
| 使用频率 | 高 | 极低 |
二、JSP
2.1 什么是JSP
Java Server Pages:Java服务器端页面,也和Servlet一样用于开发动态web
最大特点:写JSP就像在写HTML
2.2 JSP和HTML区别
| HTML | JSP | |
|---|---|---|
| 动静态 | HTML只给用户提供静态的数据 | HTML只给用户提供动态的数据 |
| 嵌入代码 | 只能嵌入前端js代码 | 除了js代码,JSP页面中可以嵌入后端JAVA代码 |
2.3 JSP原理1-基础原理
JSP是怎么运行的:
发现页面转变成了JAVA程序。
C:\Users\pcuser\AppData\Local\JetBrains\IntelliJIdea2021.2\tomcat\4be3f694-8291-4810-983d-7d84643de4d0\work\Catalina\localhost\cookie\org\apache\jsp

-
浏览器向服务器发送请求,不管访问什么资源,其实都是在访问Servlet!
-
Jsp最后也会变成java类
JSP本质上就是一个Servlet,核心方法如下
//初始化
public void _jspInit() {
}
//销毁
public void _jspDestroy() {
}
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
2.4 JSP Servlet处理步骤
查看核心方法
2.4.1 判断请求
if (!javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
final java.lang.String _jspx_method = request.getMethod();
if ("OPTIONS".equals(_jspx_method)) {
response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
return;
}
if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method)) {
response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSP 只允许 GET、POST 或 HEAD。Jasper 还允许 OPTIONS");
return;
}
}
2.4.2 内置9大对象初识
final javax.servlet.jsp.PageContext pageContext; //页面上下文
javax.servlet.http.HttpSession session = null; //session
final javax.servlet.ServletContext application; //application实际为ServletContext改名
final javax.servlet.ServletConfig config; //配置
javax.servlet.jsp.JspWriter out = null; //out
final java.lang.Object page = this; //page:代表当前页
javax.servlet.jsp.JspWriter _jspx_out = null;
javax.servlet.jsp.PageContext _jspx_page_context = null;
//传入参数
final javax.servlet.http.HttpServletRequest request, //请求
final javax.servlet.http.HttpServletResponse response //响应
2.4.3 输出页面前增加的代码
servlet帮忙完成初始化的工作
try {
response.setContentType("text/html;charset=UTF-8");
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
2.4.4 以上这些对象可以在JSP页面中直接使用
通过set.jsp负责通过jsp servlet的api接口直接set session
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>set session by jsp</h1>
<%
session.setAttribute("happy518","happy5188");
out.print("你set session attribute happy518");
%>
<a href="${pageContext.servletContext.contextPath}/get.jsp" target="_blank">通过打开这个超链接测试session是否set进去了</a>
</body>
</html>
通过get.jsp负责通过jsp servlet的api接口直接get session
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>getSession by jsp</h1>
<%
Object happy518 = session.getAttribute("happy518");
out.print(happy518);
%>
</body>
</html>


可以看到,当第一次访问对应jsp页面的时候,生成了对应的servlet.java

2.5 JSP原理2-编译servlet原理
jsp转成java遵循以下:
-
把html页面代码,转换成out.write 到java文件
-
把java代码(<%java 代码%>包裹的),原封不动的输出到java
-
把<%=name%>用out.print(name)转成到java
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>删除cookie</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/cookiedel">
您要删除的cookie的name:<input type="text" name="name"/><br/>
<input type="submit">
</form>
<%
String name="happy";
%>
name:<%=name%>
</body>
</html>
转成java
out.write("\r\n");
out.write("\r\n");
out.write("<html>\r\n");
out.write("<head>\r\n");
out.write(" <title>删除cookie</title>\r\n");
out.write("</head>\r\n");
out.write("<body>\r\n");
out.write("<form action=\"");
out.write((java.lang.String) org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate("${pageContext.request.contextPath}", java.lang.String.class, (javax.servlet.jsp.PageContext)_jspx_page_context, null));
out.write("/cookiedel\">\r\n");
out.write(" 您要删除的cookie的name:<input type=\"text\" name=\"name\"/><br/>\r\n");
out.write(" <input type=\"submit\">\r\n");
out.write("</form>\r\n");
out.write("\r\n");
String name="happy";
out.write("\r\n");
out.write("name:");
out.print(name);
out.write("\r\n");
out.write("</body>\r\n");
out.write("</html>\r\n");
2.6 JSP脚本基础语法
任何语言都有自己的语法,JSP也不例外,JSP作为JAVA技术的一种应用,它拥有一些自己扩充的语法,了解即可,java所有语法都支持。
2.6.1 JSP注释
<%-- JSP表带式--%>
2.6.2 JSP表达式
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
$END$
<%-- JSP表带式--%>
<%=new java.util.Date()%>
</body>
</html>
java+jsp写循环html
2.6.3 JSP脚本片段
脚本片段用<% 代码 %>包裹
<%--
Created by IntelliJ IDEA.
User: pcuser
Date: 2022/4/20
Time: 21:26
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>
$END$
<%-- JSP表带式--%>
<%=new java.util.Date()%>
<%
for (int i=0;i<10;i++){
out.print(i);
}
%>
<%
for (int i=0;i<10;i++){
%>
<%=i%>
<h1>hello world</h1>
<%
}
%>
</body>
</html>
for (int i=0;i<10;i++){
out.write('\n');
out.write(' ');
out.write(' ');
out.print(i);
out.write("\n");
out.write(" <h1>hello world</h1>\n");
out.write(" ");
}
2.6.4 JSP声明
声明代码用<%!代码%>包裹
<%!
static{
System.out.println("Loading jsp servlet");
}
private int globalvar=0;
public void happy(){
System.out.println("编写了方法,进入方法区的代码");
}
%>
public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent,
org.apache.jasper.runtime.JspSourceImports {
static{
System.out.println("Loading jsp servlet");
}
private int globalvar=0;
public void happy(){
System.out.println("编写了方法,进入方法区的代码");
}
private static final javax.servlet.jsp.JspFactory _jspxFactory =
javax.servlet.jsp.JspFactory.getDefaultFactory();
2.6.5 JSP表达式 VS JSP脚本片段 VS JSP声明
| JSP表达式 | JSP脚本片段 | JSP声明 |
|---|---|---|
| 代码在service中 | 代码在service中 | 代码会被放在类中 |
2.6.6 JSP注释 VS HTML注释
jsp的注释内容不在客户端显示,而html的注释会在客户端显示。
<!--html注释 -->
<%--jsp注释 --%>

2.7 JSP指令
基本语法:
<%@ %>
2.7.1 指定编码
<%@ page contentType>指定编码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
2.7.2 定制错误页面
2.7.2.1 JSP <%@ page errorPage %>
定义前
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
int i=1/0;
%>
</body>
</html>

报错页面如下:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page errorPage="error/500.jsp" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
$END$
<%-- JSP表带式--%>
<!-- html注释 -->
<%=new java.util.Date()%>
<%
for (int i=0;i<10;i++){
out.print(i);
}
%>
<%
for (int i=0;i<10;i++){
%>
${i}
<h1>hello world${i}</h1>
<%
}
%>
<%!
static{
System.out.println("Loading jsp servlet");
}
private int globalvar=0;
public void happy(){
System.out.println("编写了方法,进入方法区的代码");
}
%>
</body>
</html>
错误500自定页面如下:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>500自定义页面</h1>
<img src="${pageContext.request.contextPath}/img/img.png" alt="显示500图片"/>
</body>
</html>

2.7.2.2 web.xml 的error-page
<?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">
<error-page>
<error-code>404</error-code>
<!-- 第一个/代表当前项目-->
<location>/error/404.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<!-- 第一个/代表当前项目-->
<location>/error/500.jsp</location>
</error-page>
</web-app>
2.8 JSP标签
2.8.1 jsp:include
2.8.2 jsp:forward
2.8.3 jsp:param
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>jsptag</title>
</head>
<body>
<h1>jsptag1</h1>
<%--<jsp:param></jsp:param>相当于http://localhost:8080/jsp/jsp2.jsp?name1=happy--%>
<jsp:forward page="/jsptag2.jsp">
<jsp:param name="name1" value="jsparam1"/>
</jsp:forward>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>jsptag2</title>
</head>
<body>
<h1>jsptag2</h1>
<hr>
request.getAttribute("name1")方式获取:
<%=request.getAttribute("name1")%>
<hr>
el表达式$name1获取:
${name1}
<hr>
request.getParameter("name1")方式获取:
<%=request.getParameter("name1")%>
<hr>
el表达式$param.name1获取:
${param.name1}
</body>
</html>

2.9 JSTL标签(标准标签库)
JSP标准标签库是一个JSP标签集合,它封装了JSP应用的通用核心功能。
JSTL支持通用的,结构化的任务,比如迭代,条件判断,XML文档操作,国际化标签,SQL标签。
除了这些,它还提供了一个框架来使用集成JSTL的自定义标签。
作用:JSTL标签库的使用就是为了弥补HTML标签的不足;它自定义许多标签,可以供我们使用,标签的功能和java代码一样。
根据JSTL标签提供的功能,可以将其分为5个类别:
核心标签- 格式化标签
- SQL标签
- XML标签
- JSTL函数
2.9.1 核心标签
使用步骤
- 使用前,导入头文件,引入对应的taglib
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
- 在tomcat也需要引入jstl的包,否者会报错:JSTL解析错误。
- 使用其中的方法
<c:if>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="jsptag3.jsp" method="get">
姓名:<input type="text" name="name" value="${param.name}">
单位:<input type="text" name="unit" >
<input type="submit" value="提交"></input>
</form>
<%--<% if(request.getParameter("name").equals("admin")){--%>
<%-- request.getRequestDispatcher("/success.jsp").forward(request,response);--%>
<%--}--%>
<%--%>--%>
<c:if test="${param.name=='admin'}" var="isAdmin">
<c:out value="管理员欢迎您"></c:out>
<%pageContext.forward("/success.jsp");%>
</c:if>
<c:out value="${isAdmin}"></c:out>
</body>
</html>

<c:choose>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<c:set var="score" value="72"></c:set>
<c:choose>
<c:when test="${score>=90}">
<c:out value="您的成绩为优秀"></c:out>
</c:when>
<c:when test="${score>=80}">
<c:out value="您的成绩为良好"></c:out>
</c:when>
<c:when test="${score>=60}">
<c:out value="您的成绩为及格"></c:out>
</c:when>
<c:when test="${score<60}">
<c:out value="您的成绩为不及格"></c:out>
</c:when>
</c:choose>
</body>
</html>

<c:forEach>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
cForEach.jsp:
<%
ArrayList<String> peoples = new ArrayList<String>();
peoples.add("张三");
peoples.add("李四");
peoples.add("王五");
peoples.add("赵六");
request.setAttribute("peoples",peoples);
%>
<hr>
<c:forEach var="people" items="${peoples}">
<c:out value="${people}"></c:out>
</c:forEach>
<hr>
begin="1" end="3" step="2"
<br>
<c:forEach var="people" items="${peoples}" begin="1" end="3" step="2">
<c:out value="${people}"></c:out>
</c:forEach>
</body>
</html>

2.10 JSP九大内置对象详解
2.10.1 9大对象比较及原理
| 序号 | 对象名 | 对应java对象 | 作用 |
|---|---|---|---|
| 1 | request | 存东西,和取封装的request请求参数。作用域介于PageContext和Session之间 | |
| 2 | response | 返回对象 | |
| 3 | PageContext | 存东西,作用域最小。 | |
| 4 | session | 存东西 | |
| 5 | application | 存东西 | |
| 6 | config | pageContext.getServletConfig(); | 获取配置文件参数 |
| 7 | out | ||
| 8 | page | ||
| 9 | exception | 不同于前8个对象,对用户不可见 |

2.10.2 域范围set和get
从底层到高层(作用域),page=》request=》session=》application
和类加载器的双亲委派机制比较:
注意:同类加载器的双亲委派机制类似,当有多个域存在同一个变量名的时候,用el表达式${}获取和findAttribute从低到高寻找,但不同的是,类加载器使用高层的,而这里使用较低层即精确的。
场景一:访问独立两个页面
1.一个页面set域:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<style>
h1,h2,h3,h4,hr{
margin: 0;
}
</style>
</head>
<body>
<%--内置对象--%>
<%--方式一set--%>
<%
// 保存的数据只在一个页面中有效
pageContext.setAttribute("name1","page域");
// 保存的数据只在一次请求中有效,请求转发会携带这个数据
request.setAttribute("name2","request域");
// 保存的数据只在一次会话中有效,从打开浏览器到关闭浏览器
session.setAttribute("name3","session域");
// 保存的数据在整个应用服务器中,从打开服务器到关闭服务器
application.setAttribute("name4","application域");
%>
<%--方式二set--%>
<%pageContext.setAttribute("var1","方式2:PAGE_SCOPE",PageContext.PAGE_SCOPE);%>
<%pageContext.setAttribute("var2","方式2:REQUEST_SCOPE",PageContext.REQUEST_SCOPE);%>
<%pageContext.setAttribute("var3","方式2:SESSION_SCOPE",PageContext.SESSION_SCOPE);%>
<%pageContext.setAttribute("var3","方式2:APPLICATION_SCOPE",PageContext.APPLICATION_SCOPE);%>
<%--故意设置个重复值 给page和application域--%>
<%--<%pageContext.setAttribute("var1","方式2:APPLICATION_SCOPE",PageContext.APPLICATION_SCOPE);%>--%>
<%
// 保存的数据只在一个页面中有效
Object name1 = pageContext.getAttribute("name1");
Object name2 = pageContext.getAttribute("name2");
Object name3 = pageContext.getAttribute("name3");
Object name4 = pageContext.getAttribute("name4");
%>
<hr/>
<h3>使用pageContext.getAttribute获取数据</h3>
<h3>默认只能获取page域的</h3>
<h4><%=name1%></h4>
<h4><%=name2%></h4>
<h4><%=name3%></h4>
<h4><%=name4%></h4>
<%
//从底层到高层(作用域),page=》request=》session=》application
Object name11 = pageContext.findAttribute("name1");
Object name22 = pageContext.findAttribute("name2");
Object name33 = pageContext.findAttribute("name3");
Object name44 = pageContext.findAttribute("name4");
%>
<hr/>
<h3>使用pageContext.findAttribute获取数据</h3>
<h4><%=name11%></h4>
<h4><%=name22%></h4>
<h4><%=name33%></h4>
<h4><%=name44%></h4>
<hr/>
<h3>使用EL表达式$获取,相当于findAttribute获取数据</h3>
<h4>${name1}</h4>
<h4>${name2}</h4>
<h4>${name3}</h4>
<h4>${name4}</h4>
<h4>${name5}</h4>
</body>
</html>
一个页面get域:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>get</title>
</head>
<body>
<%Object name3 = session.getAttribute("name3");%>
<h3>跨页面,用el表达式获取session域里变量name3(用session设置):<br>${name3}</h3>
<hr/>
<h3>跨页面,用el表达式获取SESSION_SCOPE和APPLICATION_SCOPE域里,都有的变量var3(用pagecontext设置):<br>${var3}</h3>
</body>
</html>
效果如下:
pageContext.jsp:

get.jsp:

场景二:一个页面转发另一个页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%pageContext.setAttribute("var1","方式2:PAGE_SCOPE",PageContext.PAGE_SCOPE);%>
<%pageContext.setAttribute("var2","方式2:REQUEST_SCOPE",PageContext.REQUEST_SCOPE);%>
<%pageContext.setAttribute("var3","方式2:SESSION_SCOPE",PageContext.SESSION_SCOPE);%>
<%pageContext.setAttribute("var4","方式2:APPLICATION_SCOPE",PageContext.APPLICATION_SCOPE);%>
<%pageContext.setAttribute("var3","方式2:APPLICATION_SCOPE",PageContext.APPLICATION_SCOPE);%>
<%pageContext.forward("/forward.jsp");
//相当于以前的下面方式
//request.getRequestDispatcher("/forward.jsp").forward(request,response);
%>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
page域:
${var1}
<hr>
request域:
${var2}
<hr>
session域:
${var3}
<hr>
application域:
${var4}
<hr>
</body>
</html>

2.11 EL表达式详解
- 获取数据
- 执行运算
- 获取web开发的常用对象
调用java方法
三、JavaBean
3.1 定义
实体类:
Javabean有特定的写法:
- 必须要有一个无参构造
- 属性必须私有化
- 必须要有对应get/set方法
作用:一般用来和数据库的字段做映射 ORM
- 表=》类
- 行记录=》对象(实例)
- 字段=》属性
3.2 JavaBean和数据库表的对应关系
people表:
| id | name | age | address |
|---|---|---|---|
| 1 | 高兴 | 30 | 香港 |
| 2 | 高兴2 | 25 | 成都 |
| 3 | 高兴3 | 18 | 北京 |
Class People{
private int id;
private String name;
private int age;
private String address;
}
浙公网安备 33010602011771号