[spring] Spring MVC Thymeleaf(上)

[spring] Spring MVC & Thymeleaf(上)

本章内容主要过一下简单的 Spring MVC 的案例

简单来说,spring mvc 就是比较传统的网页开发流程,目前 boot 是可以比较轻松的配置 thymeleaf——毕竟 spring boot 内置对 thymeleaf 的支持

thymeleaf 是一个模板引擎,目前看起来是简单很多——我还依稀记得当年使用 JSP 写 spring mvc 的日子,那写的是真的很痛苦……

简单的 demo

这里就放一个超简单的 demo,能让页面跑起来就行

spring boot initializer

这里主要用的就是这 4 个包,下里用的案例会多一个依赖

在这里插入图片描述

实现简单 demo

因为是 spring mvc,所以肯定是需要有 Mocel-View-Controller 三个实现的。不过这个 demo 里面因为不涉及到数据的交互,所以没有 model

具体实现如下:

  • controller

    package com.example.thymeleafdemo.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.GetMapping;
    
    @Controller
    public class DemoController {
        // create a mapping for "/hello"
        @GetMapping("/hello")
        public String sayHello(Model model) {
            model.addAttribute("date", java.time.LocalDateTime.now());
    
            return "helloworld";
        }
    }
    
    
    • @Controller 的实现都比较熟悉了,这代表这是一个 Controller 的注解。因为这不是一个前后端分离的 rest api 实现,所以这里不需要使用 @RestController,也不需要做 request mapping

    • @GetMapping 这个就比较熟悉了,当用户访问 http://localhost:8080/hello 是就会调用当前方法

    • sayHello 是方法名,它返回的是一个字符串,而这个字符串代表着 view 的名字。以 thymeleaf 为例,spring mvc 会找到对应的模板渲染 view 层,这个也是下面会提到的

      实现的模板引擎的文件名为这里返回的字符串,即 helloworld.html

    • Model model 是 spring 在察觉到当前方法是 controller 的方法时,自动进行绑定的参数。view 层可以直接调用 model 里被添加的属性——model.addAttribute("date", java.time.LocalDateTime.now());,也就是 date 这个属性

  • view

    view 层具体在的位置位于 resources/templates 下:

    在这里插入图片描述

    实现为:

    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
      <head>
        <meta charset="UTF-8" />
        <link rel="stylesheet" th:href="@{/css/demo.css}" />
        <title>Title</title>
      </head>
      <body>
        <p th:text="'Time on the server is ' + ${date}" class="funny"></p>
    
        <script src="http://localhost:35729/livereload.js"></script>
      </body>
    </html>
    

    这里的的视线相对比较简单,基础的 HTML 就不谈了

    • xmlns:th="http://www.thymeleaf.org 是 thymeleaf 的命名空间,也就是说下面都可以通过 th:<attr> 使用 thymeleaf 特有的属性

    • <link rel="stylesheet" th:href="@{/css/demo.css}" /> 使用的就是 thymeleaf 的语法,这里会自动解析路径去寻找对应的 css 文件,也就是在 static/css/demo.css 这个文件

    • <p th:text="'Time on the server is ' + ${date}" class="funny"></p> 这里用的是一个新的 thymeleaf 的语法,th:text 可以将后面的表达式,也就是 'Time on the server is ' + ${date} 写入到 element 中

      ${date} 就是在 controller 中传到 model 的属性,可以通过 ${} 的方式获得

    • <script src="http://localhost:35729/livereload.js"></script> 是一个热更新的脚本,在开启了 devtool 之后可以实现保存后 HTML 页面自动更新的功能

      换言之不需要刷新页面,也不需要重启服务器……就是稍微有些慢……

效果如下:

在这里插入图片描述

简述 MVC 的工作原理

在这里插入图片描述

这张图可以描述 spring mvc 的流程是什么样的

首先,浏览器会访问 front controller 组件——spring mvc 中一般指的是 DispatcherServlet,它会:

  • 集中处理所有的 HTTP 请求,并通过 URL mapping,将对应的 http 请求委托给对应的 handler/controller 进行处理
  • 解析 view 层
  • 处理 model,并与 model 和 view 层进行交互,实现 MVC 整体的数据交互

一般来说,front controller, controller, model, view 是四个比较高度抽象化的概念,它们的实施可以通过具体的组件去实现,如:

  • DispatcherServlet 是 front controller 的组件
  • @Controller & @RestController 是 controller 的 bean/class
  • @Model 显而易见的是 model 的组件
  • JSP/Thymeleaf 是 view 的组件等
  • spring 配置文件,如 XML,注解,java 配置文件等,也是 spring 的组件

总体来说,这些组件 spring 队伍已经进行实现完毕,并且内部完成了对应的配置,所以开发需要做的事情就是使用这些组件,将具体的业务填写完毕即可,如:

  • model

    声明必要的 entity 并添加对应的属性;通过 front controller 进行 controller 层和 view 层的沟通

  • view

    实现 thymeleaf/jsp 等支持的引擎模板,从 front controller 获取数据,并进行对应的处理以完成 UI 层面的渲染

  • controller

    与 service 层进行沟通,获取并处理对应的数据,并将其处理为 view 层所需的 model 送到 front controller 去

    一般来说,业务逻辑会从 controller 中抽离出来,以保证 SPR 和代码的低耦合性,不过这篇笔记不会涉及到 crud 的操作,因此可以暂时忽略 service 层

表单 demo

下面写一个 MVC 之间互动的 demo,这样可以更好理解上一个部分中比较抽象的概念

业务逻辑如下:

request mapping via /processForm
with data
view
controller

这里省略掉了 front controller 的存在,毕竟这部分是 spring 已经实现好并且封装起来的功能

具体的实现流程如下:

  1. 创建 controller

  2. 展示 view 层,即渲染引擎模板

    这里具体要实现的功能也分为两步:

    1. 创建对应的 controller 方法去显示 html 表单
    2. 创建 HTML 模板去显示页面

    这两步必须要全部实现,才能通过访问对应的 URL 渲染对应的模板引擎

  3. 处理 HTML 表单

    根据上面的流程图所说,view 需要通过 /processForm 去和 controller 进行交互,这个过程中,view 会将用户填写的数据传给 controller

    这一步处理的过程和上面大致是一样的逻辑:

    1. 创建对应的 controller 方法去处理传来的数据,并显示处理完的页面

    2. 创建 HTML 模板去显示页面

controller 初始代码

package com.example.thymeleafdemo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class HelloWorldController {
    // need a controller method to show initial HTML form
    @RequestMapping("/showForm")
    public String showForm() {
        return "helloworld-form";
    }

    // need a controller method to process HTML form
    @RequestMapping("/processForm")
    public String processForm() {
        return "helloworld";
    }
}

这里没有什么特别复杂的地方,和上面简单 demo 提到的一样

模板引擎初始代码

这里要实现的是两个模板引擎,一个是 helloworld-form.html,用来显示表单,让用户填写数据;一个是 helloworld,这是 controller 收集了用户提交的数据后,新定向的页面,这里将会显示用户输入的数据

具体实现如下:

  • helloworld-form

    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
      <head>
        <meta charset="UTF-8" />
        <title>Hello World - Input Form</title>
      </head>
      <body>
        <form th:action="@{/processForm}" method="get">
          <input type="text" name="studentName" placeholder="Student Name" />
          <input type="submit" value="Submit" />
        </form>
    
        <script src="http://localhost:35729/livereload.js"></script>
      </body>
    </html>
    
  • helloworld

    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
      <head>
        <meta charset="UTF-8" />
        <title>Title</title>
      </head>
      <body>
        Hello World of Spring!
        <br />
        <br />
    
        Student name: <span th:text="${param.studentName}"></span>
    
        <script src="http://localhost:35729/livereload.js"></script>
      </body>
    </html>
    

这里简单的过一遍两个模板都做了什么,第一个 helloworld-form 会渲染一个表单,用户可以通过表单输入数据,并且提交数据。这里提交的方式是 get,所以提交的数据会添加到 URL 路径上;同时 action 中的路径是 @{/processForm},这也是 thymeleaf 的语法,表示会 map 到对应的 /processForm,也就是 controller 中的 @RequestMapping("/processForm") 对应的方法

helloworld 会渲染已经处理好的数据,并且通过 URL 获取用户提交的数据并将其渲染到页面上,效果如下:

在这里插入图片描述

使用 model

之前是直接使用 query parameter 通过 URL 去进行数据传递,不过这只能用在 GET 方法上,如果要使用 POST,那么就需要使用 request body 进行和 controller 的沟通

这个情况下,controller 可以通过 HttpServletRequest 或者 @RequestParam("attributeName") 的方式,从模板引擎那里获取对应的资料,具体实现方式如下:

controller 修改:

    // need a controller method to read from data and add data to the model
    @RequestMapping("/processFormV2")
    public String formWithModel(HttpServletRequest request, Model model) {
        // read req param from html form
        String name = request.getParameter("studentName");
        // convert data to all caps
        name = name.toUpperCase();
        // create the message
        String result = "Yo! " + name;
        // add message to the model
        model.addAttribute("message", result);
        return "helloworld";
    }

注意这里是通过 HttpServletRequest 获取对应的数据,HttpServletRequest 通过 dependency injection 动态完成注入的。在使用 GetMapping 的情况下,HttpServletRequest 会从 URL 的 query string 上获取对应数据;在 PostMapping 的情况下,HttpServletRequest 会从 request body 中动态获取,默认的格式为 Content-Type: application/x-www-form-urlencoded

⚠️:我这里用的是 @RequestMapping("/processFormV2"),最好是使用单独的 PostMappingGetMapping 去增强安全性

HTML 部分省略了,主要就是修改一下 form 请求的地址,变更为 processFormV2,随后就是获取信息的方式为 The message: <span th:text="${message}"></span>

完成修改后的结果如下:

在这里插入图片描述

绑定 request params

这是上面提到的,使用注解的方式获取信息:

    // need a controller method to read from data and add data to the model
    @RequestMapping("/processFormV3")
    public String formWithModel(@RequestParam("studentName") String name, Model model) {
        // convert data to all caps
        name = name.toUpperCase();
        // create the message
        String result = "Using Annotation! " + name;
        // add message to the model
        model.addAttribute("message", result);
        return "helloworld";
    }

HTML 模板方面,同样将指向的地址从 v2 修改到 v3 就可以,效果如下:

在这里插入图片描述

GetMapping & PostMapping

这是上面提到的安全性问题,从开发实现的角度来说,其实不太需要特别在意 spring 底层是怎么完成依赖注入的。不过从语义化开发和安全性的角度,分别使用 @PostMapping@GetMapping 还是挺重要的,一般来说:

  • GET 是用来获取数据的(Retrieve),而 POST 是用来发送数据的(Create, Update, Delete)

  • GET 的数据传送通过 URL Query Param,而 POST 通过 body request

  • GET 的安全性更低,而 POST 安全性更高

  • GET 可以被用来保存书签,而 POST 不可以

  • GET 长度限制比较大,而 POST 的长度限制比较小

    一般情况下 GET 是够用的,毕竟好像有 8000 个左右的字符,我只遇到过一个情况被后台拒绝了……那就是老板想要穷举一堆 AND/OR 的操作让后台可以直接拼接到数据库了去搜索,结果就……超过限制了……

目前 HTML 模板中使用的都是 GET ,如果 Spring 这里使用 @PostMapping 的话,那么 spring 就会抛出 method not allow 的错:

在这里插入图片描述

所以这部分还是要注意的,如果特地规范了 @PostMapping@GetMapping,那么 HTML 部分也要进行对应的更新,如:

    @PostMapping("/showForm")
    public String showForm() {
        return "helloworld-form";
    }

以及

    @GetMapping("/processFormV3")
    public String formWithModel(@RequestParam("studentName") String name, Model model) {
        // convert data to all caps
        name = name.toUpperCase();
        // create the message
        String result = "Using Annotation! " + name;
        // add message to the model
        model.addAttribute("message", result);
        return "helloworld";
    }

更换成 POST 的效果展现如下:

在这里插入图片描述

这里数据就不会从 URL 中传递,反而是通过 request body:

在这里插入图片描述

数据绑定

前面一直手动获取 request body 中的数据,不过,其实 spring 也提供数据绑定,回顾一下这张图:

在这里插入图片描述

数据绑定就是直接对数据进行一个预处理,将数据绑定到对应的 POJO 上,省去了很多的手动操作。下面是具体的实现:

实现一个 POJO:

package com.example.thymeleafdemo.model;

import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

@Data
@NoArgsConstructor
@ToString
public class Student {
    private String firstName;
    private String lastName;
}

更新 controller,使用新注解 @ModelAttribute

package com.example.thymeleafdemo.controller;

import com.example.thymeleafdemo.model.Student;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;

@Controller
public class StudentController {
    @GetMapping("/showStudentForm")
    public String showForm(Model model) {
        // create a student obj
        Student student = new Student();
        // add student obj to the model
        model.addAttribute("student", student);
        return "student-form";
    }

    @PostMapping("/processStudentForm")
    public String processForm(@ModelAttribute("student") Student student) {
        // log the input data
        System.out.println("student: " + student.toString());

        return "student-confirmation";
    }
}

⚠️:这里 @ModelAttribute("student") 的名字,必须要和下面 thymeleaf 中的 object 一致

更新 HTML 模板:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
  <head>
    <meta charset="UTF-8" />
    <title>Student Form</title>
  </head>
  <body>
    <h3>Student Registration Form</h3>

    <form
      th:action="@{/processStudentForm}"
      th:object="${student}"
      method="post"
    >
      First Name: <input type="text" th:field="*{firstName}" />

      <br /><br />

      Last Name: <input type="text" th:field="${student.lastName}" />

      <br /><br />

      <input type="submit" value="Submit" />

      <script src="http://localhost:35729/livereload.js"></script>
    </form>
  </body>
</html>

⚠️:这里的 th:object="${student}" 就是 @ModelAttribute("student") 中的 student,这里的名字必须一致

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
  <head>
    <meta charset="UTF-8" />
    <title>Student Confirmation</title>
  </head>
  <body>
    <h3>Student Confirmation</h3>

    The student is confirmed:
    <span th:text="${student.firstName} + ' ' + ${student.lastName}"></span>

    <script src="http://localhost:35729/livereload.js"></script>
  </body>
</html>

⚠️:这里的 student 是手动通过 model.addAttribute("student", student); 进行绑定的

最终效果如下:

在这里插入图片描述

在这里插入图片描述

thymeleaf 属性

这里新增一些比较常用的 thymeleaf 的表单属性的用法

下拉框

即 dropdown,一个比较死板的写法如下:

<select th:field="*{country}">
  <option th:value="Brazil">Brazil</option>
  <option th:value="France">France</option>
  <option th:value="Germany">Germany</option>
  <option th:value="India">India</option>
</select>

在显示的页面新增代码:

<br /><br />

Country: <span th:text="${student.country}"></span>

这时候更新一下 学生 这个 POJO,新增一个 country 的属性:

public class Student {
    private String firstName;
    private String lastName;
    private String country;
}

因为使用了数据绑定,所以 controller 部分的代码不需要进行任何的变动,实现效果如下:

在这里插入图片描述

动态获取下拉框

上面的代码是写死的,不过有的情况下,可能需要通过 properties 文件获取一些数据,这个时候就没有办法在 thymeleaf 写死所有的选项了

properties 文件更新如下:

countries=Brazil,France,Germany,India,Mexico,Spain,United States

这里新增的是一个关于国家的数组

这个时候就需要更新 controller 了,需要从 properties 文件中获取对应的国家,并且将其传到模板引擎中:

    @Value("${countries}")
    private List<String> countries;

    @GetMapping("/showStudentForm")
    public String showForm(Model model) {
        // create a student obj
        Student student = new Student();
        // add student obj to the model
        model.addAttribute("student", student);

        // add the list of countries to the model
        model.addAttribute("countries", countries);
        return "student-form";
    }

HTML 部分更新如下:

<select th:field="*{country}">
  <option
    th:each="tempCountry : ${countries}"
    th:value="${tempCountry}"
    th:text="${tempCountry}"
  ></option>
</select>

这里使用的是一个 thymeleaf 的 for 循环,最终展示效果如下:

在这里插入图片描述

单选

即 radio button,这里也通过两个方式实现,一个就是写死值的方式,另一个是通过 properties 文件导入

写死的方式如下:

Favorite Programming Language:

<label>
  <input type="radio" th:field="*{favoriteLanguage}" th:value="Go" />
  Go
</label>
<label>
  <input type="radio" th:field="*{favoriteLanguage}" th:value="Java" />
  Java
</label>
<label>
  <input type="radio" th:field="*{favoriteLanguage}" th:value="Python" />
  Python
</label>

其余需要更新的地方也只有 POJO,这里略过不提,展现效果如下:

在这里插入图片描述

动态获取单选

实现方法类似,这里也不多赘述

properties 文件更新:

languages=Go,Java,Python,Rust,TypeScript,JavaScript

controller 部分略过不提,下面是 HTML 的修改:

Favorite Programming Language:

<div th:each="language : ${languages}">
  <label>
    <input type="radio" th:field="*{favoriteLanguage}" th:value="${language}" />
    <span th:text="${language}"></span>
  </label>
</div>

⚠️:这里的 for 循环是绑定在一个外部的 div 上,如果直接迭代 label,那就代表着一个 label 会对应不同的 input,就会影响具体的功能实现

最终渲染效果:

在这里插入图片描述

多选

也就是 checkbox,具体不多赘述,丢代码即可

两个 HTML 的修改:

Favorite Operation System:

<input
  type="checkbox"
  id="Linux"
  th:field="*{favoriteOSs}"
  th:value="Linux"
/><label for="Linux">Linux</label>
<input
  type="checkbox"
  id="MacOS"
  th:field="*{favoriteOSs}"
  th:value="MacOS"
/><label for="MacOS">MacOS</label>
<input
  type="checkbox"
  id="ms"
  th:field="*{favoriteOSs}"
  th:value="'Microsoft Windows'"
/><label for="ms">Microsoft Windows</label>
Favorite Operating Systems: <span th:text="${student.favoriteOSs}"></span>

POJO:

private List<String> favoriteOSs;

效果如下:

在这里插入图片描述

循环渲染结果

这里的格式还是稍微有点奇怪的,因为多选的保存格式为 List<String>,尽管 toString() 的默认实现不是很奇怪,不过也可以稍微优化一下:

<ul>
  <li th:each="favOs: ${student.favoriteOSs}" th:text="${favOs}"></li>
</ul>

在这里插入图片描述

动态渲染多选

具体实现也略过了,和之前的实现一样:

systems=Linux,MacOS,Microsoft Windows,Android,IOS
public class StudentController {
    @Value("${systems}")
    private List<String> systems;

    @GetMapping("/showStudentForm")
    public String showForm(Model model) {
        // ...
        model.addAttribute("systems", systems);
        // ...
    }
}
Favorite Operation System:

<span th:each="system: ${systems}">
  <input
    type="checkbox"
    id="${system}"
    th:field="*{favoriteOSs}"
    th:value="${system}"
  />
  <label for="${system}" th:text="${system}"></label>
</span>

最终效果如下:

在这里插入图片描述

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

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

相关文章

快速开始一个go程序(极简-快速入门)

一、 实验介绍 1.1 实验简介 为了能更高效地使用语言进行编码&#xff0c;Go 语言有自己的哲学和编程习惯。Go 语言的设计者们从编程效率出发设计了这门语言&#xff0c;但又不会丢掉访问底层程序结构的能力。设计者们通过一组最少的关键字、内置的方法和语法&#xff0c;最终…

ChatGPT对话基本原则和玩法

一、使用三个准备 1.1 认知上 超级学霸&#xff0c;几乎所有的工作/生活场景&#xff0c;都可以找它帮忙 ChatGPT作为一个人工智能语言模型&#xff0c;具有强大的知识储备和处理能力。这意味着在许多工作和生活场景中&#xff0c;你都可以向它请教问题或寻求帮助。无论是科…

idea编码问题:需要 <标识符> 非法的类型 、需要为 class、interface 或 enum 问题解决

目录 问题现象 问题解决 问题现象 今天在idea 使用中遇到的一个编码的问题就是&#xff0c;出现了这个&#xff1a; Error:(357, 28) java: /home/luya...........anageService.java:357: 需要 <标识符> Error:(357, 41) java: /home/luya............anageService.ja…

OpenGauss数据库-3.数据库管理

第1关&#xff1a;创建数据库 gsql -d postgres -U gaussdb -w passwd123123 create database accessdb with ownergaussdb templatetemplate0;第2关&#xff1a;修改数据库 gsql -d postgres -U gaussdb -w passwd123123 alter database accessdb rename to human_tpcds; 第…

【清华大学】《自然语言处理》(刘知远)课程笔记 ——NLP Basics

自然语言处理基础&#xff08;Natural Language Processing Basics, NLP Basics&#xff09; 自然语言处理( Natural Language Processing, NLP)是计算机科学领域与人工智能领域中的一个重要方向。它研究能实现人与计算机之间用自然语言进行有效通信的各种理论和方法。自然语言…

智慧园区建设方案(Word)

1. 楼栋管理 2. 物业管理 3. 安防管理 4. 门禁管理 5. 停车管理 6. 能源管理 7. 环保管理 8. 园区生活服务 9. 招商管理 10. 收费中心 11. 园区地图 12. 门户网站 软件整套原件获取&#xff1a;本文末个人名片。

量化投资分析平台 迅投 QMT(六)资产定价绕不过去的BSM模型

量化投资分析平台 迅投 QMT [迅投 QMT](https://www.xuntou.net/?user_code7NYs7O)我目前在使用什么是BSM模型CQF课程介绍模型的五个重要的假设模型公式 我们为啥要学&#xff08;知道&#xff09;这玩意儿呢&#xff1f;隐含波动率&#xff08;Implied Volatility&#xff09…

【qt】启动窗口的玩法

启动窗口的玩法 一.应用场景二.界面类设计窗口三.main中创建四.窗口显示标识五.功能实现1.读取注册表2.md5加密3.登录实现4.保存注册表5.功能演示 六.鼠标事件拖动窗口1.找到鼠标事件的函数2.点击事件3.移动事件4.释放事件 七.总结 一.应用场景 一般我们的软件和应用都会一个登…

MATLAB实现粒子群算法优化柔性车间调度(PSO-fjsp)

柔性车间调度是典型的N-P问题&#xff0c;数学模型如下&#xff1a; 数学模型 假设有n个工件需要在m台机器上进行加工。每个工件包含一道或多道工序&#xff0c;每道工序可以在多台机器上进行加工&#xff0c;但每道工序的加工时间随机器的不同而不同。 符号定义 n&#xf…

仓储系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;管理员管理&#xff0c;用户管理&#xff0c;试剂管理&#xff0c;安全管理&#xff0c;存储管理 用户账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;试剂管理&#xff0c;安全管…

pytest构建和测试FastAPI CURD API

文章目录 概述目标FASTAPI 介绍CRUD API 项目设置freezepipreqs 代码介绍run APIpytest测试conftest测试用例测试报告 F&Q1.执行uvicorn app.main:app --host localhost --port 8000 --reload 报错 zsh: /usr/local/bin/uvicorn: bad interpreter2.生成requirement.txt时&a…

基于SSM+Jsp的家用电器销售网站

开发语言&#xff1a;Java框架&#xff1a;ssm技术&#xff1a;JSPJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包…

技术玩家实现在不支持的CPU上运行 Windows 10 22H2

最近&#xff0c;AMD 悄然确认&#xff0c;其新款 Ryzen AI 300 系列 APU 将不再为 Windows 10 制作芯片组驱动程序&#xff0c;因为它将终止对Windows 10操作系统的支持&#xff0c;尽管它完全有能力这样做。这意味着想要获得官方驱动程序支持的用户必须在其上运行 Windows 11…

8.让画面动起来

一、Unity Shader中的内置变量&#xff08;时间篇&#xff09; 动画效果往往都是把时间添加到一些变量的计算中&#xff0c;以便在时间变化的同时也可以随之变化。Unity shader提供了一系列关于时间的内置变量来允许我们方便地在Shader中访问运行时间&#xff0c;实现各种动画…

基于小波的多元信号降噪-基于马氏距离和EDF统计(MATLAB R2018a)

马氏距离是度量学习中一种常用的距离指标&#xff0c;通常被用作评定数据样本间的相似度&#xff0c;可以应对高维线性分布数据中各维度间非独立同分布的问题&#xff0c;计算方法如下。 &#xff08;1&#xff09;计算样本向量的平均值。 &#xff08;2&#xff09;计算样本向…

插卡式仪器模块:示波器模块(插卡式)

• 12 位分辨率 • 125 MSPS 采样率 • 支持单通道/双通道模块选择 • 可实现信号分析 • 上电时序测量 • 抓取并分析波形的周期、幅值、异常信号等指标 • 电源纹波与噪声分析 • 信号模板比对 • 无线充电&#xff08;信号解调&#xff09; 通道12输入阻抗Hi-Z, 1 MΩ…

物联网实战--平台篇之(十四)物模型(用户端)

目录 一、底层数据解析 二、物模型后端 三、物模型前端 四、数据下行 本项目的交流QQ群:701889554 物联网实战--入门篇https://blog.csdn.net/ypp240124016/category_12609773.html 物联网实战--驱动篇https://blog.csdn.net/ypp240124016/category_12631333.html 物联网…

LLM技术

LLM 是利用深度学习和大数据训练的人工智能系统&#xff0c;专门设计来理解、生成和回应自然语言。这些模型通过分析大量的文本数据来学习语言的结构和用法&#xff0c;从而能够执行各种语言相关任务。以 GPT 系列为代表&#xff0c;LLM 以其在自然语言处理领域的卓越表现&…

表达式求值的相关语法知识(C语言)

目录 整型提升 整型提升的意义 整型提升规则 整型提升实例 算术转换 赋值转换 操作符的属性 C语言的语法并不能保证表达式的执行路径唯一&#xff01;&#xff01;&#xff01; 问题表达式 整型提升 C的整型算术运算总是至少以缺省整型类型的精度来进行的。为了获得这…

JavaScript 动态网页实例 —— 图像运动与事件

除图像显示外,图像运动和对事件的响应也是常见的图像效果。本章介绍图像的运动与图像对事件的响应。其中,图像事件包括:图像的拖动、按钮控制图像的显示、图像感应鼠标等;图像运动包括:图像的滑动、图像的花环效果、图像的流星效果、图像的逐渐变大、图像分块飞行和图像分条飞…