001 登录(md5加密)

文章目录

    • pom.xml
    • LoginController.java
    • UserMapper.java
    • User.java
    • UserServiceImpl.java
    • UserService.java
    • MD5Util.java
    • MD5UtilTest.java
    • ValidatorUtil.java
    • LoginVo.java
    • RespBean.java
    • RespBeanEnum.java
    • SeckillApplication.java
    • UserMapper.xml
    • login.html
    • application.yaml
    • sql

传统方式:
客户端发送一个密码明文,后端用md5加密明文,判断加密后的与数据库存放的密码是否一致

改进:客户端发送的时候将密码明文md5加密,后端再用md5加密一次,判断加密后的与数据库存放的密码是否一致

改进升级版:客户端发送的时候将密码明文和salt混起来再用md5加密,后端把发送过来的再加salt并用md5加密,判断加密后的与数据库存放的密码是否一致

在实际应用中,js-md5 库可以被用来生成 MD5 哈希值,这通常用于验证数据的完整性或在不需要高度安全性的场景下存储密码的哈希值(注意,由于 MD5 已知存在碰撞性漏洞,因此在需要高安全性的场景,如密码存储,推荐使用更安全的哈希算法,如 SHA-256

pom.xml


<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.4</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>seckill</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>
    <name>seckill</name>
    <description>seckill</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>


        <!-- 工程创建需要引入的相关jar -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>


        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!--mybatis-plus-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.0</version>
        </dependency>



        <!--md5依赖-->
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.15</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.11</version>
        </dependency>

        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.7.2</version>
            <scope>compile</scope>
        </dependency>




        <!-- 引入validation依赖,完成校验 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
            <version>2.4.5</version>
        </dependency>

       
        <!--pool2 对象池依赖-->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
            <version>2.9.0</version>
        </dependency>
        

        <!--引入hutool依赖-工具类-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.3.3</version>
        </dependency>
        



        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>


LoginController.java


package com.example.controller;


import com.example.service.UserService;
import com.example.vo.LoginVo;
import com.example.vo.RespBean;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

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

@Controller
@RequestMapping("/login")
@Slf4j
public class LoginController {


    //装配UserService
    @Resource
    private UserService userService;

    //编写方法,可以进入到登录页面

    @RequestMapping("/toLogin")
    public String toLogin() {
        return "login";//到templates/login.html
    }


    //处理用户登录请求
    @RequestMapping("/doLogin")
    @ResponseBody
    public RespBean doLogin(LoginVo loginVo,
                            HttpServletRequest request,
                            HttpServletResponse response) {

        //log.info("{}",loginVo);

        return userService.doLogin(loginVo,request,response);
    }

}


UserMapper.java


package com.example.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.pojo.User;

public interface UserMapper extends BaseMapper<User> {

}


User.java


package com.example.pojo;


import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

import java.io.Serializable;
import java.util.Date;

@Data
@TableName("seckill_user")
public class User implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 用户ID,手机号码
     */
    @TableId(value = "id", type = IdType.ASSIGN_ID)//不是自增长的
    private Long id;

    private String nickname;

    /**
     * MD5(MD5(pass明文+固定salt1)+salt2)
     */
    private String password;

    private String salt;

    /**
     * 头像
     */
    private String head;

    /**
     * 注册时间
     */
    private Date registerDate;

    /**
     * 最后一次登录时间
     */
    private Date lastLoginDate;

    /**
     * 登录次数
     */
    private Integer loginCount;

}


UserServiceImpl.java


package com.example.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.mapper.UserMapper;
import com.example.pojo.User;
import com.example.service.UserService;
import com.example.util.MD5Util;
import com.example.util.ValidatorUtil;
import com.example.vo.LoginVo;
import com.example.vo.RespBean;
import com.example.vo.RespBeanEnum;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

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

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Resource
    private UserMapper userMapper;

    @Override
    public RespBean doLogin(LoginVo loginVo, HttpServletRequest request, HttpServletResponse response) {

        //接收到mobile和password[midPass]
        String mobile = loginVo.getMobile();
        String password = loginVo.getPassword();

        //判断手机号/id 和密码是否为空
        if(!StringUtils.hasText(mobile) || !StringUtils.hasText(password)) {
            return RespBean.error(RespBeanEnum.LOGIN_ERROR);
        }

        //校验手机号码是否合格
        if(!ValidatorUtil.isMobile(mobile)) {
            return RespBean.error(RespBeanEnum.MOBILE_ERROR);
        }

        //查询DB,看看用户是否存在
        User user = userMapper.selectById(mobile);
        if(null == user) {//说明用户不存在
            return RespBean.error(RespBeanEnum.LOGIN_ERROR);
        }

        //如果用户存在,则比对密码
        //注意,从loginVo取出的密码是中间密码(即客户端经过一次加密加盐处理的密码)
        if(!MD5Util.midPassToDBPass(password,user.getSalt()).equals(user.getPassword())){
           return RespBean.error(RespBeanEnum.LOGIN_ERROR);
        }

        //登录成功
        return RespBean.success();
    }
}



UserService.java


package com.example.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.example.pojo.User;
import com.example.vo.LoginVo;
import com.example.vo.RespBean;

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

/**
 * 传统方式 在接口中 定义方法/声明方法,然后在实现类中进行实现
 * 在mybatis-plus中,我们可以继承父接口IService
 * 这个IService接口声明很多方法,比如crud
 * 如果默认提供方法不能满足需求,可以再声明需要的方法,然后在实现类中实现
 */

public interface UserService extends IService<User> {
    //方法 完成用户的登录校验
    RespBean doLogin(LoginVo loginVo, HttpServletRequest request,
                     HttpServletResponse response);
}


MD5Util.java


package com.example.util;

import org.apache.commons.codec.digest.DigestUtils;

/**
 * 工具类,根据前面密码设计方案提供相应的方法
 */
public class MD5Util {

    public static String md5(String src) {
        return DigestUtils.md5Hex(src);
    }

    //前端使用的盐
    private static final String SALT = "4tIY5VcX";

    //加密加盐 md5(password明文+salt1)
    public static String inputPassToMidPass(String inputPass) {
        System.out.println("SALT.charAt(0)->"+SALT.charAt(0));
        System.out.println("SALT.charAt(6)->"+SALT.charAt(6));

        String str = SALT.charAt(0) + inputPass + SALT.charAt(6);
        return md5(str);
    }


    //加密加盐  MidPass + salt2转成DB中的密码
    //md5(md5(password明文+salt1)+salt2)
    public static String midPassToDBPass(String midPass,String salt) {
        System.out.println("SALT.charAt(1)->"+salt.charAt(1));
        System.out.println("SALT.charAt(2)->"+salt.charAt(2));
        String str = salt.charAt(1) + midPass + salt.charAt(2);
        return md5(str);
    }


    //将password明文转成DB中的密码
    public static String inputPassToDBPass(String inputPass,String salt){
        String midPass = inputPassToMidPass(inputPass);
        String dbPass = midPassToDBPass(midPass,salt);
        return dbPass;
    }


}


MD5UtilTest.java


package com.example.util;


import org.junit.jupiter.api.Test;

/**
 * 测试MD5Util
 */
public class MD5UtilTest {

    @Test
    public void fun1(){

        //密码明文"123456"
        //获取到密码明文"123456"的中间密码[即客户端加密加盐后],在网络上传输的密码
        //第一次加密加盐处理
        //这个加密加盐会在客户端/浏览器完成
        System.out.println(MD5Util.inputPassToMidPass("123456"));

        //中间密码"d5c1b5290593325eebe18c9b7b146d31"的对应的DB密码

        System.out.println(MD5Util.midPassToDBPass("2028ad83f1997056c7d60e16c36d10a7","tjAyuopC"));
//
//
//        //密码明文 "123456"直接得到存放在DB密码
        System.out.println(MD5Util.inputPassToDBPass("123456","tjAyuopC"));

    }
}


ValidatorUtil.java


package com.example.util;




import org.junit.jupiter.api.Test;
import org.springframework.util.StringUtils;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 完成一些校验,比如手机号格式是否正确
 * 正则
 */
public class ValidatorUtil {

    //校验手机号码的正则表达式
    private static final Pattern mobile_pattern = Pattern.compile("^[1][3-9][0-9]{9}$");

    //编写方法
    public static boolean isMobile(String mobile) {
        if(!StringUtils.hasText(mobile)) {
            return false;
        }

        Matcher matcher = mobile_pattern.matcher(mobile);
        return matcher.matches();
    }


    //测试校验方法
    @Test
    public void t1() {
        String mobile = "0133333333";
        System.out.println(isMobile(mobile));


        String mobile2 = "13333333333";
        System.out.println(isMobile(mobile2));
    }


}


LoginVo.java


package com.example.vo;


import lombok.Data;

/**
 * 接收用户登录时,发送的信息(moblie,password)
 */
@Data
public class LoginVo {


    private String mobile;
    private String password;

}


RespBean.java


package com.example.vo;


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

@Data
@AllArgsConstructor
@NoArgsConstructor
public class RespBean {

    private long code;
    private String message;
    private Object obj;

    //成功后 同时携带数据
    public static RespBean success(Object data) {
        return new RespBean(RespBeanEnum.SUCCESS.getCode(),RespBeanEnum.SUCCESS.getMessage(), data);
    }

    //成功后 不携带数据
    public static RespBean success() {
        return new RespBean(RespBeanEnum.SUCCESS.getCode(),RespBeanEnum.SUCCESS.getMessage(), null);
    }


    //失败 不携带数据
    public static RespBean error(RespBeanEnum respBeanEnum) {
        return new RespBean(respBeanEnum.getCode(), respBeanEnum.getMessage(), null);
    }

    //失败 携带数据
    public static RespBean error(RespBeanEnum respBeanEnum,Object data) {
        return new RespBean(respBeanEnum.getCode(), respBeanEnum.getMessage(), data);
    }



}


RespBeanEnum.java


package com.example.vo;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.ToString;

/**
 * 枚举类
 */
@Getter
@ToString
@AllArgsConstructor
public enum RespBeanEnum {


    //通用
    SUCCESS(200,"SUCCESS"),
    ERROR(500,"服务端异常"),


    //登录
    LOGIN_ERROR(500210,"用户id或者密码错误"),
    MOBILE_ERROR(500211,"手机号码格式不正确"),
    MOBILE_NOT_EXIST(500213,"手机号码不存在");


    private final Integer code;

    private final String message;

}


SeckillApplication.java


package com.example;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("com.example.mapper")
public class SeckillApplication {

    public static void main(String[] args) {
        SpringApplication.run(SeckillApplication.class, args);
    }

}


UserMapper.xml


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.mapper.UserMapper">
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.example.pojo.User">
        <id column="id" property="id"/>
        <result column="nickname" property="nickname"/>
        <result column="password" property="password"/>
        <result column="salt" property="salt"/>
        <result column="head" property="head"/>
        <result column="register_date" property="registerDate"/>
        <result column="last_login_date" property="lastLoginDate"/>
        <result column="login_count" property="loginCount"/>
    </resultMap>
</mapper>

login.html


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


    <script type="text/javascript" th:src="@{/js/jquery.min.js}"></script>


    <!-- md5.js -->
    <script type="text/javascript" th:src="@{/js/md5.min.js}"></script>
    <!-- common.js -->
    <script type="text/javascript" th:src="@{/js/common.js}"></script>

</head>
<body>
<div class="container">
    <div class="welcome">
        <div class="pinkbox">
            <!-- 登录表单 -->
            <div class="signin">
                <h1>用户登录</h1>
                <form class="more-padding" id="loginForm" method="post" autocomplete="off">
                    <input style="background-color: darkgrey;" id="mobile" name="mobile" type="text" placeholder="手机号码"
                           required="true"/>
                    <input style="background-color: darkgrey;" id="password" name="password" type="password"
                           placeholder="密码" required="true"/>
                    <button class="button sumbit" type="button" onclick="login()">Login</button>
                </form>
            </div>
        </div>
    </div>
</div>

</body>

<script>

    function login() {
        doLogin();
    }

    function doLogin() {
        //得到用户在登录表单填写的密码
        var inputPass = $("#password").val();
        //客户端盐
        var salt = g_passsword_salt;
        var str = "" + salt.charAt(0) + inputPass + salt.charAt(6);
        var password = md5(str);

        console.log("inputPass->", inputPass)
        console.log("salt->", salt)
        console.log("password->", password)

        $.ajax({
            url: "/login/doLogin",
            type: "POST",
            data: {
                mobile: $("#mobile").val(),
                password: password
            },
            success: function (data) {
                if (data.code == 200) {
                    alert(data.message)
                    //如果code是200,说明登录成功., 就直接进入其他页面
                    //window.location.href=""
                } else {
                    alert(data.message)
                }
            },
            error: function () {
                alert("失败");
            }
        });
    }

</script>
</html>

application.yaml


spring:
  thymeleaf:
    #关闭缓存
    cache: false
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/seckill?useUnicode=true&characterEncoding=utf-8&useSSL=true
    username: root
    password: 123456
    # 数据库连接池
    hikari:
      #连接池名
      pool-name: dd_Poll
      #最小空闲连接
      minimum-idle: 5
      #空闲连接存活最大时间,默认60000(10分钟)
      idle-timeout: 60000
      # 最大连接数,默认是10
      maximum-pool-size: 10
      #从连接池返回来的连接自动提交
      auto-commit: true
      #连接最大存活时间。0表示永久存活,默认180000(30分钟)
      max-lifetime: 180000
      #连接超时时间,默认30000(30秒)
      connection-timeout: 30000
      #测试连接是否可用的查询语句
      connection-test-query: select 1

  
#mybatis-plus配置
mybatis-plus:
  #配置mapper.xml映射文件
  mapper-locations: classpath*:/mapper/*Mapper.xml
  #配置mybatis数据返回类型别名
  type-aliases-package: com.example.pojo
#mybatis sql 打印
#logging:
#  level:
#    com.example.mapper: debug
#server:
#  port: 9999



sql


DROP TABLE IF EXISTS `seckill_user`;
CREATE TABLE `seckill_user` (
	`id` BIGINT(20) NOT NULL COMMENT '用户ID,设为主键,唯一手机号',
	`nickname` VARCHAR(255) NOT NULL DEFAULT '',
	`password` VARCHAR(32) NOT NULL DEFAULT '' COMMENT 'MD5(MD5(pass明文+固定salt)+salt)',
	`salt` VARCHAR(10) NOT NULL DEFAULT '',
	`head` VARCHAR(128) NOT NULL DEFAULT '' COMMENT '头像',
	`register_date` DATETIME DEFAULT NULL COMMENT '注册时间',
	`last_login_date` DATETIME DEFAULT NULL COMMENT '最后一次登录时间',
	`login_count` INT(11) DEFAULT '0' COMMENT '登录次数',
	PRIMARY KEY(`id`)
	
) ENGINE=INNODB DEFAULT CHARSET=utf8mb4;


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

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

相关文章

二叉树四种遍历方法

目录 树基本概念 二叉树二叉树的五种形态特殊二叉树二叉链表创建四种遍历方法代码实现 树 树是一个n个节点的有限集&#xff0c;当n0时称之为空树 基本概念 性质 1. 树的定义是递归的&#xff0c;树的定义中又用到了自身 2. 树的根节点没有前驱&#xff0c;除根结点外&#x…

开了个新店!

大家好&#xff0c;我是麦鸽。 一言难尽&#xff0c;五一之前&#xff0c;把大A里的钱都提出来了&#xff0c;又整了一个新的小店。熟悉我的老读者应该都知道&#xff0c;我主业是做嵌入式的&#xff0c;后面慢慢转了技术管理的路线。平时也搞点副业&#xff0c;餐饮店就是其中…

关于链表带环问题为什么要用快慢指针

判断链表是否带环 题目描述 给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测系统内部使用整数 pos 来表示链表尾连…

定制开发AI名片商城AI导购系统:引领营销自动化的新时代

在数字营销日新月异的今天&#xff0c;一个革命性的工具——定制开发AI名片商城AI导购系统&#xff0c;正逐渐崭露头角&#xff0c;成为企业私域运营中的得力助手。它不仅仅是一个营销工具&#xff0c;更是一个拥有强大营销自动化能力和先进算法技术的在线助理&#xff0c;为企…

Ubuntu 域名解析出现暂时性错误

Ubuntu 域名解析出现暂时性错误 问题描述解决方案 问题描述 由于在Ubuntu系统里面经常切换网络导致&#xff0c;系统一直处于有线网络连接但是没网状态&#xff0c;尝试ping网络也无法完成&#xff0c;尝试了很多方法均不能解决 解决方案 点击”虚拟机“ 按照要求设置好即可…

Java | Spring框架 | BeanFactory与ApplicationContext

Spring容器&#xff1a;BeanFactory与ApplicationContext Spring容器是Spring框架的核心&#xff0c;负责实例化、配置和组装Bean。 Spring容器有两种主要类型&#xff1a;BeanFactory和ApplicationContext。 一、BeanFactory 基本功能&#xff1a;BeanFactory是Spring框架…

【数据库原理及应用】期末复习汇总高校期末真题试卷02

试卷 一、填空题 数据库系统是指计算机系统中引入数据库后的系统&#xff0c;一般由数据库、________、应用系统、数据库管理员和用户构成。当数据库的存储结构发生了改变&#xff0c;由数据库管理员对________映象作相应改变&#xff0c;可以使________保持不变&#xff0c;…

牛客热题:两个链表的第一个公共节点

&#x1f4df;作者主页&#xff1a;慢热的陕西人 &#x1f334;专栏链接&#xff1a;力扣刷题日记 &#x1f4e3;欢迎各位大佬&#x1f44d;点赞&#x1f525;关注&#x1f693;收藏&#xff0c;&#x1f349;留言 文章目录 牛客热题&#xff1a;两个链表的第一个公共节点题目链…

目标检测算法YOLOv5简介

没有关于YOLOv5的直接论文&#xff0c;YOLOv5由Ultralytics维护&#xff0c;源码见&#xff1a;https://github.com/ultralytics/yolov5 &#xff0c;于2020年6月发布v1.0版本&#xff0c;最新发布版本为v7.0&#xff0c;License为AGPL-3.0. 以下内容主要来自&#xff1a; 1. U…

STM32的TIM输入捕获和PWMI详解

系列文章目录 STM32单片机系列专栏 C语言术语和结构总结专栏 文章目录 1. IC输入捕获 2. 频率测量 3. 主模式、从模式、触发源选择 4. 输入捕获基本结构 5. PWMI模式 6. 代码示例 6.1 PWM.c 6.2 PWM.h 6.3 IC.c 6.4 IC.h 6.5 完整工程文件 输出比较可以看下面这篇…

ORAN C平面优化

使用section扩展6的C平面优化 在时域和频域中&#xff0c;都可以使用section扩展6进行非连续PRB分配。Section扩展6有两个位掩码&#xff1a;symbolMask和rbgMask。使用symbolMask可以选择一个slot内任意的symbol子集。使用rbgMask可以选择startPrbc和&#xff08;startPrbc …

Android版本依赖Version catalog

曾经我们使用config.gradle文件进行版本依赖配置&#xff0c;然后在project的build.gradle.kts中使用如下方式引入&#xff1a; apply(from "./config.gradle") 缺点&#xff1a;在project的module中引用无任何提示&#xff0c;无法跳转到指定引用 一、创建versio…

Go-变量

可以理解为一个昵称 以后这个昵称就代指这些信息 var sg string "czy" 声明赋值 package mainimport "fmt"func main() {var sg string "陈政洋"fmt.Println(sg)var age int 73fmt.Println(age)var flag bool truefmt.Println(flag) } …

服务网关GateWay原理

文章目录 自动装配核心类GatewayAutoConfigurationDispatcherHandler请求处理阶段apply方法httpHandler#handle方法WebHandler#handle方法DispatchHanlder#handle方法第一步 getHandler获取请求映射第二步 invokeHandler 请求适配第三步 handleResult请求处理总结 上一篇博文我…

【刷题篇】回溯算法floodfill(七)

文章目录 1、太平洋大西洋水流问题2、扫雷游戏3、衣橱整理 1、太平洋大西洋水流问题 有一个 m n 的矩形岛屿&#xff0c;与 太平洋 和 大西洋 相邻。 “太平洋” 处于大陆的左边界和上边界&#xff0c;而 “大西洋” 处于大陆的右边界和下边界。 这个岛被分割成一个由若干方形…

Python 全栈体系【四阶】(三十九)

第五章 深度学习 八、目标检测 3. 目标检测模型 3.2 YOLO 系列 3.2.4 YOLOv4&#xff08;2020 年 4 月&#xff09; YOLOv4 将最近几年 CV 界大量的研究成果集中在一套模型中&#xff0c;从检测速度、精度、定位准确率上有了明显改善&#xff08;相对于 YOLOv3&#xff0c…

基于Springboot的家具网站

基于SpringbootVue的家具网站设计与实现 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringbootMybatis工具&#xff1a;IDEA、Maven、Navicat 系统展示 用户登录 首页 商家 家具信息 家居资讯 后台管理 后台首页 用户管理 商家管理 家具类型管理 家具…

ASV1000视频监控平台:通过SDK接入海康网络摄像机IPC

目录 一、为何要通过SDK接入海康网络摄像机 &#xff08;一&#xff09;海康网络摄像机的SDK的功能 1、视频采集和显示 2、视频存储 3、视频回放 4、报警事件处理 5、PTZ控制 6、自定义设置 7、扩展功能 &#xff08;二&#xff09;通过SDK接入的好处&#xff08;相对…

JavaEE初阶-多线程易忘点总结

文章目录 1.PCBPID文件描述符表内存指针状态上下文优先级记账信息tgid 2.线程与进程的区别3.sleep和interrupt方法的关系变量终止线程interrupt方法终止线程 4.线程状态5.出现线程不安全的原因线程在系统中是随即调度&#xff0c;抢占式执行的。多个线程修改同一个变量线程针对…

Adobe 更新 Firefly Image 3 图像生成模型

一个工具或者模型&#xff0c;对于初次使用的人来说&#xff0c;易用性和超出预期的效果很能吸引使用者&#xff0c;suno和mj在这方面我感觉确实不错&#xff0c;第一次使用感觉很惊艳。 Adobe 更新 Firefly Image 3 图像生成模型&#xff0c;我用了mj的提示词&#xff0c;最后…
最新文章