用户注册模块

用户注册模块,第1张

用户注册模块 用户注册
创建数据表 选中数据库:
use store
创建t_user表:
CREATE TABLE t_user (
	uid INT AUTO_INCREMENT COMMENT '用户id',
	username VARCHAR(20) NOT NULL UNIQUE COMMENT '用户名',
	password CHAR(32) NOT NULL COMMENT '密码',
	salt CHAR(36) COMMENT '盐值',
	phone VARCHAR(20) COMMENT '电话号码',
	email VARCHAR(30) COMMENT '电子邮箱',
	gender INT COMMENT '性别:0-女,1-男',
	avatar VARCHAR(50) COMMENT '头像',
	is_delete INT COMMENT '是否删除:0-未删除,1-已删除',
	created_user VARCHAR(20) COMMENT '日志-创建人',
	created_time DATETIME COMMENT '日志-创建时间',
	modified_user VARCHAR(20) COMMENT '日志-最后修改执行人',
	modified_time DATETIME COMMENT '日志-最后修改时间',
	PRIMARY KEY (uid)
	) ENGINE=InnoDB DEFAULT CHARSET=utf8;
创建用户的实体类 通过表的结构提取出表的公共字段,放在一个实体类的基类中,起名baseEntity基类中。
package com.cy.store.entity;
	
	import java.io.Serializable;
	import java.util.Date;
	import java.util.Objects;
	
	
	
	public class baseEntity implements Serializable {
	    private  String createdUser;
	    private Date createdTime;
	    private  String modifiedUser;
	    private Date modifiedTime;
	
	    public String getCreatedUser() {
	        return createdUser;
	    }
	
	    public void setCreatedUser(String createdUser) {
	        this.createdUser = createdUser;
	    }
	
	    public Date getCreatedTime() {
	        return createdTime;
	    }
	
	    public void setCreatedTime(Date createdTime) {
	        this.createdTime = createdTime;
	    }
	
	    public String getModifiedUser() {
	        return modifiedUser;
	    }
	
	    public void setModifiedUser(String modifiedUser) {
	        this.modifiedUser = modifiedUser;
	    }
	
	    public Date getModifiedTime() {
	        return modifiedTime;
	    }
	
	    public void setModifiedTime(Date modifiedTime) {
	        this.modifiedTime = modifiedTime;
	    }
	
	    @Override
	    public boolean equals(Object o) {
	        if (this == o) return true;
	        if (!(o instanceof baseEntity)) return false;
	
	        baseEntity that = (baseEntity) o;
	
	        if (getCreatedUser() != null ? !getCreatedUser().equals(that.getCreatedUser()) : that.getCreatedUser() != null)
	            return false;
	        if (getCreatedTime() != null ? !getCreatedTime().equals(that.getCreatedTime()) : that.getCreatedTime() != null)
	            return false;
	        if (getModifiedUser() != null ? !getModifiedUser().equals(that.getModifiedUser()) : that.getModifiedUser() != null)
	            return false;
	        return getModifiedTime() != null ? getModifiedTime().equals(that.getModifiedTime()) : that.getModifiedTime() == null;
	    }
	
	    @Override
	    public int hashCode() {
	        int result = getCreatedUser() != null ? getCreatedUser().hashCode() : 0;
	        result = 31 * result + (getCreatedTime() != null ? getCreatedTime().hashCode() : 0);
	        result = 31 * result + (getModifiedUser() != null ? getModifiedUser().hashCode() : 0);
	        result = 31 * result + (getModifiedTime() != null ? getModifiedTime().hashCode() : 0);
	        return result;
	    }
	
	    @Override
	    public String toString() {
	        return "baseEntity{" +
	                "createdUser='" + createdUser + ''' +
	                ", createdTime=" + createdTime +
	                ", modifiedUser='" + modifiedUser + ''' +
	                ", modifiedTime=" + modifiedTime +
	                '}';
	    }
	}
创建用户的实体类。需要继承baseEntity基类。
package com.cy.store.entity;
	
	import java.io.Serializable;
	
	
	public class User extends baseEntity implements Serializable {
	    private String uid;
	    private String username;
	    private String password;
	    private String salt;
	    private String phone;
	    private String email;
	    private Integer gender;
	    private String avatar;//头像
	    private  String isDelete;
	
	    //get和set方法,
	    // equals:比较两个对象是否相等
	    // hashCode()方法:地址的输出
	    // toString方法
	
	    public String getUid() {
	        return uid;
	    }
	
	    public void setUid(String uid) {
	        this.uid = uid;
	    }
	
	    public String getUsername() {
	        return username;
	    }
	
	    public void setUsername(String username) {
	        this.username = username;
	    }
	
	    public String getPassword() {
	        return password;
	    }
	
	    public void setPassword(String password) {
	        this.password = password;
	    }
	
	    public String getSalt() {
	        return salt;
	    }
	
	    public void setSalt(String salt) {
	        this.salt = salt;
	    }
	
	    public String getPhone() {
	        return phone;
	    }
	
	    public void setPhone(String phone) {
	        this.phone = phone;
	    }
	
	    public String getEmail() {
	        return email;
	    }
	
	    public void setEmail(String email) {
	        this.email = email;
	    }
	
	    public Integer getGender() {
	        return gender;
	    }
	
	    public void setGender(Integer gender) {
	        this.gender = gender;
	    }
	
	    public String getAvatar() {
	        return avatar;
	    }
	
	    public void setAvatar(String avatar) {
	        this.avatar = avatar;
	    }
	
	    public String getIsDelete() {
	        return isDelete;
	    }
	
	    public void setIsDelete(String isDelete) {
	        this.isDelete = isDelete;
	    }
	
	    @Override
	    public boolean equals(Object o) {
	        if (this == o) return true;
	        if (!(o instanceof User)) return false;
	        if (!super.equals(o)) return false;
	
	        User user = (User) o;
	
	        if (getUid() != null ? !getUid().equals(user.getUid()) : user.getUid() != null) return false;
	        if (getUsername() != null ? !getUsername().equals(user.getUsername()) : user.getUsername() != null)
	            return false;
	        if (getPassword() != null ? !getPassword().equals(user.getPassword()) : user.getPassword() != null)
	            return false;
	        if (getSalt() != null ? !getSalt().equals(user.getSalt()) : user.getSalt() != null) return false;
	        if (getPhone() != null ? !getPhone().equals(user.getPhone()) : user.getPhone() != null) return false;
	        if (getEmail() != null ? !getEmail().equals(user.getEmail()) : user.getEmail() != null) return false;
	        if (getGender() != null ? !getGender().equals(user.getGender()) : user.getGender() != null) return false;
	        if (getAvatar() != null ? !getAvatar().equals(user.getAvatar()) : user.getAvatar() != null) return false;
	        return getIsDelete() != null ? getIsDelete().equals(user.getIsDelete()) : user.getIsDelete() == null;
	    }
	
	    @Override
	    public int hashCode() {
	        int result = super.hashCode();
	        result = 31 * result + (getUid() != null ? getUid().hashCode() : 0);
	        result = 31 * result + (getUsername() != null ? getUsername().hashCode() : 0);
	        result = 31 * result + (getPassword() != null ? getPassword().hashCode() : 0);
	        result = 31 * result + (getSalt() != null ? getSalt().hashCode() : 0);
	        result = 31 * result + (getPhone() != null ? getPhone().hashCode() : 0);
	        result = 31 * result + (getEmail() != null ? getEmail().hashCode() : 0);
	        result = 31 * result + (getGender() != null ? getGender().hashCode() : 0);
	        result = 31 * result + (getAvatar() != null ? getAvatar().hashCode() : 0);
	        result = 31 * result + (getIsDelete() != null ? getIsDelete().hashCode() : 0);
	        return result;
	    }
	
	    @Override
	    public String toString() {
	        return "User{" +
	                "uid='" + uid + ''' +
	                ", username='" + username + ''' +
	                ", password='" + password + ''' +
	                ", salt='" + salt + ''' +
	                ", phone='" + phone + ''' +
	                ", email='" + email + ''' +
	                ", gender=" + gender +
	                ", avatar='" + avatar + ''' +
	                ", isDelete='" + isDelete + ''' +
	                '}';
	    }
	}
注册-持久层

通过MyBatis来 *** 作数据库。在做mybatis开发的流程。

规划需要执行的SQL语句

1.用户的注册功能,相当于在做数据的插入 *** 作。
insert into t_user (username,password) values (值列表)
2.在用户的注册时首先要去查询当前的用户名是否存在,如果存在则不能进行注册。相当于一条查询语句。
select * from t_user where username=?

设计接口和方法

1.定义Mapper接口。在项目的目录结构下首先创建一个mapper包,在这个包下再根据不同的功能模块来创建mapper接口。创建UserMapper接口。要在接口中定义两个SQL语句的抽象方法。

package com.cy.store.mapper;
	
	import com.cy.store.entity.User;
	
	
	public interface UserMapper {
	    
	    Integer insert(User user);
	
	    
	    User findByUsername(String username);
	}

2.在启动类配置mapper接口文件的位置
// MapperScan注解指定当前项目中的Mapper接口路径的位置,在项目启动的时候会自动加载所有接口
@MapperScan(“com.cy.store.mapper”)

编写映射

1.定义xml映射文件,与接口进行关联。所有的映射文件需要放置在resources目录下,在这个目录下创建一个mapper文件夹,然后在这个文件夹存放Mapper的映射文件。
2.创建接口对应的映射文件,遵循和接口的名称保持一致即可。创建一个UserMapper.xml文件。

```java
	
	
	
	
	    
	
	

3.配置接口中的方法对应上SQL语句上。需要借助标签来完成,insertdeleteupdateselect,对应的是SQL语句的增删改查 *** 作。

```java
	 
	    
	    
	        
	        
	        
	        
	        
	        
	        
	        
	        
	    
	    
	    
	    
	        INSERT INTO t_user(
	        username,password,salt,phone,email,gender,avatar,is_delete,created_user,created_time,modified_user,modified_time
	        ) VALUES (
	        #{username},#{password},#{salt},#{phone},#{email},#{gender},#{avatar},#{isDelete},#{createdTime},#{modifiedUser},#{modifiedTime}
	        )
	    
	    
	    
	    
4.将mapper文件的位置注册到properties对应的配置文件中。
	

```xml
mybatis.mapper-locations=classpath:mappers
	    @Test
	    public void insert(){
	    User user = new User();
	    user.setUsername("张三");
	    user.setPassword("123");
	    Integer i = userMapper.insert(user);
	        System.out.println(i);
	    }
	
	    @Test
	    public void findByUsername(){
	        User user = userMapper.findByUsername("张三");
	        System.out.println(user);
	    }
	}
注册-业务层 规划异常

1.RuntimeException异常,作为这异常的子类,然后再去定义具体的异常类型来继承这个异常。业务层异常的基类ServiceException异常。这个异常继承RuntimeException异常。异常机制的建立。

package com.cy.store.service.ex;
	
	
	public class ServiceException extends RuntimeException {
	    public ServiceException() {
	        super();
	    }
	
	    public ServiceException(String message) {
	        super(message);
	    }
	
	    public ServiceException(String message, Throwable cause) {
	        super(message, cause);
	    }
	
	    public ServiceException(Throwable cause) {
	        super(cause);
	    }
	
	    protected ServiceException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
	        super(message, cause, enableSuppression, writableStackTrace);
	    }
	}

根据业务层不同的业务功能来详细定义具体的异常的类型,统一的去继承ServiceException异常类。
2.用户在进行注册的时候可能会产生用户名被占用的错误,抛出一个异常:UsernameDuplicatedException异常。

package com.cy.store.service.ex;
	
	
	public class UsernameDuplicatedException extends ServiceException {
	    //alt + insert --- override methods...
	
	    public UsernameDuplicatedException() {
	        super();
	    }
	
	    public UsernameDuplicatedException(String message) {
	        super(message);
	    }
	
	    public UsernameDuplicatedException(String message, Throwable cause) {
	        super(message, cause);
	    }
	
	    public UsernameDuplicatedException(Throwable cause) {
	        super(cause);
	    }
	
	    protected UsernameDuplicatedException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
	        super(message, cause, enableSuppression, writableStackTrace);
	    }
	}
3.正在执行数据插入时,服务器数据库宕机。处于正在执行插入的过程中产生的异常:InsertException异常。
	package com.cy.store.service.ex;
	
	public class InsertException extends ServiceException {
	    public InsertException() {
	        super();
	    }
	
	    public InsertException(String message) {
	        super(message);
	    }
	
	    public InsertException(String message, Throwable cause) {
	        super(message, cause);
	    }
	
	    public InsertException(Throwable cause) {
	        super(cause);
	    }
	
	    protected InsertException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
	        super(message, cause, enableSuppression, writableStackTrace);
	    }
	}
设计接口和抽象方法的定义

1.在service包下创建一个IUserService接口。

package com.cy.store.service;
	
	import com.cy.store.entity.User;
	
	
	public interface IUserService {
	    
	    void reg(User user);
	}

2.创建一个实现类UserServiceImpl类,需要实现这个接口,并实现抽象方法。

package com.cy.store.service.impl;
	
	import com.cy.store.entity.User;
	import com.cy.store.mapper.UserMapper;
	import com.cy.store.service.IUserService;
	import com.cy.store.service.ex.InsertException;
	import com.cy.store.service.ex.UsernameDuplicatedException;
	import org.springframework.beans.factory.annotation.Autowired;
	import org.springframework.stereotype.Service;
	import org.springframework.util.DigestUtils;
	
	import java.sql.Time;
	import java.util.Date;
	import java.util.UUID;
	
	
	@Service
	public class UserServiceImpl implements IUserService {
	
	    @Autowired
	    private UserMapper userMapper;
	
	    @Override
	    public void reg(User user) {
	        //通过user参数来获取传递过来的username
	        String username = user.getUsername();
	        // 调用findByUsername()判断用户是否注册过
	        User result = userMapper.findByUsername(username);
	        //判断结果集是否为空,为空则抛出用户名被占用的异常
	        if(result != null){
	            //用户名已被注册
	            throw new UsernameDuplicatedException("用户名被占用");
	        }
	
	        //密码的加密处理
	        //(串 + password + 串) --- MD5算法加密,连续加载三次
	        //盐值 + password + 盐值 --- 盐值就是一个随机的字符串
	        String oldPassword = user.getPassword();
	        //获取盐值(随机生成一个盐值)
	        String salt = UUID.randomUUID().toString().toUpperCase();
	        //补全数据:盐值的记录
	        user.setSalt(salt);
	        //将密码和盐值作为一个整体进行加密,忽略原有密码的强度提升数据的安全性
	        String md5Password = getMD5Password(oldPassword, salt);
	        //将加密密码补全到user中
	        user.setPassword(md5Password);
	        //补全数据:is_delete设置为0
	        user.setIsDelete(0);
	        //不全数据:4个日志字段信息
	        user.setCreatedUser(user.getUsername());//创建人
	        user.setModifiedUser(user.getUsername());//最后修改执行人
	        Date date = new Date();
	        user.setCreatedTime(date);//创建时间
	        user.setModifiedTime(date);//最后修改执行时间
	
	
	        //执行注册业务功能的实现(rows == 1)
	        Integer rows = userMapper.insert(user);
	        if(rows != 1){
	            throw new InsertException("在用户注册的过程中产生了未知的异常");
	        }
	    }
	
	    
	    private String getMD5Password(String password,String salt){
	        //MD5加密算法方法的调用(进行三次机密)
	        for (int i = 0; i < 3; i++) {
	            password = DigestUtils.md5DigestAsHex((salt+password+salt).getBytes()).toUpperCase();
	        }
	        return password;
	    }
	}

3.在单元测试包下创建一个UserServiceTests类,在这个类中添加单元测试的功能。

package com.cy.store.service;
	
	
	import com.cy.store.entity.User;
	import com.cy.store.mapper.UserMapper;
	import com.cy.store.service.ex.ServiceException;
	import org.junit.Test;
	import org.junit.runner.RunWith;
	import org.springframework.beans.factory.annotation.Autowired;
	import org.springframework.boot.test.context.SpringBootTest;
	import org.springframework.test.context.junit4.SpringRunner;
	
	//@SpringBootTest:标注当前的类是测试类,不会随项目一起打包
	@SpringBootTest
	//@RunWith:启动单元测试类需要传递一个参数必须是SpringRunner的实例类型
	@RunWith(SpringRunner.class)
	public class UserServiceTests {
	
	    @Autowired
	    private IUserService userService;
	
	
	    @Test
	    public void reg() {
	        try {
	            User user = new User();
	            user.setUsername("王五");
	            user.setPassword("123");
	            userService.reg(user);
	            System.out.println("ok");
	        } catch (ServiceException e) {
	            //获取类的对象,获取类的名称
	            System.out.println(e.getClass().getSimpleName());
	            //获取异常的具体描述信息
	            System.out.println(e.getMessage());
	        }
	    }
	}
注册-控制层 创建响应

状态码,状态描述信息,数据。这部分功能封装一个类中,将这类作为方法返回值,返回给前端浏览器。
/Json的数据格式进行响应/
public class JsonResult implements Serializable {

private Integer state;

private String message;

private E data;

设计请求

依据当前的业务功能模块进行请求的设计。
请求路径:/users/reg
请求参数: User user
请求类型:POST
相应结果:JsonResult

处理请求

创建一个控制层对应的类UserController类。依赖于业务层的接口。

package com.cy.store.controller;
	
	import com.cy.store.entity.User;
	import com.cy.store.service.IUserService;
	import com.cy.store.service.ex.InsertException;
	import com.cy.store.service.ex.ServiceException;
	import com.cy.store.service.ex.UsernameDuplicatedException;
	import com.cy.store.util.JsonResult;
	import jdk.nashorn.internal.ir.RuntimeNode;
	import org.springframework.beans.factory.annotation.Autowired;
	import org.springframework.stereotype.Controller;
	import org.springframework.web.bind.annotation.RequestBody;
	import org.springframework.web.bind.annotation.RequestMapping;
	import org.springframework.web.bind.annotation.ResponseBody;
	import org.springframework.web.bind.annotation.RestController;
	
	//@Controller
	@RestController//@Controller + @ResponseBody
	@RequestMapping("/users")
	public class UserController {
	
	    @Autowired
	    private IUserService userService;
	
	    @RequestMapping("/reg")
	    //@ResponseBody//表示此方法的响应结果以json格式进行数据的相应给到前端
	    public JsonResult reg(User user) {
	        //创建响应结果对象
	        JsonResult result = new JsonResult<>();
	        try {
	            userService.reg(user);
	            result.setStatc(200);
	            result.setMessage("用户注册成功");
	        } catch (UsernameDuplicatedException e) {
	            result.setStatc(4000);
	            result.setMessage("用户名被占用");
	        } catch (InsertException e) {
	            result.setStatc(5000);
	            result.setMessage("注册用户时出现了未知的异常");
	        }
	        return result;
	    }
	
	}
控制层优化设计

在控制层抽离一个父类,在这个父类中统一的去处理关于异常的相关 *** 作。编写一个baseController类,统一处理异常。

package com.cy.store.controller;
	
	import com.cy.store.service.ex.InsertException;
	import com.cy.store.service.ex.ServiceException;
	import com.cy.store.service.ex.UsernameDuplicatedException;
	import com.cy.store.util.JsonResult;
	import org.springframework.aop.ThrowsAdvice;
	import org.springframework.web.bind.annotation.ExceptionHandler;
	
	
	public class baseController {
	
	    public static final int OK = 200;
	
	    //请求处理方法,这个方法的返回值就是要传给前端的数据
	    //自动将异常对象传递给此方法的参数列表上
	    //当项目产生了异常,被统一拦截到此方法中,这个方法此时就充当的是请求处理方法,方法的返回值直接给前端
	    @ExceptionHandler(ServiceException.class)//用于统一处理抛出的异常
	    public JsonResult ExceptionHandler(Throwable e){
	    JsonResult result = new JsonResult<>(e);
	    if(e instanceof UsernameDuplicatedException){
	        result.setStatc(4000);
	        result.setMessage("用户名已经被占用");
	    }else if(e instanceof InsertException){
	        result.setStatc(5000);
	        result.setMessage("注册时发生了未知的异常");
	    }
	    return result;
	}
	}

重新构建了reg()方法

 @RequestMapping("/reg")
    //@ResponseBody//表示此方法的响应结果以json格式进行数据的相应给到前端
    public JsonResult reg(User user) {
            userService.reg(user);
        return new JsonResult<>(OK);
    }
注册-前端页面

1.在register页面编写发送请求的方法,点击事件来完成。先选中对应的按钮(( ( " 选 择 器 " ) ) ) , 再 去 添 加 点 击 的 时 间 , ("选择器"))),再去添加点击的时间, ("选择器"))),再去添加点击的时间,.ajax()函数发送异步请求。

2.JQery封装了一个函数,称之为$.ajax()函数,通过对象调用ajax函数,可以异步加载相关的请求。依靠的是Javascript提供的一个对象XHR(XmlHttpResponse),封装了这个对象

3.ajax()使用方式。需要传递一个方法体作为方法的参数来使用,一对大括号称之为方法体,ajax接收多个参数,参数与参数之间要求使用",“进行分割,每一组参数之间使用”:"进行分割,参数的组成部分一个是参数的名称(不能随意的定义),是参数的值,参数的值要求使用字符串来标识,参数的声明顺序没有要求。

语法结构:
$.ajax({
url:"",
type:"",
data:"",
dataType:"",
success: function(){
},
error: function(){
}
});

4.ajax()函数参数的含义:
参数 功能描述
url 标识请求的地址(url地址),不能包含参数列表部分的内容。例如:url:“localhost:8080/users/reg”
type 请求类型(GET和POST请求的类型)。例如:type:“POST”
data 向指定的请求url地址提交的数据。例如:data:“username=tom&pwd=123”
datpeType 提交数据的类型。数据的类型一般指定为json类型。例如:dataType:“json”
success 当服务器正常响应客户端时,会自动调用success参数的方法,并且将服务器返回的数据以参数的形式传递给这个方法的参数上
error 当服务器未正常响应客户端时,会自动调用error参数的方法,并且将服务器返回的数据以参数的形式传递给这个方法的参数上
5.js代码可以独立声明在一个js的文件里或者声明在一个script标签中。


6.js代码无法正常被服务器解析执行,体现在点击页面中的按钮没有任何的响应。解决档案
* 在项目的maven下clear清理项目-install重新部署
* 在项目的file选项下-cash清理缓存
* 重新的去构建项目:build选项下-rebuild选项
* 重启idea
* 重启电脑

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5707715.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存