【SpringMVC】JSR 303与interceptor拦截器快速入门

目录

一、JSR303

1、什么是JSR 303?

2、为什么要使用JSR 303?

3、JSR 303常用注解

3.1、常用的JSR 303注解

3.2、@Validated与@Valid区别

3.2.1、@Validated

3.2.2、@Valid

3.2.3、区别

4、使用案例

4.1、导入依赖

4.2、配置校验规则

4.3、编写校验方法

4.4、前端代码

4.5、测试

二、interceptor拦截器

1、什么是拦截器?

2、为什么要使用拦截器?

3、拦截器与过滤器

 3.1、什么是过滤器(Filter)

3.2、拦截器与过滤器的区别

3.2.1、 过滤器(filter)

3.2.2、 拦截器(interceptor)

3.2.3、汇总

4、拦截器应用场景

5、使用案例

5.1、创建拦截器

5.2、配置拦截器

5.3、运行测试

5.4、拦截器工作原理

5.5、拦截器链

5.6、登录拦截实例

5.6.1、创建拦截器

5.6.2、配置拦截器

5.6.3、编写控制层

5.6.4、前端页面

5.6.5、测试

登入

登出


一、JSR303

1、什么是JSR 303?

JSR 303是Java规范请求(Java Specification Request)的缩写,意思是Java 规范提案。是指向JCP(Java Community Process)提出新增一个标准化技术规范的正式请求。任何人都可以提交JSR,以向Java平台增添新的API和服务。JSR已成为Java界的一个重要标准。 JSR-303 是JAVA EE 6 中的一项子规范,叫做Bean ValidationHibernate Validator Bean Validation 的参考实现 . Hibernate Validator 提供了 JSR 303 规范中所有内置 constraint(约束) 的实现,除此之外还有一些附加的 constraint。

它定义了一套用于Java Bean校验的标准。JSR 303使用注解的方式,在Spring MVC中被广泛应用于进行数据校验和验证。

验证数据是一项常见任务,它发生在从表示层到持久层的所有应用程序层中。通常在每一层都实现相同的验证逻辑,这既耗时又容易出错。为了避免重复这些验证,开发人员经常将验证逻辑直接捆绑到域模型中,将域类与验证代码混在一起,而验证代码实际上是关于类本身的元数据

2、为什么要使用JSR 303?

        在前端我们进行了数据校验,可是为什么我们还要做一篇,因为因为一点小失误我们的前端校验没有写好,但是有些人还是会绕过前端发送的请求(通过类似Postman这样的测试工具进行非常数据请求),传递一些错误的参数,这就会让我们的后端代码有大大的危险,所以我们一般都是前端一套校验,后端在一套校验,这样安全性就能够大大得到提升了。

所以我总和了JSR 303以下的好处:

  1. 提高代码的可维护性:通过在实体类中添加注解,可以清晰地标识出需要进行校验的字段和规则,使代码更易于理解和维护。
  2. 增强数据的完整性:根据定义的规则,可以自动校验输入数据的合法性,避免错误数据进入系统,保证数据的完整性和准确性。
  3. 减少重复代码:通过注解,可以在不同场景下重复使用相同的校验规则,减少编写重复代码的工作量。

3、JSR 303常用注解

3.1、常用的JSR 303注解

注解 说明 @Null 用于验证对象为null @NotNull 用于对象不能为null,无法查检长度为0的字符串 @NotBlank 只用于String类型上,不能为nulltrim()之后的size>0 @NotEmpty 用于集合类、String类不能为null,且size>0。但是带有空格的字符串校验不出来 @Size 用于对象(Array,Collection,Map,String)长度是否在给定的范围之内 @Length 用于String对象的大小必须在指定的范围内 @Pattern 用于String对象是否符合正则表达式的规则 @Email 用于String对象是否符合邮箱格式 @Min 用于NumberString对象是否大等于指定的值 @Max 用于NumberString对象是否小等于指定的值 @AssertTrue 用于Boolean对象是否为true @AssertFalse 用于Boolean对象是否为false

3.2、@Validated与@Valid区别

@Validated @Valid 是用于数据校验的注解,但它们有一些区别和应用场景的差异。

3.2.1、@Validated
  • Spring 框架提供的注解
  • 支持分组校验
  • 可以用在类型、方法和方法参数上。但是不能用在成员属性(字段)上
  • 由于无法加在成员属性(字段)上,所以无法单独完成级联校验需要配合@Valid
  • Spring 提供的校验器,默认使用的是 Hibernate Validator(实现了 JSR-303 规范),但它支持更丰富的校验场景,如分组校验。
3.2.2、@Valid
  • JDK提供的 JSR-303(Bean Validation)规范的注解
  • 不支持分组校验
  • 可以用在方法、构造函数、方法参数和成员属性(字段)上
  • 可以加在成员属性(字段)上,能够独自完成级联校验
  • 使用 @Valid 注解时,会触发 JSR-303 或者其它支持的校验框架来对被注解的对象进行校验。
3.2.3、区别
  1. 适用范围@Valid 可以应用于方法参数、返回值、字段和方法上,而 @Validated 只能应用于类、接口和方法上。
  2. 校验框架@Validated 默认使用 Hibernate Validator(实现了 JSR-303)、Spring Validator 或自定义的校验器,而 @Valid 使用的是 JSR-303 或其它支持的校验框架。
  3. 分组校验@Validated 支持分组校验,允许在不同的场景下使用不同的校验规则,而 @Valid 不直接支持分组校验。

@Validated 是 Spring 框架提供的扩展注解,并不属于 Java 标准规范。在使用时,可以根据具体的需求选择合适的注解进行数据校验。

4、使用案例

4.1、导入依赖

<!-- JSR303 -->
<hibernate.validator.version>6.0.7.Final</hibernate.validator.version><!-- JSR303 -->
<dependency><groupId>org.hibernate</groupId><artifactId>hibernate-validator</artifactId><version>${hibernate.validator.version}</version>
</dependency>

4.2、配置校验规则

在实体类里面添加配置校验

package com.tgq.model;import lombok.ToString;
import org.hibernate.validator.constraints.NotBlank;import javax.validation.constraints.NotNull;@ToString
public class MyStudent {@NotNull(message = "学生编号不能为空")private String sid;@NotBlank(message = "学生名不能为空")private String sname;@NotBlank(message = "学生年龄不能为空")private String sage;@NotBlank(message = "学生性别不能为空")private String ssex;public MyStudent(String sid, String sname, String sage, String ssex) {this.sid = sid;this.sname = sname;this.sage = sage;this.ssex = ssex;}public MyStudent() {super();}public String getSid() {return sid;}public void setSid(String sid) {this.sid = sid;}public String getSname() {return sname;}public void setSname(String sname) {this.sname = sname;}public String getSage() {return sage;}public void setSage(String sage) {this.sage = sage;}public String getSsex() {return ssex;}public void setSsex(String ssex) {this.ssex = ssex;}
}

4.3、编写校验方法

   使用@Validated注解对我们的MyStudent进行服务端校验。

    //    给数据添加服务端校验@RequestMapping("/valiAdd")public String valiAdd(@Validated MyStudent myStudent, BindingResult result, HttpServletRequest req) {
//        如果服务端验证不通过,有错误if (result.hasErrors()) {
//            服务端验证了实体类的多个属性,多个属性都没有验证通过List<FieldError> fieldErrors = result.getFieldErrors();Map<String, Object> map = new HashMap<>();for (FieldError fieldError : fieldErrors) {
//                将多个属性的验证失败信息输送到控制台System.out.println(fieldError.getField() + ":" + fieldError.getDefaultMessage());map.put(fieldError.getField(), fieldError.getDefaultMessage());}req.setAttribute("errorMap", map);} else {this.myStudentBiz.insertSelective(myStudent);return "redirect:stu/list";}return "stu/edit";}

4.4、前端代码

使用form表单进行提交

<%--Created by IntelliJ IDEA.User: tgqDate: 12/9/2023Time: 下午8:05To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>edit</title>
</head>
<body><form action="${pageContext.request.contextPath }/stu/valiAdd" method="post">用户id:<input type="text" name="sid"><span style="color: red">${errorMap.sid}</span><br>用户名:<input type="text" name="sname"><span style="color: red">${errorMap.sname}</span><br>用户年龄:<input type="text" name="sage"><spanstyle="color: red">${errorMap.sage}</span><br>用户性别:<input type="text" name="ssex"><span style="color: red">${errorMap.ssex}</span><br><input type="submit" value="提交">
</form>
</body>
</html>

4.5、测试

点击提交,如果为空就会提示

二、interceptor拦截器

1、什么是拦截器?

        拦截器是在请求进入后端处理程序之前或之后执行特定逻辑的组件。它们能够拦截处理程序执行的流程,允许在请求处理过程中插入额外的功能。

        SpringMVC的处理器拦截器,类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。依赖于web框架,在实现上基于Java的反射机制,属于面向切面编程(AOP)的一种运用。由于拦截器是基于web框架的调用,因此可以使用Spring的依赖注入(DI)进行一些业务操作,同时一个拦截器实例在一个controller生命周期之内可以多次调用

2、为什么要使用拦截器?

  1. 横向功能扩展:通过拦截器,可以在不修改原有业务逻辑的情况下添加额外的功能,例如日志记录、权限验证、性能统计等。
  2. 代码复用:多个请求中可能需要相同的处理逻辑,通过拦截器可以将这部分逻辑抽取出来,减少代码的重复编写。
  3. 解耦合:通过拦截器,可以将关注点分离,在拦截器中处理通用的逻辑,使得业务处理程序更专注于业务本身。

3、拦截器与过滤器

 3.1、什么是过滤器(Filter)

依赖于servlet容器。在实现上基于函数回调,可以对几乎所有请求进行过滤,但是缺点是一个过滤器实例只能在容器初始化时调用一次。使用过滤器的目的是用来做一些过滤操作,比如:在过滤器中修改字符编码;在过滤器中修改HttpServletRequest的一些参数,包括:过滤低俗文字、危险字符等。

3.2、拦截器与过滤器的区别

3.2.1、 过滤器(filter)
  1.   filter属于Servlet技术,只要是web工程都可以使用
  2.   filter主要由于对所有请求过滤
  3.   filter的执行时机早于Interceptor
3.2.2、 拦截器(interceptor)
  1.   interceptor属于SpringMVC技术,必须要有SpringMVC环境才可以使用
  2.   interceptor通常由于对处理器Controller进行拦截
  3.   interceptor只能拦截dispatcherServlet处理的请求
3.2.3、汇总
  • 拦截器是在应用程序处理程序内部执行的,而过滤器则是在应用程序之前或之后执行的。
  • 过滤器是基于Servlet规范的,拦截器是基于应用框架的。
  • 过滤器可以在请求到达Servlet容器之前对请求进行处理,而拦截器只能在请求到达应用程序之后进行处理。

4、拦截器应用场景

  1. 权限验证:拦截器可以检查用户是否具有操作的权限,如果没有权限,可以拦截请求并返回相应的错误信息。如果没有直接返回到登录页面。
  2. 日志记录:拦截器可以记录请求的详细信息,例如请求时间、信息、请求参数等,便于后续的日志分析和故障排查。以便进行信息监控、信息统计、计算PV(Page View)等。
  3. 性能统计:拦截器可以统计请求的执行时间,便于分析系统性能并进行优化。(如果有反向代理,如apache可以自动记录);
  4. 通用行为:读取cookie得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取Locale、Theme信息等,只要是多个Controller中的处理方法都需要的,我们就可以使用拦截器实现。

拦截器链是由多个拦截器组成的链式结构,每个拦截器都可以在请求处理程序执行之前或之后进行特定的操作。拦截器链中的拦截器按照预定义的顺序执行,每个拦截器都有机会处理请求和响应。拦截器链可以保证各个拦截器的有序执行,以达到预期的处理逻辑。

5、使用案例

5.1、创建拦截器

创建一个拦截器的包,在包下创建拦截器

package com.tgq.interceptor;import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class OneInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("【OneInterceptor】:preHandle...");return true;//返回true / false}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("【OneInterceptor】:postHandle...");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("【OneInterceptor】:afterCompletion...");}
}

5.2、配置拦截器

在我们的自己配置spring-mvc.xml里面配置我们的拦截器

<mvc:interceptors><bean class="com.tgq.interceptor.OneInterceptor"></bean></mvc:interceptors>

5.3、运行测试

启动项目,打开浏览器访问请求地址,测试拦截器的拦截效果。

他们的执行顺序为:preHandle --> postHandle --> afterCompletion

http://localhost:8080/sc/list

5.4、拦截器工作原理

  • preHandle:用于对拦截到的请求进行预处理,方法接收布尔(true,false)类型的返回值,返回true:放行,false:不放行。

执行时机:在处理器方法执行前执行

方法参数
参数说明
request      请求对象    
response    响应对象    
handler      拦截到的处理器方法  
ModelAndView处理器方法返回的模型和视图对象,可以在方法中修改模型和视图
  • afterCompletion:用于在整个流程完成之后进行最后的处理,如果请求流程中有异常,可以在方法中获取对象

  执行时机:视图渲染完成后(整个流程结束之后)

方法参数
参数说明
request  请求参数
response响应对象  
handler  拦截到的处理器方法
ex异常对象

5.5、拦截器链

如果多个拦截器能够对相同的请求进行拦截,则多个拦截器会形成一个拦截器链,主要理解拦截器链中各个拦截器的执行顺序。拦截器链中多个拦截器的执行顺序,根拦截器的配置顺序有关,先配置的先执行。

package com.tgq.interceptor;import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class TwoInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("【TwoInterceptor】:preHandle...");return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("【TwoInterceptor】:postHandle...");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("【TwoInterceptor】:afterCompletion...");}
}

配置spring-mvc.xml

<mvc:interceptors><!--2) 多拦截器(拦截器链)--><mvc:interceptor><mvc:mapping path="/**"/><bean class="com.tgq.interceptor.OneInterceptor"/></mvc:interceptor><mvc:interceptor><mvc:mapping path="/sc/**"/><bean class="com.tgq.interceptor.TwoInterceptor"/></mvc:interceptor></mvc:interceptors>

走一个拦截器:editicon-default.png?t=N7T8http://localhost:8080/stu/save

走两个拦截器:列表icon-default.png?t=N7T8http://localhost:8080/sc/list

5.6、登录拦截实例

5.6.1、创建拦截器
package com.tgq.interceptor;import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class LoginInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("【implements】:preHandle...");StringBuffer url = request.getRequestURL();if (url.indexOf("/login") > 0 || url.indexOf("/logout") > 0) {//        如果是 登录、退出 中的一种return true;}
//            代表不是登录,也不是退出
//            除了登录、退出,其他操作都需要判断是否 session 登录成功过String sname = (String) request.getSession().getAttribute("sname");if (sname == null || "".equals(sname)) {response.sendRedirect("/page/stu/login");return false;}return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {}
}
5.6.2、配置拦截器
    <!--登录拦截器实例--><mvc:interceptors><bean class="com.tgq.interceptor.LoginInterceptor"></bean></mvc:interceptors>

5.6.3、编写控制层
package com.tgq.web;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;@Controller
public class LoginController {@RequestMapping("/login")public String login(HttpServletRequest req) {String sname = req.getParameter("sname");HttpSession session = req.getSession();if ("tgq".equals(sname)) {session.setAttribute("sname", sname);}return "redirect:/sc/list";}@RequestMapping("/logout")public String logout(HttpServletRequest req) {req.getSession().invalidate();return "redirect:/sc/list";}
}
5.6.4、前端页面
<%--Created by IntelliJ IDEA.User: tgqDate: 12/9/2023Time: 下午10:03To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>用户登录</title>
</head>
<body><form action="/login" method="post">账号:<input name="sname"><input type="submit">
</form>
</body>
</html>
5.6.5、测试
登入

http://localhost:8080/logouticon-default.png?t=N7T8http://localhost:8080/login

登出

http://localhost:8080/logouticon-default.png?t=N7T8http://localhost:8080/logout

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大模型Tuning分类

类型总结 微调&#xff08;Fine-tunning&#xff09; 语言模型的参数需要一起参与梯度更新 轻量微调&#xff08;lightweight fine-tunning&#xff09; 冻结了大部分预训练参数&#xff0c;仅添加任务层&#xff0c;语言模型层参数不变 适配器微调 &#xff08;Adapter-t…

数据研发“新人”如何快速落地?

作者&#xff1a;肖迪(墨诩) 一、前言 这个季度主推安全月构筑&夯实稳定性底盘&#xff0c;就组织了组里的同学对核心业务链路进行了稳定性的摸排。在摸排过程中&#xff0c;不断有个声音在问你摸排出来的问题就是全部问题么&#xff1f;你加的监控加全了么&#xff1f;你…

进程同步与互斥

目录 进程同步与互斥&#xff08;1&#xff09; 第一节、进程间相互作用 一、相关进程和无关进程 二、与时间有关的错误 第二节、进程同步与互斥 一、进程的同步 二、进程的互斥 三、临界区 进程同步与互斥&#xff08;2&#xff09; 三、信号量与P、V操作的物理含义…

Tomcat 下部署 jFinal

1、检查web.xml 配置&#xff0c;在 tomcat 下部署需要检查 web.xml 是否存在&#xff0c;并且要确保配置正确&#xff0c;配置格式如下。 <?xml version"1.0" encoding"UTF-8"?> <web-app xmlns:xsi"http://www.w3.org/2001/XMLSchema-i…

使用命令行(CMD)编译单Java文件

1.安装JDK JDK官网&#xff1a;https://www.oracle.com/java/technologies/downloads/ 选 Windows -> x64 MSI Instaler或者x64 Installer 安装成功后。 2.配置环境变量 按下Win键&#xff0c;搜索环境变量 添加JAVA_HOME系统环境变量&#xff0c;要指定类似这样的路径(…

Dubbo学习(一)——dubbo学习背景

文章目录 前言分布式基础理论什么是分布式系统发展演变ORMMVCRPCSOA RPC(远程调用)什么是RPCRPC工作原理 为什么RPC要用到DubboDubbo的优势高性能可扩展性高可靠性监控和管理 使用示例总结 前言 分布式基础理论 什么是分布式系统 分布式系统是若干独立计算机的集合&#xff…

月木学途开发 1.后台用户模块

概述 权限控制采用springsecurity 数据库设计 用户表 DROP TABLE IF EXISTS admin; CREATE TABLE admin (aid int(32) NOT NULL AUTO_INCREMENT,email varchar(50) DEFAULT NULL,username varchar(50) DEFAULT NULL,password varchar(255) DEFAULT NULL,phoneNum varchar(2…

在Ubuntu 18.04上支持C++17的std::filesystem的方法

在Ubuntu 18.04上通过命令sudo apt install gcc g安装的gcc/g版本为7.5&#xff0c;此版本并不直接支持filesystem&#xff0c;如下图所示&#xff1a; Ubuntu 18.04上的g 7.5支持experimental的filesystem,即std::experimental::filesystem&#xff0c;若想使Ubuntu 18.04支持…

软件设计原则扩展

一、引言 经典的软件设计7大原则 开闭原则&#xff08;Open Close Principle, OCP&#xff09; 依赖倒置原则&#xff08;Dependence Inversion Principle, DIP&#xff09; 单一职责原则&#xff08;Simple Responsibility Principle, SRP&#xff09; 接口隔离原则&#xf…

OPENCV实现DNN图像分类

使用步骤1 使用步骤2 使用步骤3 使用步骤4 使用步骤5 使用步骤6 完整代码如下: import numpy as np

Git --- 基础介绍

Git --- 基础介绍 git 是什么git --- 工作区, 暂存区, 资源库git --- 文件状态git --- branch 和 HEADgit --- 一次正常的git提交流程 git 是什么 Git是一款分布式源代码管理工具(版本控制工具)Git和其他传统版本控制系统比较: 传统的版本控制系统(例如 SVN)是基于差异的版本控…

从零开始学习 Java:简单易懂的入门指南之Stream流(二十七)

Stream流 Stream流1.体验Stream流2.Stream流的常见生成方式3.Stream流中间操作方法4.Stream流终结操作方法5.Stream流的收集操作6.Stream流综合练习 Stream流 1.体验Stream流 案例需求 按照下面的要求完成集合的创建和遍历 创建一个集合&#xff0c;存储多个字符串元素把集合中…

ElasticSearch(ES)简单介绍

ES简介 Elasticsearch&#xff08;通常简称为ES&#xff09;是一个开源的分布式搜索和分析引擎&#xff0c;旨在处理各种类型的数据&#xff0c;包括结构化、半结构化和非结构化数据。它最初是为全文搜索而设计的&#xff0c;但随着时间的推移&#xff0c;它已经演变成一个功能…

后端返回的id到前端后 后面几位数全部变成0了 问题解决

这里 我在java控制台上 输出了id的值 但请求到前端后 很明显就不太一样了 这个问题比较经典的叫法是 雪花算法生成的ID过长&#xff0c;前端接收精度丢失 原因 前端使用number类型进行接收&#xff0c;number类型的范围小于后台Long类型的范围&#xff0c;出现了精度丢失问题…

【Vue】路由与Node.js下载安装及环境配置教程

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《Vue快速入门》。&#x1f3af;&#x1f3af; &…

界面控件DevExpress WinForms HTML-CSS模板:预设计UI模板加速.NET应用开发

在过去的一年里&#xff0c;DevExpress官方引入了两个强大的功能来加速/简化.NET桌面应用的开发&#xff0c;当一起使用时&#xff0c;您可以创建优雅/个性化的用户界面&#xff0c;减少重复的代码&#xff0c;从而节省更多的项目时间。 DevExpress WinForms有180组件和UI库&am…

2023_Spark_实验十二:Spark高级算子使用

掌握Spark高级算子在代码中的使用 相同点分析 三个函数的共同点&#xff0c;都是Transformation算子。惰性的算子。 不同点分析 map函数是一条数据一条数据的处理&#xff0c;也就是&#xff0c;map的输入参数中要包含一条数据以及其他你需要传的参数。 mapPartitions函数是一个…

公开研讨会|智能制造中生产管理挑战与解决方案(9月29日)

随着新能源行业的规模化发展&#xff0c;企业增效降本成为迫切需求。生产制造能力成为关键因素&#xff0c;其发展必将是在大规模生产的前提下&#xff0c;追寻极简制造、极限制造以及智能制造。然而在这个发展过程中&#xff0c;企业依旧面临着诸多挑战&#xff1a; 产品设计…

DAZ To UMA⭐一.DAZ使用简介 / 设置DAZ导出的内容 / 获取模型纹理贴图

文章目录 🟥 DAZ快捷键🟧 DAZ界面介绍🟩 设置DAZ导出的内容1️⃣ 找到要导出的参数名称2️⃣ 打开导出面板3️⃣ 设置导出规则举例 : 导出身体Assets🟦 获取模型纹理贴图🟥 DAZ快捷键 移动物体:ctrl+alt+鼠标左键 旋转物体:ctrl+alt+鼠标右键 导入模型:双击左侧模型…

大数据-玩转数据-Flink SQL编程

一、概念 1.1 Apache Flink 两种关系型 API Apache Flink 有两种关系型 API 来做流批统一处理&#xff1a;Table API 和 SQL。 Table API 是用于 Scala 和 Java 语言的查询API&#xff0c;它可以用一种非常直观的方式来组合使用选取、过滤、join 等关系型算子。 Flink SQL 是…