【JavaWeb学习笔记】13 - JSP浏览器渲染技术

项目代码

https://github.com/yinhai1114/JavaWeb_LearningCode/tree/main/jsp

JSP

一、JSP引入

1.JSP现状

1.目前主流的技术是前后端分离(比如: Spring Boot + Vue/React),我们会讲的.[看一下]

2. JSP技术使用在逐渐减少,但使用少和没有使用是两个意思,一些老项目和中小公司还在使用JSP,工作期间,你很有可能遇到JSP

3.小结: JSP使用在减少(但是现阶段还是有必要学一下, 让我们的技术栈更加全面),我们最佳

技术策略:JSP (能基本使用,能看懂,能维护相关项目,不用深入)

2.为什么需要JSP

1.servlet做页面过于繁琐,html又无法动态获得,所以引入JSP技术

2.jsp= html+java代码+标签+ javascript+css

二、JSP基本原理及使用

1.基本介绍

1. JSP全称是Java Server Pages, Java的服务器页面,就是服务器端渲染技术

2. JSP这门技术的最大的特点在于,写JSP就像在写HTML

        相比html而言,htmI只能为用户提供静态数据,而JSP技术允许在页面中嵌套java代码,为用户提供动态数

        相比Servlet而言,Servlet很难对数据进行排版,而jsp除了可以用java代码产生动态数据的同时,也很容易对数据进行排版。

3. jsp技术基于Servlet,你可以理解成JSP就是对Servlet的包装(本质JSP就是Servlet)

4.会使用JSP的程序员,再使用thymeleaf是非常容易的事情,几乎是无缝接轨。

2.快速入门

<%--
  Created by IntelliJ IDEA.
  User: 64301
  Date: 2023/12/20
  Time: 16:31
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>jsp的简单求和计算器</title>
</head>
<body>
<h1>简单计算器</h1>
<%
    //1.在jsp的 % 标签中 可以写java代码
    int i = 10;
    int j = 20;
    int res = i + j;
    //2.jsp内置对象可以直接使用 比如out
    out.println(i + "+" + j + "=" + res);
%>
</body>
</html>

注意:

1. jsp页面不能像HTML页面,直接用浏览器运行。只能通过浏览器访问Tomcat来访问jsp页面

2.如何设置jsp模板

3.JSP运行原理

1. jsp页面本质是一个Servlet程序(本质就是java程序),其性能是和java关联的,只是长得丑.

 2.第1次访问jsp页面的时候。Tomcat服务器会把jsp页面解析成为一个java源文件。并且对它进行编译成为.class字节码程序。看下Cal.jsp对应的cal_ jsp.java和cal_ jsp.class文件

4.page指令

1. language表示jsp翻译后是什么语言文件,只支持java

2. contentType表示jsp返回的数据类型,对应源码中response.setContentType()参数值

3. pageEncoding属性表示当前jsp页面文件本身的字符集

4. import属性跟java源代码中一样。用于导包,导类

三、JSP三种常用的脚本

1.声明脚本基本语法

1.声明脚本的格式是: <%! 声明java代码%>

2.作用:定义jsp的需要属性、方法、静态代码块和内部类等

<%--
  Created by IntelliJ IDEA.
  User: 银小海
  Date: 2023/12/20 Time: 16:59
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<h1>jsp声明脚本</h1>
<body>
<%!
    //这里我们可以声明该jsp需要使用的属性,方法,静态代码块, 内部类
    //也就是给 statement.jsp 对应的 statement_jsp 类定义成员
    //1. 属性
    private String name = "jack";
    private int age;
    private static String company;

    //2 方法
    public String getName() {
        return name;
    }
    //3. 静态代码块
    static {
        company = "字节跳动";
    }
%>
</body>
</html>

2.表达式脚本基本语法

1.表达式脚本的格式是:<%=表达式%>

2.表达式脚本的作用是:在jsp 页面上输出数据

3.脚本中的表达式不能以分号结束。

<%--
  Created by IntelliJ IDEA.
  User: 银小海
  Date: 2023/12/20 Time: 17:05
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>表达式脚本的使用</title>
</head>
<body>
<h1>个人信息</h1>
<%
    String name = "yinhai";
    String email = request.getParameter("email");
%>
用户名: <%=name%><br/>
工作是: <%="java工程师"%><br/>
年龄: <%=request.getParameter("age")%><br/>
电邮: <%=email%>
</body>
</html>

3.代码脚本基本语法

1.代码脚本的语法是:<%  java代码%>

2.代码脚本的作用是:可以在jsp页面中,编写我们需要的功能(使用java )

3.可以由多个代码脚本块组合完成一个完整的 java语句。

4.代码脚本还可以和表达式脚本一起组合使用,在jsp页面上输出数据

<%@ page import="com.yinhai.domain.Monster" %>
<%@ page import="java.util.ArrayList" %><%--
  Created by IntelliJ IDEA.
  User: 银小海
  Date: 2023/12/20 Time: 17:10
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>演示代码脚本</title>
</head>
<body>
<h1>演示代码脚本</h1>
<%
    //创建ArrayList ,放入两个monster对象
    ArrayList<Monster> monsterList = new ArrayList<>();
    monsterList.add(new Monster(1, "牛魔王", "芭蕉扇"));
    monsterList.add(new Monster(2, "蜘蛛精", "吐口水"));
%>
<table bgcolor="#f0f8ff" border="1px" width="300px">
    <tr>
        <th>id</th>
        <th>名字</th>
        <th>技能</th>
    </tr>
    <%
        for (int i = 0; i < monsterList.size(); i++) {
            //先取出monster对象
            Monster monster = monsterList.get(i);
    %>
    <tr>
        <td><%=monster.getId()%></td>
        <td><%=monster.getName()%></td>
        <td><%=monster.getSkill()%></td>
    </tr>
    <%
        }
    %>

</table>
</body>
</html>

四、JSP的注释

1.演示jsp注释的使用

 //在java片段中,仍然是java的注释
    String email = "xx@qq.com";
    /*
        多行注释
     */

五、JSP内置对象

1.基本介绍[讲解]

1、JSP内置对象Q),是指Tomcat在翻译jsp页面成为Servlet后,内部提供的九大对象,叫内置对象

2、内置对象,可以直接使用,不需要手动定义

2.JSP九大内置对象

1. out向客户端输出数据,out.println("); ;

2. request客户端的http请求

3. response响应对象

4. session会话对象

5. application对应ServletContext

6. pageContext jsp页面的上下文,是一个域对象,可以setAttribue(), 作用范围只是本页面

7. exception异常对象, getMessage()

8. page代表jsp这个实例本身

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>jsp内置对象</title>
</head>
<body>
<h1>jsp内置对象</h1>
<%
    //梳理jsp的内置对象
    //out 类型是 JspWriter 父类就是 Writer.
    out.println("jsp out");
    
    //request是HttpServletRequest
    request.getParameter("age");
    
    //response就是 HttpServletResponse
    //response.sendRedirect("http://www.baidu.com");
   
    //session 就是 HttpSession
    session.setAttribute("job", "PHP工程师");
    
    //application类型就是ServletContext
    application.setAttribute("name", "老韩老师");
    
    //pageContext 可以存放数据(属性), 但是该数据只能在本页面使用
    pageContext.setAttribute("age", 100);
    
    //exception 异常对象 使用比较少
    
    //page 内置对象,类似 this
    out.println("page=" + page);
    
    //config 内置对象的类型就是ServletConfig
    String pwd = config.getInitParameter("pwd");


%>
</body>
age: <%=pageContext.getAttribute("age")%>
</html>

六、JSP域对象

1.四大域对象介绍

1. pageContext (域对象,存放的数据只能在当前页面使用)

2. request (域对象,存放的数据在一次request请求有效)

3. session(域对象,存放的数据在一次会话有效)

4. application(域对象,存放的数据在整个web应用运行期间有效)

2.应用实例

1.scope文件

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>scope文件</title>
</head>
<body>
<%
    //在不同的域对象中,放入数据
    //1. 因为四个域对象,是不同的对象,因此name(key) 相同时,并不会冲突
    pageContext.setAttribute("k1", "pageContext数据(k1)");
    request.setAttribute("k1", "request数据(k1)");
    session.setAttribute("k1", "session数据(k1)");
    application.setAttribute("k1", "application数据(k1)");

    //做一个请求转发的操作
    //路径应该怎么写,请不清楚地小伙伴,去看韩老师讲的web路径专题
    //request.getRequestDispatcher("/scope2.jsp").forward(request, response);

    //做一个重定向
    String contextPath = request.getContextPath();//返回的就是 web路径=>/jsp
    //response.sendRedirect("/jsp/scope2.jsp");
    response.sendRedirect(contextPath + "/scope2.jsp");
%>
<h1>四个域对象,在本页面获取数据的情况</h1>
pageContext-k1: <%=pageContext.getAttribute("k1")%><br/>
request-k1: <%=request.getAttribute("k1")%><br/>
session-k1: <%=session.getAttribute("k1")%><br/>
application-k1: <%=application.getAttribute("k1")%><br/>
</body>
</html>

2.scope2

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>scope2.js</title>
</head>
<body>
<h1>在scope2页面获取数据的情况</h1>
pageContext-k1: <%=pageContext.getAttribute("k1")%><br/>
request-k1: <%=request.getAttribute("k1")%><br/>
session-k1: <%=session.getAttribute("k1")%><br/>
application-k1: <%=application.getAttribute("k1")%><br/>
</body>
</html>

3.四大域对象的注意事项和细节

1.域对象是可以像Map一样存取数据的对象。四个域对象功能一样。不同的是它们对数据的存储范围

2.从存储范围(作用域范围看) pageContext < request < session < application

七、请求转发标签

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>aa.jsp</title>
</head>
<body>
<h1>aa.jsp</h1>
<%--
1. jsp提供了很多标签,但是因为jsp不是重点,老韩就讲一个常用forward
2. jsp:forward 本质就是 等价 request.getRequestDispatcher("/bb.jsp").for...
--%>
<jsp:forward page="/bb.jsp"></jsp:forward>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>bb.jsp</title>
</head>
<body>
<h1>bb.jsp页面</h1>
</body>
</html>

八、JSP课后作业

需求分析:使用jsp完成-一个简单的计算器,需求如图

1)要求在前端页面对输入的num1和num2进行校验[提示:正则表达式],必须是整数

2)验证成功,提交数据给服务器,能够显示结果

3)点击超链接,可以返回界面

4)其它完整考虑[思考题]

1.calUI,前端判断是否满足数的要求并创建对应的ui

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>JSP计算器</title>
    <!--使用js+正则表达式完成数据校验-->
    <script type="text/javascript">
        function check() {
            //得到 num1 和 num2值
            var num1 = document.getElementById("num1").value;
            var num2 = document.getElementById("num2").value;

            //验证 正则表达式, 整数 => 在java基础讲过 => 学习技术一定要经常回顾
            //我们学习的所有java技术=> 其实都是基础组合[oop,io,反射,注解,集合,线程,网络]
            var reg = /^[-]?([1-9]\d*|0)$/;
            if (!reg.test(num1)) {//如果不满足验证条件
                alert("num1 不是一个整数");
                return false;//放弃提交
            }
            if (!reg.test(num2)) {//如果不满足验证条件
                alert("num2 不是一个整数");
                return false;//放弃提交
            }
            return true;//提交到action指定的位置
        }
    </script>
</head>
<body>
<h1>JSP计算器</h1>
<form action="<%=request.getContextPath()%>/calServlet"
      method="post" onsubmit="return check()">
    num1: <input type="text" id="num1" name="num1"> num1错误:xx <br/>
    num2: <input type="text" id="num2" name="num2"> num2错误:xx<br/>
    运算符号:
    <select name="oper">
        <option value="+">+</option>
        <option value="-">-</option>
        <option value="*">*</option>
        <option value="/">/</option>
    </select><br/>
    <input type="submit" value="提交计算">
</form>
</body>
</html>

2.calServlet

@WebServlet(name = "CalServlet",urlPatterns = "/calServlet")
public class CalServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("CalServlet 被调用...");
        //思路 ==> 代码
        //1. 是Servlet
        //2. 接收数据
        //String num1 = request.getParameter("num1");
        //String num2 = request.getParameter("num2");
        //进行转换->int
        double num1 = WebUtils.parseDouble(request.getParameter("num1"), 0);
        double num2 = WebUtils.parseDouble(request.getParameter("num2"), 0);
        String oper = request.getParameter("oper");
        double res = 0; //使用变量来接收运算结果
        //3. 完成计算
        if ("+".equals(oper)) {
            res = num1 + num2;
        } else if ("-".equals(oper)) {
            res = num1 - num2;
        } else if ("*".equals(oper)) {
            res = num1 * num2;
        } else if ("/".equals(oper)) {
            res = num1 / num2;
        } else {
            System.out.println(oper + " 不正确...");
        }
        //4. 把结果保存到域对象[request, session, servletContext]
        //   因为一次请求对应一次计算, 所以我建议将结果保存到request
        //   把结果组织到一个字符串中., 方便我们在下一个页面显示
        //   java基础: String.format ,可以格式化字符串
        String formatRes = String.format("%s %s %s = %s", num1, oper, num2, res);
        request.setAttribute("res", formatRes);
        //System.out.println("formatRes= " + formatRes);
        //5. 转发到显示页面 calRes.jsp
        request.getRequestDispatcher("/cal/calRes.jsp").forward(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

3.calRes

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>计算结果</title>
</head>
<body>
<h1>计算结果</h1>
<%=request.getAttribute("res")%><br/>
<%--<a href="/jsp/cal/calUI.jsp">返回重新来玩一把</a>--%>
<a href="<%=request.getContextPath()%>/cal/calUI.jsp">返回重新来玩一把~</a>
</body>
</html>

拓展

EL表达式

1. EL表达式全称: Expression Language,是表达式语言

2. EL表达式主要是代替jsp页面的表达式脚本<% = request.getAttribute("xx")%>

3. EL表达式输出数据的时,比jsp的表达式脚本简洁

4. EL表达式基本语法: ${key1},可以理解就是一个语法糖

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>el表达式的快速入门</title>
</head>
<body>
<h1>el表达式的快速入门</h1>
<%
    request.setAttribute("name", "hello EL表达式");
%>
<%--
    1. 如果name是 null, request.getAttribute() 返回的是null字符串
    2. 如果name是 null, ${name}, 返回的""
--%>
<h1>jsp表达式脚本</h1>
名字= <%=request.getAttribute("name") == null ? "": request.getAttribute("name")%><br/>
<h1>el表达式</h1>
名字= ${name}<br/>
</body>
</html>

一.EL常用输出形式

EL表达式常用输出Bean的普通属性、数组属性、List 集合属性和map集合属性

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>el 表达式输出数据演示</title>
</head>
<body>
<h1>el 表达式输出数据演示</h1>
<%
    //创建Book 对象,放入相关的属性
    //private String name;//书名
    //private String[] writer;//作者
    //private List<String> reader;//读者
    //private Map<String, Object> topics;//评讲
    Book book = new Book();
    book.setName("昆虫总动员");
    book.setWriter(new String[]{"jack", "tom"});
    ArrayList<String> readers = new ArrayList<>();
    readers.add("老韩");
    readers.add("老李");
    book.setReader(readers);//放入readers

    //创建topics
    HashMap<String, String> topics = new HashMap<>();
    topics.put("topic1", "这是我看过的最好的动画片");
    topics.put("topic2", "不错的电影~~");
    book.setTopics(topics);

    //把book 放入到request域对象
    request.setAttribute("bookkey", book);

%>
book对象: ${bookkey}<br/>.
book.name= ${bookkey.name}<br/>
book.writer= ${bookkey.writer}<br/>
book.writer[0]= ${bookkey.writer[0]}<br/>

book.readers= ${bookkey.reader}<br/>
book.readers第2个= ${bookkey.reader.get(1)}<br/>
book.readers第2个= ${bookkey.reader[1]}<br/>

book.topics= ${bookkey.topics}<br/>
book.topics第一个评论= ${bookkey.topics["topic1"]}<br/>

</body>
</html>

二、EL运算操作

1.基本语法语法: ${运算表达式}

语法:${运算表达式}

2.关系运算

3.逻辑运算

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>el的运算符</title>
</head>
<body>
<h1>el的运算符</h1>
<%
    request.setAttribute("num1", 90);
    request.setAttribute("num2", 30);
%>
num1+num2=${num1 + num2}<br/>
num1>num2=${num1 > num2}<br/>
</body>
</html>

三、EL-empty运算

1. empty运算可以判断-个数据是否为空,如果为空,返回true,否则返回false

2.以下几种情况为空

        值为null

        值为空串的时

        值是Object类型数组,长度为零

        list集合,元素个数为零

        map集合,元素个数为零

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>el empty的运算</title>
</head>
<body>
<h1>el empty的运算</h1>
<%
    request.setAttribute("k1", null);
    request.setAttribute("k2", "");
    request.setAttribute("k3", new Object[]{});
    request.setAttribute("k4", new ArrayList<>());
    request.setAttribute("k5", new HashMap<>());

    request.setAttribute("score", 70);
%>
k1是否为空= ${empty k1}<br/>
k2是否为空= ${empty k2}<br/>
k3是否为空= ${empty k3}<br/>
k4是否为空= ${empty k4}<br/>
k5是否为空= ${empty k5}<br/>
是否及格= ${score >= 60 ? "及格": "不及格"}
</body>
</html>

四、EL三元运算

1.表达式1?表达式2:表达式3

2.如果表达式1的值为真,返回表达式2的值,反之,返回表达式3的值。.

五、EL的11个隐含对象

EL四个域对象

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>演示el的四个常用的隐藏对象(域对象)</title>
</head>
<body>
<h1>演示el的四个常用的隐藏对象(域对象)</h1>
<%
    request.setAttribute("k1", "request-k1数据");
    pageContext.setAttribute("k1", "pageContext-k1数据");
    session.setAttribute("k1", "session-k1数据");
    application.setAttribute("k1", "application-k1数据");
%>
<h1>jsp脚本方式获取</h1>
request域中的k1= <%=request.getAttribute("k1")%><br/>
<h1>el方式来获取域对象的数据</h1>
request域中的k1= ${requestScope.k1}<br/>
pageContext域中的k1= ${pageScope.k1}<br/>
session域中的k1= ${sessionScope.k1}<br/>
application域中的k1= ${applicationScope.k1}<br/>
</body>
</html>

pageContext对象的使用

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>pageContext 对象的使用</title>
</head>
<body>
<h1>pageContext 对象的使用</h1>
<%--
    //通过request对象来获取和HTTP协议相关的数据
    request.getScheme() 它可以获取请求的协议
    request.getServerName() 获取请求的服务器 ip 或域名
    request.getServerPort() 获取请求的服务器端口号
    getContextPath() 获取当前工程路径
    request.getMethod() 获取请求的方式(GET 或 POST)
    request.getRemoteHost() 获取客户端的 ip 地址
    session.getId() 获取会话的唯一标识


--%>
<hr/>
<%--
    1.我们可以通过pageContext.request.xx 俩获取和http协议相关的信息
    2.相当于替代 request.getMethod()....
--%>
协议: ${ pageContext.request.scheme }<br>
服务器 ip:${ pageContext.request.serverName }<br>
服务器端口:${ pageContext.request.serverPort }<br>
工程路径:${ pageContext.request.contextPath }<br>
请求方法:${ pageContext.request.method }<br>
客户端 ip 地址:${ pageContext.request.remoteHost }<br>
会话id :${ pageContext.session.id }<br>
<h1>使用jsp表达式脚本获取如上信息</h1>
ip地址: <%=request.getRemoteHost() %> <br>
<h1>使用el表达式形式获取信息-简化写法</h1>
<%
    pageContext.setAttribute("req", request);
%>
ip地址(简化获取): ${req.remoteHost} <br>
获取请求方法(简化获取): ${req.method} <br>
</body>
</html>

JSTL标签库

一、JSTL标签库介绍

1. JSTL标签库是指JSP Standard Tag Library JSP标准标签库

2. EL表达式是为了替换jsp中的表达式脚本,JSTL是为了替换代码脚本。这样jsp页面变得更佳洁

3. JSTL由五个标签库组成

4.使用前需要导入对应的jar包

二、JSTL快速入门

底层仍然是被翻译成JAVA编译的

<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>jstl的快速入门</title>
</head>
<body>
<h1>jstl的快速入门</h1>
<%--
    1. c:if ... 类似
    2. if(10>2){
       out.println("<h1>10 > 2 成立~</h1>")
    }
--%>
<c:if test="${10 < 2}">
    <h1>10 > 2 成立~</h1>
</c:if>
</body>
</html>

三、core核心库

1.<c:set/>

1.介绍: < c;setrscope= "request" var= "username" value="hello~"/>

<c:set /> set标签可以往域中保存数据

1.等价  域对象.setAttribute(key,value);

2.scope属性设置保存到哪个域

        page表示PageContext域( 默认值)

        request表示Request域

        session表示Session域

        application表示ServletContext域

3. var属性设置key是什么

4. value属性设置值

2.<c:if />

1.介绍: <c:if test="${10 > 2}"> hello </c:if>

如果为真输出标签中间的值

1. if标签用来做if判断。

2. test属性表示判断的条件(用EL表达式输出)

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>c:if标签使用</title>
</head>
<body>
<c:set scope="request" var="num1" value="20"></c:set>
<c:set scope="request" var="num2" value="10"></c:set>
<c:if test="${num1 > num2}">
    <h1>${num1} > ${num2}</h1>
</c:if>
</body>
</html>

3.<c:choose> <c:when> <c:otherwise>标签

1.介绍:多路判断。跟switch... case... default...非常接近

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>c:choose标签的使用</title>
</head>
<body>
<h1>c:choose标签的使用</h1>
<%
    request.setAttribute("score", 50);

    //request.setAttribute("k1", "request-k1的值");
    //session.setAttribute("k1", "session-k1的值");
    //application.setAttribute("k1", "application-k1的值");
    //pageContext.setAttribute("k1", "pageContext-k1的值~");
%>
<%--
1. 如果${requestScope.score} 那么就明确的指定从request域对象取出数据
2. 如果${score}, 这是就按照从小到大的域范围去获取 pageContext->request->session->application
--%>
k1=${k1}
<c:choose>
    <c:when test="${requestScope.score > 80}">
        <h1>${score}-成绩优秀</h1>
    </c:when>
    <c:when test="${requestScope.score >= 60}">
        <h1>${score}-成绩一般, 及格了</h1>
    </c:when>
    <c:otherwise>
        <h1>${score}-没有及格,下次努力~</h1>
    </c:otherwise>
</c:choose>
</body>
</html>

4.<c:forEach />标签

1.介绍: c:forEach标签用来遍历输出,主要有4种形式

        普通遍历输出i到j

        遍历数组

        遍历Map

        遍历List

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>c:forEach 标签</title>
</head>
<body>
<h1>c:forEach 标签</h1>
<hr/>
<h1>第1种遍历方式从i到j</h1>
<ul>
    <%--
    1.遍历 1 到 5,
    2. 输出 begin 属性设置开始的索引 end 属性设置结束的索引
    3. var 属性表示循环的变量(也是当前正在遍历到的数据)
    4. 等价 for (int i = 1; i <= 5; i++) {}
    5. 在默认情况下, i 每次会递增1
    --%>
    <c:forEach begin="1" end="5" var="i">
        <li>排名=${i}</li>
    </c:forEach>
</ul>
<hr/>
<h1>第2种遍历方式:遍历数组</h1>
<%
    request.setAttribute("sports", new String[]{"打篮球", "乒乓球"});
%>
<%--
    <c:forEach items="${ requestScope.sports }" var="item"/>
    1. items 遍历的集合/数组
    2. var 遍历到的数据
    3. 等价 for (Object item: arr) {}
--%>
<c:forEach items="${requestScope.sports}" var="sport">
    运动名称= ${sport}<br/>
</c:forEach>
<hr/>
<h1>第3种遍历方式:遍历Map</h1>
<%
    Map<String, Object> map = new HashMap<>();
    map.put("key1", "北京");
    map.put("key2", "上海");
    map.put("key3", "天津");
    request.setAttribute("cities", map);
%>
<%--
    1. items 遍历的map集合
    2. var 遍历到的数据
    3. entry.key 取出key
    4. entry.value 取出值
--%>
<c:forEach items="${requestScope.cities}" var="city">
    城市信息: ${city.key}--${city.value}<br/>
</c:forEach>
<hr/>
<h1>第4种遍历方式:遍历List</h1>
<%
    List<Monster> monsters = new ArrayList<>();
    monsters.add(new Monster(100, "小妖怪", "巡山的"));
    monsters.add(new Monster(200, "大妖怪", "做饭的"));
    monsters.add(new Monster(300, "老妖怪", "打扫位置的"));
    request.setAttribute("monsters", monsters);
%>
<%--
    items 表示遍历的集合
    var 表示遍历到的数据
    begin 表示遍历的开始索引值 ,从0开始计算
    end 表示结束的索引值
    step 属性表示遍历的步长值
    varStatus 属性表示当前遍历到的数据的状态,可以得到step,begin,end等属性值
    //老师提示, 对于jstl标签,能看懂,会使用即可
--%>
<c:forEach items="${requestScope.monsters}" var="monster">
    妖怪的信息: ${monster.id}-${monster.name}-${monster.skill}<br/>
</c:forEach>
</body>
</html>

JSTL和EL的作业

需求分析:使用jsp+servlet+jstl+el完成查询 - 显示案例,需求如图

1)点击超链接,可以显示所有的妖怪信息

2)要求显示的数据在Servlet准备,并放入到request域对象

3)扩展,如果要求增加根据id条件过滤,怎么处理? 一定要自己先思考
 

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>显示所有的妖怪</title>
</head>
<body>
<h1>显示所有的妖怪</h1>
<table border="1px" width="400px">
    <tr>
        <td>id</td>
        <td>name</td>
        <td>skill</td>
    </tr>
<%--    使用c:foreach循环显示即可 显示id > 200--%>
    <c:forEach items="${monsters}" var="monster">
        <c:if test="${monster.id >= 200}">
            <tr>
                <td>${monster.id}</td>
                <td>${monster.name}</td>
                <td>${monster.skill}</td>
            </tr>
        </c:if>
    </c:forEach>

</table>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>查询妖怪</title>
</head>
<body>
<h1>查询妖怪</h1>
<a href="<%=request.getContextPath()%>/queryServlet">点击查询所有的妖怪</a>
</body>
</html>
public class QueryServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //1. 准备要显示的数据--> 从DB
        ArrayList<Monster> list = new ArrayList<>();
        list.add(new Monster(100, "牛魔王", "芭蕉扇"));
        list.add(new Monster(200, "狐狸精", "美人计"));
        list.add(new Monster(300, "白骨精", "吃人骨头"));

        //2. 把list放入到request域, 供jsp页面使用
        request.setAttribute("monsters", list);
        //3. 请求转发 list.jsp
        request.getRequestDispatcher("/hm/list.jsp")
                .forward(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/265808.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

DB207S-ASEMI迷你贴片整流桥DB207S

编辑&#xff1a;ll DB207S-ASEMI迷你贴片整流桥DB207S 型号&#xff1a;DB207S 品牌&#xff1a;ASEMI 封装&#xff1a;DBS-4 最大平均正向电流&#xff1a;2A 最大重复峰值反向电压&#xff1a;1000V 产品引线数量&#xff1a;4 产品内部芯片个数&#xff1a;4 产品…

Spring security之授权

前言 本篇为大家带来Spring security的授权&#xff0c;首先要理解一些概念&#xff0c;有关于&#xff1a;权限、角色、安全上下文、访问控制表达式、方法级安全性、访问决策管理器 一.授权的基本介绍 Spring Security 中的授权分为两种类型&#xff1a; 基于角色的授权&…

2024最新苹果手机APP软件下架了,怎么安装?

如果你是一个iPhone用户&#xff0c;你可能会遇到这样的情况&#xff1a;你想下载或更新一个软件&#xff0c;但发现它已经从APP Store上消失了。这可能是因为软件违反了苹果的规则&#xff0c;或者开发者主动撤下了软件。那么&#xff0c;这种情况下&#xff0c;你还能安装或使…

OpenCV | 霍夫变换:以车道线检测为例

霍夫变换 霍夫变换只能灰度图&#xff0c;彩色图会报错 lines cv2.HoughLinesP(edge_img,1,np.pi/180,15,minLineLength40,maxLineGap20) 参数1&#xff1a;要检测的图片矩阵参数2&#xff1a;距离r的精度&#xff0c;值越大&#xff0c;考虑越多的线参数3&#xff1a;距离…

Unreal5.3 PCG 笔记

目录 ElectricDreams场景功能移动中间山体向周围随机生成倒下的树干树干上随机生成的植被 ElectricDreams场景功能 移动中间山体向周围随机生成倒下的树干 配置内容 中心山体Spline周围沟渠Spline&#xff08;土堆&#xff09;PCG规则 主要功能节点 SplineSample&#xff08;…

基于Java web的住院管理系统论文

目 录 目 录 I 摘 要 III ABSTRACT IV 1 绪论 1 1.1 课题背景 1 1.2 研究现状 1 1.3 研究内容 2 2 系统开发环境 3 2.1 vue技术 3 2.2 JAVA技术 3 2.3 MYSQL数据库 3 2.4 B/S结构 4 2.5 SSM框架技术 4 3 系统分析 5 3.1 可行性分析 5 3.1.1 技术可行性 5 3.1.2 操作可行性 5 3…

Linux 操作系统(用户注册、删除、权限修改等)

添加用户 格式&#xff1a;useradd 用户名 ( 添加用户 ) passwd 用户名 (给用户设置密码) Linux 用户切换原则&#xff1a; 高权限向低权限切换无需输入密码 低权限向高权限或同级用户切换需要输入密码 用户切换&#xff1a;su su – 用户名 &#xff08;用户切换&#x…

【经典LeetCode算法题目专栏分类】【第9期】深度优先搜索DFS与并查集:括号生成、岛屿问题、扫雷游戏

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能AI、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推荐--…

蓝牙技术在物联网中的应用

随着蓝牙技术的不断演进和发展&#xff0c;蓝牙已经从单一的传统蓝牙技术发展成集传统蓝牙。高速蓝牙和低耗能蓝牙于一体的综合技术&#xff0c;不同的应用标准更是超过40个越来越广的技术领域和越来越多的应用场景&#xff0c;使得目前的蓝牙技术成为包含传感器技术、识别技术…

DRF从入门到精通三(反序列化数据校验源码分析、断言Assert、DRF之请求、响应)

文章目录 一、反序列化数据校验源码分析二、断言Assert三、DRF之请求、响应Request类和Response类请求中的Request 能够解析前端传入的编码格式响应中的Response能够响应的编码格式 一、反序列化数据校验源码分析 反序列化数据校验&#xff0c;校验顺序为&#xff1a;先校验字段…

懂机器学习?先来回答这三个问题 >>

机器学习是一种数据分析技术&#xff0c;让计算机学习人类和动物与生俱来的能力&#xff1a;从经验中学习。 机器学习算法使用计算方法直接从数据中“学习”信息&#xff0c;而不依赖于预定方程作为模型。 随着可用于学习的样本数量的增加&#xff0c;算法也会相应地提高性能。…

探索栈数据结构:深入了解其实用与实现(c语言实现栈)

上次结束了链表部分的内容&#xff1a;链接未来&#xff1a;深入理解链表数据结构&#xff08;二.c语言实现带头双向循环链表&#xff09; 然而&#xff0c;当我们涉及特定问题时&#xff0c;另一个非常有用的数据结构也开始显得至关重要——栈 栈与链表有着截然不同的特性&a…

MySQL数据库基础和基本的增删改查操作

目录 前瞻 数据库的基本概念 数据库管理系统&#xff08;DBMS&#xff09; 数据库系统(DBS) 数据库类型和常用数据库 关系型数据库 SQL 非关系型数据库 NoSQL SQL语句 简介 SQL语句分类 常用的数据类型 MySQL的六大约束特性 SQL语句的使用 创建及删除数据库和表 …

H5小游戏加固方案

今年的中国游戏产业年会上&#xff0c;小游戏成了万众瞩目的行业新风口。据伽马数据统计&#xff1a;2023年小游戏市场规模可达200亿元&#xff0c;同比增长300% 。 小游戏有着分发更精准、用户转化率更高、研发成本更低、场景适用性更强等优势&#xff0c;具备巨大的市场潜力…

openGauss学习笔记-171 openGauss 数据库运维-备份与恢复-导入数据-深层复制

文章目录 openGauss学习笔记-171 openGauss 数据库运维-备份与恢复-导入数据-深层复制171.1 使用CREATE TABLE执行深层复制171.1.1 操作步骤 171.2 使用CREATE TABLE LIKE执行深层复制171.2.1 操作步骤 171.3 通过创建临时表并截断原始表来执行深层复制171.3.1 操作步骤 openGa…

服务器数据恢复-昆腾存储StorNext文件系统下raid5数据恢复案例

服务器数据恢复环境&#xff1a; 昆腾某型号存储&#xff0c;StorNext文件存储系统。 共有9个分别配置了24块磁盘的磁盘柜&#xff0c;其中8个磁盘柜存放普通数据&#xff0c;1个磁盘柜存放元数据。 存放元数据的磁盘柜中的24块磁盘组建了8组RAID1阵列和1组4盘RAID10阵列&#…

Java 虚拟机中的内存结构

1 内存结构 1.1 程序计数器 1.1.1 定义 Program Counter Register 程序计数器&#xff08;寄存器&#xff09; 作用&#xff1a;是记住下一条 jvm 指令的执行地址 特点&#xff1a; 是线程私有的&#xff08;每个线程独有自己的一份&#xff09;不会存在内存溢出 1.1.2 作…

、写入Shellcode到注册表上线

其实本质就是将shellcode写入到注册表中&#xff0c;然后读取注册表中的shellcode&#xff0c;然后创建线程去执行shellcode。 如下图: 写入注册表shellcode 这里将shellcode写入到注册表中&#xff0c;在我们需要的时候再去读取然后执行。 这里用到如下两个Windows API函…

Zookeeper-应用实战

Zookeeper Java客户端实战 ZooKeeper应用的开发主要通过Java客户端API去连接和操作ZooKeeper集群。 ZooKeeper官方的Java客户端API。 第三方的Java客户端API&#xff0c;比如Curator。 ZooKeeper官方的客户端API提供了基本的操作:创建会话、创建节点、读取节点、更新数据、…

Leetcode—415.字符串相加【简单】

2023每日刷题&#xff08;六十八&#xff09; Leetcode—415.字符串相加 实现代码 class Solution { public:string addStrings(string num1, string num2) {string ans;int len1 num1.size();int len2 num2.size();int i len1 - 1, j len2 - 1;int sum 0, c 0;while(i…