JSP概述

掌握了servlet后,就可以利用servlet来开发动态页面了,但是使用Servlet开发动态页面,存在种种问题,来看下面的例子:

使用Servlet来开发百度首页:

分析上面的案例不难发现以下问题:

Html与Java代码混合在一起,维护困难
每一行都是一个println语句,效率低下
编译器无法检测问题,调试麻烦

JSP概念

全称JavaServerPage服务器页面,为了使开发动态页面更加简单而出现,本质上也是一个Servlet

动态与静态

一个页面如果不会随着任何条件(时间,用户信息...)改变而发生变化,那它就是静态的,静态页面通常只能提供最基本的信息展示

动态页面是会随着访问时的时间,地点,提交的数据不同而展示不同的内容,它就是动态页面,例如可以根据登录用户的不同而展示的不同的购物信息,通常页面的数据来自于数据库

特点:

  • JSP可将原本都在Servlet中的java代码与HTML分离,降低耦合,可维护性好

  • 可编写原生HTML,且编译器会进行语法检查,开发效率更高

  • JSP本质就是Servlet,被执行前会被先转译为java文件

  • 注意:JSP文件需放在web(webContent)资源目录下,后缀为.jsp

jsp执行过程

示例:

转译后的java文件解析

找到转译后的java文件

打开该文件

可以看到其原理与servlet完全相同,利用printWriter来向前台返回响应数据

JSP语法

表达式

语法格式<%=表达式%>

作用:通过表达式可以输出表达式的结果值。其本质就是执行了print语句;

示例:

注意:表达式中不能有分号,只能是一行

代码块

语法格式<%代码内容%>

作用:编写任何Java代码,通常是用来输出产生HTML文本内容的,这是与普通HTML最大的区别,有了代码块你可以很轻松的实现动态页面

示例:

声明块

语法格式<%!代码内容%>

作用:在JSP中声明方法和变量

示例:

注释

语法:

<%-- jsp注释 --%> 	 页面不可见
<!-- html注释 --> 页面可见
// /**/ 代码块内java注释 转译jsp时会放到java文件中

指令

编译指令

编译指令,用于处理当前jsp全局配置,例如导入Java类,使用标签库,或内容编码等,由Servlet引擎处理,在JSP转译Servlet时生效

通常位于JSP文件开始的地方,这样可以保证要使用的资源已经被导入

指令名 作用
include 静态引入其他JSP页面
taglib 导入标签库,设置标签前缀等
page 导入Java类,设置响应编码等

语法:<%@ page 属性名称="属性值">

示例:<%@ page import="java.util.HashMap" %>

动作指令

动作指令通常可以被JSP脚本替代,是对JSP脚本的HTML标准化写法

指令名 作用
jsp:forward 执行页面转向,将请求的处理转发到下一个页面/servlet。
jsp:param 用于传递参数,必须与其他支持参数的标签一起使用。
jsp:include 用于动态引入一个JSP页面。
jsp:plugin 用于下载JavaBean或Applet到客户端执行。
jsp:useBean 创建一个JavaBean实例。
jsp:setProperty 设置JavaBean实例的属性值。
jsp:getProperty 输出JavaBean实例的属性值。

语法:<jsp:动作名称 名称="值">

示例<jsp:forward page="/FirstServlet"></jsp:forward>

JSP语法汇总

Cookie

由于HTTP协议状态无连接的特性,造成了用户状态无法维持的问题,客户端前脚刚刚登陆成功,后脚就要重新登陆,毫无体验,为了解决这个问题,出现了Cookie,以及后来的session

  • Cookie是服务器保存在浏览器的一小段文本数据(4k内),通常与用户个人信息有关
  • cookie数据以键值对形式存在
  • 用于在HTTP协议下维持客户端与服务器的状态
  • cookie具有时效性,在有效期内
  • 每次请求相同的服务器(域名相同,路径相同)时,浏览器都会自动将cookie放入请求头一起发送给服务器

图解:

Cookie相关方法

方法名称 作用
Cookie(key,value) cookie的构造函数。
setMaxAge() 设置cookie的最大存活时间。
getValue(key) 获取对应key的cookie值。
setValue(key,newValue) 修改对应key的cookie的值。
response.addCookie(cookie) 往响应中添加对应key的cookie对象。

利用Cookie来实现7天免登陆

用于处理登录请求的LoginServlet:

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException; @WebServlet(name = "LoginServlet",urlPatterns = "/LoginServlet")
public class LoginServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//登录判断逻辑 (实际开发中从请求中获取参数匹配数据库)
System.out.println("login success");
//创建Cookie对象
Cookie c = new Cookie("user","admin");
//设置cookie有效期
c.setMaxAge(60*60*24*7);
//添加cookie到响应中
response.addCookie(c);
}
}

用于作为用户主页的IndexServlet

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException; @WebServlet(name = "IndexServlet",urlPatterns = "/IndexServlet")
public class IndexServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取请求中所有cookie
Cookie[] cs = request.getCookies();
//判断是否有cookie
if(cs!=null){
String name = null;
//遍历所有cookie
for (Cookie c: cs) {
//找到用户名称
if(c.getName().equals("user")){
name =c.getValue();
}
}
//在页面输出已经登录过的用户名称
response.setContentType("text/html;charset=utf-8");
if(name != null){
response.getWriter().println("user:" + name);
}
}
}
}

在浏览器中先访问LoginServlet,重新启动浏览器,访问IndexServlet可以看到之前登录的用户信息

注意:

如果没有设置最大有效期,cookie则是临时的浏览器进程关闭就消失了

Cookie解决了客户端与服务器需要维持状态的问题,但也带来了新的问题

  • cookie是存储在客户端的磁盘上的,虽然经过加密,但是也有被破解和盗用的风险
  • 每次请求都需要附带cookie,cookie数据较多时造成较大的网络开销

就像你把现金放在家里每次买东西都必须带着现金去一样

为了解决上面的问题,而出现了session

Session

Session(会话),字面上理解,它是一个抽象的概念,描述浏览器和服务器在一段时间内的所有交互动作

本质上:

  • session用于保存与浏览器进程对应的数据

  • 数据存储在服务器内存中,具有时效性,默认为30分钟,可通过代码或web.xml修改

  • 服务器从Cookie中获取sessionID来找到对应的session对象,从而实现维持用户的状态

  • session在服务器是一个Java对象,可以添加任何类型的属性到其中

  • 当session在一段时间内没有被访问时将被销毁

图解:

注意:如果请求的是JSP将自动创建session对象

session常用方法

方法名称 作用
session.setAttribute(key,value); 为session增加额外的属性,用于传值
session.getAttribute(key); 从session中取出指定的属性
request.getSession(boolean); 获取当前session对象,如果没有是否创建新的
session.getId(); 获取ID
session.setMaxInactiveInterval(); 设置最大超时时间单位为秒
session.getMaxInactiveInterval(); 获取最大超时时间
session.getCreationTime(); 获取创建时间
session.getLastAccessedTime(); 获取当前会话最后一次请求时间
session.invalidate(); 使session立即失效

利用session来实现登录状态同步

处理登录请求的LoginServlet:

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException; @WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//登陆了验证逻辑
System.out.println("login success!");
//获取session并 添加用户信息到session中
req.getSession().setAttribute("user","张三");
}
}

用于显示用户主页的IndexServlet:

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException; @WebServlet("/IndexServlet")
public class IndexServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取session
HttpSession session = req.getSession();
//取出用户信息
String name = (String) session.getAttribute("user");
//设置响应编码并输出用户名称
resp.setContentType("text/html;charset=utf-8");
if(name != null){
resp.getWriter().println("user is :"+name);
}else{
resp.getWriter().println("user not login!");
}
}
}

登录成功后进入IndexServlet可以看到用户信息

但是重启浏览器时用户信息就没有了

注意:

浏览器进程结束时sessionID就消失了,但这并不意味着服务器对应的session对象立即会销毁,如果没有调用session.invalidate方法session将达到超时时间后才会销毁,这意味着大量的session将导致资源耗尽

web.xml配置超时时间:

JSP内置对象

JSP本质还是Servlet,只是对其进行了简化封装,为了方便在JSP中进行操作,JSP提供了经常需要使用到的对象

本质:

打开一个转移后的java文件,找到79行左右可以看到一个非常熟悉的方法_jspService,尽管前面多了__jsp

上图中圈出了9个JSP的内置对象,大多数都是在Servlet中见过的,除了下面的

  • page,是当前jsp对象实例的this引用

  • pageContext,页面上下文,页面的的内置对象都来自于该对象,它是JSP对象操作web资源对象的中转站(jsp本身并不是Servlet)

  • exception对象仅在错误页面中可用,即用于展示错误信息的页面

错误页面

当服务器处理过程产生异常或是,请求不正确是,tomcat会显示自带的最基础的错误页面,通常需要进行定制

1.编写错误页面,利用page指令,将这个jsp设置为错误页面

2.在web.xml中配置错误页面,指定要处理的状态码和对应的页面

3.也可以针对某个特殊异常作处理,优先匹配异常类,然后匹配状态码

4.在某个servlet中模拟异常

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
throw new ArrayIndexOutOfBoundsException("索引越界了!");
}

页面内容:

注意:

400+的错误页面无法使用jsp来完成,因为400+错误通常都是HTTP协议问题,请求是不正确的,服务器不会产生任何相关的对象

JSP中的四个作用域

作用域值得就是有效范围,在概念上与大家知道的局部作用域,全局作用域一个意思,

但是这里不是自定义的作用域,而是jsp已经提供了的作用域

四个作用域:

名称 描述
page PageContext页面上下文,在当前页面有效
request 对同一个请求有效,(请求转发是同一个,重定向是新的)
session 当前会话有效
application ServletContext,当前web应用程序全局有效

用来做什么?

在不同servlet或jsp中切换传参,是非常常见的操作,而要传参就必须借助上述4个对象

学习作用域的目的是为了合理的选择最合适的对象来存储数据,从而节省服务器资源开销

作用域范围图解

老司机经验:能用小的就别用大的

EL表达式

使用代码块可以利用java代码,来操作对象的属性,展示数据等,但是对于简单频繁的数据展示操作,使用代码块或者表达式都会导致html整体结构变得混乱,

那动作指令呢?,虽然语法近似html标签,但还是不够简洁,于是便有了EL表达式

EL概念

EL(Expression Language) 是为了使JSP写起来更加简单。它提供了在 JSP 中简化表达式的方法,让Jsp的代码更加简化。

简单的说,EL就是要在不影响页面结构的情况下没用简洁的语法来对作用域中的数据进行存取,并提供了完善的运算符支持,

基本语法:

${对象名称.属性}					获取对象属性
${对象名称.方法(参数)} 调用对象方法
${参数1 表达式 参数2} 使用运算符

EL包含的内容:

作用域访问

自动投影,EL会从4个作用域找自动查找匹配的属性名称,从小到大查找

//测试代码
${requestScope.user="jerry2"}
${applicationScope.user="jerry4"}
${pageScope.user="jerry1"}
${sessionScope.user="jerry3"} <h1>${user}</h1>

运算符

https://tva1.sinaimg.cn/large/006tNbRwgy1g9tz7scwisj30p606r752.jpg

隐式对象

https://tva1.sinaimg.cn/large/006tNbRwgy1g9tz8lnbslj30qh0gkwik.jpg

注意:在使用EL存取对象属性时必须保证对象提供了相应的get/set方法

示例:

JSTL

有了EL我们可极大的减少在页面中插入java代码块的情况,但是EL是表达式,这意味着其无法提供流程控制能力,即(分支,循环)

于是在广大程序员的吐槽中,JAVAEE又推出了JSTL标准

概述:

JSTL(JSP Standard Tag Library,JSP标准标签库)是一个不断完善的开放源代码的JSP标签库,是由apache的jakarta小组来维护的。其使命是使用标签来替换JAVA的流程控制,最终实现JSP中完全或尽量不包含JAVA代码

注意:如果要使用JSTL,则必须将jstl.jar和 standard.jar文件放到classpath中。

下载地址:

http://archive.apache.org/dist/jakarta/taglibs/standard/binaries/

IDEA下配置步骤:

博客链接

使用案例:

<%--
Created by IntelliJ IDEA.
User: jerry
Date: 2019/12/12
Time: 4:12 下午
To change this template use File | Settings | File Templates.
--%>
<%@ 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> <%--输出1-10之间的偶数
st表示循环状态 可获取当前循环的索引等信息
var 表示每次遍历的临时变量
--%>
<c:forEach begin="1" end="10" varStatus="st" var="num">
<c:if test="${st.index % 2 ==0}">
<h1>${num}是偶数啊</h1>
</c:if>
</c:forEach> <%--重定向--%>
<%--<c:redirect url="404.html"></c:redirect>--%> <%--输出--%>
<c:out value="hello world"></c:out> <%--添加属性到某个scope--%>
<c:set scope="request" var="number" value="a"></c:set> <%--选择结构--%>
<c:choose >
<c:when test="${number=='as'}">
<c:out value="你选择a了"/>
</c:when>
<c:when test="${number=='b'}">
<c:out value="你选择b了"/>
</c:when>
<c:otherwise>
<c:out value="不是a和b"/>
</c:otherwise>
</c:choose> </body>
</html>

以后就用JSP做动态页面吗?NO

看看动态页面的技术发展吧

JSP + Session Cookie详解的更多相关文章

  1. 【转】Cookie/Session机制详解

    Cookie/Session机制详解   会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话.常用的会话跟踪技术是Cookie与Session.Cookie通过在客户端记录信息 ...

  2. Session和Cookie详解(1)

    面试常问的有关session和cookie的问题: 1.session在分布式环境下怎么解决 2.集群下如何保证session踩中 3.cookie的大小 4.服务器怎么识别一个用户的 5.sessi ...

  3. session及cookie详解(七)

    前言 文章说明 在每整理一个技术点的时候,都要清楚,为什么去记录它.是为了工作上项目的需要?还是为了搭建技术基石,为学习更高深的技术做铺垫? 让每一篇文章都不是泛泛而谈,复制粘贴,都有它对自己技术提升 ...

  4. cookie session token详解

    cookie session token详解 转自:http://www.cnblogs.com/moyand/ 发展史 1.很久很久以前,Web 基本上就是文档的浏览而已, 既然是浏览,作为服务器, ...

  5. Chrome的cookie放在哪里了,Cookie/Session机制详解

    Chrome的cookie放在哪里了,Cookie/Session机制详解:https://blog.csdn.net/u010002184/article/details/82082951

  6. Cookie的使用、Cookie详解、HTTP cookies 详解、获取cookie的方法、客户端获取Cookie、深入解析cookie

    Cookie是指某些网站为了辨别用户身份.进行session跟踪而存储在用户本地终端上的数据(通常经过加密),比如说有些网站需要登录才能访问某个页面,在登录之前,你想抓取某个页面内容是不允许的.那么我 ...

  7. Hibernate Session & Transaction详解

    Hibernate Session & Transaction详解 HIbernate中的Session Session是JAVA应用程序和Hibernate进行交互时使用的主要接口,它也是持 ...

  8. 网络基础 cookie详解

    cookie详解 by:授客 QQ:1033553122 cookie干嘛用的? 参见文章http 会话(session)详解: 网络基础 http 会话(session)详解   cookie分类 ...

  9. cookie详解(含vue-cookie)

    今天看到一篇cookie的文章,写的特别详细,感谢 晚晴幽草轩 的分享,原文链接http://mp.weixin.qq.com/s/NXrH7R8y2Dqxs9Ekm0u33w 原文如下,记录到此供以 ...

随机推荐

  1. CHRONY 时间服务器

    时间同步服务chrony ntp network time Protocol之前使用的同步协议 chrony ntp协议的实现,兼容网络中的ntp服务(centos7之后就不再使用ntp,转而使用ch ...

  2. 1011课堂小结 day21

    组合 什么是组合 组合指的是一个对象中的属性,是另一个对象. 为什么要使用组合 为了减少代码冗余 封装 什么是封装 封装指的是把一堆属性(特征与技能)封装到一个对象中 为什么要封装 封装的目的为了方便 ...

  3. jquery写$ document.getElementById效果

    jquery写$ document.getElementById效果<pre>document.getElementById('video-canvas')和$('#video-canva ...

  4. 利用Python获取统计自己的qq群成员信息

    利用python获取自己的qq群成员信息! 首先说明一下需要使用的工具以及技术:python3 + selenium selenium安装方法:pip install selenium 前提:获取自己 ...

  5. 【Swift】UNNotificationServiceExtension

    一.简介 An object that modifies the content of a remote notification before it's delivered to the user. ...

  6. sql性能分析(explain关键字)

    explain关键字结果 列名所代表的的含义: Id:MySQL QueryOptimizer 选定的执行计划中查询的序列号.表示查询中执行 select 子句或操作表的顺序,id 值越大优先级越高, ...

  7. Laravel框架安装RabbitMQ消息中间件步骤

    Laravel5.6 整合 RabbitMQ 消息队列 简介: Laravel 队列为不同的后台队列服务提供了统一的 API,例如 Beanstalk,Amazon SQS,Redis,甚至其他基于关 ...

  8. 领扣(LeetCode)二叉树的中序遍历 个人题解

    给定一个二叉树,返回它的中序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,3,2] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 递归的思路很简单,不再累 ...

  9. HashMap的源码学习以及性能分析

    HashMap的源码学习以及性能分析 一).Map接口的实现类 HashTable.HashMap.LinkedHashMap.TreeMap 二).HashMap和HashTable的区别 1).H ...

  10. 消除router-link 的下划线问题

    <div class="small-size"> <router-link to="/About"> <img src=" ...