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

SpringMVC系列(五)之JSR303和拦截器

目录

一. JSR303

1.1 JSR303是什么

1.2 为什么要使用JSR303

1.3 JSR303常用注解

1.4 JSR303快速入门

1. 导入相关pom依赖

2. 配置校验规则

 3. 入门示例

 二. SpringMVC的拦截器

2.1 什么是拦截器

2.2 拦截器与过滤器的区别

2.3 拦截器工作原理

2.4 入门示例

1. 创建拦截器

2. 配置拦截器

 2.5 拦截器链

2.6  用户登录权限控制


一. JSR303

1.1 JSR303是什么

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

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

1.2 为什么要使用JSR303

前端不是已经校验过数据了吗?为什么我们还要做校验呢,直接用不就好了?草率了,假如说前端代码校验没写好又或者是对于会一点编程的人来说,直接绕过前端发请求(通过类似Postman这样的测试工具进行非常数据请求),把一些错误的参数传过来,后端代码不就危险了嘛。

所以我们一般都是前端一套校验,后端在一套校验,这样安全性就能够大大得到提升了。

1.3 JSR303常用注解

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

@Validated与@Valid区别

@Validated:

  • Spring提供的

  • 支持分组校验

  • 可以用在类型、方法和方法参数上。但是不能用在成员属性(字段)上

  • 由于无法加在成员属性(字段)上,所以无法单独完成级联校验,需要配合@Valid

@Valid:

  • JDK提供的(标准JSR-303规范)

  • 不支持分组校验

  • 可以用在方法、构造函数、方法参数和成员属性(字段)上

  • 可以加在成员属性(字段)上,能够独自完成级联校验

1.4 JSR303快速入门

1. 导入相关pom依赖

<!-- 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>

2. 配置校验规则

package com.xissl.model;import lombok.ToString;import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;@ToString
public class clazz {@NotNull(message = "班级编号不能为空")
//    @Size(max = 100,min = 10,message = "大小必须在10至100之间")protected Integer cid;@NotBlank(message = "班级名不能为空")protected String cname;@NotBlank(message = "班级教员老师不能为空")protected String cteacher;private String pic="暂无图片";public clazz(Integer cid, String cname, String cteacher, String pic) {this.cid = cid;this.cname = cname;this.cteacher = cteacher;this.pic = pic;}public clazz() {super();}public Integer getCid() {return cid;}public void setCid(Integer cid) {this.cid = cid;}public String getCname() {return cname;}public void setCname(String cname) {this.cname = cname;}public String getCteacher() {return cteacher;}public void setCteacher(String cteacher) {this.cteacher = cteacher;}public String getPic() {return pic;}public void setPic(String pic) {this.pic = pic;}
}

 3. 入门示例

在请求处理方法中,使用@Validated或@Valid注解要验证的对象,并根据BindingResult判断校验是否通过;

controller层

    //    给数据添加服务端校验@RequestMapping("/valiAdd")public String valiAdd(@Validated clazz clazz, 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.clazzBiz.insertSelective(clazz);return "redirect:clzlist";}return "clz/clzedit";}

前端代码:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>编辑界面</title>
</head>
<body>
<form action="${pageContext.request.contextPath }/${empty c ? 'clazz/valiAdd' : 'clazz/edit'}" method="post">班级编号:<input type="text" name="cid" value="${s.cid }"><span style="color: red">${errorMap.cid}</span><br>班级名称:<input type="text" name="cname" value="${s.cname }"><span style="color: red">${errorMap.cname}</span><br>带班教员:<input type="text" name="cteacher" value="${s.cteacher }"><span style="color: red">${errorMap.cteacher}</span><br>班级logo:<input type="text" name="pic" value="${s.pic }"><br><input type="submit">
</form>
</body>
</html>

运行效果:

 

 二. SpringMVC的拦截器

2.1 什么是拦截器

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

2.2 拦截器与过滤器的区别

什么是过滤器(Filter)

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

拦截器与过滤器的区别

  • 过滤器(filter)

    1.filter属于Servlet技术,只要是web工程都可以使用

    2.filter主要由于对所有请求过滤

    3.filter的执行时机早于Interceptor

  • 拦截器(interceptor)

    1.interceptor属于SpringMVC技术,必须要有SpringMVC环境才可以使用

    2.interceptor通常由于对处理器Controller进行拦截

    3.interceptor只能拦截dispatcherServlet处理的请求

应用场景:日志处理、登录权限验证等

2.3 拦截器工作原理

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

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

    方法参数

    参数说明
    request请求对象
    response响应对象
    handler拦截到的方法处理
  • postHandle:用于对拦截到的请求进行后处理,可以在方法中对模型数据和视图进行修改

    执行时机:在处理器的方法执行后,视图渲染之前

    方法参数

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

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

    方法参数

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

2.4 入门示例

在 Spring MVC 框架中定义一个拦截器需要对拦截器进行定义和配置,主要有以下 2 种方式。

  1. 通过实现 HandlerInterceptor 接口或继承 HandlerInterceptor 接口的实现类(例如 HandlerInterceptorAdapter)来定义;
  2. 通过实现 WebRequestInterceptor 接口或继承 WebRequestInterceptor 接口的实现类来定义。

这里以实现 HandlerInterceptor 接口的定义方式为例

1. 创建拦截器

package com.xissl.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;}@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...");}
}

这里的preHandle()方法返回值为true时,则表示未拦截,

返回值为false时,则表示拦截 

2. 配置拦截器

<!--    配置拦截器--><mvc:interceptors><bean class="com.xissl.interceptor.OneInterceptor"></bean></mvc:interceptors>

 未拦截:

已拦截:

 2.5 拦截器链

  • 当配置多个拦截器时,形成拦截器链
  • 拦截器链的运行顺序参照拦截器添加顺序为准
  • 当拦截器中出现对原始处理器的拦截,后面的拦截器均终止运行
  • 当拦截器运行中断,仅运行配置在前面的拦截器的afterCompletion操作

创建拦截器

package com.xissl.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...");}
}

配置拦截器

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

 <mvc:interceptors>:该元素用于配置一组拦截器。

<bean>:该元素是 <mvc:interceptors> 的子元素,用于定义全局拦截器,即拦截所有的请求。

<mvc:interceptor>:该元素用于定义指定路径的拦截器。

<mvc:mapping>:该元素是 <mvc:interceptor> 的子元素,用于配置拦截器作用的路径,该路径在其属性 path 中定义。path 的属性值为/**时,表示拦截所有路径,值为/clazz/**

时,表示拦截所有以/clazz/**结尾的路径。如果在请求路径中包含不需要拦截的内容,可以通过 <mvc:exclude-mapping> 子元素进行配置。

需要注意的是,<mvc:interceptor> 元素的子元素必须按照 <mvc:mapping.../>、<mvc:exclude-mapping.../>、<bean.../> 的顺序配置。

2.6  用户登录权限控制

登录拦截器

package com.xissl.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 uname = (String) request.getSession().getAttribute("uname");if (uname == null || "".equals(uname)){response.sendRedirect("/page/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 {}
}

配置拦截器

    <mvc:interceptors><bean class="com.xissl.interceptor.LoginInterceptor"></bean></mvc:interceptors>

controller层

package com.xissl.web;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;/*** @author xissl* @create 2023-09-11 19:19*/
@Controller
public class LoginController {@RequestMapping("/login")public String login(HttpServletRequest req){String uname = req.getParameter("uname");HttpSession session = req.getSession();if ("zs".equals(uname)){session.setAttribute("uname",uname);}return "redirect:/clz/clzlist";}@RequestMapping("/logout")public String logout(HttpServletRequest req){req.getSession().invalidate();return "redirect:/clz/clzlist";}
}

前端代码:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>登录</title>
</head>
<body>
<form action="/login" method="post">用户名:<input name="uname"><input type="submit"></form>
</body>
</html>

这里由于做了限制,只要输入的用户名不是zs,便不会被拦截器放行

 

相关文章:

SpringMVC系列(五)之JSR303和拦截器

目录 一. JSR303 1.1 JSR303是什么 1.2 为什么要使用JSR303 1.3 JSR303常用注解 1.4 JSR303快速入门 1. 导入相关pom依赖 2. 配置校验规则 3. 入门示例 二. SpringMVC的拦截器 2.1 什么是拦截器 2.2 拦截器与过滤器的区别 2.3 拦截器工作原理 2.4 入门示例 1. 创建…...

LCP 01.猜数字

​​题目来源&#xff1a; leetcode题目&#xff0c;网址&#xff1a;LCP 01. 猜数字 - 力扣&#xff08;LeetCode&#xff09; 解题思路&#xff1a; 遍历比较即可。 解题代码&#xff1a; class Solution {public int game(int[] guess, int[] answer) {int res0;for(int …...

智能小车开发

1.材料 店铺&#xff1a;店内搜索页-risym旗舰店-天猫Tmall.com 1.四个小车轮子 2.四个直流减速电机 3.两节18650锂电池&#xff08;每节3.7V&#xff09;&#xff0c;大概电压在7.4V左右&#xff0c;电压最好不要超过12V不然会损坏电机驱动 4.一个18650锂电池盒 5.一个L…...

RDMA性能测试工具集preftest_README

文章目录 1 概述2 安装3 测试方法说明4 测试说明5 运行测试所有测试的通用选项延迟测试选项带宽测试选项ib_send_lat&#xff08;发送延迟测试&#xff09;和 ib_send_bw&#xff08;发送带宽测试&#xff09;的选项ib_atomic_lat&#xff08;原子延迟测试&#xff09;和 ib_at…...

墨天轮专访星环科技刘熙:“向量热”背后的冷思考,Hippo如何打造“先发”优势?

导读&#xff1a; 深耕技术研发数十载&#xff0c;坚持自主可控发展路。星环科技一路砥砺前行、坚持创新为先&#xff0c;建设了全面的产品矩阵&#xff0c;并于2022年作为首个独立基础软件产品公司成功上市。星环科技在今年的向星力•未来技术大会上发布了分布式向量数据库Tra…...

逆向-beginners之非递归

/* * 非递归 */ void f() { } void main() { f(); } #if 0 /* * intel */ 0000000000001129 <f>: 1129: f3 0f 1e fa endbr64 112d: 55 push %rbp 112e: 48 89 e5 mov %rsp,%…...

Spring for Apache Kafka概述和简单入门

一、概述 Spring for Apache Kafka 的高级概述以及底层概念和可运行的示例代码。 二、准备工作 注意:进行工作开始之前至少要有一个 Apache Kafka 环境 2.1、依赖 使用 Spring Boot<dependency><groupId>org.springframework.kafka</groupId><artifact…...

基于SSM+Vue的医院医患管理系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用Vue技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…...

再次理解Android账号管理体系

目录 ✅ 0. 需求 &#x1f4c2; 1. 前言 &#x1f531; 2. 使用 2.1 账户体系前提 2.2 创建账户服务 2.3 操作账户-增删改查 &#x1f4a0; 3. 源码流程 ✅ 0. 需求 试想&#xff0c;自己去实现一个账号管理体系&#xff0c;该如何做呢&#xff1f; ——————————…...

如何在Blender中压缩/减小GLTF模型的大小

GLTF 如何在Blender中压缩/减小GLTF模型的大小 Blender是一款功能强大的开源软件&#xff0c;旨在创建3D图形&#xff0c;动画和视觉效果。它支持多种文件格式的导入和导出&#xff0c;包括GLB&#xff0c;GLTF&#xff0c;DAE&#xff0c;OBJ&#xff0c;ABC&#xff0c;USD…...

IntelliJ IDEA使用_Plugin插件推荐

官网插件库&#xff1a;https://plugins.jetbrains.com/search 代码规范检测&#xff1a;Alibaba Java Coding Guidelines码云&#xff1a;Giteemybatis插件&#xff1a;MyBatisX多颜色括号&#xff1a;Rainbow Brackets操作快捷键提示&#xff1a;Key Promoter X力扣&#xff…...

Ajax fetch navigator.sendBeacon 三个的区别

Ajax、fetch 和 navigator.sendBeacon 是用于发送网络请求的不同方法。 Ajax: Ajax 是一种传统的用于发送异步请求的技术。它使用 XMLHttpRequest 对象来发送数据和接收响应。通过创建 XMLHttpRequest 对象&#xff0c;你可以通过调用其 open() 方法指定请求的类型和 URL&#…...

map-reduce执行过程

Map阶段 Map 阶段是 MapReduce 框架中的一个重要阶段&#xff0c;它负责将输入数据转换为中间数据。Map 阶段由一个或多个 Map 任务组成&#xff0c;每个 Map 任务负责处理输入数据的一个子集。 执行步骤 Map 阶段的过程可以分为以下几个大步骤&#xff1a; 输入数据分配&a…...

技术人员怎样提升对业务的理解

技术服务于业务。 一个技术人员想要走得更远&#xff0c;不能仅局限于技术&#xff0c;需要对自己所从事的业务领域有不断深入和全面的理解。 所谓业务领域&#xff0c;就是大家平常自我介绍&#xff0c;不会仅简单说我是搞C的&#xff0c;我是搞JAVA的&#xff0c;而是游戏后台…...

【分布式】分布式事务:2PC

分布式事务的问题可以分为两部分&#xff1a; 并发控制 concurrency control原子提交 atomic commit 分布式事务问题的产生场景&#xff1a;一份数据被分片存在多台服务器上&#xff0c;那么每次事务处理都涉及到了多台机器。 可序列化&#xff08;并发控制&#xff09;&…...

回归与聚类算法系列④:岭回归

目录 1. 背景 2. 数学模型 3. 特点 4. 应用领域 5. 岭回归与其他正则化方法的比较 6、API 7、代码 8、总结 &#x1f343;作者介绍&#xff1a;双非本科大三网络工程专业在读&#xff0c;阿里云专家博主&#xff0c;专注于Java领域学习&#xff0c;擅长web应用开发、数…...

idea配置git(gitee)并提交(commit)推送(push)

Intellij Idea VCS | 版本控制 - 知乎 IDEA项目上传到gitee仓库_idea上传代码到gitee_robin19712的博客-CSDN博客 git程序下载国内镜像地址&#xff1a; https://registry.npmmirror.com/binary.html?pathgit-for-windows/v2.42.0.windows.2/ 解压后放到固定路径&#xff1a…...

(19)Task异步:任务创建,返回值,异常捕捉,任务取消,临时变量

一、Task任务的创建 1、用四种方式创建&#xff0c;界面button,info各一。 程序代码 private void BtnStart_Click(object sender, EventArgs e){Task t new Task(() >{DisplayMsg($"[{Environment.CurrentManagedThreadId}]new Task.---1");});t.Start()…...

设备树的理解与运用

设备树&#xff1a; 本质是一个文件&#xff0c;包含很多节点&#xff0c;每个节点里边是对设备属性的描述&#xff08;包括GPIO&#xff0c;时钟&#xff0c;中断等等&#xff09;,其中节点&#xff08;node&#xff09;和属性&#xff08;property&#xff09;就是设备树最重…...

【AIGC】提示词 Prompt 分享

提示词工程是什么&#xff1f; Prompt engineering&#xff08;提示词工程&#xff09;是指在使用语言模型进行生成性任务时&#xff0c;设计和调整输入提示&#xff08;prompts&#xff09;以改善模型生成结果的过程。它是一种优化技术&#xff0c;旨在引导模型产生更加准确、…...

【Axure视频教程】取整函数

今天教大家在Axure里如何使用三种不同的取整函数&#xff0c;包括向上取整、向下取整和四舍五入取整。具体效果可以参考下方视频。该教程从0开始制作&#xff0c;手把手教学&#xff0c;无论是新手小白还是有一定基础的同学&#xff0c;都可以学习的哦。 【视频教程——试看版…...

MySQL清空表

当我们需要清空一个表中的所有行时&#xff0c;除了使用 DELETE * FROM table 还可以使用 TRUNCATE TABLE 语句。 如果想要清空一个表&#xff0c; TRUNCATE TABLE 语句比 DELETE语句更加有效。 TRUNCATE TABLE 语法 TRUNCATE TABLE 的语法很简单&#xff0c;如下&#xff1a…...

使用IDEA创建Vue3通过Vite实现工程化

1、创建Vite项目的分步说明 IntelliJ IDEA与Vite构建工具集成&#xff0c;改善了前端开发体验。Vite 由一个开发服务器和一个构建命令组成。构建服务器通过本机 ES 模块提供源文件。生成命令将代码与汇总捆绑在一起&#xff0c;汇总预配置为输出高度优化的静态资产以供生产。In…...

GitLab使用的最简便方式

GitLab介绍 GitLab是一个基于Git版本控制系统的开源平台&#xff0c;用于代码托管&#xff0c;持续集成&#xff0c;以及协作开发。它提供了一套完整的工具&#xff0c;以帮助开发团队协同工作、管理和部署代码。 往往在企业内部使用gitlab管理代码&#xff0c;记录一下将本地代…...

MySQL数据库20G数据迁移至其他服务器的MySQL库或者云MySQL库

背景&#xff1a;20G的MySQL数据迁移至火山云MySQL库&#xff0c;使用navicat的数据传输工具迁移速度耗费时间过长。 方案一&#xff1a;使用火山云提供的MySQL数据迁移服务&#xff08;其他大厂应该提供的也有&#xff09; 方案二&#xff1a;使用数据迁移工具kettle&#x…...

build.gradle配置文件详解

Andorid Studio高版本和低版本的build.gradle配置逻辑有些差异 安卓项目中相关编译文件的介绍 gradle-wrapper.properites&#xff1a;配置Gradle Wrapper gradle.properties&#xff1a;配置Gradle的编译参数。具体配置见Gradle官方文档:com.android.build.gradle | Andro…...

2024拼多多校招面试真题汇总及其解答(二)

6. 【算法题】归并排序 归并排序(Merge Sort)是一种分治算法,它将待排序的序列递归地分成两个子序列,然后将两个有序的子序列合并成一个有序的序列。 归并排序的算法流程如下: 递归地将待排序的序列分成两个子序列,直到每个子序列只有一个元素。将两个有序的子序列合并…...

自动化运维工具Ansible教程(一)【入门篇】

文章目录 前言Ansible 入门到精通入门篇进阶篇精通篇入门篇1. Ansible 简介2. 安装 Ansible1. 通过包管理器安装&#xff1a;2. 通过源码安装&#xff1a; 3. Ansible 的基本概念和核心组件4. 编写和运行第一个 Ansible Playbook5. 主机清单和组织结构主机清单组织结构 6. Ansi…...

计算机毕业设计 微信小程序 uniapp+vue大学生兼职平台

任何系统都要遵循系统设计的基本流程&#xff0c;本系统也不例外&#xff0c;同样需要经过市场调研&#xff0c;需求分析&#xff0c;概要设计&#xff0c;详细设计&#xff0c;编码&#xff0c;测试这些步骤&#xff0c;本系统前台采用微信开发者结合后台Java语言设计并实现了…...

JavaScript框架:构建交互性、现代化Web应用的利器

&#x1f482; 个人网站:【工具大全】【游戏大全】【神级源码资源网】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 寻找学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】 引言 JavaScript框架已…...

电力行业网站建设/企业公司网站建设

前言 也许这个话题并不新鲜&#xff0c;因为LD_PRELOAD所产生的问题由来已久。不过&#xff0c;在这里&#xff0c;我还是想讨论一下这个环境变量。因为这个环境变量所带来的安全问题非常严重&#xff0c;值得所有的Unix下的程序员的注意。在开始讲述为什么要当心LD_PRELOAD环境…...

哪个网站可以代做试题/网络营销推广方案有哪些

公众号新增加了一个栏目&#xff0c;就是每天给大家解答一道Python常见的面试题&#xff0c;反正每天不贪多&#xff0c;一天一题&#xff0c;正好合适&#xff0c;只希望这个面试栏目&#xff0c;给那些正在准备面试的同学&#xff0c;提供一点点帮助&#xff01;小猿会从最基…...

甘肃省建设厅执业注册中心网站/国际域名注册网站

原文来源&#xff1a;MySQL 5.5 Reference Manual 部分翻译取自&#xff1a;《MySQL_5.1中文参考手册》 转载请注明原文链接http://www.cnblogs.com/lenagt/archive/2012/06/06/2538201.html 谢谢。 ------------------------------------------------------------------------…...

外贸零售网站建设/广州搜索排名优化

T1题目&#xff1a; 【问题描述】 有一天&#xff0c;小 A 得到了一个长度为 n 的序列。 他把这个序列的所有连续子序列都列了出来&#xff0c;并对每一个子序列 都求了其平均值&#xff0c;然后他把这些平均值写在纸上&#xff0c;并对它们进行排序&#xff0c; 最后他报出了第…...

wordpress 内存溢出/seoul什么意思

错是谁都会犯的。只不过有人犯的是五十步&#xff0c;有人犯的是一百步&#xff1b;有人犯了之后能改&#xff0c;有人犯了之后不改&#xff1b;有人心里一直在自省我有没有犯错&#xff0c;有人从来没有这样做的概念。今天我发现自己犯了错&#xff0c;错在为了一个“主义”问…...

国外教做蛋糕的网站/seo赚钱

Eclipse MyEclipse 没有响应 JVM terminated. Exit code1073807364 错误 卡住 等怪问题怪现象[解决办法]问题描述&#xff1a; Eclipse的WTP和MyEclipse都会的怪毛病 在WTP或者MyEclipse下 在JSP页面中<% 和 %>之间写代码&#xff08;即写&#xff1…...