东莞销售网站建设汕头市企业网站建设服务机构

news/2025/9/25 21:32:56/文章来源:
东莞销售网站建设,汕头市企业网站建设服务机构,广东网站优化公司,适合个人站长的网站有哪些点击去看上一篇 一、创建用户 model 1.创建用户数据库库 leadnews_user 核心表 ap_user 建库建表语句 这里一定要使用 navicat#xff0c;执行SQL 文件#xff0c;以防止 cmd 中的编码问题 先将 SQL 语句#xff0c;保存在电脑中#xff0c;再使用 navicat 打开 CREATE…点击去看上一篇 一、创建用户 model 1.创建用户数据库库 leadnews_user 核心表 ap_user 建库建表语句 这里一定要使用 navicat执行SQL 文件以防止 cmd 中的编码问题 先将 SQL 语句保存在电脑中再使用 navicat 打开 CREATE DATABASE IF NOT EXISTS leadnews_user DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; USE leadnews_user; SET NAMES utf8; /* Navicat MySQL Data TransferSource Server : localhost Source Server Version : 50721 Source Host : localhost:3306 Source Database : leadnews_userTarget Server Type : MYSQL Target Server Version : 50721 File Encoding : 65001Date: 2021-04-12 13:58:42 */SET FOREIGN_KEY_CHECKS0;-- ---------------------------- -- Table structure for ap_user -- ---------------------------- DROP TABLE IF EXISTS ap_user; CREATE TABLE ap_user (id int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 主键,salt varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 密码、通信等加密盐,name varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 用户名,password varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 密码,md5加密,phone varchar(11) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 手机号,image varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 头像,sex tinyint(1) unsigned DEFAULT NULL COMMENT 0 男\r\n 1 女\r\n 2 未知,is_certification tinyint(1) unsigned DEFAULT NULL COMMENT 0 未\r\n 1 是,is_identity_authentication tinyint(1) DEFAULT NULL COMMENT 是否身份认证,status tinyint(1) unsigned DEFAULT NULL COMMENT 0正常\r\n 1锁定,flag tinyint(1) unsigned DEFAULT NULL COMMENT 0 普通用户\r\n 1 自媒体人\r\n 2 大V,created_time datetime DEFAULT NULL COMMENT 注册时间,PRIMARY KEY (id) USING BTREE ) ENGINEInnoDB AUTO_INCREMENT7 DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_unicode_ci ROW_FORMATDYNAMIC COMMENTAPP用户信息表;-- ---------------------------- -- Records of ap_user -- ---------------------------- INSERT INTO ap_user VALUES (1, abc, zhangsan, abc, 13511223453, null, 1, null, null, 1, 1, 2020-03-19 23:22:07); INSERT INTO ap_user VALUES (2, abc, lisi, abc, 13511223454, , 1, null, null, 1, 1, 2020-03-19 23:22:07); INSERT INTO ap_user VALUES (3, sdsa, wangwu, wangwu, 13511223455, null, null, null, null, null, 1, null); INSERT INTO ap_user VALUES (4, 123abc, admin, 81e158e10201b6d7aee6e35eaf744796, 13511223456, null, 1, null, null, 1, 1, 2020-03-30 16:36:32); INSERT INTO ap_user VALUES (5, 123, suwukong, suwukong, 13511223458, null, 1, null, null, 1, 1, 2020-08-01 11:09:57); INSERT INTO ap_user VALUES (6, null, null, null, null, null, null, null, null, null, null, null);-- ---------------------------- -- Table structure for ap_user_fan -- ---------------------------- DROP TABLE IF EXISTS ap_user_fan; CREATE TABLE ap_user_fan (id int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 主键,user_id int(11) unsigned DEFAULT NULL COMMENT 用户ID,fans_id int(11) unsigned DEFAULT NULL COMMENT 粉丝ID,fans_name varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 粉丝昵称,level tinyint(1) unsigned DEFAULT NULL COMMENT 粉丝忠实度\r\n 0 正常\r\n 1 潜力股\r\n 2 勇士\r\n 3 铁杆\r\n 4 老铁,created_time datetime DEFAULT NULL COMMENT 创建时间,is_display tinyint(1) unsigned DEFAULT NULL COMMENT 是否可见我动态,is_shield_letter tinyint(1) unsigned DEFAULT NULL COMMENT 是否屏蔽私信,is_shield_comment tinyint(1) unsigned DEFAULT NULL COMMENT 是否屏蔽评论,PRIMARY KEY (id) USING BTREE ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_unicode_ci ROW_FORMATDYNAMIC COMMENTAPP用户粉丝信息表;-- ---------------------------- -- Records of ap_user_fan -- ------------------------------ ---------------------------- -- Table structure for ap_user_follow -- ---------------------------- DROP TABLE IF EXISTS ap_user_follow; CREATE TABLE ap_user_follow (id int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 主键,user_id int(11) unsigned DEFAULT NULL COMMENT 用户ID,follow_id int(11) unsigned DEFAULT NULL COMMENT 关注作者ID,follow_name varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 粉丝昵称,level tinyint(1) unsigned DEFAULT NULL COMMENT 关注度\r\n 0 偶尔感兴趣\r\n 1 一般\r\n 2 经常\r\n 3 高度,is_notice tinyint(1) unsigned DEFAULT NULL COMMENT 是否动态通知,created_time datetime DEFAULT NULL COMMENT 创建时间,PRIMARY KEY (id) USING BTREE ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_unicode_ci ROW_FORMATDYNAMIC COMMENTAPP用户关注信息表;-- ---------------------------- -- Records of ap_user_follow -- ------------------------------ ---------------------------- -- Table structure for ap_user_realname -- ---------------------------- DROP TABLE IF EXISTS ap_user_realname; CREATE TABLE ap_user_realname (id int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 主键,user_id int(11) unsigned DEFAULT NULL COMMENT 账号ID,name varchar(20) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT 用户名称,idno varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 资源名称,font_image varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 正面照片,back_image varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 背面照片,hold_image varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 手持照片,live_image varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 活体照片,status tinyint(1) unsigned DEFAULT NULL COMMENT 状态\r\n 0 创建中\r\n 1 待审核\r\n 2 审核失败\r\n 9 审核通过,reason varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 拒绝原因,created_time datetime DEFAULT NULL COMMENT 创建时间,submited_time datetime DEFAULT NULL COMMENT 提交时间,updated_time datetime DEFAULT NULL COMMENT 更新时间,PRIMARY KEY (id) USING BTREE ) ENGINEInnoDB AUTO_INCREMENT6 DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_unicode_ci ROW_FORMATDYNAMIC COMMENTAPP实名认证信息表;-- ---------------------------- -- Records of ap_user_realname -- ---------------------------- INSERT INTO ap_user_realname VALUES (1, 1, zhangsan, 512335455602781278, http://161.189.111.227/group1/M00/00/00/rBFwgF9bbHSAQlqFAAXIZNzAq9E126.jpg, http://161.189.111.227/group1/M00/00/00/rBFwgF9bbF6AR16RAAZB2e1EsOg460.jpg, http://161.189.111.227/group1/M00/00/00/rBFwgF9bbDeAH2qoAAbD_WiUJfk745.jpg, http://161.189.111.227/group1/M00/00/00/rBFwgF9ba9qANVEdAAS25KJlEVE291.jpg, 9, , 2019-07-30 14:34:28, 2019-07-30 14:34:30, 2019-07-12 06:48:04); INSERT INTO ap_user_realname VALUES (2, 2, lisi, 512335455602781279, http://161.189.111.227/group1/M00/00/00/rBFwgF9bbHSAQlqFAAXIZNzAq9E126.jpg, http://161.189.111.227/group1/M00/00/00/rBFwgF9bbF6AR16RAAZB2e1EsOg460.jpg, http://161.189.111.227/group1/M00/00/00/rBFwgF9bbDeAH2qoAAbD_WiUJfk745.jpg, http://161.189.111.227/group1/M00/00/00/rBFwgF9ba9qANVEdAAS25KJlEVE291.jpg, 1, , 2019-07-11 17:21:18, 2019-07-11 17:21:20, 2019-07-12 06:48:04); INSERT INTO ap_user_realname VALUES (3, 3, wangwu6666, 512335455602781276, http://161.189.111.227/group1/M00/00/00/rBFwgF9bbHSAQlqFAAXIZNzAq9E126.jpg, http://161.189.111.227/group1/M00/00/00/rBFwgF9bbF6AR16RAAZB2e1EsOg460.jpg, http://161.189.111.227/group1/M00/00/00/rBFwgF9bbDeAH2qoAAbD_WiUJfk745.jpg, http://161.189.111.227/group1/M00/00/00/rBFwgF9ba9qANVEdAAS25KJlEVE291.jpg, 9, , 2019-07-11 17:21:18, 2019-07-11 17:21:20, 2019-07-12 06:48:04); INSERT INTO ap_user_realname VALUES (5, 5, suwukong, 512335455602781279, http://161.189.111.227/group1/M00/00/00/rBFwgF9bbHSAQlqFAAXIZNzAq9E126.jpg, http://161.189.111.227/group1/M00/00/00/rBFwgF9bbF6AR16RAAZB2e1EsOg460.jpg, http://161.189.111.227/group1/M00/00/00/rBFwgF9bbDeAH2qoAAbD_WiUJfk745.jpg, http://161.189.111.227/group1/M00/00/00/rBFwgF9ba9qANVEdAAS25KJlEVE291.jpg, 1, , 2020-08-01 11:10:31, 2020-08-01 11:10:34, 2020-08-01 11:10:36);2.在 heima-leadnews-model 模块底下创建 com.heima.model.user 包 3.在 com.heima.model.user 包底下创建 pojos 包 dtos 包的创建暂时忽略不过这里也会讲解 dtos 包的大概作用存放 DTO 类型 POJO POJO 的全程有几种如 pure old java object 、plain ordinary java object 等。但意思都差不多可以理解为就是简单的 Java 对象符合没有被继承类、没有实现接口、属性私有、拥有无参构造方法等规则的 Java 对象 POJO 可划分为 VO、DTO、BO、DO 等 POJO全称作用VOView Object前端会将 VO 内的属性渲染到页面上DTOData Transfer Object前后端通过 DTO 传输数据、后端的服务与服务之间也可以通过 DTO 传输数据BOBusiness ObjectBO 内会封装多个 DO即业务直接处理 BO间接处理 DO。如简历相关业务简历就是 BO专业技能、实习经历、项目经历、个人信息等为 DODOData ObjectDO 中的属性与数据库表中的属性一一对应即实体类 这里黑马头条中的包划分可能不够严谨也可能有其他考量不是重点暂时不关心 在阿里开发规范中规定类名中的 DO/BO/DTO/VO/AO/PO/UID 需要大写 4.在 pojos 包中创建 ApUser 类 package com.heima.model.user.pojos;import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data;import java.io.Serializable; import java.util.Date;/*** p* APP用户信息表* /p** author itheima*/ Data TableName(ap_user) public class ApUser implements Serializable {private static final long serialVersionUID 1L;/*** 主键*/TableId(value id, type IdType.AUTO)private Integer id;/*** 密码、通信等加密盐*/TableField(salt)private String salt;/*** 用户名*/TableField(name)private String name;/*** 密码,md5加密*/TableField(password)private String password;/*** 手机号*/TableField(phone)private String phone;/*** 头像*/TableField(image)private String image;/*** 0 男1 女2 未知*/TableField(sex)private Boolean sex;/*** 0 未1 是*/TableField(is_certification)private Boolean certification;/*** 是否身份认证*/TableField(is_identity_authentication)private Boolean identityAuthentication;/*** 0正常1锁定*/TableField(status)private Boolean status;/*** 0 普通用户1 自媒体人2 大V*/TableField(flag)private Short flag;/*** 注册时间*/TableField(created_time)private Date createdTime;} MyBatisPlus 注解 import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; ApUser 类使用了 MybatisPlus 中的 4 个注解 注解作用TableName 让 MybatisPlus 识别当前类对应的表ApUser ap_user TableId让 MybatisPlus 识别当前属性为表的主键id idIdType让 MybatisPlus 识别当前主键的类型IdType.AUTO 自增类型TableField让 MybatisPlus 识别当前属性对应的表字段name name 添加注解是为了防止数据库字段或 Java 代码属性的命名不规范、不统一 蛇形驼峰转化 如果满足以下三个条件即可开启蛇形驼峰转化可以不用上面的 MybatisPlus 注解来进行识别 Java 严格按照驼峰命名名字中单词首字母大写如属性名 helloWorld、类名 HelloWorld数据库严格按照蛇形命名名字中的单词之间用下划线分割如 hello_world名字都一一对应完全相同名字都是 hello world 只是命名形式不同 在 yml 中开启蛇形驼峰转化 黑马提供的初始项目的 model 模块下并没有 resources 目录需要自己创建。然后在 resources 目录下创建 application.yml 文件来进行配置黑马并没有使用 MybatisPlus 的自动命名转化配置为了不给后面埋雷不建议大家做这个配置 mybatis-plus:configuration:map-underscore-to-camel-case: true MyBatisPlus POM 依赖 在 heima-leadnews-model 模块的 pom.xml 中添加依赖 dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactId /dependencydependencygroupIdorg.mybatis/groupIdartifactIdmybatis/artifactId /dependencydependencygroupIdcom.baomidou/groupIdartifactIdmybatis-plus-boot-starter/artifactId /dependency 实际上 mybatis-plus-boot-starter 中包含了 mybatis但是可能和导入的 mybatis 相比版本什么的有点不同建议按照黑马的来 Lombok 注解 import lombok.Data; 注解作用Data为当前类的所有属性添加 getter setter 方法 Lombok POM 依赖 该依赖已经在父工程 pom.xml 中的 dependencies 标签下被引入在该标签下被引入的依赖会在所有子模块中生效因此无需再次引入 !-- lombok -- dependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdversion${lombok.version}/versionscopeprovided/scope /dependency 二、用户 service 微服务搭建 微服务搭建口诀建 module、改 pom、写 yml、主启动、业务类不绝对仅提供参考 1.在heima-leadnews-service 模块底下的 pom.xml 中添加所有微服务公用的依赖 黑马提供的初始工程中已经添加好了不必再次添加 引入其他子模块 !-- 引入依赖模块 -- dependencygroupIdcom.heima/groupIdartifactIdheima-leadnews-model/artifactId /dependencydependencygroupIdcom.heima/groupIdartifactIdheima-leadnews-common/artifactId /dependencydependencygroupIdcom.heima/groupIdartifactIdheima-leadnews-feign-api/artifactId /dependency 依赖作用heima-leadnews-model导入实体类等如 ApUserheima-leadnews-common导入全局配置、全局功能等如全局异常捕获heima-leadnews-feign-api导入该模块中统一管理的 feign 远程调用接口一般微服务之间的调用都通过 feign 来调用 引入开发和测试相关依赖 !-- Spring boot starter -- dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId /dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope /dependency 依赖作用spring-boot-starter-web 包含 Controller、Service、RequestMapping 等 web 相关注解实现相关 web 功能 spring-boot-starter-test包含 SpringBootTest、Test 等测试相关注解实现相关测试功能 SpringBoot 把许多场景抽象为了启动器 starter。当前我们需要一个搭建 web 服务的应用场景因此使用 starter-web 启动器即可自动完成 web 服务的所有相关配置使用默认值如将使用了 Bean 注解的类注册进 spring 容器、将内置的 tomcat 配置好等等。与 Spring 相比方便了许多减少了大量配置文件、配置操作 引入 nacos 服务注册、配置中心相关依赖 !-- Spring Cloud Alibaba Nacos-- dependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-nacos-discovery/artifactId /dependencydependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-nacos-config/artifactId /dependency 依赖作用spring-cloud-starter-alibaba-nacos-discovery 实现 nacos 相关服务发现、服务注册等功能 spring-cloud-starter-alibaba-nacos-config实现 nacos 相关配置拉取功能 注册中心 在微服务架构中会有某些服务需要由许多机器/容器来提供而每个机器/容器的 url 都是不一样的。因此我们需要通过服务注册中心将不同的 url 注册到同一个服务名底下之后再调用该服务名的时候会从注册中心将服务注册表包含着 url 与服务名之间映射关系拉取到本地然后 nacos 内置的 Ribbon 会将服务名转化为具体的 url默认轮询这次是第一个 url下次就轮到另一个 url再进行服务调用 配置中心 由于在微服务架构下有许许多多的服务因此也会产生许许多多的配置文件每个配置文件也会有许许多多的配置项。当有需求变更时修改起配置来十分头疼管理起来也很混乱很容易改错配置开发环境直接成为修罗炼狱。而配置中心可以让项目中的配置全部统一管理并且还可以实现动态修改、运行环境区分开发、测试、生产等、配置回滚等功能很好的解决上述问题 2.在 heima-leadnews-service 模块底下创建 heima-leadnews-user 子模块 黑马提供初始项目中已经建好了的不必再重建 3.修改 heima-leadnews-user 底下的 pom.xml 由于我们已经在 heima-leadnews-user 的父工程 heima-leadnews-service 中引入了必要的依赖因此这里暂时不需要添加依赖 ?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdparentartifactIdheima-leadnews-service/artifactIdgroupIdcom.heima/groupIdversion1.0-SNAPSHOT/version/parentmodelVersion4.0.0/modelVersionartifactIdheima-leadnews-user/artifactIdpropertiesmaven.compiler.source8/maven.compiler.sourcemaven.compiler.target8/maven.compiler.target/properties/project 4.编写 heima-leadnews-user 的 yml 配置 在 heima-leadnews-user 底下的 resources 目录中新建 bootstrap.yml 文件 SpringBoot 核心配置文件有两种bootstrap 和 application bootstrap bootstrap 是应用程序的父上下文由父 ApplicationContext 加载优先级更高。一般用来做系统层级的参数配置 application application 是当前应用程序的上下文优先级较低。一般用来做应用层级的参数配置 为什么用 bootstrap 由于 Spring 根据优先级会先加载 bootstrap 中 nacos 服务的 url没有就先使用 nacos 默认的并进行连接尝试如果你的 nacos 不在默认的 url 上那么就会报错。因此一定要在 bootstrap 上做好配置避免报错才能启动成功 编写 bootstarp 文件的内容 server:port: 51801 spring:application:name: leadnews-usercloud:nacos:discovery:server-addr: localhost:8848config:server-addr: localhost:8848file-extension: ymlprofiles:active: dev 注意使用自己的 nacos 服务地址 nacos 下载  Releases · alibaba/nacos · GitHub 通过 GitHub 下载可以自行选择版本我当时下载的是 1.1.4点击版本下的 Assets 中的 nacos-server-1.1.4.zip不论 tar.gz/zip 在 linux 和 windows 都能使用应该 https://github.com/alibaba/nacos/releases/download/1.1.4/nacos-server-1.1.4.zip nacos 启动 解压后双击 bin/startup.cmd 启动 nacos默认端口为 8848 在 nocos 配置中心添加 heima-leadnews-user 的服务配置 左边导航栏选择配置列表点击列表右上方的加号添加配置 Data ID spring.application.name (即 leadnews-user) - spring.profiles.active (即 dev) . spring.cloud.nacos.config.file-extension (即 yml) leadnews-user-dev.yml spring:datasource:driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://localhost:3306/leadnews_user?useUnicodetruecharacterEncodingUTF-8serverTimezoneUTCusername: rootpassword: 159357 # 设置Mapper接口所对应的XML文件位置如果你在Mapper接口中有自定义方法需要进行该配置 mybatis-plus:mapper-locations: classpath*:mapper/*.xml# 设置别名包扫描路径通过该属性可以给包中的类注册别名type-aliases-package: com.heima.model.user.pojos 5.完善 heima-leadnews-user 的主启动类 UserApplication 创建 com.heima.user.UserApplication 主启动类黑马提供的初始工程也建好了 package com.heima.user;import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient;SpringBootApplication EnableDiscoveryClient MapperScan(com.heima.user.mapper) public class UserApplication {public static void main(String[] args) {SpringApplication.run(UserApplication.class,args);} } SpringBootApplication 注解 用来标记当前类为 SpringBoot 的主配置类SpringBoot 应用由当前类的 main 方法启动当 mian 方法执行下面这条代码的时候 SpringApplication.run(UserApplication.class,args); SpringBoot 将会把当前包底下的 Bean 方法返回的对象以及 Component 类的实例化对象自动存放入 Spring 容器中并且将所有的配置项以默认值自动装配约定大于配置 EnableDiscoveryClient 注解 该注解是由 SpringBoot 提供的拥有服务注册与订阅的相关功能。使用该注解后SpringBoot 应用会自动向配置的服务注册中心注册自己并定时发送心跳包告知注册中心自己的服务状态 MapperScan 注解 由 heima-leadnews-model 中的 MyBatis 依赖所提供的注解可以自动扫描指定包下的类将扫描到的接口作为 Mapper 并将其实现。有了这个注解可以不必再 XXXMapper 接口上再写 Mapper 注解了。如果当前服务有许多的 Mapper 接口那每一个接口上都要写 Mapper 注解就会有许多的 Mapper 注解。如果使用 MapperScan 注解即可用一个 MapperScan 注解代替大量 Mapper 注解 6.构建 heima-leadnews-user 的微服务目录 config、controller、service、mapper config 存放配置相关类 controller 为前端提供访问接口不关心具体业务逻辑只负责接收参数和返回结果 service 向 contrller 提供业务逻辑接口serviceImpl 负责将接口中的方法实现 mapper 向 service 提供操作持久层数据的接口mapper.xml 负责实现接口 为什么这样设计 这种设计方式体现了一种思想 MVC即 model view controller 分层作用view从 controller 获取数据并展示给用户controller接收 view 的请求让 model 进行处理并返回处理结果给 viewmodel操作数据完成业务将结果返回给 controller view 对应项目中的 前端controller 对应项目中的 controllermodel 对应项目中的 service controller。controller 就如一个中介者封装 view 和 model 之间的交互松散耦合集中控制交互。而 service 与 serviceIpml 分开mapper 与 mapper.xml 分开体现了依赖倒转使调用方不依赖于实现而是依赖于抽象接口 7.开发 heima-leadnews-user 登录功能相关的 controller 层代码 在 controller 下新建 v1 包表示第一个版本 在 v1 包底下新建 ApUserLoginController 类 登录接口 接口路径/api/v1/login/login_auth请求方式POST参数LoginDto响应结果ResponseResult LoginDto 在 heima-leadnews-model 模块下的 com.heima.model.user.dtos 包下创建 LoginDto Data public class LoginDto {/*** 手机号*/private String phone;/*** 密码*/private String password; } ResponseResult 在 heima-leadnews-model 中的 com.heima.model.common.dtos 包底下创建 ResponseResult 类 /*** 通用的结果返回类* param T*/ public class ResponseResultT implements Serializable {private String host;private Integer code;private String errorMessage;private T data;public ResponseResult() {this.code 200;}public ResponseResult(Integer code, T data) {this.code code;this.data data;}public ResponseResult(Integer code, String msg, T data) {this.code code;this.errorMessage msg;this.data data;}public ResponseResult(Integer code, String msg) {this.code code;this.errorMessage msg;}public static ResponseResult errorResult(int code, String msg) {ResponseResult result new ResponseResult();return result.error(code, msg);}public static ResponseResult okResult(int code, String msg) {ResponseResult result new ResponseResult();return result.ok(code, null, msg);}public static ResponseResult okResult(Object data) {ResponseResult result setAppHttpCodeEnum(AppHttpCodeEnum.SUCCESS, AppHttpCodeEnum.SUCCESS.getErrorMessage());if(data!null) {result.setData(data);}return result;}public static ResponseResult errorResult(AppHttpCodeEnum enums){return setAppHttpCodeEnum(enums,enums.getErrorMessage());}public static ResponseResult errorResult(AppHttpCodeEnum enums, String errorMessage){return setAppHttpCodeEnum(enums,errorMessage);}public static ResponseResult setAppHttpCodeEnum(AppHttpCodeEnum enums){return okResult(enums.getCode(),enums.getErrorMessage());}private static ResponseResult setAppHttpCodeEnum(AppHttpCodeEnum enums, String errorMessage){return okResult(enums.getCode(),errorMessage);}public ResponseResult? error(Integer code, String msg) {this.code code;this.errorMessage msg;return this;}public ResponseResult? ok(Integer code, T data) {this.code code;this.data data;return this;}public ResponseResult? ok(Integer code, T data, String msg) {this.code code;this.data data;this.errorMessage msg;return this;}public ResponseResult? ok(T data) {this.data data;return this;}public Integer getCode() {return code;}public void setCode(Integer code) {this.code code;}public String getErrorMessage() {return errorMessage;}public void setErrorMessage(String errorMessage) {this.errorMessage errorMessage;}public T getData() {return data;}public void setData(T data) {this.data data;}public String getHost() {return host;}public void setHost(String host) {this.host host;}}AppHttpCodeEnum 在 heima-leadnews-model 模块中的 com.heima.model.common.enums 包下新建 AppHttpCodeEnum 类 public enum AppHttpCodeEnum {// 成功段固定为200SUCCESS(200,操作成功),// 登录段1~50NEED_LOGIN(1,需要登录后操作),LOGIN_PASSWORD_ERROR(2,密码错误),// TOKEN50~100TOKEN_INVALID(50,无效的TOKEN),TOKEN_EXPIRE(51,TOKEN已过期),TOKEN_REQUIRE(52,TOKEN是必须的),// SIGN验签 100~120SIGN_INVALID(100,无效的SIGN),SIG_TIMEOUT(101,SIGN已过期),// 参数错误 500~1000PARAM_REQUIRE(500,缺少参数),PARAM_INVALID(501,无效参数),PARAM_IMAGE_FORMAT_ERROR(502,图片格式有误),SERVER_ERROR(503,服务器内部错误),// 数据错误 1000~2000DATA_EXIST(1000,数据已经存在),AP_USER_DATA_NOT_EXIST(1001,ApUser数据不存在),DATA_NOT_EXIST(1002,数据不存在),// 数据错误 3000~3500NO_OPERATOR_AUTH(3000,无权限操作),NEED_ADMIND(3001,需要管理员权限);int code;String errorMessage;AppHttpCodeEnum(int code, String errorMessage){this.code code;this.errorMessage errorMessage;}public int getCode() {return code;}public String getErrorMessage() {return errorMessage;} } ApUserLoginController 代码 RestController RequestMapping(/api/v1/login) public class ApUserLoginController {Autowiredprivate ApUserService apUserService;PostMapping(/login_auth)public ResponseResult login(RequestBody LoginDto dto){return apUserService.login(dto);} } RestController 注解 Target({ElementType.TYPE}) Retention(RetentionPolicy.RUNTIME) Documented Controller ResponseBody public interface RestController {AliasFor(annotation Controller.class)String value() default ; } 本质是个复合注解即 RestController Controller ResponseBody 注解作用Target 规定注解的使用范围 ElementType.TYPE 类注解 ElementType.FIELD 属性注解 ElementType.METHOD 方法注解... Retention 规定注释的有效时期 RetentionPolicy.SOUTCE 代码注解, RetenionPolicy.CLASS 字节码注解, RetentionPolicy.RUNTIME 运行注解... Documented 将该注解写入 JAVADOC 中 Inherited使用该注解的类的子类可以继承该注解 注解作用Controller包含 Component 注解可以将使用该注解的类的实例化对象注册到 Spring IOC 容器中ResponseBody将方法的返回值直接写入 HTTP Response 的 body 中 RequestMapping 注解 当请求路径与 RequestMapping 的 value 值一致时对请求进行路由路由到当前类或方法 AutoWired 注解 自动装载将注册进容器中的 ApUserService 类的实例化对象取出并注入到当前的 ApUserController 类中。为 ApUserController 提供业务方法ApUserService 还没建好可以先不注入 RequestBody 与 RequestParam 的区别 RequestBody 发送 RequestBody 接收 RestController public class TestController {RequestMapping(value /test)public void test(RequestBody String body) {System.out.println(body);} } RequestParam 发送 第一种 query params 第二种 body form-data RequestParam 接收 RestController public class TestController {RequestMapping(value /test)public void test(RequestParam String param) {System.out.println(param);} } 8.开发 heima-leadnews-user 登录功能相关的 service 层代码 在 service 下新建 apUserService 接口 public interface ApUserService extends IServiceApUser {/*** app端登录功能* param dto* return*/public ResponseResult login(LoginDto dto); } IService 是由 MyBatis Plus 提供的一个接口MyBatis 也提供了对应的实现类 ServiceImpl ServiceImpl 类注入了 baseMapper 接口而 MyBatis Plus 也实现了该接口 因此我们可以使用 ServiceImpl 中的丰富的基础数据处理方法间接调用 mapper 来进行数据库操作 在 service 下新建 impl 包并创建 ApUserServiceImpl 类实现 ApUserService 接口 Service Transactional Slf4j public class ApUserServiceImpl extends ServiceImplApUserMapper, ApUser implements ApUserService {/*** app端登录功能* param dto* return*/Overridepublic ResponseResult login(LoginDto dto) {//1.正常登录 用户名和密码if(StringUtils.isNotBlank(dto.getPhone()) StringUtils.isNotBlank(dto.getPassword())){//1.1 根据手机号查询用户信息ApUser dbUser getOne(Wrappers.ApUserlambdaQuery().eq(ApUser::getPhone, dto.getPhone()));if(dbUser null){return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST,用户信息不存在);}//1.2 比对密码String salt dbUser.getSalt();String password dto.getPassword();String pswd DigestUtils.md5DigestAsHex((password salt).getBytes());if(!pswd.equals(dbUser.getPassword())){return ResponseResult.errorResult(AppHttpCodeEnum.LOGIN_PASSWORD_ERROR);}//1.3 返回数据 jwt userString token AppJwtUtil.getToken(dbUser.getId().longValue());MapString,Object map new HashMap();map.put(token,token);dbUser.setSalt();dbUser.setPassword();map.put(user,dbUser);return ResponseResult.okResult(map);}else {//2.游客登录MapString,Object map new HashMap();map.put(token,AppJwtUtil.getToken(0L));return ResponseResult.okResult(map);}} } 判断用户名和密码是否为空 使用 StringUtils 的 isNotBlank 方法判断字符串是否为空、是否有长度、是否含有空白字符 if(StringUtils.isNotBlank(dto.getPhone()) StringUtils.isNotBlank(dto.getPassword())) {// 1.正常登录 } else {// 2.游客登录MapString,Object map new HashMap();map.put(token,AppJwtUtil.getToken(0L));return ResponseResult.okResult(map); } 游客登陆返回 {host: ,code: 200, // AppHttpCodeEnum.SUCCESSerrorMessage: 操作成功,data: {token: // 使用 AppJwtUtil.getToken(0L) 方法生成游客 token具体实现下面会讲} }判断该用户是否存在 使用 ServiceImpl 中的 getOne 方法用 Wrapper 构造查询条件 dbUser.getPhone() 等与 dto.getPhone //1.1 根据手机号查询用户信息 ApUser dbUser getOne(Wrappers.ApUserlambdaQuery().eq(ApUser::getPhone, dto.getPhone())); if(dbUser null){return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST,用户信息不存在); } 不存在返回 {host: ,code: 1002, // AppHttpCodeEnum.DATA_NOT_EXISTerrorMessage: 用户信息不存在,data: {} }判断密码是否正确 数据库中的密码加密是通过先加盐再MD5的方式完成的 MD5 为一种单向加密算法只能加密不能解密。因此很适合用来加密密码这样连数据库所有者都无法知道用户的真实密码大大提高安全性。但是既然这么安全为什么还要加盐呢因为MD5的广泛使用黑客认为有利可图于是使用暴力学习将许多密码进行 MD5 加密并将映射关系存起来这样就能用映射表将 MD5 加密后的密码转为真实的密码。所以我们通过加盐也就是给原有的密码加上其他的字符/字符串再进行 MD5 加密使得暴力解密后的密码也不是真正的密码 使用 org.springframework.util 中的 DigestUtils 类里的 md5DigestAsHex 方法对 用户输入的密码 数据库中获取的盐值 进行加密然后将加密后的输入密码与数据库中的比较 //1.2 比对密码 String salt dbUser.getSalt(); String password dto.getPassword(); String pswd DigestUtils.md5DigestAsHex((password salt).getBytes()); if(!pswd.equals(dbUser.getPassword())){return ResponseResult.errorResult(AppHttpCodeEnum.LOGIN_PASSWORD_ERROR); } 密码错误返回 {host: ,code: 2, // AppHttpCodeEnum.LOGIN_PASSWORD_ERRORerrorMessage: 密码错误,data: {token: // 使用 AppJwtUtil.getToken(0L) 方法生成游客 token具体实现下面会讲} }生成 JWT JWT即 Json Web Token。它由三部分组成 header JWT头 一个 JSON 对象用来描述 JWT 的签名算法、令牌类型 payload JWT载荷 一个 JSON 对象用来传递数据 signature JWT签名 使用 base64 加密后的 header  base64 加密后的 payload 服务器生成的密钥通过指定算法生成签名 形如 headerheaderheader.payloadpayloadpayload.signaturesignaturesignature 即 header 与 payload 与 signature 之间使用 . 点号隔开 eyJhbGciOiJIUzUxMiIsInppcCI6IkdaSVAifQ.H4sIAAAAAAAAADWLQQrDMAzA_uJzA_biuKa_cWnKUigEnMLG2N_nHnaTEPrAMRosUFhUmCmZUEmsImnN-kgZ90q2Z1EWmKDZgIVmRBRS1gn8WuP2t4963t099FnbaWF2bWHWe3B99f9Z-D5bNPz-AKKQJrqAAAAA.0ZNpu7dGgNtoF-UBGM3LvFZxEsltZFHazfByij_IW5KIv82oNxV4VremFE4zAx_lFAxE2XuOZ53LGb1u2mY7Lg 由于 base64 可以解密因此不要在 payload 中存放重要的隐私信息 为什么需要 JWT JWT 用来存储客户端与服务器之间的身份识别信息相当于是存会话信息。既然是会话为什么不用 session 呢因为 session 依赖于 cookiesession 中会存放用户信息浏览器的 cookie 中会存 session 的 id每次浏览器发送请求的时候就会携带 cookie这样也能将 cookie 中的 sessionID 发送给服务器这样服务器就能识别出这个请求时哪个用户发出的。可是有些客户端并没有 cookie因此也无法存储 sessionID于是我们就使用 JWT客户端发送请求的时候带上 JWT而 JWT 中又有用户的信息这样服务器也能识别出请求的来源。抛弃掉 session cookie实现前后端分离 在 heima-leadnews-utils 模块下创建 com.heima.utils.common.AppJwtUtil 类 public class AppJwtUtil {// TOKEN的有效期一天Sprivate static final int TOKEN_TIME_OUT 3_600;// 加密KEYprivate static final String TOKEN_ENCRY_KEY MDk4ZjZiY2Q0NjIxZDM3M2NhZGU0ZTgzMjYyN2I0ZjY;// 最小刷新间隔(S)private static final int REFRESH_TIME 300;// 生产IDpublic static String getToken(Long id){MapString, Object claimMaps new HashMap();claimMaps.put(id,id);long currentTime System.currentTimeMillis();return Jwts.builder().setId(UUID.randomUUID().toString()).setIssuedAt(new Date(currentTime)) //签发时间.setSubject(system) //说明.setIssuer(heima) //签发者信息.setAudience(app) //接收用户.compressWith(CompressionCodecs.GZIP) //数据压缩方式.signWith(SignatureAlgorithm.HS512, generalKey()) //加密方式.setExpiration(new Date(currentTime TOKEN_TIME_OUT * 1000)) //过期时间戳.addClaims(claimMaps) //cla信息.compact();}/*** 获取token中的claims信息** param token* return*/private static JwsClaims getJws(String token) {return Jwts.parser().setSigningKey(generalKey()).parseClaimsJws(token);}/*** 获取payload body信息** param token* return*/public static Claims getClaimsBody(String token) {try {return getJws(token).getBody();}catch (ExpiredJwtException e){return null;}}/*** 获取hearder body信息** param token* return*/public static JwsHeader getHeaderBody(String token) {return getJws(token).getHeader();}/*** 是否过期** param claims* return -1有效0有效1过期2过期*/public static int verifyToken(Claims claims) {if(claimsnull){return 1;}try {claims.getExpiration().before(new Date());// 需要自动刷新TOKENif((claims.getExpiration().getTime()-System.currentTimeMillis())REFRESH_TIME*1000){return -1;}else {return 0;}} catch (ExpiredJwtException ex) {return 1;}catch (Exception e){return 2;}}/*** 由字符串生成加密key** return*/public static SecretKey generalKey() {byte[] encodedKey Base64.getEncoder().encode(TOKEN_ENCRY_KEY.getBytes());SecretKey key new SecretKeySpec(encodedKey, 0, encodedKey.length, AES);return key;}} 生成过程 //1.3 返回数据 jwt user String token AppJwtUtil.getToken(dbUser.getId().longValue()); MapString,Object map new HashMap(); map.put(token,token); dbUser.setSalt(); dbUser.setPassword(); map.put(user,dbUser);return ResponseResult.okResult(map); public static String getToken(Long id){MapString, Object claimMaps new HashMap();claimMaps.put(id,id);long currentTime System.currentTimeMillis();return Jwts.builder().setId(UUID.randomUUID().toString()).setIssuedAt(new Date(currentTime)) //签发时间.setSubject(system) //说明.setIssuer(heima) //签发者信息.setAudience(app) //接收用户.compressWith(CompressionCodecs.GZIP) //数据压缩方式.signWith(SignatureAlgorithm.HS512, generalKey()) //加密方式.setExpiration(new Date(currentTime TOKEN_TIME_OUT * 1000)) //过期时间戳.addClaims(claimMaps) //cla信息.compact(); } 使用 jjwt 依赖提供的 jsonwebtoken 包中的 Jwts.builder 方法构建 jwt并将用户 id 存放在 jwt 的 payload 中从而让服务器能够识别请求的发送者 三、测试接口 {host: null,code: 200,errorMessage: 操作成功,data: {user: {id: 4,salt: ,name: admin,password: ,phone: 13511223456,image: null,sex: true,certification: null,identityAuthentication: null,status: true,flag: 1,createdTime: 2020-03-30T08:36:32.00000:00},token: eyJhbGciOiJIUzUxMiIsInppcCI6IkdaSVAifQ.H4sIAAAAAAAAADWL0QrDIAwA_yXPFZLqau3fpBqZg4IQCxuj_770YW93HPeF12iwAfqEiWRxNefiAu-rYx-z48dMNZKUtSaYoPGAjSIizcHjMoGeu9360SHH3VVNn9IONuOzmHHvxvLu_zOm-2zWwvUD7al0KoAAAAA.5GEoiqO9MH7WCZeBWM95XAlAtlrkHvrbzUqZOO0HktuJjcCCJ20MVprJjXXa-DuNY9qdHIy0yt7Z1ziaflTHUw} } 基础用户登录功能完成

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

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

相关文章

网站架构优化南宁广告网页设计招聘

PHP取整数函数常用的四种方法,下面收集了四个函数;经常用到取整的函数,今天小小的总结一下!其实很简单,就是几个函数而已~~主要是:ceil,floor,round,intvalPH…

2025秋_3

今天学习了java

day004

今日完成:计算机登录系统验证码程序 明日完成:斗地主 遇到问题:无

软件测试团队准备解散了......

在大厂做测试五年,没想到整个部门说没就没了最近一位粉丝发来消息,说起他一段真实的职场经历: 在大厂做测试五年,没想到整个部门说没就没了。项目戛然而止,签离职、收拾东西,一天内全部结束,走出公司大门时,整…

2025秋_4

今天我学会了可视化界面的实现,以及简单的设置宽高等操作

【STM32H7】从零开始搭建的HAL库工程模板(基于CubeMX)

CubeMX基本配置 第一步:选择芯片 1.从搜索框中搜索“STM32H743IIT6”双击即可。2.这里说的是强烈建议内核为M7的设备预先配置内存保护单元(MPU),是否应用此类默认配置? 由于我们这里是从零开始的配置,并且默认配…

洛阳酒店网站开发大全中国十大门窗品牌排行榜前十名

首先,要说一下两者的概念:系统调用 :是操作系统为用户态运行的进程和硬件设备(如CPU、磁盘、打印机等)进行交互提供的一组接口,即就是设置在应用程序和硬件设备之间的一个接口层。可以说是操作系统留给用户程序的一个接口。再来说…

重生之从零开始的神经网络算法学习之路 —— 第八篇 大型数据集与复杂模型的 GPU 训练实践

重生之从零开始的神经网络算法学习之路 —— 第八篇 大型数据集与复杂模型的 GPU 训练实践重生之从零开始的神经网络算法学习之路——第八篇 大型数据集与复杂模型的GPU训练实践 引言 在前一篇中,我们实现了基础的SRC…

Avalonia:开发Android应用

我把成功开发Android应用的经过记录下来,在开发过程中,模拟器经常出问题,将Java Development Kit的位置和Android SDK的位置改动一下,就解决了模拟器报错的问题,这是在Github上看到的解决办法。 先建Models文件夹…

MIT s6.828环境搭建

前言:建议ubuntu镜像版本在22.04以下,亲测新版本会报错 本文默认读者ubuntu搭建完成,且可以联网 sudo apt update开始配置环境前先更新软件包列表sudo apt install -y binutils gcc git libpixman-l-dev python2 pk…

做微网站的第三方登录wordpress 目录布局

目录 一、引言 二、代码整体结构 三、宏定义与头文件 四、插入排序函数(Insertsort) 函数作用 代码要点分析 五、希尔排序函数(ShellSort) 函数作用 代码要点分析 六、打印数组函数(PrintSort&#x…

关键词搜索爱站网自己如何建立网站

一、设计模式分类 软件开发的23种模式,主要分类有创建型模式,结构型模式,行为型模式三种,相关分类如下: 设计模式是一种面向对象编程的思想,它是由Gamma等人在《设计模式:可复用面向对象软件的…

详细介绍:ES6核心基础

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

kubernetes事件监控工具--Kube-Event

在日常使用中,总会碰到容器“不经意间”重启的情况,但我完全不知道上次重启是什么时候。容器一旦重启,旧实例就会被销毁,如果旧容器日志没有被收集或转存,就彻底丢失了。这样一来,想通过历史日志排查问题原因就显…

wordpress 中英文站点佛山的网站建设公司

引言 C语⾔是结构化的程序设计语⾔,这⾥的结构指的是顺序结构、选择结构、循环结构。为什么有着三种结构呢,大家其实可以想象一下,生活中的绝大数事情都可以抽象着三种结构,而我们今天要给大家介绍的就是三大结构之一——选择结构…

做电子简历的网站悦西安

本文主要介绍Linux 字体颜色的调整,常用于shell脚本当中。我们举一个例子:echo-e"\033[44;37;5m ME \033[0m COOL" 以上命令设置背景成为蓝色,前景白色,闪烁光标,输出字符“ME”,然后重新设置屏幕…

企业档案管理系统:精准破局制造行业档案管理困境 - 指南

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

实用指南:【 GUI自动化测试】GUI自动化测试(一) 环境安装与测试

实用指南:【 GUI自动化测试】GUI自动化测试(一) 环境安装与测试pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "C…

怎么建一个卖东西的网站网站怎样关键词排名优化

在日常编码环节,很大比例的错误处理工作和参数的输入有关。当程序里的某些数据直接来自用户输入时,必须先校验这些输入值,再进行之后的处理,否则就会出现难以预料的错误。 需求: 写一个命令行小程序,它要求…

喵喵大王の新日记

2025 9.25 突然心血来潮了,于是开了新日记,但是实际上我也不一定更的多么频繁,毕竟上了大学还是有点忙的。才不是一直打三角洲懒得更新 这里应当有一篇新文章。啥时候写完想起来放上。本文来自博客园,作者:北烛青…