JavaWeb-8-JSP

跟着狂神学JavaWeb --> 8. JSP

8.1 什么是JSP?
  • Java Server Pages : Java服务器端页面;
  • 和Servlet一样,也是用于动态Web技术;
  • 最大的特点:写JSP,就像再写HTML;
  • 与HTML的区别:
    • HTML只给用户提供静态数据;
    • JSP页面中可以嵌入Java代码,为用户提供动态数据。
8.2 JSP原理

思路:JSP到底是怎么运行的?

  • 代码层面没有任何问题:
    在这里插入图片描述

  • 服务器端

    • Tomcat服务器工作的目录:D:\Tomcat\apache-tomcat-10.0.4\work
      在这里插入图片描述

    • IDEA中使用Tomcat的会在IDEA的tomcat中生成一个work目录,位置:C:\Users\用户名\AppData\Local\JetBrains\IntelliJIdea2020.2\tomcat

在这里插入图片描述

  • C:\Users\用户名\AppData\Local\JetBrains\IntelliJIdea2020.2\tomcat\Unnamed_javaweb-session-cookie\work\Catalina\localhost\ROOT\org\apache\jsp

在这里插入图片描述

  • 发现页面转变成了java程序文件!

  • 浏览器向服务器发送请求,不管访问什么资源,其实都是在访问Servlet

  • JSP最终也会被转变为Java类

  • JSP本质上就是一个Servlet

在这里插入图片描述

在这里插入图片描述

  • 分析原理:
//初始化
public void _jspInit() {}
//销毁
public void _jspDestroy() {}
//JSPService 参数对象:request、response
public void _jspService(final jakarta.servlet.http.HttpServletRequest request, final jakarta.servlet.http.HttpServletResponse response)
      throws java.io.IOException, jakarta.servlet.ServletException {
    
	//1.判断请求
    if (!jakarta.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.内置对象
    final jakarta.servlet.jsp.PageContext pageContext; //页面上下文
    jakarta.servlet.http.HttpSession session = null; //session
    final jakarta.servlet.ServletContext application; //applicationContext
    final jakarta.servlet.ServletConfig config; //config 配置
    jakarta.servlet.jsp.JspWriter out = null; //out 输出对象
    final java.lang.Object page = this; //page当前页
    jakarta.servlet.jsp.JspWriter _jspx_out = null;
    jakarta.servlet.jsp.PageContext _jspx_page_context = null;

    try {
      //3.输出页面前的操作,这些对象可以在JSP页面中直接使用
      response.setContentType("text/html"); //设置响应的页面类型
      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;
	
      //4.输出页面
      out.write("<html>\n");
      out.write("<body>\n");
      out.write("<h2>Hello World!</h2>\n");
      out.write("</body>\n");
      out.write("</html>\n");
    } catch (java.lang.Throwable t) {
      if (!(t instanceof jakarta.servlet.jsp.SkipPageException)){
        out = _jspx_out;
        if (out != null && out.getBufferSize() != 0)
          try {
            if (response.isCommitted()) {
              out.flush();
            } else {
              out.clearBuffer();
            }
          } catch (java.io.IOException e) {}
        if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
        else throw new ServletException(t);
      }
    } finally {
      _jspxFactory.releasePageContext(_jspx_page_context);
    }
}
  • 原理流程:

在这里插入图片描述

  • 在JSP页面中,如果是Java代码,会原封不动的输出;如果是HTML代码,会被转化为out.write(“XXXX”)的格式输出到前端页面

  • 示例如下:

hello.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%--java代码需要写在<% %>中--%>
<%
    String name = "ano";
%>
name:<%=name%>
</body>
</html>

运行hello.jsp

在这里插入图片描述

查看服务器工作目录:

在这里插入图片描述

观察hello_jsp.java文件:

在这里插入图片描述

8.3 JSP基础语法
  • 支持所有Java语法
  • JSP表达式
<%--JSP表达式
作用:将程序的输出输出到客户端
<%=变量或者表达式>
--%>

<%=new Date()%>
  • JSP脚本片段
<%--JSP脚本片段--%>
<%
    int sum = 0;
    for (int i = 0; i <= 100; i++) {
        sum+=i;
    }
    out.println("<h1>Sum=" + sum + "</h1>");
%>
  • JSP脚本片段再实现
<%
    int x = 10;
    out.println(x);
%>
<p>这是一个jsp文件</p>
<%
    int y = 15;
    out.println(y);
%>

<hr>

<%--在java代码中嵌入HTML元素--%>
<%
    for (int i = 0; i < 5; i++) {
%>
    <h2>Hello,ano <%=i%></h2>
<%
    }
%>

<%--简化为EL表达式--%>
<% for (int i = 0; i < 5; i++) { %>
     <h2>Hello,ano ${i}</h2>   
<%    } %>

测试结果:

在这里插入图片描述

  • 分析:

在这里插入图片描述

  • 以上的示例JSP代码服务器将JSP页面编译为java文件时,这些代码都被写在了public void _jspService(HttpServletRequest request, response)方法中,如果想要写在外部呢?即JSP声明。如下:
  • JSP声明
<%--jsp声明--%>
<%!
    static {
        System.out.println("Loading Servlet...");
    }

    private int globalVar = 0;
    public void ano() {
        System.out.println("进入了ano方法!");
    }
%>
  • 分析:

在这里插入图片描述

  • Java声明会被编译到JSP生成的Java类中,其他的会被生成到该类的_jspService方法中。

  • JSP的注释不会出现在客户端,而HTML的会显示在客户端。

    <!--这是一行HTML注释-->
    

在这里插入图片描述

8.4 JSP指令
8.4.1 @page指令
<%@page args...... %>
  • 自定义错误页面的示例代码:

500.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h2>自定义500错误页面</h2>
<img src="../img/500.png" alt="500">
</body>
</html>

400.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h2>自定义404错误页面</h2>
<img src="${pageContext.request.contextPath}/img/404.png" alt="404">
</body>
</html>
  1. 第一种方式:
<%@page errorPage="error/500.jsp" %>

测试代码:

test.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<%--定制错误页面--%>
<%@page errorPage="error/500.jsp" %>

<html>
<head>
    <title>Title</title>
</head>
<body>
<%
    int x = 1/0;
%>
</body>
</html>

测试结果如下:

在这里插入图片描述

  1. 第二种方式:在web.xml中配置如下:
<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>

测试结果:

在这里插入图片描述

8.4.2 @include指令
<%@include file="" %>
  • 给网页添加头部和底部的示例代码:

header.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<h3>This is Header</h3>

footer.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<h3>This is Footer</h3>

测试代码如test2.jsp,有两种方式:

  1. 使用@include指令
  2. 使用jsp:include标签
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

<%@include file="common/header.jsp"%>
<h2>网页主体</h2>
<%@include file="common/footer.jsp"%>


<hr>

<%--jsp标签--%>
<jsp:include page="/common/header.jsp"/>
<h2>网页主体2</h2>
<jsp:include page="/common/footer.jsp"/>
</body>
</html>

测试结果:

在这里插入图片描述

  • 两种方式的区别如下:
    • @include指令的方式本质是合并页面为一个
    • jsp:include标签的方式本质是拼接页面

在这里插入图片描述

8.5 JSP的9大内置对象及作用域
8.5.1 内置对象
  • pageContext:存东西
  • request:存东西
  • response
  • session:存东西
  • application: ServletContext,存东西
  • config: ServletConfig
  • out: JspWriter
  • page: 几乎不用
  • exception
8.5.2 作用域
pageContext.setAttribute("name1","ano1"); //保存的数据只在一个页面有效
request.setAttribute("name2","ano2"); //保存的数据旨在一次请求中有效,请求转发会携带这个数据
session.setAttribute("name3","ano3"); //保存的数据在一次会话中有效,即从打开浏览器到关闭浏览器
application.setAttribute("name4","ano4"); //保存的数据旨在服务器中有效,即从打开服务器到关闭服务器
  • 示意图理解:

在这里插入图片描述

  • request:客户端向服务器发送请求,产生的数据,用户看完就没有用了,比如:新闻;
  • session: 客户端向服务器发送请求,产生的数据,用户看完后,一会还有用,比如:购物车;
  • application: 客户端向服务器发送请求,产生的数据,一个用户看完后,其他用户还可能使用,比如:聊天数据。

pageContextDemo01.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%--内置对象--%>
<%
    pageContext.setAttribute("name1","ano1"); //保存的数据只在一个页面有效
    request.setAttribute("name2","ano2"); //保存的数据旨在一次请求中有效,请求转发会携带这个数据
    session.setAttribute("name3","ano3"); //保存的数据在一次会话中有效,即从打开浏览器到关闭浏览器
    application.setAttribute("name4","ano4"); //保存的数据旨在服务器中有效,即从打开服务器到关闭服务器
%>

<%
    //从内置对象pageContext取出
    //通过get方式只能自己去自己的值
//    String name1 = (String)pageContext.getAttribute("name1");
    //从内置对象pageContext取出,通过寻找的方式取值
    //原理:从底层到高层(作用域):pageContext -> request -> session -> application
    //JVM:双亲委派机制
    String name1 = (String)pageContext.findAttribute("name1");  //ano1
    String name2 = (String)pageContext.findAttribute("name2");  //ano2
    String name3 = (String)pageContext.findAttribute("name3");  //ano3
    String name4 = (String)pageContext.findAttribute("name4");  //ano4

    pageContext.forward("/pageDemo02.jsp");

%>
<%--使用EL表达式输出${}--%>
<h2>取出的值为:</h2>
<h3>${name1}</h3>
<h3>${name2}</h3>
<h3>${name3}</h3>
<h3>${name4}</h3>

</body>
</html>

pageDemo02.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%
    String name1 = (String)pageContext.findAttribute("name1");
    String name2 = (String)pageContext.findAttribute("name2");
    String name3 = (String)pageContext.findAttribute("name3");
    String name4 = (String)pageContext.findAttribute("name4");
%>
<%--使用EL表达式输出${}--%>
<h2>取出的值为:</h2>
<h3>${name1}</h3>
<h3>${name2}</h3>
<h3>${name3}</h3>
<h3>${name4}</h3>
</body>
</html>
  • 测试结果(注意对比观察):

在这里插入图片描述

8.6 EL表达式、 JSP标签、JSTL标签
8.6.1 EL表达式
<!--JSTL表达式的依赖-->
<dependency>
  <groupId>javax.servlet.jsp.jstl</groupId>
  <artifactId>jstl-api</artifactId>
  <version>1.2</version>
</dependency>
<!--standard标签库-->
<dependency>
  <groupId>taglibs</groupId>
  <artifactId>standard</artifactId>
  <version>1.1.2</version>
</dependency>
  • ${}
  • 获取数据
  • 执行运输
  • 获取web开发的常用对象
8.6.2 JSP标签

jsptag.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

<h1>1</h1>
<%--<jsp:include page=""--%>


<%--
http://localhost:8080/jsptag.jsp?name=trouble&age=26
--%>
<jsp:forward page="/jsptag2.jsp">
    <jsp:param name="name" value="trouble"/>
    <jsp:param name="age" value="26"/>
</jsp:forward>

</body>
</html>

jsptag2.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>2</h1>

<%--取出参数--%>
Name: <%=request.getParameter("name")%>
Age: <%=request.getParameter("age")%>

</body>
</html>

测试结果:

在这里插入图片描述

8.6.3 JSTL标签
  • JSTL标签库的使用就是为了弥补HTML标签的不足;

  • 它定义了许多标签,可以供我们使用,标签的功能和Java代码一样。

  • 查看教程

  • 包括核心标签、格式化标签、SQL标签、XML标签

  • 引入核心标签库的语法:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
  • 掌握核心标签的部分即可:

在这里插入图片描述

  • JSTL标签使用步骤如下:
    • 引入对应的taglib;
    • 使用其中的方法。
    • 注意:使用Tomcat 10会报错org.apache.taglibs.standard.tlv.JstlCoreTLV cannot be cast to jakarta.servlet.jsp.tagext.TagLibraryV,解决方案:换成Tomcat 9即可

coreif.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--引入JSPL核心标签库--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

<h4>if测试</h4>

<form action="coreif.jsp" method="get">
    <%--
    EL表达式获取表单中的数据
    ${param.参数名}
    --%>
    <input type="text" name="username" value="${param.username}">
    <input type="submit" value="登录">
</form>


<%--判断如果提交的用户名是管理员,也登录成功--%>
<c:if test="${param.username=='admin'}" var="isAdmin">
    <c:out value="管理员,欢迎您"></c:out>
</c:if>
<c:out value="${isAdmin}"></c:out>
</body>
</html>

测试结果:

在这里插入图片描述在这里插入图片描述

corewhen.jsp

<%@ 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>

<%--定义一个变量为score,该变量的值为88--%>
<c:set var="score" value="88"></c:set>
<c:choose>
    <c:when test="${score>=90}">
        你的成绩为优秀
    </c:when>
    <c:when test="${score>=80}">
        你的成绩为良好
    </c:when>
    <c:when test="${score>=70}">
        你的成绩为一般
    </c:when>
    <c:when test="${score<60}">
        你的成绩为不及格
    </c:when>
</c:choose>
</body>
</html>

测试结果:

在这里插入图片描述

coreforeach.jsp

<%@ 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>

<%
    ArrayList<String> people = new ArrayList<>();
    people.add(0,"zhangsan");
    people.add(1,"lisi");
    people.add(2,"wangwu");
    people.add(3,"zhaoliu");
    people.add(4,"tianqi");
    request.setAttribute("list",people);
%>

<%--
var:每一次遍历出来的变量
items:要遍历的对象
begin:开始位置
end:结束位置
step:步长
--%>
    
<c:forEach var="person" items="${list}">
    <c:out value="${person}"></c:out><br>
</c:forEach>

<hr>

<c:forEach var="person" items="${list}" begin="1" end="4" step="2">
    <c:out value="${person}"></c:out><br>
</c:forEach>

</body>
</html>

测试结果:

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值