2、点评搜索服务&推荐系统 -用户模块 - 实现用户的登录注册登出服务
一、用户服务搭建
用户业务模型后端服务:
- 用户注册,由于手机号的唯一性,最靠谱的就是使用数据库的唯一索引保证,同时catch duplicatedkey异常,抛出有意义的手机号已注册异常
- 用户注册,使用密码加密的方式以秘文方式入库,保证用户信息的安全性
- 用户登录,通过无状态的http session机制,通过cookie传递sessionId信息并保存登录凭证
实现用户的登录注册登出服务
点评dianpingdb数据库 用户表user
/*
Navicat Premium Data Transfer
Source Server : 本地测试
Source Server Type : MySQL
Source Server Version : 50728
Source Host : localhost:3306
Source Schema : dianpingdb
Target Server Type : MySQL
Target Server Version : 50728
File Encoding : 65001
Date: 05/05/2020 12:53:23
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`created_at` datetime(0) NOT NULL,
`updated_at` datetime(0) NOT NULL,
`telphone` varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '',
`password` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '',
`nick_name` varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '',
`gender` int(11) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `telphone_unique_index`(`telphone`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (1, '2020-02-01 11:46:46', '2020-05-05 11:46:56', '10987654321', '123456', '菜鸡文', 1);
SET FOREIGN_KEY_CHECKS = 1;
实现用户的登录注册服务
-
用户服务
-
用户模型
-
用户行为 - 登录注册
-
用户登录态管理
可用代码生成器mybatis-generator自动生成,生成PO类,生成mapper映射文件(其中包括基本的增删改查功能)、生成mapper接口等。要做些修改,添加下自己需要的功能或删除自己不需要的功能即可。mybatis-generator.xml
实现用户的登录注册服务
在src/main/java目录下,创建一个com.awen.dianping.service包,并在包中创建接口UserService,接口中定义一系列方法,代码如下所示。
interface UserService.java
public interface UserService {
UserModel getUser(Integer id);
UserModel register(UserModel registerUser) throws BusinessException, UnsupportedEncodingException, NoSuchAlgorithmException;
UserModel login(String telphone,String password) throws UnsupportedEncodingException, NoSuchAlgorithmException, BusinessException;
Integer countAllUser();
}
在src/main/java目录下,创建一个com.awen.dianping.dal包,并在包中创建接口UserModelMapper,接口中定义一系列方法,代码如下所示。
UserModelMapper.java
public interface UserModelMapper {
int deleteByPrimaryKey(Integer id);
int insert(UserModel record);
int insertSelective(UserModel record);
UserModel selectByPrimaryKey(Integer id);
UserModel selectByTelphoneAndPassword(@Param("telphone") String telphone, @Param("password")String password);
int updateByPrimaryKeySelective(UserModel record);
int updateByPrimaryKey(UserModel record);
Integer countAllUser();
}
在src/main/resources/mapping目录下,UserModelMapper.xml 代码生成就不写了,加了点添自己需要的功能,最后有源码。
在com.awen.dianping.service包下,创建UserService接口的实现类UserServiceImpl,该类需要实现接口中的所有方法,代码如下所示。
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserModelMapper userModelMapper;
@Override
public UserModel getUser(Integer id) {
return userModelMapper.selectByPrimaryKey(id);
}
@Override
@Transactional
public UserModel register(UserModel registerUser) throws BusinessException, UnsupportedEncodingException, NoSuchAlgorithmException {
registerUser.setPassword(encodeByMd5(registerUser.getPassword()));
registerUser.setCreatedAt(new Date());
registerUser.setUpdatedAt(new Date());
try{
userModelMapper.insertSelective(registerUser);
}catch (DuplicateKeyException ex){
throw new BusinessException(EmBusinessError.REGISTER_DUP_FAIL);
}
return getUser(registerUser.getId());
}
@Override
public UserModel login(String telphone, String password) throws UnsupportedEncodingException, NoSuchAlgorithmException, BusinessException {
UserModel userModel = userModelMapper.selectByTelphoneAndPassword(telphone,encodeByMd5(password));
if(userModel == null){
throw new BusinessException(EmBusinessError.LOGIN_FAIL);
}
return userModel;
}
@Override
public Integer countAllUser() {
return userModelMapper.countAllUser();
}
private String encodeByMd5(String str) throws NoSuchAlgorithmException, UnsupportedEncodingException {
//确认计算方法MD5
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
BASE64Encoder base64Encoder = new BASE64Encoder();
return base64Encoder.encode(messageDigest.digest(str.getBytes("utf-8")));
}
}
在com.awen.dianping.request包下,创建LoginReq,RegisterReq封装登录、注册请求数据,代码如下所示。
RegisterReq
public class RegisterReq {
@NotBlank(message = "手机号不能为空")
private String telphone;
@NotBlank(message = "密码不能为空")
private String password;
@NotBlank(message = "昵称不能为空")
private String nickName;
@NotNull(message = "性别不能为空")
private Integer gender;
public String getTelphone() {
return telphone;
}
public void setTelphone(String telphone) {
this.telphone = telphone;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public Integer getGender() {
return gender;
}
public void setGender(Integer gender) {
this.gender = gender;
}
}
LoginReq.java
public class LoginReq {
@NotBlank(message = "手机号不能为空")
private String telphone;
@NotBlank(message = "密码不能为空")
private String password;
public String getTelphone() {
return telphone;
}
public void setTelphone(String telphone) {
this.telphone = telphone;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
在com.awen.dianping.controller包下,创建UserController,代码如下所示。
UserController.java
@Controller("/user")
@RequestMapping("/user")
public class UserController {
public static final String CURRENT_USER_SESSION = "currentUserSession";
@Autowired
private HttpServletRequest httpServletRequest;
@Autowired
private UserService userService;
//get用户信息
@RequestMapping("/get")
@ResponseBody
public CommonRes getUser(@RequestParam(name="id")Integer id) throws BusinessException {
UserModel userModel = userService.getUser(id);
if(userModel == null){
//return CommonRes.create(new CommonError(EmBusinessError.NO_OBJECT_FOUND),"fail");
throw new BusinessException(EmBusinessError.NO_OBJECT_FOUND);
}else{
return CommonRes.create(userModel);
}
}
//注册
@RequestMapping("/register")
@ResponseBody
public CommonRes register(@Valid @RequestBody RegisterReq registerReq, BindingResult bindingResult) throws BusinessException, UnsupportedEncodingException, NoSuchAlgorithmException {
if(bindingResult.hasErrors()){
throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, CommonUtil.processErrorString(bindingResult));
}
UserModel registerUser = new UserModel();
registerUser.setTelphone(registerReq.getTelphone());
registerUser.setPassword(registerReq.getPassword());
registerUser.setNickName(registerReq.getNickName());
registerUser.setGender(registerReq.getGender());
UserModel resUserModel = userService.register(registerUser);
return CommonRes.create(resUserModel);
}
//登录
@RequestMapping("/login")
@ResponseBody
public CommonRes login(@RequestBody @Valid LoginReq loginReq,BindingResult bindingResult) throws BusinessException, UnsupportedEncodingException, NoSuchAlgorithmException {
if(bindingResult.hasErrors()){
throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR,CommonUtil.processErrorString(bindingResult));
}
UserModel userModel = userService.login(loginReq.getTelphone(),loginReq.getPassword());
httpServletRequest.getSession().setAttribute(CURRENT_USER_SESSION,userModel);
return CommonRes.create(userModel);
}
//注销
@RequestMapping("/logout")
@ResponseBody
public CommonRes logout() throws BusinessException, UnsupportedEncodingException, NoSuchAlgorithmException {
httpServletRequest.getSession().invalidate();
return CommonRes.create(null);
}
//获取当前用户信息
@RequestMapping("/getcurrentuser")
@ResponseBody
public CommonRes getCurrentUser(){
UserModel userModel = (UserModel) httpServletRequest.getSession().getAttribute(CURRENT_USER_SESSION);
return CommonRes.create(userModel);
}
}
运行测试
GET http://localhost:8010/user/get?id=1
POST 注册 http://localhost:8080/user/register
POST 登录 http://localhost:8080/user/login
GET 获取当前用户信息 http://localhost:8080/user/getcurrentuser
GET 退出 http://localhost:8080/user/logout
代码 Github:https://github.com/liuawen/dianping
SpringBoot、ElasticSearch、Spark 完成一个点评搜索推荐项目 用户服务