当前位置: 首页 > news >正文

第七章:SpringMVC中

第七章:SpringMVC中

7.1:SpringMVC的视图

SpringMVC中的视图是View接口,视图的作用渲染数据,将模型Model中的数据展示给用户SpringMVC视图的种类很多,默认有转发视图和重定向视图。

​ 当工程引入jstl的依赖,转发视图会自动转换为JstlView,若使用的视图技术为Thymeleaf,在SpringMVC的配置文件中配置了Thymeleaf的视图解析器,由此视图解析器解析之后得到的是ThymeleafView

  1. ThymeleafView

    ​ 当控制器方法中所设置的视图名称没有任何前缀时,此时的视图名称会被SpringMVC配置文件中所配置的视图解析器解析,视图名称拼接视图前缀和视图后缀。后缀所得到的最终路径,会通过转发的方式实现跳转。

    @RequestMapping("/test/view/thymeleaf")
    public String testThymeleafView() {return "success";
    }
    

    在这里插入图片描述

  2. 转发视图

    SpringMVC中默认的转发视图是InternalResoutceViewSpringMVC中创建转发视图的情况:当控制器方法中所设置的视图名称以forward:为前缀时,创建InternalResourceView视图,此时的视图名称不会被SpringMVC配置文件中所配置的视图解析器解析,而是会将前缀forward:去掉,剩余部分作为最终路径通过转发的方式实现跳转。

    @RequestMapping("/test/view/forward")
    public String testInternalResourceView() {return "forward:/test/model";
    }
    

    在这里插入图片描述

  3. 重定向视图

    SpringMVC中默认的重定向视图是RedirectView,当控制器方法中所设置的视图名称以redirect:为前缀时,创建RedirectView视图,此时的视图名称不会被SpringMVC配置文件中所配置的视图解析器解析,而是会将前缀redirect:去掉,剩余部分作为最终路径通过重定向的方式实现跳转。

    ​ 重定向视图在解析是,会先将redirect:前缀去掉,然后会判断剩余部分是否以/开头,若是则会自动拼接上下文路径。

    @RequestMapping("/test/view/redirect")
    public String testRedirectView() {return "redirect:/test/model";
    }
    

    在这里插入图片描述

  4. 视图控制器view-controller

    当控制器方法中,仅仅用来实现页面跳转,即只需要设置视图名称时,可以将处理方法使用view-controller标签进行表示。

    <!-- 在Springmvc.xml中配置 -->
    <!-- 开启mvc的注解驱动 -->
    <mvc:annotation-driven /><!-- 视图控制器:为当前的请求直接设置视图名称实现页面跳转若设置视图监控器,则只有视图监控器所设置的请求会被处理,其他的请求将全部404,此时必须在配置一个开启mvc的注解驱动的标签-->
    <mvc:view-controller path="/" view-name="index"></mvc:view-controller>
    

7.2:RESTful

  1. RESTful简介

    RESTRepresentational State Transfer,表现层资源状态转移。

    • 资源

      ​ 资源是一种看待服务器的方式,即,将服务器看作由很多离散的资源组成。每个资源是服务器上一个可命名的抽象概念。一个资源可以有一个或多个URI来标识。URI既是资源的名称,也是资源在Web上的地址。对某个资源感兴趣的客户端应用,可以通过资源的URI与其进行交互。

    • 资源的表述

      ​ 资源的表述是一段对于资源在某个特定时刻的状态的描述。可以在客户端-服务器之间转义。资源的表述可以有多种格式。资源的表述格式可以通过协商机制来确定。请求-响应方向的表述通常使用不同的格式。

    • 状态转移

      ​ 在客户端和服务器端之间转义(transfer)代表资源状态的表述。通过转移和操作资源的表述,来间接实现操作资源的目的。

  2. RESTful的实现

    ​ 具体说,就是HTTP协议里面,四个表示操作方式的动词:GETPOSTPUTDELETE。它们分别对应四种基本操作:GET用来获取资源,POST用来新建资源,PUT用来更新资源,DELETE用来删除资源。

    REST风格提倡URL地址使用统一的风格设计,从前到后各个单词使用斜杠分开,不使用问号键值对方式携带请求参数,而是将要发送给服务器的数据作为URL地址的一部分,以保证整体风格的一致性。

    操作传统方式REST风格
    查询操作getUserById?id=1user/1 —> get请求方式
    保存操作saveUseruser ----> post请求方式
    删除操作deleteUser?id=1user/1 —> delete请求方式
    更新操作updateUseruser —> put请求方式
  3. HiddenHttpMethodFilter

    ​ 创建一个新的模块,spring_mvc_rest_15,复用spring_mvc_demo_14的依赖、web.xmlspringmvc.xml配置文件、html页面。

    • 使用REST风格完成查询所有的用户信息

      // @RequestMapping(value = "/user", method = RequestMethod.GET)
      @GetMapping("/user")
      public String getAllUser() {System.out.println("查询所有的用户信息 ----> /user ----> get");return "success";
      }
      
    • 使用REST风格完成查询单个的用户信息

      // @RequestMapping(value = "/user/{id}", method = RequestMethod.GET)
      @GetMapping("/user/{id}")
      public String getUserById(@PathVariable("id") Integer id) {System.out.println("根据id查询用户信息 ----> /user/" + id + " ----> get");return "success";
      }
      
    • 使用REST风格完成添加用户信息

      // @RequestMapping(value = "/user", method = RequestMethod.POST)
      @PostMapping("/user")
      public String insertUser() {System.out.println("添加用户信息 ----> /user ----> post");return "success";
      }
      
    • 使用REST风格完成修改用户信息

      ​ 由于浏览器只支持发送getpost方式的请求,若要发送putdelete请求,需要在web.xml中配置一个过滤器HiddenHttpMethodFilter,配置了过滤器之后,发送的请求要满足两个条件,才能将请求方式转换为putdelete

      1. 当前请求的请求方式必须为post
      2. 当前请求必须传输请求参数_method_method的值才是最终的请求方式。
      <!-- 设置处理请求方式的过滤器 -->
      <filter><filter-name>HiddenHttpMethodFilter</filter-name><filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
      </filter>
      <filter-mapping><filter-name>HiddenHttpMethodFilter</filter-name><url-pattern>/*</url-pattern>
      </filter-mapping>
      
      // @RequestMapping(value = "/user", method = RequestMethod.PUT)
      @PutMapping("/user")
      public String updateUser() {System.out.println("修改用户信息 ----> /user ----> put");return "success";
      }
      
      <form th:action="@{/user}" method="post"><input type="hidden" name="_method" value="put"><input type="submit" value="修改用户信息">
      </form>
      
    • 使用REST风格完成删除用户信息

      // @RequestMapping(value = "/user/{id}", method = RequestMethod.DELETE)
      @DeleteMapping("/user/{id}")
      public String deleteUser(@PathVariable("id") Integer id) {System.out.println("删除用户信息 ----> /user/" + id + " ----> put");return "success";
      }
      
    • HiddenHttpMethodFilter原理

      public class HiddenHttpMethodFilter extends OncePerRequestFilter {private static final List<String> ALLOWED_METHODS = Collections.unmodifiableList(Arrays.asList(HttpMethod.PUT.name(), HttpMethod.DELETE.name(), HttpMethod.PATCH.name()));public static final String DEFAULT_METHOD_PARAM = "_method";private String methodParam = DEFAULT_METHOD_PARAM;public void setMethodParam(String methodParam) {Assert.hasText(methodParam, "'methodParam' must not be empty");this.methodParam = methodParam;}@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {HttpServletRequest requestToUse = request;if ("POST".equals(request.getMethod()) && request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE) == null) {String paramValue = request.getParameter(this.methodParam);if (StringUtils.hasLength(paramValue)) {String method = paramValue.toUpperCase(Locale.ENGLISH);if (ALLOWED_METHODS.contains(method)) {requestToUse = new HttpMethodRequestWrapper(request, method);}}}filterChain.doFilter(requestToUse, response);}private static class HttpMethodRequestWrapper extends HttpServletRequestWrapper {private final String method;public HttpMethodRequestWrapper(HttpServletRequest request, String method) {super(request);this.method = method;}@Overridepublic String getMethod() {return this.method;}}
      }
      

7.3:SpringMVC处理ajax请求

创建一个新的模块,spring_mvc_ajax_16,复用spring_mvc_rest_15的依赖、web.xmlspringmvc.xml配置文件。

  1. @RequestBody

    @RequestBody可以获取请求体信息,使用@RequestBody注解标识控制器方法的形参,当前请求的请求体就会为当前注解锁标识的形参赋值。

    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head><meta charset="UTF-8"><title>首页</title>
    </head>
    <body>
    <div id="app"><h1>index.html</h1><input type="button" value="测试SpringMVC处理ajax" @click="testAjax()">
    </div><script type="text/javascript" th:src="@{/js/vue.js}"></script>
    <script type="text/javascript" th:src="@{/js/axios.min.js}"></script>
    <script type="text/javascript">var vue = new Vue({el: "#app",methods: {testAjax() {axios.post("/SpringMVC/test/ajax?id=1001",{username:"admin", password:"123456"}).then(response => {console.log(response.data);});}  }})
    </script>
    </body>
    </html>
    
    @RequestMapping("/test/ajax")
    public void testAjax(Integer id,@RequestBody String requestBody,HttpServletResponse response)throws IOException{System.out.println("requestBody: " + requestBody);System.out.println("id: " + id);response.getWriter().write("hello, axios");
    }
    
  2. @RequestBody获取json格式的请求参数

    使用@RequestBody注解将json格式的请求参数转换为java对象,需要以下步骤:

    • 导入jackson的依赖

      <dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.12.1</version>
      </dependency>
      
    • SpringMVC的配置文件中设置:<mvc:annotation-driven />

    • 在处理请求的控制器方法的形参位置,直接设置json格式的请求参数要求转换的java类型的形参,使用@RequestBody注解标识即可。

    <input type="button" value="使用@RequestBody处理json格式的请求参数" @click="testRequestBody()"><br>
    
    testRequestBody() {axios.post("/SpringMVC/test/RequestBody/json",{username: "admin", password: "123456", age: 23, gender: "男"}).then(response=> {console.log(response.data);});
    }
    
    // 根据上面传递的参数自行创建User实体类
    @RequestMapping("/test/RequestBody/json")
    public void testRequestBody(@RequestBody User user, HttpServletResponse response) throws IOException {System.out.println(user);response.getWriter().write("hello, RequestBody");
    }
    
  3. @ResponseBody

    @ResponseBody用于标识一个控制器方法,可以将该方法的返回值直接作为响应报文的响应体响应到浏览器。

    @RequestMapping("/test/ResponseBody")
    @ResponseBody
    public String testResponseBody() {return "success";
    }
    
    <a th:href="@{/test/ResponseBody}">测试@ResponseBody注解响应浏览器数据</a><br>
    
  4. @ResponseBody响应浏览器josn数据

    使用@ResponseBody注解响应浏览器json格式的数据,需要以下步骤:

    • 导入jackson的依赖
    • SpringMVC的配置文件中设置:<mvc:annotation-driven />
    • 将需要转换为json字符串的java对象直接作为控制器方法的返回值,使用@ResponseBody注解标识控制器方法就可以将java对象直接转换为json字符串,并响应到浏览器。
    • 常用的java对象转换为json的结果
      1. 实体类 ——> json对象
      2. map ——> json对象
      3. list ——> list数组
    <input type="button" value="使用@ResponseBody注解响应json格式的数据" @click="testResponseBody()"><br>
    
    testResponseBody() {axios.post("/SpringMVC/test/ResponseBody/json").then(response => {console.log(response.data);})
    }
    
    @RequestMapping("/test/ResponseBody/json")
    @ResponseBody
    public List<User> testResponseBodyJson() {User user1 = new User(1001, "admin1", "123456", 20, "男");User user2 = new User(1002, "admin2", "123456", 20, "男");User user3 = new User(1003, "admin3", "123456", 20, "男");List<User> list = Arrays.asList(user1, user2, user3);return list;
    }
    
  5. @RestContrller注解

    @RestContrller注解是SpringMVC提供的一个复合注解,标识在控制器的类上,就相当于为添加了@Controller注解,并且为其中的每个方法添加了@ResponseBody注解。

7.4:文件上传和下载

  1. 文件下载

    ResponseEntity用于控制器方法的返回值类型,该控制器方法的返回值就是响应到浏览器的响应报文使用ResponseEntity实现下载文件的功能。

    @RequestMapping("/test/down")
    public ResponseEntity<byte[]> testResponseEntity(HttpSession session) throws IOException {//获取ServletContext对象ServletContext servletContext = session.getServletContext();//获取服务器中文件的真实路径String realPath = servletContext.getRealPath("img");realPath = realPath + File.separator + "1.jpg";//创建输入流InputStream is = new FileInputStream(realPath);//创建字节数组,is.available()获取输入流所对应文件的字节数byte[] bytes = new byte[is.available()];//将流读到字节数组中is.read(bytes);//创建HttpHeaders对象设置响应头信息MultiValueMap<String, String> headers = new HttpHeaders();//设置要下载方式以及下载文件的名字headers.add("Content-Disposition", "attachment;filename=1.jpg");//设置响应状态码HttpStatus statusCode = HttpStatus.OK;//创建ResponseEntity对象ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(bytes, headers, statusCode);//关闭输入流is.close();return responseEntity;
    }
    
  2. 文件上传

    ​ 文件上传要求form表单的请求方式必须为post,并且添加enctype="multipart/form-data"SpringMVC中将上传的文件封装到MultipartFile对象中,通过此对象可以获取文件相关信息。

    • 添加依赖

      <!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
      <dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.3.1</version>
      </dependency>
      
    • SpringMVC的配置文件中添加配置

      <!-- 配置文件上传解析器 id必须为multipartResolver -->
      <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
      </bean>
      
    • 控制器方法

      @RequestMapping("/test/up")
      public String testUp(MultipartFile photo, HttpSession session) throws IOException {//获取上传的文件的文件名String fileName = photo.getOriginalFilename();//处理文件重名问题String hzName = fileName.substring(fileName.lastIndexOf("."));String uuid = UUID.randomUUID().toString();fileName = uuid + hzName;//获取ServletContext对象ServletContext servletContext = session.getServletContext();//获取当前工程下photo目录的真实路径String photoPath = servletContext.getRealPath("photo");//创建photoPath所对应的File对象File file = new File(photoPath);//判断file所对应目录是否存在if(!file.exists()){file.mkdir();}String finalPath = photoPath + File.separator + fileName;//上传文件photo.transferTo(new File(finalPath));return "success";
      }
      

相关文章:

第七章:SpringMVC中

第七章&#xff1a;SpringMVC中 7.1&#xff1a;SpringMVC的视图 ​ SpringMVC中的视图是View接口&#xff0c;视图的作用渲染数据&#xff0c;将模型Model中的数据展示给用户SpringMVC视图的种类很多&#xff0c;默认有转发视图和重定向视图。 ​ 当工程引入jstl的依赖&…...

MySQL数据库——DQL操作——基本查询

文章目录 前言事前准备——测试数据整表查询指定列查找别名查询MySQL运算符条件查询模糊查询排序查询聚合查询分组查询分组之后的条件筛选 分页查询将整张表的数据插入到另一张表中 前言 MySQL数据库常见的操作是增删查改&#xff0c;而其中数据的查询是使用最多&#xff0c;也…...

Electron 开发,报handshake failed; returned -1, SSL error code 1,错误

代码说明 在preload.js代码中&#xff0c;暴露参数给渲染线程renderer.js访问&#xff0c; renderer.js 报&#xff1a;ERROR:ssl_client_socket_impl.cc(978)] failed; returned -1, SSL error code 1,错误 问题原因 如题所说&#xff0c;跨进程传递消息&#xff0c;这意味…...

知识区博主转型——兼做知识区和改造区博主!!!!!

想脱单的进来&#xff0c;一起交流如何能脱单&#xff01;&#xff01;&#xff01; 为什么——我太羡慕有对象的人了哭死&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 你是不是很羡慕别人怎么都有女朋友 别人家的女朋友怎么都那么好&#xff…...

Resnet与Pytorch花图像分类

1、介绍 1.1数据集介绍 flower_data├── train│ └── 1-102&#xff08;102个文件夹&#xff09;│ └── XXX.jpg&#xff08;每个文件夹含若干张图像&#xff09;├── valid│ └── 1-102&#xff08;102个文件夹&#xff09;└── ─── └── XXX.jp…...

【NLP概念源和流】 03-基于计数的嵌入,GloVe(第 3/20 部分)

接续上文 【NLP概念源和流】 02-稠密文档表示(第 2/20 部分)...

【React】关于组件之间的通讯

&#x1f31f;组件化&#xff1a;把一个项目拆成一个一个的组件&#xff0c;为了便与开发与维护 组件之间互相独立且封闭&#xff0c;一般而言&#xff0c;每个组件只能使用自己的数据&#xff08;组件状态私有&#xff09;。 如果组件之间相互传参怎么办&#xff1f; 那么就要…...

item_get-小红薯-商品详情

一、接口参数说明&#xff1a; smallredbook.item_get&#xff0c;点击更多API调试&#xff0c;请移步注册API账号点击获取测试key和secret 公共参数 请求地址: https://api-gw.onebound.cn/smallredbook/item_get 名称类型必须描述keyString是调用key&#xff08;http://o0…...

网络安全进阶学习第十课——MySQL手工注入

文章目录 一、MYSQL数据库常用函数二、MYSQL默认的4个系统数据库以及重点库和表三、判断数据库类型四、联合查询注入1、具体步骤&#xff08;靶场演示&#xff09;&#xff1a;1&#xff09;首先判断注入点2&#xff09;判断是数字型还是字符型3&#xff09;要判断注入点的列数…...

2.3 网络安全协议

数据参考&#xff1a;CISP官方 目录 OSI七层模型TCP/IP体系架构TCP/IP安全架构 一、OSI七层模型 简介 开放系统互连模型&#xff08;Open System Interconnection Reference Model&#xff0c;OSI&#xff09;是国际标准化组织&#xff08;ISO&#xff09;于1977年发布的…...

Apache Flink概述

Flink 是构建在数据流之上的一款有状态的流计算框架&#xff0c;通常被人们称为第三代大数据分析方案 第一代大数据处理方案&#xff1a;基于Hadoop的MapReduce 静态批处理 | Storm 实时流计算 &#xff0c;两套独立的计算引擎&#xff0c;难度大&#xff08;2014年9月&#x…...

django使用mysql数据库

Django开 发操作数据库比使用pymysql操作更简单&#xff0c;内部提供了ORM框架。 下面是pymysql 和orm操作数据库的示意图&#xff0c;pymysql就是mysql的驱动&#xff0c;代码直接操作pymysql ,需要自己写增删改查的语句 django 就是也可以使用pymysql、mysqlclient作为驱动&a…...

MongoDB文档--基本概念

阿丹&#xff1a; 不断拓展自己的技术栈&#xff0c;不断学习新技术。 基本概念 MongoDB中文手册|官方文档中文版 - MongoDB-CN-Manual mongdb是文档数据库 MongoDB中的记录是一个文档&#xff0c;它是由字段和值对组成的数据结构。MongoDB文档类似于JSON对象。字段的值可以包…...

【TypeScript】TS入门及基础学习(一)

【TypeScript】TS入门及基础学习&#xff08;一&#xff09; 【TypeScript】TS入门及基础学习&#xff08;一&#xff09;一、前言二、基本概念1.强类型语言和弱类型语言2.动态语言和静态语言 三、TypeScript与JavaScript的区别四、环境搭建及演练准备4.1 安装到本地4.2 在线运…...

Dockerfile构建LNMP镜像(yum方式)

目录 Dockerfile构建LNMP镜像 1、建立工作目录 2、编写Dockerfile文件 3、构建镜像 4、测试容器 5、浏览器访问测试&#xff1a; Dockerfile构建LNMP镜像 1、建立工作目录 [roothuyang1 ~]# mkdir lnmp/ [roothuyang1 ~]# cd lnmp/ 2、编写Dockerfile文件 [roothuyang1 …...

Flink Windows(窗口)详解

Windows&#xff08;窗口&#xff09; Windows是流计算的核心。Windows将流分成有限大小的“buckets”&#xff0c;我们可以在其上应用聚合计算&#xff08;ProcessWindowFunction&#xff0c;ReduceFunction&#xff0c;AggregateFunction或FoldFunction&#xff09;等。在Fl…...

AssetBundle学习

官方文档&#xff1a;AssetBundle 工作流程 - Unity 手册 (unity3d.com) 之前写的博客&#xff1a;AssetBundle学习_zaizai1007的博客-CSDN博客 使用流程图&#xff1a; 1&#xff0c;指定资源的AssetBundle属性 &#xff08;xxxa/xxx&#xff09;这里xxxa会生成目录&…...

CompletableFuture原理与实践

文章目录 1 为何需要并行加载2 并行加载的实现方式2.1 同步模型2.2 NIO异步模型2.3 为什么会选择CompletableFuture&#xff1f; 3 CompletableFuture使用与原理3.1 CompletableFuture的背景和定义3.1.1 CompletableFuture解决的问题3.1.2 CompletableFuture的定义 3.2 Complet…...

8.3 作业

整理思维导图 2. 递归实现&#xff0c;输入一个数&#xff0c;输出这个数的每一位 #include <myhead.h> void fun(int t) {if(t 0) return;fun(t/10);printf("%d\n",t%10); } int main(int argc,const char *argv[]) {int t1623809; fun(t);return 0; } 3.递…...

c# COM组件原理

COM&#xff08;Component Object Model&#xff09;是一种微软的软件组件技术&#xff0c;用于实现软件组件之间的互操作性。它是一种二进制接口标准&#xff0c;允许不同的软件组件在不同的进程中进行通信。COM组件可以用多种编程语言编写&#xff0c;并且可以在多个应用程序…...

JavaSec-RCE

简介 RCE(Remote Code Execution)&#xff0c;可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景&#xff1a;Groovy代码注入 Groovy是一种基于JVM的动态语言&#xff0c;语法简洁&#xff0c;支持闭包、动态类型和Java互操作性&#xff0c…...

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现

摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序&#xff0c;以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务&#xff0c;提供稳定高效的数据处理与业务逻辑支持&#xff1b;利用 uniapp 实现跨平台前…...

unix/linux,sudo,其发展历程详细时间线、由来、历史背景

sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作

一、上下文切换 即使单核CPU也可以进行多线程执行代码&#xff0c;CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短&#xff0c;所以CPU会不断地切换线程执行&#xff0c;从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...

AGain DB和倍数增益的关系

我在设置一款索尼CMOS芯片时&#xff0c;Again增益0db变化为6DB&#xff0c;画面的变化只有2倍DN的增益&#xff0c;比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析&#xff1a; 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

Python Ovito统计金刚石结构数量

大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...