guns为我们提供了自动的dao接口代码生成器。到user模块的test文件夹中找到generator包中的EntityGeneragtor。然后对其中的信息进行修改。主要是一些目录和数据库的配置信息。目录信息就配置为工程的java目录。
gc.setOutputDir("D:\\IDEA_project_new\\guns\\guns-user\\src\\main\\java");//这里写你自己的java目录
dsc.setDriverName("com.mysql.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("961212");
dsc.setUrl("jdbc:mysql://127.0.0.1:3306/guns_rest?autoReconnect=true&useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8");
mpg.setDataSource(dsc);
pc.setEntity("com.stylefeng.guns.rest.common.persistence.model");
pc.setMapper("com.stylefeng.guns.rest.common.persistence.dao");
pc.setXml("com.stylefeng.guns.rest.common.persistence.dao.mapping");
修改完成之后执行这个文件,就会自动生成用户模块的数据实体bean。
可以看到我们在gateway模块中也是添加了两个模块的。但是gateway中的模块是用于和其他模块之间进行信息交互使用的。而user中的只是自己在用的实体。
关系如下:
@Override
public boolean register(UserModel userModel) {
//获取注册信息
//将注册信息实体转换为数据实体【mooc_user_t】
MoocUserT moocUserT = new MoocUserT();
//将数据实体存入数据库
moocUserT.setUserName(userModel.getUsername());
moocUserT.setEmail(userModel.getEmail());
moocUserT.setAddress(userModel.getAddress());
moocUserT.setUserPhone(userModel.getPhone());
//创建时间和修改时间
//数据加密[MD5数据加密+salt]就是指两次md5
String md5Password = MD5Util.encrypt(userModel.getPassword());
moocUserT.setUserPwd(md5Password);
//将数据插入到数据库当中
Integer insert = moocUserTMapper.insert(moocUserT);
if(insert>0){
return true;
}else return false;
}
注册功能很简单,无非就是调用方获取到注册信息。传递到服务提供方。然后服务提供方执行如上的几部操作。
注意这里的加密。一般我们使用的应该是两次MD5加密,但是这里为了简单一点,只使用了一次。要学习更加安全的加密可以参考shior的加密方式。更加的安全。
@Override
public int login(String username, String password) {
//根据登录账号获取数据库
MoocUserT moocUserT = new MoocUserT();
moocUserT.setUserName(username);
MoocUserT result = moocUserTMapper.selectOne(moocUserT);
//将获取到的结果来与加密后的password进行比较
if(result!=null&&result.getUuid()>0){
String p = MD5Util.encrypt(password);
if(result.getUserPwd().equals(p)){
return result.getUuid();
}
}
return 1;
}
@Override
public boolean checkUsername(String username) {
EntityWrapper<MoocUserT> entityWrapper = new EntityWrapper<>();
entityWrapper.eq("user_name",username);
Integer result = moocUserTMapper.selectCount(entityWrapper);
if(result!=null && result>0){
return false;
}else{
return true;
}
}
private UserInfoModel do2UserInfo(MoocUserT moocUserT){
UserInfoModel userInfoModel = new UserInfoModel();
userInfoModel.setUuid(moocUserT.getUuid());
userInfoModel.setHeadAddress(moocUserT.getHeadUrl());
userInfoModel.setPhone(moocUserT.getUserPhone());
userInfoModel.setUpdateTime(moocUserT.getUpdateTime().getTime());
userInfoModel.setEmail(moocUserT.getEmail());
userInfoModel.setUsername(moocUserT.getUserName());
userInfoModel.setNickname(moocUserT.getNickName());
userInfoModel.setLifeState(""+moocUserT.getLifeState());
userInfoModel.setBirthday(moocUserT.getBirthday());
userInfoModel.setAddress(moocUserT.getAddress());
userInfoModel.setSex(moocUserT.getUserSex());
userInfoModel.setBeginTime(moocUserT.getBeginTime().getTime());
userInfoModel.setBiography(moocUserT.getBiography());
return userInfoModel;
}
@Override
public UserInfoModel getUserInfo(int uuid) {
// 根据主键查询用户信息 [MoocUserT]
MoocUserT moocUserT = moocUserTMapper.selectById(uuid);
// 将MoocUserT转换UserInfoModel
UserInfoModel userInfoModel = do2UserInfo(moocUserT);
// 返回UserInfoModel
return userInfoModel;
}
@Override
public UserInfoModel updateUserInfo(UserInfoModel userInfoModel) {
// 将传入的参数转换为DO 【MoocUserT】
MoocUserT moocUserT = new MoocUserT();
moocUserT.setUuid(userInfoModel.getUuid());
moocUserT.setNickName(userInfoModel.getNickname());
moocUserT.setLifeState(Integer.parseInt(userInfoModel.getLifeState()));
moocUserT.setBirthday(userInfoModel.getBirthday());
moocUserT.setBiography(userInfoModel.getBiography());
moocUserT.setBeginTime(null);
moocUserT.setHeadUrl(userInfoModel.getHeadAddress());
moocUserT.setEmail(userInfoModel.getEmail());
moocUserT.setAddress(userInfoModel.getAddress());
moocUserT.setUserPhone(userInfoModel.getPhone());
moocUserT.setUserSex(userInfoModel.getSex());
moocUserT.setUpdateTime(null);
// DO存入数据库
Integer integer = moocUserTMapper.updateById(moocUserT);
if(integer>0){
// 将数据从数据库中读取出来
UserInfoModel userInfo = getUserInfo(moocUserT.getUuid());
// 将结果返回给前端
return userInfo;
}else{
return null;
}
}
再gateway模块当中,所有的业务实现都在package com.stylefeng.guns.rest.modular.user的UserController当中。实际上这个controller就是最开始接受前端请求的位置了。这个controller的主要通过调用user模块提供的service来实现。实现代码如下:
package com.stylefeng.guns.rest.modular.user;
import com.alibaba.dubbo.config.annotation.Reference;
import com.stylefeng.guns.rest.common.CurrentUser;
import com.stylefeng.guns.rest.modular.vo.ResponseVO;
import com.stylefeng.guns.user.UserApi;
import com.stylefeng.guns.user.vo.UserInfoModel;
import com.stylefeng.guns.user.vo.UserModel;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/user/")
@RestController
public class UserController {
@Reference(interfaceClass = UserApi.class,check = false)
private UserApi userAPI;
@RequestMapping(value="register",method = RequestMethod.POST)
public ResponseVO register(UserModel userModel){
if(userModel.getUsername() == null || userModel.getUsername().trim().length()==0){
return ResponseVO.serviceFail("用户名不能为空");
}
if(userModel.getPassword() == null || userModel.getPassword().trim().length()==0){
return ResponseVO.serviceFail("密码不能为空");
}
boolean isSuccess = userAPI.register(userModel);
if(isSuccess){
return ResponseVO.success("注册成功");
}else{
return ResponseVO.serviceFail("注册失败");
}
}
@RequestMapping(value="check",method = RequestMethod.POST)
public ResponseVO check(String username){
if(username!=null && username.trim().length()>0){
// 当返回true的时候,表示用户名可用
boolean notExists = userAPI.checkUsername(username);
if (notExists){
return ResponseVO.success("用户名不存在");
}else{
return ResponseVO.serviceFail("用户名已存在");
}
}else{
return ResponseVO.serviceFail("用户名不能为空");
}
}
@RequestMapping(value="logout",method = RequestMethod.GET)
public ResponseVO logout(){
/*
应用:
1、前端存储JWT 【七天】 : JWT的刷新
2、服务器端会存储活动用户信息【30分钟】
3、JWT里的userId为key,查找活跃用户
退出:
1、前端删除掉JWT
2、后端服务器删除活跃用户缓存
现状:
1、前端删除掉JWT
*/
return ResponseVO.success("用户退出成功");
}
@RequestMapping(value="getUserInfo",method = RequestMethod.GET)
public ResponseVO getUserInfo(){
// 获取当前登陆用户
String userId = CurrentUser.getCurrentUser();
if(userId != null && userId.trim().length()>0){
// 将用户ID传入后端进行查询
int uuid = Integer.parseInt(userId);
UserInfoModel userInfo = userAPI.getUserInfo(uuid);
if(userInfo!=null){
return ResponseVO.success(userInfo);
}else{
return ResponseVO.appFail("用户信息查询失败");
}
}else{
return ResponseVO.serviceFail("用户未登陆");
}
}
@RequestMapping(value="updateUserInfo",method = RequestMethod.POST)
public ResponseVO updateUserInfo(UserInfoModel userInfoModel){
// 获取当前登陆用户
String userId = CurrentUser.getCurrentUser();
if(userId != null && userId.trim().length()>0){
// 将用户ID传入后端进行查询
int uuid = Integer.parseInt(userId);
// 判断当前登陆人员的ID与修改的结果ID是否一致
if(uuid != userInfoModel.getUuid()){
return ResponseVO.serviceFail("请修改您个人的信息");
}
UserInfoModel userInfo = userAPI.updateUserInfo(userInfoModel);
if(userInfo!=null){
return ResponseVO.success(userInfo);
}else{
return ResponseVO.appFail("用户信息修改失败");
}
}else{
return ResponseVO.serviceFail("用户未登陆");
}
}
}
到这里呢我们user模块的业务层就完成了。
验证忽略URL列表
ignore-url: /user/register,/user/check #忽略列表配置
申请JWT
使用JWT访问其他的权限功能
在测试的时候我遇到了这样的一个问题。对register接口进行测试的时候。回报出无法访问的错误。首先我们要知道。dubbo是一款RPC框架。在进行方法远程调用的时候,会将方法中的参数首先进行序列化,然后在远端进行反序列化。报这个错的原因就是作为参数类型的实体类没有实现序列化接口。加上之后报错就没有了。