Servlet/JSP学习笔记(二)(JSP入门,JSP动作和标签,JSTL库,EL表达式)

概述

如果单独使用Servlet生成HTML页面是可以的,但是这个过程实在是太痛苦,因为所有HTML代码都没有任何提示功能,中间如果出现错误也无法查看,需要自己慢慢查找,所以出现了一门技术模版引擎
在这里插入图片描述

JSP算是一种模版引擎,其它的还有:Freemarker、Thymleaf等等

JSP 入门

Java Server Page Java:服务端页面,
本质就是Servlet,
优点:HTML代码和Java代码混合书写

<%@ page import="java.util.Random" %><%--
  Created by IntelliJ IDEA.
  User: Administrator
  Date: 2021/6/20
  Time: 11:40
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>JSP01</title>
    </head>
    <body>
        JSP本质:</br>
        <%
            //书写java语言,不能定义类
            double rand = new Random().nextInt(1000);
            out.write("<h3>"+rand+"</h3>");//类似于PrintWrite功能,不太推荐
        %>
        <hr>
        <!--混合书写-->
        <h3 style="color: plum;font-size: 32px"><%=rand%></h3>
    </body>
</html>

在这里插入图片描述

Tomcat中的work文件夹存储的JSP的临时文件,C:\Users\Administrator\.IntelliJIdea2019.3\system\tomcat目录,

JSP被翻译成了Java文件,该文件继承了org.apache.jasper.runtime.HttpJspBase又继承HttpServlet,所以我们说JSP就是一个Servlet

package org.apache.jsp;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import java.util.Random;

public final class demo01_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent,
                 org.apache.jasper.runtime.JspSourceImports {
	/* WEB容器翻译JSP的时候帮骂我已经创建好的内置对象的名称,固定,request和response的变量名称HttpJspBase声明*/
    final javax.servlet.jsp.PageContext pageContext;
    javax.servlet.http.HttpSession session = null;
    final javax.servlet.ServletContext application;
    final javax.servlet.ServletConfig config;
    javax.servlet.jsp.JspWriter out = null;
    final java.lang.Object page = this;
    javax.servlet.jsp.JspWriter _jspx_out = null;
    javax.servlet.jsp.PageContext _jspx_page_context = null;


    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;

      out.write("\r\n");
      out.write("\r\n");
      out.write("<html>\r\n");
      out.write("    <head>\r\n");
      out.write("        <base href=\"");
      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("/\">\r\n");
      out.write("        <title>JSP的本质</title>\r\n");
      out.write("    </head>\r\n");
      out.write("    <body>\r\n");
      out.write("        JSP的本质:<br/>\r\n");
      out.write("        ");

        //书写是Java语句,不能定义类<%%>
        double rand = new Random().nextInt(1000);
        out.write("<h3>"+rand+"</h3>");//类似于PrintWrite功能,不太推荐
        
      out.write("\r\n");
      out.write("        <hr/>\r\n");
      out.write("        <!-- 混合书写 -->\r\n");
        //<%=%>
      out.write("        <h3 style=\"color:blue\">");
      out.print(rand);
      out.write("</h3>\r\n");
      out.write("    </body>\r\n");
      out.write("</html>\r\n");

  }
}

实际开发中,如何使用Servlet和JSP?

  • Servlet做控制使用(获取数据-客户端数据或者服务端数据)
  • JSP做显示使用(获得Servlet给我们的数据,我来只是做显示使用)

一.JSP工作原理(内置九个对象)

在这里插入图片描述

访问JSP的时候,JSP会给我们提供哪些对象?九个内置对象
final javax.servlet.jsp.PageContext pageContext;
javax.servlet.http.HttpSession session = null;
final javax.servlet.ServletContext application;
final javax.servlet.ServletConfig config;
javax.servlet.jsp.JspWriter out = null;
final java.lang.Object page = this;
javax.servlet.jsp.JspWriter _jspx_out = null;
javax.servlet.jsp.PageContext _jspx_page_context = null;
//父类中
HttpServletRequest request;
httpServletResponse response;

有存储功能:4个对象(Web域对象)

<%@ page import="java.util.Random" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <base href="${pageContext.request.contextPath}/">
        <title>JSP的九个内置对象</title>
    </head>
    <body>
      <%-- 有存储功能对象HttpServletRequest/HttpSession/ServletContext --%>
      <%
          application.setAttribute("bookName","application三国演义");//在当前应用的范围有效
          session.setAttribute("bookName","session水浒传");//在当前会话范围有效
          request.setAttribute("bookName","request红楼梦");//在一次请求转发范围有效
          pageContext.setAttribute("bookName","pageContext西游记");//只能在当前页面中有效

      %>
        <hr/>
            <h3><%=pageContext.getAttribute("bookName")%></h3>
            <h3><%=request.getAttribute("bookName")%></h3>
            <h3><%=session.getAttribute("bookName")%></h3>
            <h3><%=application.getAttribute("bookName")%></h3>

        <hr/>
    </body>
</html>

  • response:HttpServletResponse
  • out : 输出对象
  • config :读取配置信息web.xml中
  • page : 当前页面的信息
  • exception : 异常处理对象

二.服务端和客户端路径跳转设置

JSP就是Servlet,只是默认使用自动映射为自己文件名称(包含文件夹),JSP跳转JSP的时候路径的设置

1.个人不推荐使用相对路径

    <a href="result02.jsp">同级别访问</a><br/>
    <a href="../demo04.jsp">如果访问不同层,使用..进行控制</a><br/>
    <a href="../WEB-INF/view.jsp">WEB-INF无法直接访问,必须使用请求转发才能访问</a><br/>
    <hr/>

2./:最前面设置/代表从端口号位置开始访问

    <!-- http://127.0.0.1:8001/result02.jsp 不可以访问:缺少发布的路径 -->
    <a href="/result02.jsp">发布路径,无法访问</a><br/>
    <hr/>

3.推荐方式:从项目根目录开始查找★★

    <a href="/yf06/view/result02.jsp">从发布路径根上开始查找</a><br/>
    <a href="/yf06/demo04.jsp">从发布路径根上开始查找</a><br/>
    <hr/>
    <h3>获取发布的路径:<%=request.getContextPath()%></h3>
    <a href="<%=request.getContextPath()%>/view/result02.jsp">从发布路径根上开始查找</a><br/>
    <a href="<%=request.getContextPath()%>/demo04.jsp">从发布路径根上开始查找</a><br/>

4.获取发布的路径:<%=request.getContextPath()%>配合base标签设置</

    <h3>获取发布的路径:<%=request.getContextPath()%>配合base标签设置</h3>
    <a href="view/result02.jsp">base标签,所有的访问的路径,都会自动追加base里面的值</a><br/>
    <a href="demo04.jsp">设置路径不是以/开头</a><br/>

请求转发和重定向的标准写法

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    result03.jsp<br/>
    <!-- request请求转换和response重定向的标准写法,Servlet-->
    <%
        //请求转换中使用/开头,代表就是发布的路径
        //请求转发可以访问WEB-INF中的资源
        request.getRequestDispatcher("/WEB-INF/view.jsp").forward(request,response);

        //重定向无法访问WEB-INF中的资源,重定向的标准写法如下 request.getContextPath() 发布路径
        response.sendRedirect(request.getContextPath()+"/demo04.jsp");
    %>
</body>
</html>

请求转发可以访问WEB-INF中的资源

三.JSP动作和标签

关于JSP的动作:<%@ page 页面相关属性的设置%> <%@ include 引入资源页面%> <%@ taglib 引入标签资源%>

关于JSP的标签:当设置了JSP标签之后,在进行翻译的时候,会自动转换成响应Java代码,标签化更加符合模版。

A. 静态包含

先包含后运行,执行一次,如果涉及到Java代码,需要注意定义的变量重复问题

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>Title</title>
    </head>
    <body>
        <h3>test01.jsp,我们静态包含需要使用相对路径或者绝对路径</h3>
        <%
            int x = 888;
        %>
        <%@include file="/view/result02.jsp"%>
    </body>
</html>
result02.jsp代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
        <head>
            <title>Title</title>
        </head>
        <body>
            <%
               int x = 999;
            %>
			 result02.jsp<br/>
		</body>
</html>        

注意:不能重复定义相同变量,否则jsp翻译时候会重复出错

B. 动态包含​

先运行后包含,执行多次。一般不会出现变量重复定义问题

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>Title</title>
    </head>
    <body>
        <h3>test01.jsp,我们静态包含需要使用相对路径或者绝对路径</h3>
        <%
            int x = 888;
        %>
        <!-- 翻译这个标签的时候,会执行预先设置好的代码 -->
        <!-- 将result02.jsp的运行结果包含进来 -->
        <jsp:include page="/view/result02.jsp"></jsp:include>
    </body>
</html>

四.EL表达式${}

在实际开发过程中,如果公司当中使用了JSP的这种方式,一般情况下不会使用<%=%>这种输出数据的方式,会使用专门替换,使用Expression Language表达式

作用:

  • 获取数据:WEB域的数据pageContext/request/session/application
  • 执行运算:
  • 调用Java方法
  • 运算符:.或者[]

演示:
A_servlet代码:

package com.os.servlet;

import com.os.model.Student;

import javax.servlet.ServletContext;
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;
import java.util.ArrayList;
import java.util.List;

@WebServlet("/data01")
public class WEB域传递数据 extends HttpServlet {
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("演示EL表达式:默认查找规则");
		request.setAttribute("bookName","HttpServletRequest-西游记");
		HttpSession session = request.getSession();
		session.setAttribute("bookName","HttpSession-红楼梦");
		ServletContext application = request.getServletContext();
		application.setAttribute("bookName","ServletContext-三国演义");

		System.out.println("演示EL表达式:演示单个对象如何获取数据");
		Student student = new Student();
		student.setStudentId(100);
		student.setStudentName("悟空");
		student.setSex("1");
		student.setAge(100);

		request.setAttribute("student",student);

		System.out.println("演示EL表达式:演示多个对象如何获取数据");
		List<Student> studentList = new ArrayList<>();
		Student s1 = new Student();
		s1.setStudentId(666);
		s1.setStudentName("林黛玉");
		s1.setSex("2");
		s1.setAge(18);
		studentList.add(s1);

		s1 = new Student();
		s1.setStudentId(777);
		s1.setStudentName("贾宝玉");
		s1.setSex("1");
		s1.setAge(18);
		studentList.add(s1);

		request.setAttribute("studentList",studentList);
		//请求转发的标准写法
		request.getRequestDispatcher("/WEB-INF/el01.jsp").forward(request,response);

	}
}

B_jsp代码

获取web域的数据,演示的默认规则

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>Title</title>
    </head>
    <body>
        <%
            pageContext.setAttribute("bookName","PageContext-三国演义");
        %>
        <!--
         EL表达式获取WEB域中的KEY是相同的时候,默认的操作规则如下
         pageContext>HttpServletRequest>HttpSession>ServletContext
         找到对应的KEY,立即返回后续就不再查找!
         -->
        <h3>
            演示默认获取数据的规则:${bookName}
        </h3>
        <hr>
          <!--
       request.getParameter("name") 等价于 param.name 或者param["name"]
       request.getParameterValues("name") 等价于 paramValues.name
       -->
        <h2>EL表达式,提供内置11个对象,关于web域对象如下:</h2>
        <h3>${pageScope.bookName}</h3>
        <h3>${requestScope.bookName}</h3>
        <h3>${sessionScope["bookName"]}</h3>
        <h3>${applicationScope['bookName']}</h3>
        <hr>
        <h2>传统方式,直接内置对象获取对应的数据</h2>
        <h3><%=pageContext.getAttribute("bookName")%></h3>
        <h3><%=request.getAttribute("bookName")%></h3>
        <h3><%=session.getAttribute("bookName")%></h3>
        <h3><%=application.getAttribute("bookName")%></h3>

    </body>
</html>

在这里插入图片描述

  • 运算符的介绍
    EL表达式11个隐式对象:
    在这里插入图片描述
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>Title</title>
    </head>
    <body>
       <!--
       request.getParameter("name") 等价于 param.name 或者param["name"]
       request.getParameterValues("name") 等价于 paramValues.name
       -->
      <h3>对象的获取方式</h3>
      <h4>标准获取方式:${requestScope.student.studentName} 或者 ${requestScope["student"]["age"]}</h4>
      <h4>当之后一个KEY的时候:${student.studentName},需要知道查找pageContext里面是否包含</h4>
      <!--判断是否为空及取反-->
      <h3>==${requestScope.author}==**${empty requestScope.author}**
           ##${not empty requestScope.author}##${!empty requestScope.author}##</h3>
      <!--比较数值是否相等-->
      <h3>${student.age==100}
          或者${student.studentName=="悟空"}
          或者${student.studentName=='悟空'}
          或者${student.studentName eq '悟空'}</h3>
      <h3>
      <!--不等于:ne-->
          ${student.age!=100}
          或者${student.studentName!="悟空"}
          或者${student.studentName!='悟空'}
          或者${student.studentName ne '悟空'}
      </h3>
       <h3>
        <!--大于:gt-->
           ${student.age>200}
           或者${student.age gt 200}
       </h3>
       <h3>
        <!--大于等于:ge-->
           ${student.age>=200}
           或者${student.age ge 200}
       </h3>
       <h3>
        <!--小于:lt-->
           ${student.age<200}
           或者${student.age lt 200}
       </h3>
       <h3>
        <!--小于等于:le-->
           ${student.age<=200}
           或者${student.age le 200}
       </h3>
        <!--也支持关系运算符-->
      <!-- && and  /   ||  or   / ! not -->
        <h2>集合</h2>
        <h3>学生有:${studentList.size()}</h3>
        <h3>现在无法变量,我也不推荐&lt;%Java代码的遍历方式%&gt;</h3>
        <h3>${studentList[1].studentName}</h3>
    </body>
</html>

如果遍历数据,需要我们使用第三库提供的标签

五.JSTL标签库

刚才我们已经使用过JSP自带标签<jsp:include>作用就是当我发现该标签的时候,会执行预先定义好的代码。

我们不推荐使用<%%>在JSP中属性代码,原因就是不好看,格式化有一些乱七八糟。

  • 核心标签库(重点)

  • 格式化标签库(掌握)

  • 函数标签库(掌握)

  • SQL标签库(不需要了解)

  • XML标签库(不需要了解)

核心标签库

  1. 表达式
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%-- 引入JSLT核心标签库 --%>
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %>
<html>
    <head>
        <base href="${pageContext.request.contextPath}/">
        <title>核心标签库</title>
    </head>
    <body>
        <h3>输出标签+必须要跟EL标签配合使用</h3>
        <h4>${applicationScope.bookName}</h4>
        <h4>
            <c:out value="齐天大圣"></c:out>
        </h4>
        <h4>
            默认对HTML标签会转义:
            <c:out value="${applicationScope.bookName}"></c:out>
        </h4>
        <h4>
            对HTML标签解释:
            <c:out value="${applicationScope.bookName}" escapeXml="false"></c:out>
        </h4>

        <c:set value="三国志" var="bookName" scope="application"></c:set>
        <h4>${applicationScope.bookName}</h4>

        <c:remove var="bookName" scope="application"></c:remove>
        <h4>${bookName}</h4>

        <h4><c:out value="${applicationScope.bookName}">JSTL获取的数据没有值,显示的内容</c:out></h4>
        <h4>${empty applicationScope.bookName?"EL获取的数据没有值,显示的内容":applicationScope.bookName}</h4>
    </body>
</html>

  1. 循环数据
        <h3>循环</h3>
        <table style="width: 500px">
            <tr>
                <th>序号</th>
                <th>索引</th>
                <th>奇偶行</th>
                <th>1或最后</th>
                <th>姓名</th>
                <th>性别</th>
                <th>年龄</th>
                <th>操作</th>
            </tr>
            <%--
                items="${requestScope.studentList}
                List<Student> studentList = request.getAttribute("studentList")
                for(int i=0;i<studnetList.size();i++){
                    Student student = studentList.get(i); --> var="student"
                    序号(i+1)
                }
            --%>
            <c:forEach items="${requestScope.studentList}" var="student" varStatus="vs">
                <tr style="background-color: ${vs.index%2==0?'yellow':'gray'}">
                    <td>${vs.count}</td>
                    <td>${vs.index}</td>
                    <td>${vs.index%2==0}</td>
                    <td>${vs.first} -- ${vs.last}</td>
                    <td>${student.studentName}</td>
                    <td>${student.sex=="1"?"男":"女"}</td>
                    <td>${student.age}</td>
                    <td>
                        <a href="${pageContext.request.contextPath}/update?id=${student.studentId}">更新</a>
                        <a href="<%=request.getContextPath()%>/update?id=${student.studentId}">更新</a>
                        <a href="<c:url value="update?id=${student.studentId}"></c:url>">编辑</a>

                    </td>
                </tr>
            </c:forEach>
        </table>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

月色夜雨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值