一.创建序列化工具类JackSonUtils
明确一点工具类对外的方法我们一般设置为静态方法,因为后续需要使用到将对象存到redis中或者存到rabbitMq消息队列中我们就需要序列化(object ->string) ,反序列化(string -> object),关键类我们需要使用到一个ObjectMapper的WriteValueAsString(序列化),readValue(反序列化),序列化都是一样的传一个object就行了,但是反序列化需要传一个string和要转化的对象的类型class,普通对象没有什么问题,但是如果是集合list,map之类的,第二个参数就不能是List.class,是需要我们传入JavaType类
第一个参数是集合类型,第二个参数是集合内的元素类型
WriteValueAsString(序列化),readValue(反序列化)两个方法,注意spring4.0.0以下版本这两个方法会要我们抛异常或者trycatch,所以我们在写工具类的使用也要加上trycatch,如果不加我们可以参考一下spring框架的序列化类是怎么写的,首先将objectMapper对象单例化,然后通过tryParse来进行trycatch,我们也可以学习借鉴使用一下spring的tryParse,
调用tryParse方法第一个参数我们使用lambda表达式,第二个参数是要捕获的类型,把他这个方法copy过来再进行一层封装,对我们的方法来trycatch,封装的时候我们给他传上我们会抛出的异常给第二个参数,即可用这个方法来帮助我们完成trycatch,提供反序列化方法参考记住分类


二.日志的配置
在配置文件中加上日志的配置,我们的日志有分别设置开发环境和上线环境所以 spring.profiles.active=dev # 部署后需要变成 # spring.profiles.active=test logging.config=classpath:logback-spring.xml 日志的具体配置在这个xml文件下具体
我们还可以自定义一些过滤器,这个过滤器是用于过滤出日志中我们想要的信息,添加到日志配置文件中即可,使用已下方法来构建日志对象,参数为定位的类的类型LoggerFactory.getLogger(FilterTest.class);
三.加密
我们需要对存储于数据库中的重要隐私信息进行加密,我们有对称,非对称,摘要加密(没有逆过) 我们有数据库中有两个比较重要的数据需要加密一个是,手机号,一个是密码,手机号因为我们后端后续需要使用所以我们需要解密,我们这里使用对称加密,密码我们不适用仅仅是存储我们使用摘要加密让其不可被解密,摘要加密,我们还可以给他加上盐值来提高防护等级,我们这里使用hutool这个工具包来进行加密解密
Maven 仓库地址:https://mvnrepository.com/artifact/cn.hutool
HuTool 官⽹地址:https://hutool.cn/
我们对称加密使用:aes 摘要加密使用:SHA-256,具体工具类的使用可以参考hutool工具类文档
注意aes的密钥必须是16个字节 24个字节 32个字节,具体使用可以参考hutool官方文档
四.完成用户注册模块
注意,在工程中我们为每一层每一个模块写有专门的对象传输,也有分参数接收的对象,响应的对象,所以对象转换的方法是必要的
0.在完成具体业务逻辑之前,添加mysql依赖,以及相关的配置文件,根据库以及业务模块,创建好与数据库对应的DBObject,以及相应的mapper接口,我们可以发现所有的类都有id,创建时间,更新时间,所以我们可以创建一个父类包含这三个属性然后其他类去继承,注意继承的类使用@Data注解时候,需要搭配 @EqualsAndHashCode(callSuper = true) 来包含父类属性,这里注册的用户有两个一个是管理员用户注册(有密码),一个是管理员创建普通用户(没有密码),这里我们采用创建两个用户使用的是同一个接口,所以做好相关的判断
1.根据接口文档创建接收类,还有我们的响应返回类,注意参数接收类我们可以添加注解做好一些基础的参数校验(参数校验注解需要添加相关的依赖),以及一些特定的属性只有我们预设的值的属性,我们可以使用枚举类来定义
2.进入接口后有三板斧,打印日志,参数校验,异常捕获(我们不手动异常捕获后续使用统一异常处理),具体业务逻辑我们放到service层里,controller层我们只负责接收参数,进行初步参数校验,不合法我们可以抛出自定义异常,然后对于service层返回来的对象进行对象转换,可以写一个私有的转化方法也可以写一个对象转换的工具类
3.对于service层我们采用分离式设计,即定义一个接口,然后具体业务在他的实现类中,对于service层方法接收参数,即是controller层传来的我们不需要在定义一个,但是我们需要定义一个service用来返回结果响应的对象
4.service层的具体逻辑:
校验部分:
1.对于controller层传来的参数进行校验,由于controller层已经校验过参数里面的属性了,我们只需要对参数整体判断是否为空即可,还有进行更细致的参数是否符合业务的校验 ,这里有很多,邮箱格式校验,手机号格式校验(这里我们使用正则表达式的工具类来校验,网上找一下相关的工具类即可),身份信息是否为我们定义的枚举类(我们可以在枚举类中定义一个静态方法来进行这方面的校验),身份信息如果是管理员的话密码不能为空,如果存在密码的话密码格式校验(同样使用正则表达式,这里是大于6位),还有邮箱是否已经被人使用,手机号是否已经被人使用,注意这两种需要我们回数据库中查表来进行判断,对于不满足检查的我们可以直接抛出该层自定义的总异常+我们不同的错误码
2.对于邮箱我们直接去库里面查找就行,但是对于手机号注意,手机号是用户的私密信息他在数据库中是以密文存储所以我们直接查找的时候(取出来)解密,进入加密,每次我们都需要进行这样子一个操作,那么我们有没有办法让他直接让他自动进行相关的操作呢,我们可以通过Mybatis中帮我们实现的TypeHandler这个类来实现帮助我们自动实现类的转化,他会在搜索相关类的时候自动转化成数据库中的类型,注意我们不能直接用string因为他这样子所有的string都会被这样子处理,我们只需要手机号的那个string,所以我们要为手机号的那个string外面套一个类来让他唯一识别,注意后续我们java层面所使用DBobject都要变成这个包装类不能使用string

中间TH部分可以通过我们的编写让他进行加密处理或者解密,最后变为数据中的类型
以及重写对应接口下面的四个方法
1.进入的方法

以及另外三个出来的方法,注意出来的时候我们加上解密的操作就可以保证数据库中存的是密文,但是我们不需要在进行特殊的操作


最后要使用以上的功能需要添加相关的配置
用户入库:
完成了校验之后接下来的一部是实现入库的功能:入库的时候注意要给密码进行加密(如果有密码的情况下才需要加密),以及我们已将将DBobject的phone包装了,类型要使用我们的包装类,注意根据接口文档我们需要拿回相应的id所以,我们入库的时候,可以给使用DBobject,开启加上相关的注解然后插入之后将id赋值给对象,来方便我们拿到@Options注解

返回结果:
实例化service返回给controller层的对象,做好相关的属性赋值并且返回即完成了service层相关的操作
5.controller对于service层返回来的结果再进行对象转换,转换成controller层需要的对象(可以写一个转化的方法),最好加上校验,对于service给我们返回来的结果
注意我们进行了一些校验不满足可以直接抛出我们定义对应层的异常,并且加上我们定义的错误码
五.统一异常处理
以上我们完成了用户注册的模块,我们进行了许多模块的校验并且抛出异常,我们直接将那些异常抛给前端并不友好,我们可以进行统一异常捕获通过@ControllerAdvice以及@Responsebody @Exception来进行统一的异常捕获,并且捕获后返回统一的结果对前端来说比较友好,我们是按层来定义异常,通过不同异常码,来区分同一层的不同逻辑错误,所以我们真的controller,service,以及exception(兜底)捕获异常,通过不同code以及msg来进行异常描述,然后返回统一结果
这里完成了用户注册的后端操作,接下来完成前端即可,前端页面(一个页面两用,管理员注册,管理员创建用户)会在url中带一个参数admin,如果有admin并且=false的话他就隐藏密码框,以及他是通过表单提交的所以,我们如果没有输入密码框就是""空字符串,所以我们后端接收所有的参数都不会是null要么是空字符串,前端代码有相关同学帮我实现,我只需要提交ajax请求接收返回的结果并且做一些相应的校验即可