JSP详解使用

news2024/12/24 20:35:07

一、JSP概述

1.1 、JSP基础

1.1.1 、JSP简介

JSP全称是Java Server Page,它和Servlet一样,也是sun公司推出的一套开发动态web资源的技术,称为JSP/Servlet规范。JSP的本质其实就是一个Servlet。

1.1.2 、JSP和HTML以及Servlet的适用场景

类别适用场景
HTML只能开发静态资源,不能包含java代码,无法添加动态数据。
Servlet写java代码,可以输出页面内容,但是很不方便,开发效率极低。
JSP它包括了HTML的展示技术,同时具备Servlet输出动态资源的能力。但是不适合作为控制器来用。

1.1.3 、JSP简单入门

创建JavaWeb工程

在index.jsp中填写内容

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>JSP</title>
</head>
<body>
   <h1>这是我的第一个jsp页面</h1>
</body>
</html>

部署项目

测试运行

http://localhost:8080/demo01/index.jsp

image-20240830180855805

1.1.4 JSP说明

写在之前: 明确JSP就是一个Servlet。是一个特殊的Servlet。

JSP的原理:

​ 客户端提交请求

​ ——Tomcat服务器解析请求地址

​ ——找到JSP页面

​ ——Tomcat将JSP页面翻译成Servlet的java文件

​ ——将翻译好的.java文件编译成.class文件

​ ——返回到客户浏览器上。

1.2、JSP原理

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

<%
    System.out.println("hello,jsp~");
%>
</body>
</html>

image-20240830181713115

我们之前说 JSP 就是一个页面,那么在 JSP 中写 html 标签,我们能理解,但是为什么还可以写 Java 代码呢?

因为 ==JSP 本质上就是一个 Servlet。==接下来我们聊聊访问jsp时的流程

image-20240830181435423

  1. 浏览器第一次访问 hello.jsp 页面
  2. tomcat 会将 hello.jsp 转换为名为 hello_jsp.java 的一个 Servlet
  3. tomcat 再将转换的 servlet 编译成字节码文件 hello_jsp.class
  4. tomcat 会执行该字节码文件,向外提供服务

image-20240830181841227

我们可以到项目所在磁盘目录下找

C:\Users\shixiaochuang\AppData\Local\JetBrains\IntelliJIdea2024.1\tomcat\5ad44f52-f79d-4ce2-b548-fa0e596389c9\work\Catalina\localhost\demo01\org\apache\jsp

目录,而这个目录下就能看到转换后的 servlet

image-20240830182024161

打开 hello_jsp.java 文件,来查看里面的代码

public final class hello_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent,
                 org.apache.jasper.runtime.JspSourceImports {

image-20240830182140108

由上面的类的继承关系可以看到继承了名为 HttpJspBase 这个类,那我们在看该类的继承关系。

https://github.com/apache/tomcat/blob/main/java/org/apache/jasper/runtime/HttpJspBase.java

image-20240830182404872

可以看到该类继承了 HttpServlet ;那么 hello_jsp 这个类就间接的继承了 HttpServlet ,也就说明 hello_jsp 是一个 servlet

继续阅读 hello_jsp 类的代码,可以看到有一个名为 _jspService() 的方法,该方法就是每次访问 jsp 时自动执行的方法,和 servlet 中的 service 方法一样 。

而在 _jspService() 方法中可以看到往浏览器写标签的代码:

  out.write("\r\n");
      out.write("<html>\r\n");
      out.write("<head>\r\n");
      out.write("    <title>Title</title>\r\n");
      out.write("</head>\r\n");
      out.write("<body>\r\n");
      out.write("<h1>hello jsp</h1>\r\n");
      out.write("\r\n");

image-20240830182505694

以前我们自己写 servlet 时,这部分代码是由我们自己来写,现在有了 jsp 后,由tomcat完成这部分功能。

讲到这里,我们应该清楚的认识到,JSP它是一个特殊的Servlet,主要是用于展示动态数据。它展示的方式是用流把数据输出出来,而我们在使用JSP时,涉及HTML的部分,都与HTML的用法一致,这部分称为jsp中的模板元素,在开发过程中,先写好这些模板元素,因为它们决定了页面的外观。

二、JSP应用

2.1 、JSP脚本

1)Java代码块

在jsp中,可以使用java脚本代码。形式为:<% 此处写java代码 %>

但是,在实际开发中,极少使用此种形式编写java代码。同时需要注意的是:

<%
	在里面写java程序脚本需要注意:这里面的内容由tomcat负责翻译,翻译之后是service方法的成员变量
%>

示例:

<%--Java代码块--%>
<%
    System.out.println("这里是Java代码块");
    String[] arr = new String[]{"Java","JavaWeb","JSP"};
    for (String s : arr) {
        System.out.println(s);
    }
%>
<hr/>

2)JSP表达式

在jsp中,可以使用特定表达式语法,形式为:<%=表达式%>

jsp在翻译完后是out.print(表达式内容);

所以:<%out.print("当前时间);%>和<%=“当前时间”%>是一样的。

在实际开发中,这种表达式语法用的也很少使用。

示例:

<!--JSP表达式-->
<%="这是JSP表达式"%><br/>
就相当于<br/>
<%out.println("这是没有JSP表达式输出的");%>

3)JSP声明

在JSP中也可以声明一些变量,方法,静态方法,形式为:<%! 声明的内容 %>

使用JSP声明需要注意:

<%! 
	需要注意的是: 写在里面的内容将会被tomcat翻译成全局的属性或者类方法。
%>                                    

示例:

<!--JSP声明-->
<%! String str = "声明语法格式";%>
<%=str%>

4)JSP注释

在使用JSP时,它有自己的注释,形式为:<%–注释–%>

需要注意的是:

​ 在Jsp中可以使用html的注释,但是只能注释html元素,不能注释java程序片段和表达式。同时,被html注释部分会参与翻译,并且会在浏览器上显示

​ jsp的注释不仅可以注释java程序片段,也可以注释html元素,并且被jsp注释的部分不会参与翻译成.java文件,也不会在浏览器上显示。

示例:

<%--JSP注释--%>
<!--HTML注释-->

5)语法的示例

JSP语法完整示例代码

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%--Java代码块--%>
<%
    System.out.println("这里是Java代码块");
    String[] arr = new String[]{"Java", "JavaWeb", "JSP"};
    for (String s : arr) {
        System.out.println(s);
    }
%>
<hr/>
<%--这是JSP表达式--%>
<%=
"这是JSP表达式"
%>
就相当于<br/>
<%out.println("这是没有JSP表达式输出的");%>
<hr/>
<!--JSP声明-->
<%! String str = "声明语法格式";%>
<%=str%>

<%--JSP注释--%>
<!--HTML注释-->
</body>
</html>

JSP语法运行结果

http://localhost:8080/demo01/demo01.jsp

image-20240830191532347

6)区分三大脚本

JSP 脚本有如下三个分类:

  • <%…%>:内容会直接放到_jspService()方法之中
  • <%=…%>:内容会放到out.print()中,作为out.print()的参数
  • <%!…%>:内容会放到_jspService()方法之外,被类直接包含
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>区分三角脚本</title>
</head>
<body>
<h1>hello jsp</h1>

<%
    System.out.println("hello,jsp~");
    int i = 3;
%>


<%="hello"%>
<%=i%>

<%!
    void show() {
    }

    String name = "zhangsan";
%>


</body>
</html>

image-20240830192609263

image-20240830192836539

image-20240830192932090

2.2、JSP指令

1)page指令

**language:**告知引擎,脚本使用的是java,默认是java,支持java。不写也行。

extends:告知引擎,JSP对应的Servlet的父类是哪个,不需要写,也不需要改。

import:告知引擎,导入哪些包(类)。

注意:引擎会自动导入:java.lang.*,javax.servlet.*,javax.servlet.http.*,javax.servlet.jsp.*

导入的形式:

<%@page import=”java.util.Date,java.util.UUID”%>或者:

<%@page import=”java.util.Date”%>

<%@page import=”java.util.UUID”%> 用Eclipse:Alt+/ 自动导入

session:告知引擎是否产生HttpSession对象,即是否在代码中调用request.getSession()。默认是true。

buffer:JspWriter用于输出JSP内容到页面上。告知引擎,设定他的缓存大小。默认8kb。

errorPage:告知引擎,当前页面出现异常后,应该转发到哪个页面上(路径写法:/代表当前应用)

小贴士:当在errorpage上使用了isErrorPage=true之后,ie8有时候不能正常显示

配置全局错误页面:web.xml

<error-page>    
    <exception-type>java.lang.Exception</exception-type>    			
    <location>/error.jsp</location>
</error-page>
<error-page>
    <error-code>404</error-code>
    <location>/404.html</location>
</error-page>                                 

当使用了全局错误页面,就无须再写errorPage来实现转到错误页面,而是由服务器负责跳转到错误页面。

isErrorPage:告知引擎,是否抓住异常。如果该属性为true,页面中就可以使用exception对象,打印异常的详细信息。默认值是false。

contentType:告知引擎,响应正文的MIME类型。contentType=“text/html;charset=UTF-8”

​ 相当于response.setContentType(“text/html;charset=UTF-8”);

pageEncoding:告知引擎,翻译jsp时(从磁盘上读取jsp文件)所用的码表。pageEncoding="UTF-8"相当于告知引擎用UTF-8读取JSP

isELIgnored*:告知引擎,是否忽略EL表达式,默认值是false,不忽略。

2)include指令

语法格式:<%@include file=“” %>该指令是包含外部页面。

属性:file,以/开头,就代表当前应用。

使用示例

静态包含1

静态包含的特点

静态包含2

3)taglib指令

语法格式:<%taglib uri=“” prefix=“”%>

作用:该指令用于引入外部标签库。html标签和jsp标签不用引入。

属性:

​ uri:外部标签的URI地址。

​ prefix:使用标签时的前缀。

2.3、 JSP细节

1)九大隐式对象

什么是隐式对象呢?它指的是在jsp中,可以不声明就直接使用的对象。它只存在于jsp中,因为java类中的变量必须要先声明再使用。其实jsp中的隐式对象也并非是未声明,只是它是在翻译成.java文件时声明的。所以我们在jsp中可以直接使用。

隐式对象名称类型备注
requestjavax.servlet.http.HttpServletRequest
responsejavax.servlet.http.HttpServletResponse
sessionjavax.servlet.http.HttpSessionPage指令可以控制开关
applicationjavax.servlet.ServletContext
pageJava.lang.Object当前jsp对应的servlet引用实例
configjavax.servlet.ServletConfig
exceptionjava.lang.Throwablepage指令有开关
outjavax.servlet.jsp.JspWriter字符输出流,相当于printwriter
pageContextjavax.servlet.jsp.PageContext很重要

2)PageContext对象

简介

它是JSP独有的对象,Servlet中没有这个对象。本身也是一个域(作用范围)对象,但是它可以操作其他3个域对象中的属性。而且还可以获取其他8个隐式对象。

生命周期

它是一个局部变量,所以它的生命周期随着JSP的创建而诞生,随着JSP的结束而消失。每个JSP页面都有一个独立的PageContext。

常用方法

PageContext方法详解

在上图中,同学们发现没有页面域操作的方法,其实是定义在了PageContext的父类JspContext中,如下图所示:

JspContext

3)四大域对象

JavaWeb中有四大域对象,分别是:

  • page:当前页面有效
  • request:当前请求有效
  • session:当前会话有效
  • application:当前应用有效

image-20240830211859105

域对象名称范围级别备注
PageContext页面范围最小,只能在当前页面用因范围太小,开发中用的很少
ServletRequest请求范围一次请求或当期请求转发用当请求转发之后,再次转发时请求域丢失
HttpSession会话范围多次请求数据共享时使用多次请求共享数据,但不同的客户端不能共享
ServletContext应用范围最大,整个应用都可以使用尽量少用,如果对数据有修改需要做同步处理

三、EL 表达式

3.1、 EL表达式

EL(全称Expression Language )表达式语言,用于简化 JSP 页面内的 Java 代码。

EL 表达式的主要作用是 获取数据。其实就是从域对象中获取数据,然后将数据展示在页面上。

而 EL 表达式的语法也比较简单,== e x p r e s s i o n = = 。例如: {expression}== 。例如: expression==。例如:{brands} 就是获取域中存储的 key 为 brands 的数据。

3.1.1 EL表达式概述

基本概念

EL表达式,全称是Expression Language。意为表达式语言。它是Servlet规范中的一部分,是JSP2.0规范加入的内容。其作用是用于在JSP页面中获取数据,从而让我们的JSP脱离java代码块和JSP表达式。

基本语法

EL表达式的语法格式非常简单,写为 ${表达式内容}

例如:在浏览器中输出请求域中名称为message的内容。

假定,我们在请求域中存入了一个名称为message的数据(request.setAttribute("message","EL");),此时在jsp中获取的方式,如下表显示:

Java代码块JSP表达式EL表达式
<%<br/> <br/> String message = (String)request.getAttribute("message");<br/> out.write(message);<br/>%><%=request.getAttribute("message")%>${message}

通过上面我们可以看出,都可以从请求域中获取数据,但是EL表达式写起来是最简单的方式。这也是以后我们在实际开发中,当使用JSP作为视图时,绝大多数都会采用的方式。

3.1.2、 EL表达式的入门案例

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>EL表达式快速入门</title>
</head>
<body>
<%--向域对象中添加请求--%>
<%
    request.setAttribute("username", "shixiaochuang");
%>
<%--获取数据--%>
Java代码块:
<%
    Object username = request.getAttribute("username");
    out.println(username);
%>
<hr/>
JSP表达式:
<%=
request.getAttribute("username")
%>
<hr/>
EL表达式:${username}
</body>
</html>
http://localhost:8080/demo02/el01.jsp

image-20240830202725026

3.2、 EL表达式基本用法

在前面的概述介绍中,我们介绍了EL表达式的作用,它就是用于获取数据的,那么它是从哪获取数据呢?

1)获取四大域中的数据

它只能从四大域中获取数据,调用的就是findAttribute(name,value);方法,根据名称由小到大逐个域中查找,找到就返回,找不到就什么都不显示。

它可以获取对象,可以是对象中关联其他对象,可以是一个List集合,也可以是一个Map集合。具体代码如下:

创建两个实体类,User和Address

package com.jsp.demo02;

import java.io.Serializable;

/**
 * 用户的实体类
 */
public class User implements Serializable {

    private String name = "史小创";
    private int age = 18;
    private Address address = new Address();

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Address getAddress() {
        return address;
    }
    public void setAddress(Address address) {
        this.address = address;
    }

}
package com.jsp.demo02;

import java.io.Serializable;

/**
 * @Author: 史小创
 * @Time: 2024/8/30 下午8:33
 * @Description: 地址的实体类
 */
public class Address implements Serializable {

    private String province = "北京";
    private String city = "昌平区";
    public String getProvince() {
        return province;
    }
    public void setProvince(String province) {
        this.province = province;
    }
    public String getCity() {
        return city;
    }
    public void setCity(String city) {
        this.city = city;
    }
}
<%--
@Author: 史小创
@Time: 2024/8/30 下午8:38
@Description:
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="com.jsp.demo02.User" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.HashMap" %>
<%@ page import="java.util.Map" %>
<html>
<head>
    <title>EL入门</title>
</head>
<body>
<%--EL表达式概念:
				它是Expression Language的缩写。它是一种替换jsp表达式的语言。
			EL表达式的语法:
				${表达式}
				表达式的特点:有明确的返回值。
				EL表达式就是把内容输出到页面上
			EL表达式的注意事项:
				1.EL表达式没有空指针异常
				2.EL表达式没有数组下标越界
				3.EL表达式没有字符串拼接
			EL表达式的数据获取:
				它只能在四大域对象中获取数据,不在四大域对象中的数据它取不到。
				它的获取方式就是findAttribute(String name)
		 --%>
<br/>-----------获取对象数据---------------------<br/>
<%
    //1.把用户的信心存入域中
    User user = new User();
    pageContext.setAttribute("u", user);
%>
${u}===============输出的是内存地址
<br/>
${u.name}
${u.age}
<hr/>
<%--与下面代码的含义是一致的--%>
<%--<%--%>
<%--    user = (User) pageContext.findAttribute("u");--%>
<%--    out.print(user);--%>
<%--    System.out.println();--%>
<%--    user.getName();--%>
<%--    user.getAge();--%>
<%--%>--%>
<br/>-----------获取关联对象数据------------------<br/>
${u.address}==========输出的address对象的地址<br/>
${u.address.province}${u.address.city}<br/>
${u["address"]['province']}
<hr/>
<br/>-----------获取数组数据---------------------<br/>
<%
    String[] strs = new String[]{"He", "llo", "Expression", "Language"};
    pageContext.setAttribute("strs", strs);
%>
${strs[0]}==========取的数组中下标为0的元素<br/>
${strs[3]}
${strs[5]}===========如果超过了数组的下标,则什么都不显示<br/>
${strs["2"]}=========会自动为我们转换成下标<br/>
${strs['1']}
<hr/>
<br/>-----------获取List集合数据-----------------<br/>
<%
    List<String> list = new ArrayList<String>();
    list.add("AAA");
    list.add("BBB");
    list.add("CCC");
    list.add("DDD");
    pageContext.setAttribute("list", list);
%>
${list}<br/>
${list[0] }<br/>
${list[3] }<br/>
<hr/>
<br/>-----------获取Map集合数据------------------<br/>
<%
    Map<String, User> map = new HashMap<String, User>();
    map.put("aaa", new User());
    pageContext.setAttribute("map", map);
%>
${map}<br/>
${map.aaa}<%--获取map的value,是通过get(Key) --%><br/>
${map.aaa.name}${map.aaa.age}<br/>
${map["aaa"].name }

<hr/>

</body>
</html>
http://localhost:8080/demo02/el02.jsp

image-20240830210812548

2)EL表达式的注意事项

在使用EL表达式时,它帮我们做了一些处理,使我们在使用时可以避免一些错误。它没有空指针异常,没有数组下标越界,没有字符串拼接。

<%--
@Author: 史小创  
@Time: 2024/8/30 下午9:08
@Description: el表达式的注意事项
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>el表达式的注意事项</title>
</head>
<body>
<%--EL表达式的三个没有--%>
第一个:没有空指针异常<br/>
<% 
    String str = null;
    request.setAttribute("testNull", str);
%>
${testNull}
<hr/>
第二个:没有数组下标越界<br/>
<% 
    String[] strs = new String[]{"a", "b", "c"};
    request.setAttribute("strs", strs);
%>
取第一个元素:${strs[0]}
取第六个元素:${strs[5]}
<hr/>
第三个:没有字符串拼接<br/>
<%--${strs[0]+strs[1]}--%>
${strs[0]}+${strs[1]}
</body>
</html>

运行结果图:

http://localhost:8080/demo02/el03.jsp

image-20240830211056586

3)EL表达式的使用细节

EL表达式除了能在四大域中获取数据,同时它可以访问其他隐式对象,并且访问对象有返回值的方法.

4)EL表达式的运算符

EL表达式中运算符如下图所示,它们都是一目了然的:

image-20240830211229879

但是有两个特殊的运算符,使用方式的代码如下:

<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.List" %><%--
@Author: 史小创  
@Time: 2024/8/30 下午9:12
@Description: 
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>EL两个特殊的运算符</title>
</head>
<body>
<%--empty运算符:
			它会判断:对象是否为null,字符串是否为空字符串,集合中元素是否是0个
		--%>
<%
    String str = null;
    String str1 = "";
    List<String> slist = new ArrayList<String>();
    pageContext.setAttribute("str", str);
    pageContext.setAttribute("str1", str1);
    pageContext.setAttribute("slist", slist);
%>

${empty str}============当对象为null返回true<br/>
${empty str1 }==========当字符串为空字符串是返回true(注意:它不会调用trim()方法)<br>
${empty slist}==========当集合中的元素是0个时,是true
<hr/>
<%--三元运算符
     条件?真:假
--%>
<% request.setAttribute("gender", "female"); %>
<input type="radio" name="gender" value="male" ${gender eq "male"?"checked":""} >男
<input type="radio" name="gender" value="female" ${gender eq "female"?"checked":""}>女
</body>
</html>
http://localhost:8080/demo02/el04.jsp

image-20240830211539530

3.3、EL表达式的11个隐式对象

EL表达式也为我们提供隐式对象,可以让我们不声明直接来使用,十一个对象见下表,需要注意的是,它和JSP的隐式对象不是一回事:

EL中的隐式对象类型对应JSP隐式对象备注
PageContextJavax.serlvet.jsp.PageContextPageContext完全一样
ApplicationScopeJava.util.Map没有应用层范围
SessionScopeJava.util.Map没有会话范围
RequestScopeJava.util.Map没有请求范围
PageScopeJava.util.Map没有页面层范围
HeaderJava.util.Map没有请求消息头key,值是value(一个)
HeaderValuesJava.util.Map没有请求消息头key,值是数组(一个头多个值)
ParamJava.util.Map没有请求参数key,值是value(一个)
ParamValuesJava.util.Map没有请求参数key,值是数组(一个名称多个值)
InitParamJava.util.Map没有全局参数,key是参数名称,value是参数值
CookieJava.util.Map没有Key是cookie的名称,value是cookie对象

3.4、EL表达式的综合使用

package com.jsp.demo02;

public class Brand {
    private int id;
    private String brandName;
    private String companyName;
    private int order;
    private String description;
    private int status;

    // Constructors, getters and setters
    public Brand(int id, String brandName, String companyName, int order, String description, int status) {
        this.id = id;
        this.brandName = brandName;
        this.companyName = companyName;
        this.order = order;
        this.description = description;
        this.status = status;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getBrandName() {
        return brandName;
    }

    public void setBrandName(String brandName) {
        this.brandName = brandName;
    }

    public String getCompanyName() {
        return companyName;
    }

    public void setCompanyName(String companyName) {
        this.companyName = companyName;
    }

    public int getOrder() {
        return order;
    }

    public void setOrder(int order) {
        this.order = order;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public int getStatus() {
        return status;
    }

    public void setStatus(int status) {
        this.status = status;
    }
}
package com.jsp.demo02;

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

/**
 * @Author: 史小创
 * @Time: 2024/8/30 下午9:20
 * @Description:
 */

@WebServlet("/eldemo")
public class ELServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1. 准备数据
        List<Brand> brands = new ArrayList<Brand>();
        brands.add(new Brand(1, "三只松鼠", "三只松鼠", 100, "三只松鼠,好吃不上火", 1));
        brands.add(new Brand(2, "优衣库", "优衣库", 200, "优衣库,服适人生", 0));
        brands.add(new Brand(3, "小米", "小米科技有限公司", 1000, "为发烧而生", 1));

        // 2.将数据储存在request请求中
        req.setAttribute("brands", brands);

        // 3.转发至jsp
        // 此处需要用转发,因为转发才可以使用 request 对象作为域对象进行数据共享
        req.getRequestDispatcher("/el05.jsp").forward(req, resp);

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}
<%--
    @Author: 史小创  
    @Time: 2024/8/30 下午9:28
    @Description: 
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

${brands[0].id} - ${brands[0].brandName} - ${brands[0].companyName} - ${brands[0].order} - ${brands[0].description} - ${brands[0].status} <br/>
${brands[1].id} - ${brands[1].brandName} - ${brands[1].companyName} - ${brands[1].order} - ${brands[1].description} - ${brands[1].status} <br/>
${brands[2].id} - ${brands[2].brandName} - ${brands[2].companyName} - ${brands[2].order} - ${brands[2].description} - ${brands[2].status} <br/>

</body>
</html>
http://localhost:8080/demo02/eldemo

image-20240830214848001

el 表达式获取数据,会依次从JavaWeb中四大域对象中寻找,直到找到为止。

例如: ${brands},el 表达式获取数据,会先从page域对象中获取数据,如果没有再到 requet 域对象中获取数据,如果再没有再到 session 域对象中获取,如果还没有才会到 application 中获取数据。

四、JSTL

4.1、JSTL概述

1)简介

JSTL的全称是:JSP Standard Tag Libary。它是JSP中标准的标签库。它是由Apache实现的。

它由以下5个部分组成:

组成作用说明
Core核心标签库。通用逻辑处理
Fmt国际化有关。需要不同地域显示不同语言时使用
FunctionsEL函数EL表达式可以使用的方法
SQL操作数据库。不用
XML操作XML。不用

JSTL 提供了很多标签,如下图

image-20240830215250999

2)基本使用

在我们实际开发中,用到的jstl标签库主要以核心标签库为准,偶尔会用到国际化标签库的标签。下表中把我们经常可能用到的标签列在此处,其余标签库请同学们参考【JSTL标签库.doc】文档。

标签名称功能分类分类作用
<c:if>流程控制核心标签库用于判断
<c:choose> ,<c:when>,<c:otherwise>流程控制核心标签库用于多个条件判断
<c:foreache>迭代操作核心标签库用于循环遍历
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %><%--
    @Author: 史小创  
    @Time: 2024/8/30 下午9:56
    @Description:  基本使用
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--导入jstl标签库 --%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
    <title>基本使用</title>
</head>
<body>
<%-- c:if  c:choose   c:when c:otherwise --%>
<% pageContext.setAttribute("score", "F"); %>
<c:if test="${pageScope.score eq 'A' }">
    优秀
</c:if>
<c:if test="${pageScope.score eq 'C' }">
    一般
</c:if>
<hr/>
<c:choose>
    <c:when test="${pageScope.score eq 'A' }">
        AAA
    </c:when>
    <c:when test="${pageScope.score eq 'B' }">BBB
    </c:when>
    <c:when test="${pageScope.score eq 'C' }">CCC
    </c:when>
    <c:when test="${pageScope.score eq 'D' }">DDD
    </c:when>
    <c:otherwise>其他</c:otherwise>
</c:choose>

<%-- c:forEach 它是用来遍历集合的
     属性:
         items:要遍历的集合,它可以是EL表达式取出来的
         var:把当前遍历的元素放入指定的page域中。 var的取值就是key,当前遍历的元素就是value
             注意:它不能支持EL表达式,只能是字符串常量
         begin:开始遍历的索引
         end:结束遍历的索引
         step:步长。i+=step
         varStatus:它是一个计数器对象。里面有两个属性,一个是用于记录索引。一个是用于计数。
                    索引是从0开始。计数是从1开始
--%>
<hr/>
<% List<String> list = new ArrayList<String>();
    list.add("AAA");
    list.add("BBB");
    list.add("CCC");
    list.add("DDD");
    list.add("EEE");
    list.add("FFF");
    list.add("GGG");
    list.add("HHH");
    list.add("III");
    list.add("JJJ");
    list.add("KKK");
    list.add("LLL");
    pageContext.setAttribute("list", list);
%>
<c:forEach items="${list}" var="s" begin="1" end="7" step="2">
    ${s}<br/>
</c:forEach>
<hr/>
<c:forEach begin="1" end="9" var="num">
    <a href="#">${num}</a>
</c:forEach>
<hr/>
<table>
    <tr>
        <td>索引</td>
        <td>序号</td>
        <td>信息</td>
    </tr>
    <c:forEach items="${list}" var="s" varStatus="vs">
        <tr>
            <td>${vs.index}</td>
            <td>${vs.count}</td>
            <td>${s}</td>
        </tr>
    </c:forEach>
</table>
</body>
</html>
http://localhost:8080/demo03/jstl01.jsp

image-20240830215903692

4.2、常用标签

4.2.1、if 标签

<c:if>:相当于 if 判断

  • 属性:test,用于定义条件表达式
<c:if test="${flag == 1}">
    男
</c:if>
<c:if test="${flag == 2}">
    女
</c:if>

代码演示:

package com.jsp.demo03;

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;

/**
 * @Author: 史小创
 * @Time: 2024/8/30 下午10:07
 * @Description: 定义一个 `servlet` ,在该 `servlet` 中向 request 域对象中添加 键是 `status` ,值为 `1` 的数据
 */

@WebServlet("/jsp01")
public class JSPServlet01 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 储存数据到reaquest域中
        req.setAttribute("status", 1);

        // 2. 转发到 jstl-if.jsp
        req.getRequestDispatcher("/jstl-if.jsp").forward(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
    @Author: 史小创  
    @Time: 2024/8/30 下午10:09
    @Description:  定义 `jstl-if.jsp` 页面,在该页面使用 `<c:if>` 标签
--%>

<html>
<head>
    <title>Title</title>
</head>
<body>
<%--
      c:if:来完成逻辑判断,替换java  if else
  --%>
<c:if test="${status==1}">
    启动
</c:if>
<c:if test="${status==0}">
    禁用
</c:if>
</body>
</html>
http://localhost:8080/demo03/jsp01

image-20240830221447796

4.2.1、forEach 标签

<c:forEach>:相当于 for 循环。java中有增强for循环和普通for循环,JSTL 中的 <c:forEach> 也有两种用法

4.2.1.1、用法一

类似于 Java 中的增强for循环。涉及到的 <c:forEach> 中的属性如下

  • items:被遍历的容器

  • var:遍历产生的临时变量

  • varStatus:遍历状态对象

如下代码,是从域对象中获取名为 brands 数据,该数据是一个集合;遍历遍历,并给该集合中的每一个元素起名为 brand,是 Brand对象。在循环里面使用 EL表达式获取每一个Brand对象的属性值

<c:forEach items="${brands}" var="brand">
    <tr align="center">
        <td>${brand.id}</td>
        <td>${brand.brandName}</td>
        <td>${brand.companyName}</td>
        <td>${brand.description}</td>
    </tr>
</c:forEach>
package com.jsp.demo03;

/**
 * 品牌实体类
 */

public class Brand {
    // id 主键
    private Integer id;
    // 品牌名称
    private String brandName;
    // 企业名称
    private String companyName;
    // 排序字段
    private Integer ordered;
    // 描述信息
    private String description;
    // 状态:0:禁用  1:启用
    private Integer status;


    public Brand() {
    }

    public Brand(Integer id, String brandName, String companyName, String description) {
        this.id = id;
        this.brandName = brandName;
        this.companyName = companyName;
        this.description = description;
    }

    public Brand(Integer id, String brandName, String companyName, Integer ordered, String description, Integer status) {
        this.id = id;
        this.brandName = brandName;
        this.companyName = companyName;
        this.ordered = ordered;
        this.description = description;
        this.status = status;
    }
    // getId  ${brand.id}   Id   getId
    public Integer getId() {
        System.out.println("getId方法被调用了...");
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getBrandName() {
        return brandName;
    }

    public void setBrandName(String brandName) {
        this.brandName = brandName;
    }

    public String getCompanyName() {
        return companyName;
    }

    public void setCompanyName(String companyName) {
        this.companyName = companyName;
    }

    public Integer getOrdered() {
        return ordered;
    }

    public void setOrdered(Integer ordered) {
        this.ordered = ordered;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }

    @Override
    public String toString() {
        return "Brand{" +
                "id=" + id +
                ", brandName='" + brandName + '\'' +
                ", companyName='" + companyName + '\'' +
                ", ordered=" + ordered +
                ", description='" + description + '\'' +
                ", status=" + status +
                '}';
    }
}
package com.jsp.demo03;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


/**
 * @Author: 史小创
 * @Time: 2024/8/30 下午10:23
 * @Description:
 */

@WebServlet("/jsp02")
public class JSPServlet02 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1. 准备数据
        List<Brand> brands = new ArrayList<Brand>();
        brands.add(new Brand(1,"三只松鼠","三只松鼠",100,"三只松鼠,好吃不上火",1));
        brands.add(new Brand(2,"优衣库","优衣库",200,"优衣库,服适人生",0));
        brands.add(new Brand(3,"小米","小米科技有限公司",1000,"为发烧而生",1));


        //2. 存储到request域中
        req.setAttribute("brands",brands);
        req.setAttribute("status",1);

        // 2.将数据储存在request请求中
        req.setAttribute("brands", brands);

        // 3.转发至jsp
        // 此处需要用转发,因为转发才可以使用 request 对象作为域对象进行数据共享
        req.getRequestDispatcher("/jstl-foreach.jsp").forward(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}
package com.jsp.demo03;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


/**
 * @Author: 史小创
 * @Time: 2024/8/30 下午10:23
 * @Description:
 */

@WebServlet("/jsp02")
public class JSPServlet02 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1. 准备数据
        List<Brand> brands = new ArrayList<Brand>();
        brands.add(new Brand(1,"三只松鼠","三只松鼠",100,"三只松鼠,好吃不上火",1));
        brands.add(new Brand(2,"优衣库","优衣库",200,"优衣库,服适人生",0));
        brands.add(new Brand(3,"小米","小米科技有限公司",1000,"为发烧而生",1));


        //2. 存储到request域中
        req.setAttribute("brands",brands);
        req.setAttribute("status",1);

        // 2.将数据储存在request请求中
        req.setAttribute("brands", brands);

        // 3.转发至jsp
        // 此处需要用转发,因为转发才可以使用 request 对象作为域对象进行数据共享
        req.getRequestDispatcher("/jstl-foreach.jsp").forward(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<table border="1" cellspacing="0" width="80%">
    <tr>
        <th>序号</th>
        <th>品牌名称</th>
        <th>企业名称</th>
        <th>排序</th>
        <th>品牌介绍</th>
        <th>状态</th>
    </tr>
    <c:forEach items="${brands}" var="brand" varStatus="status">
        <tr align="center">
                <%--<td>${brand.id}</td>--%>
            <td>${status.count}</td>
            <td>${brand.brandName}</td>
            <td>${brand.companyName}</td>
            <td>${brand.ordered}</td>
            <td>${brand.description}</td>
            <c:if test="${brand.status == 1}">
                <td>启用</td>
            </c:if>
            <c:if test="${brand.status != 1}">
                <td>禁用</td>
            </c:if>
        </tr>
    </c:forEach>

</table>
</body>
</html>
http://localhost:8080/demo03/jsp02

image-20240830225216379

4.2.1.2、用法二

类似于 Java 中的普通for循环。涉及到的 <c:forEach> 中的属性如下

  • begin:开始数

  • end:结束数

  • step:步长

实例代码:

从0循环到10,变量名是 i ,每次自增1

<c:forEach begin="0" end="10" step="1" var="i">
    ${i}
</c:forEach>

五、MVC模式和三层架构

MVC 模式和三层架构是一些理论的知识,将来我们使用了它们进行代码开发会让我们代码维护性和扩展性更好。

5.1 、MVC模式

MVC 是一种分层开发的模式,其中:

  • M:Model,业务模型,处理业务

  • V:View,视图,界面展示

  • C:Controller,控制器,处理请求,调用模型和视图

image-20240830225333138

控制器(serlvlet)用来接收浏览器发送过来的请求,控制器调用模型(JavaBean)来获取数据,比如从数据库查询数据;控制器获取到数据后再交由视图(JSP)进行数据展示。

MVC 好处:

  • 职责单一,互不影响。每个角色做它自己的事,各司其职。

  • 有利于分工协作。

  • 有利于组件重用

5.2、三层架构

三层架构是将我们的项目分成了三个层面,分别是 表现层业务逻辑层数据访问层

image-20240830225402333

  • 数据访问层:对数据库的CRUD基本操作
  • 业务逻辑层:对业务逻辑进行封装,组合数据访问层层中基本功能,形成复杂的业务逻辑功能。例如 注册业务功能 ,我们会先调用 数据访问层selectByName() 方法判断该用户名是否存在,如果不存在再调用 数据访问层insert() 方法进行数据的添加操作
  • 表现层:接收请求,封装数据,调用业务逻辑层,响应数据

而整个流程是,浏览器发送请求,表现层的Servlet接收请求并调用业务逻辑层的方法进行业务逻辑处理,而业务逻辑层方法调用数据访问层方法进行数据的操作,依次返回到serlvet,然后servlet将数据交由 JSP 进行展示。

5.3、MVC 和 三层架构

通过 MVC 和 三层架构 的学习,有些人肯定混淆了。那他们有什么区别和联系?

image-20240830225451366

如上图上半部分是 MVC 模式,上图下半部分是三层架构。 MVC 模式 中的 C(控制器)和 V(视图)就是 三层架构 中的表现层,而 MVC 模式 中的 M(模型)就是 三层架构 中的 业务逻辑层 和 数据访问层。

可以将 MVC 模式 理解成是一个大的概念,而 三层架构 是对 MVC 模式 实现架构的思想。 那么我们以后按照要求将不同层的代码写在不同的包下,每一层里功能职责做到单一,将来如果将表现层的技术换掉,而业务逻辑层和数据访问层的代码不需要发生变化。

六、JSP 缺点

通过上面的案例,我们可以看到 JSP 的很多缺点。

由于 JSP页面内,既可以定义 HTML 标签,又可以定义 Java代码,造成了以下问题:

  • 书写麻烦:特别是复杂的页面

    既要写 HTML 标签,还要写 Java 代码

  • 阅读麻烦

    上面案例的代码,相信你后期再看这段代码时还需要花费很长的时间去梳理

  • 复杂度高:运行需要依赖于各种环境,JRE,JSP容器,JavaEE…

  • 占内存和磁盘:JSP会自动生成.java和.class文件占磁盘,运行的是.class文件占内存

  • 调试困难:出错后,需要找到自动生成的.java文件进行调试

  • 不利于团队协作:前端人员不会 Java,后端人员不精 HTML

    如果页面布局发生变化,前端工程师对静态页面进行修改,然后再交给后端工程师,由后端工程师再将该页面改为 JSP 页面

由于上述的问题, ==JSP 已逐渐退出历史舞台,==以后开发更多的是使用 HTML + Ajax 来替代。Ajax 是我们后续会重点学习的技术。有个这个技术后,前端工程师负责前端页面开发,而后端工程师只负责前端代码开发。下来对技术的发展进行简单的说明

image-20240830225609551

  1. 第一阶段:使用 servlet 即实现逻辑代码编写,也对页面进行拼接。这种模式我们之前也接触过

  2. 第二阶段:随着技术的发展,出现了 JSP ,人们发现 JSP 使用起来比 Servlet 方便很多,但是还是要在 JSP 中嵌套 Java 代码,也不利于后期的维护

  3. 第三阶段:使用 Servlet 进行逻辑代码开发,而使用 JSP 进行数据展示

image-20240830225620785

  1. 第四阶段:使用 servlet 进行后端逻辑代码开发,而使用 HTML 进行数据展示。而这里面就存在问题,HTML 是静态页面,怎么进行动态数据展示呢?这就是 ajax 的作用了。

那既然 JSP 已经逐渐的退出历史舞台,那我们为什么还要学习 JSP 呢?原因有两点:

  • 一些公司可能有些老项目还在用 JSP ,所以要求我们必须动 JSP
  • 我们如果不经历这些复杂的过程,就不能体现后面阶段开发的简单

七、环境搭建

软件版本网址
Maven3.8.4https://archive.apache.org/dist/maven/maven-3/3.8.4/binaries/
Tomcat9.0.29https://archive.apache.org/dist/tomcat/tomcat-9/v9.0.29/bin/
JDK1.8.0_411https://www.oracle.com/java/technologies/javase/javase8u211-later-archive-downloads.html

代码汇总:

https://github.com/shixiaochuangjob/markdownfile/tree/main/20240831

image-20240831074406573

https://mp.weixin.qq.com/s?__biz=MzkwOTczNzUxMQ==&mid=2247485225&idx=1&sn=a1adb2bacfa135f2bbb8655a9082d275&chksm=c1376c61f640e57758c6a7f24cfcd581246baff9846b61b809aebfe05d2da18e5e00ffabdae5#rd

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

阿尔茨海默病症识别+图像识别Python+人工智能+深度学习+TensorFlow+机器学习+卷积神经网络算法

一、介绍 阿尔茨海默病症识别。使用Python作为主要编程语言进行开发&#xff0c;基于深度学习等技术使用TensorFlow搭建ResNet50卷积神经网络算法&#xff0c;通过对病症图片4种数据集进行训练[‘轻度痴呆’, ‘中度痴呆’, ‘非痴呆’, ‘非常轻微的痴呆’]&#xff0c;最终得…

SimpleTranslationAIAgent借助SiliconCloud API 构建自己的专属翻译助手

SimpleTranslationAIAgent介绍 SimpleTranslationAIAgent是一款基于C#与LLM通过简单对话即可实现文件到文件的翻译任务的简单应用&#xff0c;基于WPF与Semantic Kernel构建。 该软件是MIT协议完全开源免费的&#xff0c;但是调用LLM的API可能需要费用&#xff0c;但是没关系…

暴雪前总裁:主机永远不会死 索尼独占策略很成功

近年来&#xff0c;我们不断听到“主机即将消亡”的消息。然而&#xff0c;前暴雪娱乐总裁Mike Ybarra却认为&#xff0c;主机不会消亡&#xff0c;并暗讽微软正在推动一种有利于自己的叙事。 Ybarra在社交媒体X上表示&#xff0c;索尼的独占游戏策略是正确的&#xff0c;如果想…

AI写作神器!这四款免费工具让你文思泉涌

近年来&#xff0c;AI写作工具的火爆&#xff0c;让我们看到了AI技术在写作领域的巨大潜力。在这里&#xff0c;我给大家推荐四款好用的的AI写作工具&#xff0c;希望可以在大家的工作和学习等等场景中给到一定的帮助哦~ 一、笔灵ai写作 直通车&#xff08;粘贴到浏览器打开&…

五、实现随机地图

一、创建场景 拖拽层级面板&#xff0c;删除摄像机 二、使用Addressable 给场景设置碰撞器 三、场景切换 场景中增加一个数据集合选择场景 四、字典 1、作用 根据列表中的RoomType查找数据 创建一个RoomDataSO的列表&#xff1b;创建一个字典&#xff0c;匹配房间类型和数据…

QT实现MP4播放器

1、实现功能 播放本地MP4文件。 1、可以将文件添加到列表中&#xff0c;双击列表中的歌曲进行播放。 2、实现视频的播放与暂停。 3、上一首和下一首的按钮选择功能。 4、视频名称的滚动显示。 5、当前的播放时长和总时长。 6、播放模式的选择&#xff1a;单曲循环、随机播…

2025年事业编考试证件照有什么要求和条件?

在事业编考试中&#xff0c;证件照作为考生身份识别的重要材料&#xff0c;其要求十分严格。一般而言&#xff0c;合格的事业编考试证件照需满足以下要求&#xff1a; 图片组合包活动地址&#xff1a;点击进入 一、事业编考试证件照要求 格式与大小&#xff1a;照片应为JPG或…

c++ STL 容器相关

容器库&#xff1a;容器库 - cppreference.com 一、std::priority_queue #include <queue> template<class T,class Container std::vector<T>,class Compare std::less<typename Container::value_type> > class priority_queue; 优先级队列是一…

学习资料销售平台小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;资料类型管理&#xff0c;学习资料管理&#xff0c;订单管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;学习资料&#xff0c;购物车&#xff0c;…

C/C++二维码生成库qrencode编译与使用

1 qrencode介绍 qrencode 是一个用于生成 QR 码&#xff08;Quick Response Code&#xff09;的工具和库。QR 码是一种矩阵条形码或二维条形码&#xff0c;能够在水平和垂直方向上存储信息。qrencode 支持多种编码方式&#xff0c;并能够生成不同复杂度和错误校正级别的 QR 码…

计算机组成原理:实验四常规型微程序控制器组成实验

一、实验目的 1.掌握时序产生器的组成原理。 2.掌握微程序控制器的组成原理。 3.掌握微指令格式的化简和归并。 二、实验电路 1.时序发生器 TEC-4计算机组成原理实验系统的时序电路如图4.1所示。电路采用2片GAL22V10&#xff08;U6、U7&#xff09;&#xff0c;可产生两极…

微信小程序App实现小车方向控制

目录 概述 1 系统框架结构 1.1 结构介绍 1.2 硬件模块介绍 1.2.1 蓝牙模块介绍 1.2 .2 模块功能介绍 2 功能实现 2.1 微信小程序APP 2.2 下位机功能 3 功能测试 3.1 小程序UI测试 3.2 小车方向控制 微信小程序和蓝牙模块控制小车运行状态 概述 本文主要介绍使用微信…

vue.js项目实战案例源码

Vue.js是一个用于构建用户界面的渐进式框架&#xff0c;非常适合开发单页面应用。以下是一些实战案例的源码&#xff0c;可以帮助你更好地理解和使用Vue.js&#xff1a; Vue TodoMVC 简介&#xff1a;这是学习Vue.js的入门级项目&#xff0c;主要实现了一个待办事项列表。源码地…

Python优化算法17——黄金正弦算法(GSA)

科研里面优化算法都用的多&#xff0c;尤其是各种动物园里面的智能仿生优化算法&#xff0c;但是目前都是MATLAB的代码多&#xff0c;python几乎没有什么包&#xff0c;这次把优化算法系列的代码都从底层手写开始。 需要看以前的优化算法文章可以参考&#xff1a;Python优化算…

从 CRX 文件安装 Chrome 扩展程序

在使用嵌入式 Browser 中的扩展程序时&#xff0c;您可能希望将它们打包并分发在应用程序中&#xff0c;并静默安装。 在本教程中&#xff0c;我将演示如何通过编程方式从 CRX 文件中安装扩展程序&#xff0c;保持它们的更新&#xff0c;并使用它们。 此外&#xff0c;我还会…

8.30工作笔记

要做的事情&#xff1a; 1 测试剩下的三个因子&#xff1a;coppock 潮汐因子 云开雾散 2 整理需要时间序列的因子 以及截面因子 3 灾后重建多了一列&#xff0c;灾后重建’所有值都是nan&#xff0c;这里不仅是灾后重建&#xff0c;所有的都要改 4 coppock 潮汐因子 云开雾散在…

排列数+时间戳+逆元取模

前言&#xff1a;这个题目是真的难&#xff0c;不会做&#xff0c;看了题解才发现是咋回事 题目地址 最主要的就是为啥是除以3&#xff0c;c之前需要完成a 和 b&#xff0c;d 和 e 对我们的答案没有影响&#xff0c;所以我们要除以 A(3,3) ,但是 a 和 b 的排列没有要求&#xf…

Sinc Function介绍

1、定义 Sinc函数全称&#xff1a;sine cardinal&#xff0c;也称作是sampling function&#xff08;采样函数&#xff09;。 2、分类 &#xff08;1&#xff09;归一化sinc函数&#xff1a; 这种定义在信号处理中被广泛采用&#xff0c;其中 x 是一个无量纲的变量&#xff0c;…

基于YOLO的车牌检测识别(YOLO+Transformer)

概述&#xff1a; 基于深度学习的车牌识别&#xff0c;其中&#xff0c;车辆检测网络直接使用YOLO侦测。而后&#xff0c;才是使用网络侦测车牌与识别车牌号。 车牌的侦测网络&#xff0c;采用的是resnet18&#xff0c;网络输出检测边框的仿射变换矩阵&#xff0c;可检测任意形…

同城小程序怎么做 同城小程序系统开发制作方案

很多同城创业的老板们想要做一个同城小程序但是不知道怎么做&#xff0c;本次瀚林就为大家详细介绍一下做同城小程序系统开发制作方法&#xff0c;给大家做个参考。 目前同城类型的小程序系统市面上比较常见的有&#xff1a;同城配送、鲜花订花、同城上门服务、同城跑腿、同城便…