Java框架(九)--Spring Boot入门(2)

news2024/9/27 23:33:34

SpringBoot 核心功能讲解

SpringBoot之web请求静态资源

我们可以在浏览器访问src/main/resources/static目录下的静态资源,在此目录下新建test.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>静态资源文件</title>
</head>
<body>
    <div id="test">
        Hello SpringBoot~
    </div>
</body>
</html>

运行项目,浏览器访问http://localhost:8090/test.html
在这里插入图片描述
也可以访问之前放的图片
在这里插入图片描述
我们也可以在application.yml中定义更多层级的目录的

spring:
  banner:
    location: classpath:static/banner.txt
  mvc:
    static-path-pattern: /abc/**

在这里插入图片描述
我们先改回去,然后在src/main/resources/static目录下创建index.html,该文件为默认首页,访问时不需要文件名。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
    <div id="test">
        Hello Index~
    </div>
</body>
</html>

然后启动项目,浏览器直接访问http://localhost:8090/
在这里插入图片描述
在src/main/resources/static引入文件名为favicon.ico的图标,maven install项目之后运行项目,浏览器再访问的时候浏览器tab上已经有了改图标
在这里插入图片描述

通过Lombok提高开发效率以及日志设置

首先打开pom.xml文件引入Lombok依赖

<!--lombok插件-->
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
		</dependency>

然后在IDEA通过点击File=>Settings开发设置面板,找到Plugins,然后搜索Lombok安装(本人IDEA是2022版,发现IDEA默认装过了)
在这里插入图片描述
然后在com.ql.springbootlearn.pojo包下创建Student.java

package com.ql.springbootlearn.pojo;

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

@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class Student {
    public String name;
    public Integer age;
}

其中@Data生成get和set方法,@ToString生成toString方法,@NoArgsConstructor生成默认构造方法,@AllArgsConstructor生成全参构造方法。

然后在HelloController.java中调用

@RestController
@Slf4j
public class HelloController {
...
    @GetMapping("getStudent")
    public Object getStudent(){
        Student student = new Student();
        student.setName("Smith");
        student.setAge(28);
        Student student1 = new Student("Jams", 34);
        log.debug(student.toString());
        log.info(student.toString());
        log.warn(student.toString());
        log.error(student.toString());
        return student;
    }
}

其中@Slf4j也是Lombok的注解,注入日志组件

运行项目,浏览器访问http://localhost:8090/getStudent
在这里插入图片描述
在这里插入图片描述
因为SpringBoot项目默认日志级别是info,所以debug日志没显式。

注意:当然Lombok也有缺点,在团队开发的时候,只要有一个人使用,所有人必须使用Lombok,不然项目无法编译通过。如果是个人的话,完全没有问题。

Restful 接口请求风格

GET 主要用于查询类的操作。
POST 主要用于Form表单提交或相对安全的一些请求。主要保存新的数据。
PUT 主要用于数据的修改。
DELETE 用户数据的删除。
有些公司强制要求用四种请求。另外有些公司使用的是弱规范,就是查询使用GET,增删改使用POST。

在com.ql.springbootlearn.controller包下创建StuController.java

package com.ql.springbootlearn.controller;

import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/stu")
public class StuController {
    @GetMapping("get")
    public String getStu(){
        return "查询Stu";
    }
    @PostMapping("create")
    public String crrateStu(){
        return "新增Stu";
    }
    @PutMapping("update")
    public String updateStu(){
        return "修改Stu";
    }
    @DeleteMapping("delete")
    public String deleteStu(){
        return "删除Stu";
    }
}

运行项目,打开postman测试
在这里插入图片描述
在这里插入图片描述

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

SpringBoot 之接受参数的常用注解

@RequestParam 用于获得URL中的请求参数,如果参数变量名保持一致,该注解可以省略。
@PathVarible 用于获得路径的参数
@RequestBody 用于获得请求的body
@RequestHeader 用于获得请求头中的一些参数
@CookieValue 用于获得Cookie中一些参数

打开StuController.java修改getStu方法

    @GetMapping("{stuId}/get")
    public String getStu(@PathVariable("stuId") String stuId,
                         @RequestParam Integer id,
                         @RequestParam String name){
        log.info("stuId="+ stuId);
        log.info("id="+ id);
        log.info("name="+ name);
        return "查询Stu";
    }

运行项目,打开postman请求测试
在这里插入图片描述
在这里插入图片描述
打开StuController.java修改crrateStu方法

    @PostMapping("create")
    public String crrateStu(@RequestBody Map<String, Object> map,
                            @RequestHeader("token") String token,
                            @CookieValue("clientId") String clientId,
                            HttpServletRequest request){
        log.info("token="+token);
        log.info("clientId="+clientId);
        log.info("map="+map.toString());
        String requestHeader = request.getHeader("token");
        log.info("requestHeader="+requestHeader);
        return "新增Stu";
    }

运行项目,打开postman请求测试
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

SpringBoot 之接口返回响应对象

在com.ql.springbootlearn.utils包下新增接口返回响应JSONResult工具类

package com.ql.springbootlearn.utils;

/**
 * 自定义响应数据结构
 * 本类可提供给 H5/ios/安卓/公众号/小程序 使用
 * 前端接受此类数据(json object)后,可自行根据业务去实现相关功能
 * 200: 表示成功
 * 500: 表示错误,错误信息在msg字段中
 */
public class JSONResult {
    private Integer status;//响应业务状态
    private String msg;//响应消息
    private Object data;//响应中的数据

    public static JSONResult build(Integer status, String msg, Object data){
        return new JSONResult(status, msg, data);
    }

    public static JSONResult ok(Object data){
        return new JSONResult(data);
    }

    public static JSONResult ok(){
        return new JSONResult(null);
    }

    public static JSONResult errorMsg(String msg){
        return new JSONResult(500, msg, null);
    }

    public JSONResult() {
    }

    public JSONResult(Integer status, String msg, Object data) {
        this.status = status;
        this.msg = msg;
        this.data = data;
    }

    public JSONResult(Object data){
        this.status = 200;
        this.msg = "OK";
        this.data = data;
    }

    public Integer getStatus() {
        return status;
    }

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

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }
}

然后修改HelloController.java的getStudent方法测试

    @GetMapping("getStudent")
    public JSONResult getStudent(){
        Student student = new Student();
        student.setName("Smith");
        student.setAge(28);
        Student student1 = new Student("Jams", 34);
        log.debug(student.toString());
        log.info(student.toString());
        log.warn(student.toString());
        log.error(student.toString());
        return JSONResult.errorMsg("调用接口出现异常");
        //return JSONResult.ok(stu);
    }

在这里插入图片描述

    @GetMapping("getStudent")
    public JSONResult getStudent(){
        Student student = new Student();
        student.setName("Smith");
        student.setAge(28);
        Student student1 = new Student("Jams", 34);
        log.debug(student.toString());
        log.info(student.toString());
        log.warn(student.toString());
        log.error(student.toString());
        //return JSONResult.errorMsg("调用接口出现异常");
        return JSONResult.ok(stu);
    }

在这里插入图片描述

SpringBoot实现文件上传

打开src/main/resources/static/test.html文件,添加文件上传的代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>静态资源文件</title>
</head>
<body>
    <div id="test">
        Hello SpringBoot~
    </div>
    <!--文件上传-->
    <form action="/upload" method="post" enctype="multipart/form-data">
        <div>
            <input type="file" id="file" name="file" value="选择图片"
                accept="image/jpeg,image/jpg,image/png">
        </div>
        <div>
            <input type="submit" value="上传文件">
        </div>
    </form>
</body>
</html>

打开HelloController.java添加文件上传的方法

    @PostMapping("upload")
    public String upload(MultipartFile file) throws Exception{
        file.transferTo(new File("D:/upload/"+file.getOriginalFilename()));
        return "上传成功";
    }

运行项目,浏览器访问http://localhost:8090/test.html上传文件
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

SpringBoot 之自定义异常页面

我们在application.yml中添加文件上传的相关配置

spring:
  servlet:
    multipart:
      max-file-size: 200KB # 文件上传大小的限制,设置最大值,不能超过,否则报错
      max-request-size: 2MB # 文件最大请求限制,用于批量

启动项目,浏览器访问http://localhost:8090/test.html上传一个大于200KB的图片
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
现在报异常之后,页面展示的不友好,所以我们需要自定义一个异常页面。
首先,打开pom.xml文件,引入thymeleaf模板引擎

		<!--SpringBoot官方推荐的模板thymeleaf-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>

然后在src/main/resources/templates目录下创建error.html页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>静态资源文件</title>
</head>
<body>
    <div id="test" style="color: red">
        系统发生异常,请联系管理员!
    </div>
</body>
</html>

重新运行项目,再上传刚才的图片,返回的是我们写好的页面。
在这里插入图片描述

SpringBoot 之统一异常封装处理

如果是前后端分离的项目,出现异常就不能返回页面了,应该把异常信息返回去。
在com.ql.springbootlearn包下创建一个GraceExceptionHandler.java统一异常拦截处理类

package com.ql.springbootlearn;

import com.ql.springbootlearn.utils.JSONResult;
import org.apache.tomcat.util.http.fileupload.impl.FileSizeLimitExceededException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * 统一异常拦截处理
 * 可以针对异常自定义去处理去捕获,返回指定的类型(json类型)到前端
 */
@ControllerAdvice
public class GraceExceptionHandler {

    @ExceptionHandler(FileSizeLimitExceededException.class)
    @ResponseBody
    public JSONResult returnMaxFileSizeLimit(FileSizeLimitExceededException e){
        return JSONResult.errorMsg("文件大小不能超过200KB");
    }
}

运行项目,再上传刚才的图片测试。
在这里插入图片描述

SpringBoot 实现拦截器

在com.ql.springbootlearn.controller.interceptor包下创建拦截器UserInfoInterceptor.java

package com.ql.springbootlearn.controller.interceptor;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.thymeleaf.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Slf4j
public class UserInfoInterceptor implements HandlerInterceptor {
    /**
     * 拦截请求,访问Controller之前
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String userId = request.getHeader("userId");
        String userToken = request.getHeader("userToken");
        if(StringUtils.isEmpty(userId) || StringUtils.isEmpty(userToken)){
            log.error("用户校验不通过,信息不完整!");
            return false;
        }
        //假设真实的用户id是1001,用户token是abcxyz
        if(!userId.equalsIgnoreCase("1001") ||
            !userToken.equalsIgnoreCase("abcxyz")){
            log.error("用户权限不通过!");
            return false;
        }
        /**
         * false: 请求被拦截
         * true: 请求放行,可以继续访问后面的Controller
         */
        return true;
    }

    /**
     * 请求访问到Controller之后,渲染视图之前
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    /**
     * 请求访问到Controller之后,渲染视图之后
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}

然后注册拦截器,在com.ql.springbootlearn包下创建InterceptorConfig.java拦截器配置类

package com.ql.springbootlearn;

import com.ql.springbootlearn.controller.interceptor.UserInfoInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    @Bean
    public UserInfoInterceptor userInfoInterceptor(){
        return new UserInfoInterceptor();
    }

    public void addInterceptors(InterceptorRegistry registry){
        //注册拦截器
        registry.addInterceptor(userInfoInterceptor())
                .addPathPatterns("/upload");
    }
}

运行项目,打开postman测试
在这里插入图片描述
当用户id和token为空时
在这里插入图片描述
在这里插入图片描述
当用户id和token错误时
在这里插入图片描述
在这里插入图片描述
当所有信息正确时,上传成功。
在这里插入图片描述

自定义异常与拦截器整合返回JSON对象

首先,在com.ql.springbootlearn.exception包下创建一个自定义异常类MyCustomException

package com.ql.springbootlearn.exception;

/**
 * 自定义异常
 * 目的:
 *  统一处理异常信息
 *  便于解耦,可以在拦截器,控制层,业务层去使用
 */
public class MyCustomException extends RuntimeException{
    public MyCustomException(String errorMsg){
        super(errorMsg);
    }
}

然后在GraceExceptionHandler.java中捕获该异常

package com.ql.springbootlearn.exception;

import com.ql.springbootlearn.utils.JSONResult;
import org.apache.tomcat.util.http.fileupload.impl.FileSizeLimitExceededException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * 统一异常拦截处理
 * 可以针对异常自定义去处理去捕获,返回指定的类型(json类型)到前端
 */
@ControllerAdvice
public class GraceExceptionHandler {

    @ExceptionHandler(FileSizeLimitExceededException.class)
    @ResponseBody
    public JSONResult returnMaxFileSizeLimit(FileSizeLimitExceededException e){
        return JSONResult.errorMsg("文件大小不能超过200KB");
    }

    @ExceptionHandler(MyCustomException.class)
    @ResponseBody
    public JSONResult returnMyCustomException(MyCustomException e){
        return JSONResult.errorMsg(e.getMessage());
    }
}

然后在com.ql.springbootlearn.exception写一个抛出异常的调用类GraceException.java

package com.ql.springbootlearn.exception;

/**
 * 优雅的处理异常,进行调用
 */
public class GraceException {
    public static void display(String errMsg) {
        throw new MyCustomException(errMsg);
    }
}

然后,在前面的用户信息拦截器UserInfoInterceptor.java里调用抛出异常

package com.ql.springbootlearn.controller.interceptor;

import com.ql.springbootlearn.exception.GraceException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.thymeleaf.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Slf4j
public class UserInfoInterceptor implements HandlerInterceptor {
    /**
     * 拦截请求,访问Controller之前
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String userId = request.getHeader("userId");
        String userToken = request.getHeader("userToken");
        if(StringUtils.isEmpty(userId) || StringUtils.isEmpty(userToken)){
            log.error("用户校验不通过,信息不完整!");
            GraceException.display("用户校验不通过,信息不完整!");
            return false;
        }
        //假设真实的用户id是1001,用户token是abcxyz
        if(!userId.equalsIgnoreCase("1001") ||
            !userToken.equalsIgnoreCase("abcxyz")){
            log.error("用户权限不通过!");
            GraceException.display("用户权限不通过!");
            return false;
        }
        /**
         * false: 请求被拦截
         * true: 请求放行,可以继续访问后面的Controller
         */
        return true;
    }

    /**
     * 请求访问到Controller之后,渲染视图之前
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    /**
     * 请求访问到Controller之后,渲染视图之后
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}

再运行项目,打开postman测试
在这里插入图片描述

SpringBoot定时任务的实现

在com.ql.springbootlearn.utils包下创建MyTask定时任务演示类

package com.ql.springbootlearn.utils;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;

import java.time.LocalDateTime;

@Configuration    //1.标记配置类,使得springboot容器可以扫描到
@EnableScheduling //2.开启定时任务
@Slf4j
public class MyTask {
    //3.添加一个任务,并且注明任务的运行表达式
    @Scheduled(cron = "*/5 * * * * ?")
    public void publishMsg(){
        log.warn("开始执行任务:"+ LocalDateTime.now());
    }
}

运行项目,查看控制台。
在这里插入图片描述
注意:当前定时任务为Spring自带的,只适合单体环境运行,如果是一个集群或者分布式环境就不适合该方案了。

SpringBoot异步任务的实现

在com.ql.springbootlearn.utils包下创建异步任务类

package com.ql.springbootlearn.utils;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

@Component
@EnableAsync
@Slf4j
public class MyAsyncTask {
    @Async
    public void publishMsg(){
        try {
            Thread.sleep(5000);
            log.warn("异步任务处理完毕");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

然后在HelloController.java里调用

	...
    @Autowired
    private MyAsyncTask myAsyncTask;

    @GetMapping("getMyConfig")
    public Object getMyConfig(){
        myAsyncTask.publishMsg();
        log.info("这是跳过异步任务的执行");
        return myConfig;
    }

运行项目,浏览器访问http://localhost:8090/getMyConfig,查看控制台
在这里插入图片描述
注意:该方案适合单应用,若是分布式环境一般通过消息队列去处理。

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

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

相关文章

MybatisPlus实战笔记

概述 Mybatis支持定制化SQL、存储过程以及高级映射&#xff0c;避免几乎所有的 JDBC 代码和手动设置参数以及获取结果集。可以使用简单的 XML 或注解来配置和映射原生信息&#xff0c;将接口和Java的POJO映射成数据库中的记录。 缺点&#xff1a; SQL工作量很大&#xff0c;尤…

结构体和 Json 相互转换(序列化反序列化)

关于 JSON 数据 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也 易于机器解析和生成。RESTfull Api 接口中返回的数据都是 json 数据。 Json 的基本格式如下&#xff1a; { "a": "Hello", "b": "…

DC-2靶机

文章目录 信息收集漏洞发现漏洞利用 DC-2介绍 DC-2环境下载 请注意&#xff0c;您需要将渗透测试设备上的 hosts 文件设置为&#xff1a; 192.168.0.145 dc-2 显然&#xff0c;将 192.168.0.145 替换为 DC-2 的实际 IP 地址。 它将使生活变得更加简单&#xff08;如果没有它&am…

【Linux】从0到1实现一个进度条小程序

个人主页&#xff1a;&#x1f35d;在肯德基吃麻辣烫 我的gitee&#xff1a;gitee仓库 分享一句喜欢的话&#xff1a;热烈的火焰&#xff0c;冰封在最沉默的火山深处 文章目录 前言一、理解回车 \r 和换行 \n二、初步认识缓冲区1. 认识第一个函数&#xff1a;sleep2.观察缓冲区…

固态继电器:电气开关的革命

简介&#xff1a;在电气工程领域&#xff0c;固态技术的发展为各个领域的显着进步铺平了道路。固态继电器 (SSR) 就是其中一项备受关注的创新。与传统机电继电器不同&#xff0c;SSR 采用固态元件&#xff0c;具有许多优点&#xff0c;例如更高的可靠性、更快的响应时间和增强的…

dvwa靶场通关(十)

第十关&#xff1a;DOM Based Cross Site Scripting (XSS) DOM—based XSS漏洞的产生 DOM—based XSS漏洞是基于文档对象模型Document Objeet Model&#xff0c;DOM)的一种漏洞。DOM是一个与平台、编程语言无关的接口&#xff0c;它允许程序或脚本动态地访问和更新文档内容、…

有效的括号字符串(力扣)动态规划、贪心 JAVA

给你一个只包含三种字符的字符串&#xff0c;支持的字符类型分别是 ‘(’、‘)’ 和 ‘*’。请你检验这个字符串是否为有效字符串&#xff0c;如果是有效字符串返回true 。 有效字符串符合如下规则&#xff1a; 任何左括号 ‘(’ 必须有相应的右括号 ‘)’。 任何右括号 ‘)’ …

postgresql表膨胀处理之pgcompacttable部署及使用

环境&#xff1a; 1&#xff09;redhat-release&#xff1a;CentOS Linux release 7.6.1810 (Core) 2&#xff09;database version&#xff1a;postgresql 14.6 一、添加pgstattuple pgcompacttable工具使用过程中需要依赖pgstattuple&#xff0c;因此需先添加pgstattuple…

[C++]01.基础,数据类型,运算符

01.基础,数据类型,运算符 一.C基础入门1.HelloWorld2.注释3.变量4.常量5.关键字6.命名规则 二.数据类型1.整形2.sizeof关键字3.浮点型4.字符型5.转义字符6.字符串型7.布尔类型8.数据的输入 三.运算符1.算数运算符2.赋值运算符3.比较运算符4.逻辑运算符 一.C基础入门 1.HelloWo…

【雕爷学编程】MicroPython动手做(30)——物联网之Blynk 4

知识点&#xff1a;什么是掌控板&#xff1f; 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片&#xff0c;支持WiFi和蓝牙双模通信&#xff0c;可作为物联网节点&#xff0c;实现物联网应用。同时掌控板上集成了OLED…

力扣 C++|一题多解之动态规划专题(1)

动态规划 Dynamic Programming 简写为 DP&#xff0c;是运筹学的一个分支&#xff0c;是求解决策过程最优化的过程。20世纪50年代初&#xff0c;美国数学家贝尔曼&#xff08;R.Bellman&#xff09;等人在研究多阶段决策过程的优化问题时&#xff0c;提出了著名的最优化原理&…

【习题】几道二叉树题目,进来看看你会不?

几道二叉树题目解析 前言正式开始1. 根据二叉树创建字符串&#xff08;力扣606&#xff09;题目描述解析代码 2. 二叉树的层序遍历1&#xff08;力扣102&#xff09;题目描述解析代码 3. 二叉树的层序遍历2&#xff08;力扣107&#xff09;代码 4. 二叉树的最近公共祖先&#x…

接口测试之json中的key获取

在很多情况下我们在进行接口测试的时候都会有获取上个接口返回的json数据中的某个key值&#xff0c;然后下个接口调用这个key值。今天给大家讲解一下针对不同类型的json获取某个key的值。 一、首先是单纯object格式key值获取 获取图中的token的值&#xff0c;首先这是一个响应…

SSM(Vue3+ElementPlus+Axios+SSM前后端分离)【四】

文章目录 SSM(Vue3ElementPlusAxiosSSM前后端分离)--基础环境搭建【四】项目介绍项目功能/界面● SSM 整合项目界面 创建表&#xff0c;使用逆向工程生成Bean、XxxMapper 和XxxMapper.xml1. 创建furns_ssm 数据库和furns 表使用MyBatis Generator 逆向工程生成bean mapper 接口…

基于Jonswap谱的随机波高及波压力生成

内容目录 基于Jonswap谱的随机波高及波压力生成基于Jonswap谱的随机波高及波压力生成 海面高程可视为是平稳高斯随机过程,可通过对波浪谱确定的一系列分量波进行叠加得到。JONSWAP谱是在海洋结构设计和分析中常用的波浪频谱,可以用其来模拟随机波浪。 式中:有义波高H1/3和…

GPIO简介

一、GPIO GPIO&#xff08;General-purpose input/output&#xff09;即通用型输入输出&#xff0c;GPIO可以控制连接在其之上的引脚实现信号的输入和输出 芯片的引脚与外部设备相连&#xff0c;从而实现与外部硬件设备的通讯、控制及信号采集等功能 LED实验步骤 实验步骤 以L…

1. CUDA中的grid和block

1. CUDA中的grid和block基本的理解 Kernel: Kernel不是CPU&#xff0c;而是在GPU上运行的特殊函数。你可以把Kernel想象成GPU上并行执行的任务。当你从主机&#xff08;CPU&#xff09;调用Kernel时&#xff0c;它在GPU上启动&#xff0c;并在许多线程上并行运行。 Grid: 当你…

C高级【day2】

思维导图&#xff1a; 递归实现&#xff0c;输入一个数&#xff0c;输出这个数的每一位&#xff1a; #include<myhead.h>//递归函数 void fun(int num){//num没值不再递归if(0 num){return;}//输出数的最后一位printf("%d\t", num%10);//递归fun(num/10);}…

AI Chat 设计模式:11. 状态模式

本文是该系列的第十一篇&#xff0c;采用问答式的方式展开&#xff0c;问题由我提出&#xff0c;答案由 Chat AI 作出&#xff0c;灰色背景的文字则主要是我的一些思考和补充。 问题列表 Q.1 你知道状态模式吗A.1Q.2 它与有限状态机有什么联系吗&#xff1f;A.2Q.3 知道了&…

Spring:IOC技术、Bean、DI

前言 Spring是一个开源的项目&#xff0c;并不是单单的一个技术&#xff0c;发展至今已形成一种开发生态圈。也就是说我们可以完全使用Spring技术完成整个项目的构建、设计与开发。Spring是一个基于IOC和AOP的架构多层j2ee系统的架构。 SpringFramework&#xff1a;Spring框架…