文章目录

引言

在上一节​​《果然新鲜电商项目(21)- 会员注册功能》​​,主要讲解如何实现会员注册功能,目的主要还是讲解Feign客户端的调用。

本文主要讲解微服务接口的安全问题,使用DTO如何细分接口中的实体。

1.问题引入

我们看看目前项目中注册接口:
《果然新鲜》电商项目(22)- DTO接口细分_spring
其中里面的请求实体类如下:

@Data
@ApiModel(value = "用户中注册")
public class UserEntity {

/**
* userid
*/
@ApiModelProperty(value = "用户id")
private Long userid;
/**
* 手机号码
*/
@ApiModelProperty(value = "手机号码")
private String mobile;
/**
* 邮箱
*/
@ApiModelProperty(value = "邮箱")
private String email;
/**
* 密码
*/
@ApiModelProperty(value = "密码")
private String password;
/**
* 用户名称
*/
@ApiModelProperty(value = "用户名称")
private String userName;
/**
* 性别 0 男 1女
*/
@ApiModelProperty(value = "用户性别")
private char sex;
/**
* 年龄
*/
@ApiModelProperty(value = "用户年龄")
private Long age;
/**
* 注册时间
*/
@ApiModelProperty(value = "创建时间")
private Date createTime;
/**
* 修改时间
*
*/
@ApiModelProperty(value = "修改时间")
private Date updateTime;
/**
* 账号是否可以用 1 正常 0冻结
*/
@ApiModelProperty(value = "账号是否可以用 1 正常 0冻结")
private char is_avalible;
/**
* 用户头像
*/
@ApiModelProperty(value = " 用户头像")
private String pic_img;
/**
* 用户关联 QQ 开放ID
*/
@ApiModelProperty(value = "用户关联 QQ 开放ID")
private Date qq_openid;
/**
* 用户关联 微信 开放ID
*/
@ApiModelProperty(value = "用户关联 微信 开放ID")
private Date WX_OPENID;
}

是否想过,请求的实体类是和数据库的实体类是一模一样的,这样会不会造成安全的问题?譬如我需要增加一个字段​​isVip​​​(表示是否为会员),那请求者如果是非会员,通过抓包,设置为​​true​​,那岂不是会造成数据安全的问题么?其实,我们需要改造一下请求的实体内容,让其与数据库对应的实体类有所区别。

2.何为VO、DO、DTO?

在日常的项目开发中:

  • VO对应于页面上需要显示的数据(表单)
  • DO对应于数据库中存储的数据(数据表)
  • DTO对应于除二者之外需要进行接口形式传递的数据。
    在传统的项目中,一般不使用DTO和VO的原因无非以下几个:

项目太小,对于一种业务实体,封装成一个DO就够了。

  1. 并不熟悉DTOVO,更不知道他们之间的区别。
  2. 了解DO\DTO\VO之间的区别,但是懒得用。
  3. 直接进入主题,修改我们的项目。

3.项目改造

首先需要构建新的新的模块:​​guoranxinxian-shop-api-dto​​​,并删除旧的模块​​guoranxinxian-shop-api-entity​​​:
《果然新鲜》电商项目(22)- DTO接口细分_spring_02
除此,在​​​guoranxinxian-shop-common-core​​​模块,添加​​DTO​​转换工具类:

package com.guoranxinxian.util;

public class BeanUtils<Dto, Do> {

/**
* dot 转换为Do 工具类
*
* @param dtoEntity
* @param doClass
* @return
*/
public static <Do> Do dtoToDo(Object dtoEntity, Class<Do> doClass) {
// 判断dto是否为空!
if (dtoEntity == null) {
return null;
}
// 判断DoClass 是否为空
if (doClass == null) {
return null;
}
try {
Do newInstance = doClass.newInstance();
org.springframework.beans.BeanUtils.copyProperties(dtoEntity, newInstance);
// Dto转换Do
return newInstance;
} catch (Exception e) {
return null;
}
}

/**
* do 转换为Dto 工具类
*
* @param dtoClass
* @param doEntity
* @return
*/
public static <Dto> Dto doToDto(Object doEntity, Class<Dto> dtoClass) {
// 判断dto是否为空!
if (doEntity == null) {
return null;
}
// 判断DoClass 是否为空
if (dtoClass == null) {
return null;
}
try {
Dto newInstance = dtoClass.newInstance();
org.springframework.beans.BeanUtils.copyProperties(doEntity, newInstance);
// Dto转换Do
return newInstance;
} catch (Exception e) {
return null;
}
}
// 后面集合类型带封装
}

3.1 会员微服务改造

3.1.1 新增VO、DO

1.在会员​​DTO​​​模块下,新建两个包:​​input​​​(输入参数,请求参数)、​​output​​​(输出参数,返回响应参数):
《果然新鲜》电商项目(22)- DTO接口细分_intellij-idea_03
2.修改​​​guoranxinxian-shop-api-member-entity​​​中的​​UserEntity​​​->​​UserInDTO​​​,并把​​UserInDTO​​复制到第一步的“输入参数”包里,改造内容如下:

package com.guoranxinxian.member.dto.input;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

/**
* description: 用户输入DTO
*/
@Data
@ApiModel(value = "用户信息实体类")
public class UserInDTO {

/**
* userid
*/
@ApiModelProperty(value = "用户id")
private Long userId;
/**
* 手机号码
*/
@ApiModelProperty(value = "手机号码")
private String mobile;
/**
* 邮箱
*/
@ApiModelProperty(value = "邮箱")
private String email;
/**
* 密码
*/
@ApiModelProperty(value = "密码")
private String password;
/**
* 用户名称
*/
@ApiModelProperty(value = "用户名称")
private String userName;
/**
* 性别 0 男 1女
*/
@ApiModelProperty(value = "用户性别")
private char sex;
/**
* 年龄
*/
@ApiModelProperty(value = "用户年龄")
private Integer age;

/**
* 用户头像
*/
@ApiModelProperty(value = " 用户头像")
private String picImg;
/**
* 用户关联 QQ 开放ID
*/
@ApiModelProperty(value = "用户关联 QQ 开放ID")
private String qqOpenId;
/**
* 用户关联 微信 开放ID
*/
@ApiModelProperty(value = "用户关联 微信 开放ID")
private String wxOpenId;

}

3.修改​​guoranxinxian-shop-api-member-entity中​​​的​​UserEntity​​​->​​UserOutDTO​​​,并把​​UserOutDTO​​复制到第一步的“输出参数”包里,改造内容如下:

package com.guoranxinxian.member.dto.output;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.util.Date;

/**
* description: 响应返回参数
*/
@Data
@ApiModel(value = "用户返回参数")
public class UserOutDTO {

/**
* userid
*/
@ApiModelProperty(value = "用户id")
private Long userId;
/**
* 手机号码
*/
@ApiModelProperty(value = "手机号码")
private String mobile;
/**
* 邮箱
*/
@ApiModelProperty(value = "邮箱")
private String email;
/**
* 用户名称
*/
@ApiModelProperty(value = "用户名称")
private String userName;
/**
* 性别 0 男 1女
*/
@ApiModelProperty(value = "用户性别")
private char sex;
/**
* 年龄
*/
@ApiModelProperty(value = "用户年龄")
private Integer age;
/**
* 注册时间
*/
@ApiModelProperty(value = "创建时间")
private Date createTime;
/**
* 修改时间
*
*/
@ApiModelProperty(value = "修改时间")
private Date updateTime;
/**
* 账号是否可以用 1 正常 0冻结
*/
@ApiModelProperty(value = "账号是否可以用 1 正常 0冻结")
private char isAvalible;
/**
* 用户头像
*/
@ApiModelProperty(value = " 用户头像")
private String picImg;
/**
* 用户关联 QQ 开放ID
*/
@ApiModelProperty(value = "用户关联 QQ 开放ID")
private String qqOpenId;
/**
* 用户关联 微信 开放ID
*/
@ApiModelProperty(value = "用户关联 微信 开放ID")
private String wxOpenId;

}

4.在会员服务​​guoranxinxian-shop-service-member​​​,新建​​UserDo​​(DO实体类)

package com.guoranxinxian.entity;

import lombok.Data;

import java.util.Date;

@Data
public class UserDo {

/**
* userid
*/

private Long userId;
/**
* 手机号码
*/
private String mobile;
/**
* 邮箱
*/
private String email;
/**
* 密码
*/
private String password;
/**
* 用户名称
*/
private String userName;
/**
* 性别 0 男 1女
*/
private char sex;
/**
* 年龄
*/
private Long age;
/**
* 注册时间
*/
private Date createTime;
/**
* 修改时间
*
*/
private Date updateTime;
/**
* 账号是否可以用 1 正常 0冻结
*/
private char isAvalible;
/**
* 用户头像
*/
private String picImg;
/**
* 用户关联 QQ 开放ID
*/
private String qqOpenid;
/**
* 用户关联 微信 开放ID
*/
private String wxOpenid;
}

3.1.2 替换之前的实体类

1.替换注册接口的实体类

替换前
《果然新鲜》电商项目(22)- DTO接口细分_maven_04
替换后
《果然新鲜》电商项目(22)- DTO接口细分_maven_05
2.替换查询手机号是否存在接口的实体类:

改造前:
《果然新鲜》电商项目(22)- DTO接口细分_spring_06
改造后:
《果然新鲜》电商项目(22)- DTO接口细分_intellij-idea_07

3.2 微信微服务改造

过程大致同上!

4. 测试

1.启动微信项目,成功:
《果然新鲜》电商项目(22)- DTO接口细分_maven_08
2.启动会员项目,成功:
《果然新鲜》电商项目(22)- DTO接口细分_maven_09
公众号测试,成功!
《果然新鲜》电商项目(22)- DTO接口细分_maven_10
《果然新鲜》电商项目(22)- DTO接口细分_maven_11
《果然新鲜》电商项目(22)- DTO接口细分_maven_12

5.总结

《果然新鲜》电商项目(22)- DTO接口细分_java_13