关于@JsonSerialize序列化与@JsonDeserialize反序列化注解的使用(密码加密与解密举例)

news2024/11/16 17:51:27

注:另一种方式参考

关于@TableField中TypeHandler属性,自定义的类型处理器的使用(密码加密与解密举例)icon-default.png?t=N7T8http://t.csdnimg.cn/NZy4G

1.简介

1.1 序列化与反序列化

        学习注解之前,我们可以先了解一下什么是序列化与反序列化?

1.1.1序列化

        序列化是将对象的状态信息转换为可以存储或传输的形式的过程。通常,对象会被转换为字节序列,这样它们就可以被写入文件、存储在数据库中,或者通过网络发送给其他计算机。

目的

  1. 持久化:将对象的状态保存到文件或数据库中,以便在程序下次运行时可以恢复对象的状态。
  2. 网络传输:通过将对象转换为字节序列,可以在网络上传输对象的状态,使得分布式系统中的不同部分可以共享数据。

过程

  • 确定对象的状态:选择需要保存的属性或字段。
  • 转换为字节序列:将这些状态转换为字节序列,通常是通过某种编码方式。

1.1.2反序列化

        反序列化是序列化的逆过程,即将字节序列恢复为对象的过程。在反序列化过程中,字节序列被重新构造为原来的对象,恢复其状态。

目的

  1. 恢复对象状态:从文件、数据库或网络中读取字节序列,并将其转换回对象。
  2. 数据共享:在分布式系统中,接收方可以通过反序列化接收到的数据来恢复对象的状态。

过程

  • 读取字节序列:从存储介质或网络中读取字节序列。
  • 构造对象:根据字节序列中的信息重新构造对象。

1.2 @JsonSerialize与@JsonDeserialize

    @JsonSerialize@JsonDeserialize 是 Jackson 库提供的注解,用于在序列化(将对象转换为 JSON 字符串)和反序列化(将 JSON 字符串转换为对象)过程中对特定字段进行自定义处理。这些注解允许你控制 JSON 数据的格式和内容,而不需要改变对象本身的数据结构。

1.2.1@JsonSerialize

  @JsonSerialize 注解用于指定一个自定义的序列化器,该序列化器用于将 Java 对象转换成 JSON 字符串。当你需要在序列化过程中对某些字段进行特殊处理时,可以使用这个注解。

定义与用途

  • 定义:@JsonSerialize注解用于指定在将Java对象序列化为JSON字符串时使用的序列化器。
  • 用途:通过该注解,开发者可以自定义序列化过程,如格式化日期、调整数字的小数位数、将枚举类型序列化为特定的字符串等。

使用场景

  • 当Java对象的某个属性需要按照特定的格式或逻辑进行序列化时,可以使用@JsonSerialize注解。
  • 例如,将日期时间格式化为“yyyy-MM-dd HH:mm:ss”格式的字符串,或将金额从元转换为万元等。

使用方式

  • 可以将@JsonSerialize注解应用于字段、get方法或类级别。
  • 通过using属性指定自定义的序列化器类。指定一个实现了 JsonSerializer 接口的类,用于处理字段的序列化。

例如:SexSerializer是自定义处理性别的序列化器

  @Schema(name="sex",description=" 性别 ")
  @JsonSerialize(using = SexSerializer.class)
  private Integer sex;

1.2.2@JsonDeserialize

   @JsonDeserialize 注解用于指定一个自定义的反序列化器,该反序列化器用于将 JSON 字符串转换成 Java 对象。当你需要在反序列化过程中对某些字段进行特殊处理时,可以使用这个注解。

定义与用途

  • 定义:@JsonDeserialize注解用于指定在将JSON字符串反序列化为Java对象时使用的反序列化器。
  • 用途:通过该注解,开发者可以自定义反序列化过程,如将特定格式的字符串转换为日期对象、将JSON中的某个字段映射到Java对象的不同属性等。

使用场景

  • 当JSON数据的格式与Java对象的属性不完全匹配,或者需要按照特定的逻辑将JSON数据转换为Java对象时,可以使用@JsonDeserialize注解。
  • 例如,将JSON中的“金额”字段从万元转换为元,或将自定义格式的日期字符串转换为Java的LocalDateTime对象等。

使用方式

  • 可以将@JsonDeserialize注解应用于字段、set方法或类级别。
  • 通过using属性指定自定义的反序列化器类。指定一个实现了 JsonDeserializer接口的类,用于处理字段的序列化。

例如:UserAccountDeserializer是自定义处理用户账号的反序列化器

  @Schema(name="account",description=" 账号 ")
  @JsonDeserialize(using= UserAccountDeserializer.class)
  private String account;

2.场景实现

2.1需求分析

(1)数据库中性别字段为数字,将性别转化为汉字给前端进行展示

(2)保存密码时,进行加密存储,查询时给它明文展示(这里只是举例查所有,真正的场景肯定不能这样搞)       

开始分析:

        (1)关于性别的转化、密码的明文展示。这俩基本一致,都是查询时给前端进行展示。那你想想,我们给前端进行展示,肯定涉及到了传输。那就是将我们的实体对象,转化成Json字符串的形式,那就是在Vo对象字段上加@JsonSerialize注解实现自定义序列化器来操作。

        (2)关于密码的加密保存。那你想想,前端传给我们的肯定是明文,而且是Json串,我们将Json转化成java对象进行保存。那这个不就是反序列话操作吗。我们可以在入参Dto对象字段上加@JsonDeserialize注解实现自定义反序列化器来操作

        那这里,可能有个疑问,从数据库中查出来,不也涉及到了,反序列化操作,将数据库对象映射成了java对象?保存时,不也涉及到了序列化操作,将java对象映射成Json串?是的没错,但是我这里用了mybatis-plus来实现,我查询了一下,mybatis-plus自带的crud他好像不一定会实现序列化与反序列化,就对导致我们的注解失效,所以这里我没在数据库entity实体上加@JsonSerialize和@JsonDeserialize注解)也有另一种实现方法,使用mybatis-plus支持的typeHandler的形式(typeHandler我在另一篇文章里去写)

2.2通用部分

2.2.1 Entity数据库实体,User对象

package com.zsh.test.swagger3test.model.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.zsh.test.swagger3test.handler.Sm4TypeHandler;
import lombok.Data;
import lombok.experimental.Accessors;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.v3.oas.annotations.media.Schema;

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

/**
 * @Description 
 * @Author  ZhaoShuhao
 * @Date: 2024-07-21 12:45:39
 */

@Data
@Accessors(chain = true)
@Schema(name="用户信息")
@TableName(value = "user",autoResultMap = true)
public class User implements Serializable {
  private static final long serialVersionUID = 1L;

  @TableId(value = "id",type = IdType.ASSIGN_ID)
  @Schema(name="id",description=" 主键 ")
  private Long id;

  @TableField(value = "name")
  @Schema(name="name",description=" 姓名 ")
  private String name;
 

  @TableField(value = "age")
  @Schema(name="age",description=" 年龄 ")
  private Integer age;
 

  @TableField(value = "phone")
  @Schema(name="phone",description=" 电话 ")
  private String phone;


//  @TableField(value = "account",typeHandler = Sm4TypeHandler.class)
  @Schema(name="account",description=" 账号 ")
  private String account;


//  @TableField(value = "pwd",typeHandler = Sm4TypeHandler.class)
  @Schema(name="pwd",description=" 密码 ")
  private String pwd;

  @TableField(value = "sex")
  @Schema(name="sex",description=" 性别 ")
  private Integer sex;


  @TableField(value = "creat_time")
  @Schema(name="reatTime",description=" 创建时间 ")
  @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
  private Date creatTime;

  @TableField(value = "update_time")
  @Schema(name="updateTime",description=" 更新时间 ")
  @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
  private Date updateTime;

}

2.2.2 Vo实体,UserVo视图对象

package com.zsh.test.swagger3test.model.vo;

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.zsh.test.swagger3test.serializer.SexSerializer;
import com.zsh.test.swagger3test.serializer.UserPwdSerializertest;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.experimental.Accessors;

import java.io.Serializable;

/**
 * @Description 
 * @Author  ZhaoShuhao
 * @Date: 2024-07-21 12:45:39
 */

@Data
@Accessors(chain = true)
@Schema(name=" user ", description=" null ")
public class UserVo implements Serializable {
  private static final long serialVersionUID =  1L;

  @Schema(name="id",description=" 主键 ")
  private Long id;
 

  @Schema(name="name",description=" 姓名 ")
  private String name;
 

  @Schema(name="age",description=" 年龄 ")
  private Integer age;
 

  @Schema(name="phone",description=" 电话 ")
  private String phone;

  @Schema(name="account",description=" 账号 ")
  private String account;
 

  @Schema(name="pwd",description=" 密码 ")
  @JsonSerialize(using= UserPwdSerializertest.class)
  private String pwd;


  @Schema(name="sex",description=" 性别 ")
  @JsonSerialize(using = SexSerializer.class)
  private Integer sex;
}

2.2.3 Dto实体,UserDto入参对象

package com.zsh.test.swagger3test.model.dto;

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.zsh.test.swagger3test.serializer.UserPwdDeSerializer;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

import java.io.Serializable;

/**
 * @Description 
 * @Author  ZhaoShuhao
 * @Date: 2024-07-21 12:45:39
 */

@Data
public class UserDto implements Serializable {
  private static final long serialVersionUID =  1L;

  @Schema(name="name",description=" 姓名 ")
  private String name;


  @Schema(name="age",description=" 年龄 ")
  private Integer age;


  @Schema(name="phone",description=" 电话 ")
  private String phone;


  @Schema(name="account",description=" 账号 ")
  private String account;

  @JsonDeserialize(using= UserPwdDeSerializer.class)
  @Schema(name="pwd",description=" 密码 ")
  private String pwd;

  @Schema(name="sex",description=" 性别 ")
  private Integer sex;
}

2.2.4 UserMapper

package com.zsh.test.swagger3test.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zsh.test.swagger3test.model.entity.User;
import org.apache.ibatis.annotations.Mapper;

/**
* @author KeepHappy
* @description 针对表【user】的数据库操作Mapper
* @createDate 2024-07-21 12:55:52
* @Entity src/main/java/com/zsh/test/swagger3test.model.User
*/
@Mapper
public interface UserMapper extends BaseMapper<User> {

}

2.2.5 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.zsh.test.swagger3test.mapper.UserMapper">

</mapper>

2.2.6 UserService

package com.zsh.test.swagger3test.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.zsh.test.swagger3test.model.dto.UserDto;
import com.zsh.test.swagger3test.model.entity.User;
import com.zsh.test.swagger3test.model.vo.UserVo;

import java.util.List;

/**
* @author KeepHappy
* @description 针对表【user】的数据库操作Service
* @createDate 2024-07-21 12:55:52
*/
public interface UserService extends IService<User> {


}

2.2.7 UserServiceImpl

package com.zsh.test.swagger3test.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zsh.test.swagger3test.model.dto.UserDto;
import com.zsh.test.swagger3test.mapper.UserMapper;
import com.zsh.test.swagger3test.model.entity.User;
import com.zsh.test.swagger3test.model.vo.UserVo;
import com.zsh.test.swagger3test.service.UserService;
import io.swagger.v3.core.util.Json;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
* @author KeepHappy
* @description 针对表【user】的数据库操作Service实现
* @createDate 2024-07-21 12:55:52
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

}

2.3@JsonDeserialize的使用 

UserDto入参对象:

  @JsonDeserialize(using= UserPwdDeSerializer.class)
  @Schema(name="pwd",description=" 密码 ")
  private String pwd;

 2.3.1 UserPwdDeSerializer密码加密反序列化器

package com.zsh.test.swagger3test.serializer;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.Mode;
import cn.hutool.crypto.Padding;
import cn.hutool.crypto.symmetric.SM4;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;


/**
 * 反序列化 对用户字段进去加密
 */
public class UserPwdDeSerializer extends JsonDeserializer<String> {

    private static final Logger logger = LoggerFactory.getLogger(UserPwdDeSerializer.class);

    private static final String hexKey ="79C37CDBCD6FAB9D0619F511B2031234";

    @Override
    public String deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
        String text = jsonParser.getText();
        String enPwd = StrUtil.isBlank(text) ? "" : getEncryptInfo(text);
        return enPwd;
    }
    public static String getEncryptInfo(String value) {
        return getEncryptInfoSm4(value);
    }
    private static String getEncryptInfoSm4(String value){
        SM4 sm4 = new SM4(Mode.ECB, Padding.PKCS5Padding,ByteUtils.fromHexString(hexKey));
        return sm4.encryptHex(value);
    }

}

2.3.2 UserController用户接口

package com.zsh.test.swagger3test.controller;

import cn.hutool.core.bean.BeanUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.zsh.test.swagger3test.config.Result;
import com.zsh.test.swagger3test.model.dto.UserDto;
import com.zsh.test.swagger3test.model.entity.User;
import com.zsh.test.swagger3test.model.vo.UserVo;
import com.zsh.test.swagger3test.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @author ZhaoShuhao
 * @data 2024/7/21 15:12
 */
@Tag(name = "用户接口")
@RestController
@RequestMapping("/user/api")
public class UserController {
    @Resource
    private UserService userService;
    @PostMapping("/save")
    @Operation( summary= "添加用户信息")
    public Result saveUserInfo(@RequestBody List<UserDto> userList) {
        List<User> users = BeanUtil.copyToList(userList, User.class);
        boolean b = userService.saveBatch(users);
        return b ? Result.success() : Result.error("添加失败");
    }

}

 2.3.3 结果展示

 

2.4@JsonSerialize的使用

UserVo视图对象:

 @Schema(name="pwd",description=" 密码 ")
  @JsonSerialize(using= UserPwdSerializertest.class)
  private String pwd;


  @Schema(name="sex",description=" 性别 ")
  @JsonSerialize(using = SexSerializer.class)
  private Integer sex;

 2.4.1SexSerializer性别转化序列化器

package com.zsh.test.swagger3test.serializer;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;

import java.io.IOException;

/**序列化
 * @author ZhaoShuhao
 * @data 2024/7/25 23:30
 */
public class SexSerializer extends JsonSerializer<Integer> {

    @Override
    public void serialize(Integer integer, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {

        if (integer == 1) {
            jsonGenerator.writeString("男");
        } else if (integer == 2) {
            jsonGenerator.writeString("女");
        }else {
            jsonGenerator.writeString("未知");
        }
    }
}

2.4.2 UserPwdSerializertest密码解密序列化器

package com.zsh.test.swagger3test.serializer;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.Mode;
import cn.hutool.crypto.Padding;
import cn.hutool.crypto.symmetric.SM4;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
 *  序列化 对用户字段进去解密
 */
public class UserPwdSerializertest extends JsonSerializer<String> {

    private static final Logger logger = LoggerFactory.getLogger(UserPwdSerializertest.class);

    private static final String hexKey ="79C37CDBCD6FAB9D0619F511B2031234";

    @Override
    public void serialize(String s, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        String dePwd = StrUtil.isBlank(s) ? "" : deserializeText(s);
        jsonGenerator.writeString(dePwd);
    }
    public static String deserializeText(String text){
        return getDecryptInfoSm4(text) ;
    }
    private static String getDecryptInfoSm4(String value){
        try {
            SM4 sm4 = new SM4(Mode.ECB, Padding.PKCS5Padding,ByteUtils.fromHexString(hexKey));
            return sm4.decryptStr(value, StandardCharsets.UTF_8);
        }catch (Exception e){
            logger.error("解密数据{}",value);
            return value;
        }

    }



}

 2.4.5 UserController用户接口

package com.zsh.test.swagger3test.controller;

import cn.hutool.core.bean.BeanUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.zsh.test.swagger3test.config.Result;
import com.zsh.test.swagger3test.model.dto.UserDto;
import com.zsh.test.swagger3test.model.entity.User;
import com.zsh.test.swagger3test.model.vo.UserVo;
import com.zsh.test.swagger3test.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @author ZhaoShuhao
 * @data 2024/7/21 15:12
 */
@Tag(name = "用户接口")
@RestController
@RequestMapping("/user/api")
public class UserController {
    @Resource
    private UserService userService;
    @PostMapping("/save")
    @Operation( summary= "添加用户信息")
    public Result saveUserInfo(@RequestBody List<UserDto> userList) {
        List<User> users = BeanUtil.copyToList(userList, User.class);
        boolean b = userService.saveBatch(users);
        return b ? Result.success() : Result.error("添加失败");
    }
    @PostMapping("/getAllUserInfo")
    @Operation(summary = "查询所有用户信息")
    public Result<List<UserVo>> getAllUserInfo(){
        List<User> list = userService.list();
        List<UserVo> userVos = BeanUtil.copyToList(list, UserVo.class);
        return Result.success((userVos));
    }
}

 2.4.3 结果展示

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

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

相关文章

JAVA里的配置文件(Properties)详解

package Properties;import java.util.Map; import java.util.Properties; import java.util.Set;public class demo1 {public static void main(String[] args) {/*Properties作为Map集合的操作*///1.创建集合的对象Properties pnew Properties();//2.添加数据//细节&#xff…

谷粒商城实战笔记-79-商品服务-API-平台属性-销售属性维护

文章目录 一&#xff0c;列表接口开发1&#xff0c;新建常量类2&#xff0c;路径参数识别规格参数和销售属性 二&#xff0c;其他接口三&#xff0c;编码经验-使用常量类为什么要用常量类&#xff1f;示例 这一节的主要内容是&#xff1a; 销售属性列表查询接口的开发将代码中的…

C++ 沙漏图案(Hour-glass Pattern)

给定正整数 n&#xff0c;以沙漏形式打印数字模式。示例&#xff1a; 输入&#xff1a;rows_no 7 输出&#xff1a; 1 2 3 4 5 6 7 2 3 4 5 6 7 3 4 5 6 7 4 5 6 7 5 6 7 6 7 7 6 7 5 6 7 4 5 6 7 3 4 5 6 7 2 3 4 5 6 7 1 2 3 4 5 6…

等保2.0测评 — 容器测评对象选取

之前有小伙伴提问到&#xff0c;关于容器到底要测评哪些内容&#xff0c;也就是测评对象的选取。 首先要区分的是容器与容器集群这两个概念。容器集群概念可参考该篇文章。 不使用容器扩展要求情况 当仅使用容器技术时&#xff0c;采用安全通用要求&#xff0c;无需使用容器…

AFSim仿真系统-架构概览

引言 本文档从最终用户的角度描述了AFSIM架构&#xff0c;旨在帮助最终用户深入了解AFSIM的操作概念。 核心架构 AFSIM基于面向对象的C架构&#xff0c;提供了一种可扩展和模块化的架构&#xff0c;使得许多附加功能能够轻松集成。AFSIM允许新的组件模型&#xff08;如传感器、…

2019数字经济公测大赛-VMware逃逸

文章目录 环境搭建漏洞点exp 环境搭建 ubuntu :18.04.01vmware: VMware-Workstation-Full-15.5.0-14665864.x86_64.bundle 这里环境搭不成功。。patch过后就报错&#xff0c;不知道咋搞 发现可能是IDA加载后的patch似乎不行对原来的patch可能有影响&#xff0c;重新下了patch&…

LiteFlow条件组件的设计组件标签|组件参数,EL与或非表达式正反解析,元数据管理

个人博客&#xff1a;无奈何杨&#xff08;wnhyang&#xff09; 个人语雀&#xff1a;wnhyang 共享语雀&#xff1a;在线知识共享 Github&#xff1a;wnhyang - Overview 参考 https://juejin.cn/post/7005869798483558431 &#x1f349;组件参数 | LiteFlow &#x1f34…

黑龙江等保测评如何做到既全面又高效?

在黑龙江省进行等保测评&#xff0c;必须在全面和高效之间寻求一个平衡点&#xff0c;以保证网络的安全性和可靠性。黑龙江等保测评怎样才能在二者之间发现黄金交汇点&#xff1f;下面&#xff0c;我们来揭开谜底。 精准定位&#xff0c;明确测评范围 首先&#xff0c;一个综…

LLaMA Factory添加新模型template的实战解析

大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于大模型算法的研究与应用。曾担任百度千帆大模型比赛、BPAA算法大赛评委,编写微软OpenAI考试认证指导手册。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。授权多项发明专利。对机器学…

OpenCV facedetect 人脸检测官方示例项目配置

运行程序。该程序会自动打开摄像头&#xff0c;识别并定位摄像头前的人脸以及眼睛部位。 输入q或者Q&#xff0c;退出程序。 或进行文本中所包含的图片路径 或 单个图片进行检测&#xff0c;自行修改代码即可 配置环境项目&#xff0c;debug 解决error C4996: ‘fopen’: This…

python 可视化探索(一):基础图表

总结&#xff1a;本文为和鲸python 可视化探索训练营资料整理而来&#xff0c;加入了自己的理解&#xff08;by GPT4o&#xff09; 原作者&#xff1a;作者&#xff1a;大话数据分析&#xff0c;知乎、公众号【大话数据分析】主理人&#xff0c;5年数据分析经验&#xff0c;前…

六、Spring Boot - 上手篇(2)

&#x1f33b;&#x1f33b;目录 一、SpringBoot 构建RESTful API1.1 RESTful介绍1.2 RESTful接口设计1.3 用户实体bean创建 User1.4 创建Controller UserController1.5 Postman 测试RESTful 接口 二、SpringBoot 使用Swagger2 构建API文档2.1 Swagger2介绍2.2 SpringBoot 开启…

2020年 - 2022年 上市公司-劳动投资效率数据(原始数据、代码do文件、参考文献、最终结果)

劳动投资效率概述 劳动投资效率是衡量企业在人力资源管理方面效果和效率的关键指标。它关注企业在劳动力投资上的效益&#xff0c;即企业对于人力资源的投入与产出之间的比率。这一指标对于评估企业的人力资源管理策略及其对企业绩效的影响至关重要。 劳动投资效率的测度指标…

【Golang 面试 - 基础题】每日 5 题(八)

✍个人博客&#xff1a;Pandaconda-CSDN博客 &#x1f4e3;专栏地址&#xff1a;http://t.csdnimg.cn/UWz06 &#x1f4da;专栏简介&#xff1a;在这个专栏中&#xff0c;我将会分享 Golang 面试中常见的面试题给大家~ ❤️如果有收获的话&#xff0c;欢迎点赞&#x1f44d;收藏…

Redis快速入门基础

Redis入门 Redis是一个基于内存的 key-value 结构数据库。mysql是二维表的接口数据库 优点&#xff1a; 基于内存存储&#xff0c;读写性能高 适合存储热点数据(热点商品、资讯、新闻) 企业应用广泛 官网:https://redis.io 中文网:https://www.redis.net.cn/ Redis下载与…

带你学会Git必会操作

文章目录 带你学会Git必会操作1Git的安装2.Git基本操作2.1本地仓库的创建2.2配置本地仓库 3.认识一些Git的基本概念3.1操作流程&#xff1a; 4.一些使用场景4.1添加文件场景一4.2查看git文件4.3修改文件4.4Git版本回退4.5git撤销修改 5.分支管理5.1查看分支5.2创建本地分支5.3切…

功能实现——使用 OpenPDF 将 HTML 转换为 PDF,并将其上传到 FTP 服务器

目录 1.需求分析2.项目环境搭建3.将 HTML 转换为 PDF3.1.代码实现mail.htmlHtmlToPDFController.javaPDFConverterService.javaPDFConverterServiceImpl.java 3.2.测试3.3.注意事项 4.将生成的 PDF 上传到 FTP 服务器4.1.搭建 FTP 服务器4.2.配置文件4.3.代码实现FtpUtil.javaF…

PostgreSQL性能优化之体系结构

本文介绍 PostgreSQL 数据库的体系结构&#xff0c;包括实例结构&#xff08;进程与内存&#xff09;、存储结构&#xff08;物理与逻辑&#xff09;以及插件式存储引擎。 实例与数据库聚簇 PostgreSQL 使用典型的客户端/服务器&#xff08;Client/Server&#xff09;架构&am…

【Android】Fragment的添加

上一篇文章学到了碎片的创建与生命周期&#xff0c;接下来学习碎片的常用操作&#xff0c;其中会用到上一篇文章的三个碎片&#xff0c;就做一个简单的说明吧&#xff1a;LeftFragment&#xff08;包含一个按钮&#xff09;、RightFragment4&#xff08;以粉色为背景的文本&…

【人工智能】穿越科技迷雾:解锁人工智能、机器学习与深度学习的奥秘之旅

文章目录 前言一、人工智能1. 人工智能概述a.人工智能、机器学习和深度学习b.人工智能发展必备三要素c.小案例 2.人工智能发展历程a.人工智能的起源b.发展历程 3.人工智能的主要分支 二、机器学习1.机器学习工作流程a.什么是机器学习b.机器学习工作流程c.特征工程 2.机器学习算…