• springboot项目注册接口


    基于eclipse工具上的

    一、Controller层

    package cn.kooun.controller;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import cn.kooun.pojo.params.UserLoginParam;
    import cn.kooun.pojo.params.UserRegisterParam;
    import cn.kooun.service.UserService;
    
    /**
     * 	用户Controller
     * @author HuangJingNa
     * @date 2019年12月20日 上午9:21:38
     *
     */
    @RestController	//@Controller+@Responsebody
    @RequestMapping("user")
    public class UserController {
    	@Autowired
    	private UserService userService;
    	
    	/**
    	 *	 用户注册
    	 * @author HuangJingNa
    	 * @date 2019年12月20日 上午9:23:15
    	 *
    	 * @return
    	 * 客户端请求的数据一般封装在自定义的pojo类中(XxxParam)
    	 */
    	/* 业务需求
    	 * 1.校验数据
    	 * 	校验账号(非空、长度、唯一性)
    	 * 	校验密码(非空、长度、格式)
    	 * 2.数据库操作(插入操作)
    	 * 3.将数据响应给客户端/页面
    	 */
    	@GetMapping("register")
    	public Object register(UserRegisterParam userRegisterParam) {
    		return userService.register(userRegisterParam);
    	}
    }
    

    注册接口参数封装类UserRegisterParam

    package cn.kooun.pojo.params;
    
    import lombok.Getter;
    import lombok.Setter;
    import lombok.ToString;
    
    /**
     * 	注册接口参数封装
     * @author HuangJingNa
     * @date 2019年12月20日 上午9:28:47
     *
     */
    @Setter
    @Getter
    @ToString
    public class UserRegisterParam {
    	/**账号名称*/
    	private String username;
    	/**账号密码*/	
    	private String password;
    }
    

    二、service层

    业务层:主要分为三步走:
    1. 数据校验
    2. 数据库的相关操作
    3. 返回响应结果给客户端/页面

    一般多次创建实例的,可以使用工厂模式
    加密:使用Md5(较易破解),可以加入“盐”混合加密,越复杂越难破解
    一般的标准校验(非空、长度、格式的判断)放在数据校验工具类中
    操作数据库的代码较多,一般封装成一个方法(选中按alt+shift+M可以生成方法)

    package cn.kooun.service;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.util.StringUtils;
    
    import cn.kooun.common.CheckUtils;
    import cn.kooun.common.Md5Utils;
    import cn.kooun.common.UuidUtils;
    import cn.kooun.common.result.Result;
    import cn.kooun.common.result.ResultUtils;
    import cn.kooun.mapper.UserMapper;
    import cn.kooun.pojo.params.UserLoginParam;
    import cn.kooun.pojo.params.UserRegisterParam;
    import cn.kooun.pojo.table.User;
    
    /**
     *	 用户service
     * @author HuangJingNa
     * @date 2019年12月20日 上午9:29:25
     *
     */
    @Service
    public class UserService {
    	@Autowired
    	private UserMapper userMapper;
    
    	/**
    	 * 	注册业务
    	 * @author HuangJingNa
    	 * @date 2019年12月20日 上午9:30:21
    	 *
    	 * @param userRegisterParam
    	 * @return
    	 */
    	public Object register(UserRegisterParam userRegisterParam) {
    		//数据校验
    		Object result = this.checkRegister(userRegisterParam);
    		if(result != null) {
    			return result;
    		}
    		//插入数据库
    		//由于字段可能会发生变化,插入需要动态生成(使mapper类继承通用mapper)
    		this.saveRegister(userRegisterParam);
    		//返回友好提示,注册成功(使用工具类)
    		return ResultUtils.success("注册成功~", Result.JUMP_LOGIN);
    	}
    	/**
    	 * 	将账号密码插入数据库中
    	 * @author HuangJingNa
    	 * @date 2019年12月20日 下午3:33:48
    	 *
    	 * @param userRegisterParam
    	 */
    	private void saveRegister(UserRegisterParam userRegisterParam) {
    		User user = new User();
    		user.setId(UuidUtils.getUuid());
    		user.setUsername(userRegisterParam.getUsername());
    		user.setPassword(Md5Utils.getPassword(
    				userRegisterParam.getPassword(),
    				userRegisterParam.getUsername()));
    		user.setNickName("kooun_" + user.getId());
    		user.setType(1);
    		userMapper.insertSelective(user);
    	}
    	/**
    	 * 	注册业务数据校验
    	 * @author HuangJingNa
    	 * @date 2019年12月20日 下午2:43:37
    	 *
    	 * @param userRegisterParam
    	 * @return
    	 */
    	private Object checkRegister(UserRegisterParam userRegisterParam) {
    		String username = userRegisterParam.getUsername();
    		String password = userRegisterParam.getPassword();
    		
    		//校验账号
    		if(!CheckUtils.checkUsername(username)) {
    			return ResultUtils.error("账号不合法,请输入6-16个字母和数字的组合");
    		}
    			//校验账号是否存在
    		if(userMapper.isExistUserNameByUsername(username)) {
    			return ResultUtils.error("账号已被占用了~");
    		}
    		//校验密码
    		if(!CheckUtils.checkPassword(password)) {
    			return ResultUtils.error("密码不合法,请输入6-20个字母和数字的组合");
    		}
    		return null;
    	}
    }
    

    数据校验工具类CheckUtils

    package cn.kooun.common;
    
    import org.springframework.util.StringUtils;
    
    /**
     * 	数据校验工具
     * @author HuangJingNa
     * @date 2019年12月20日 下午2:49:58
     *
     */
    public class CheckUtils {
    	/**
    	 * 	校验账户数据
    	 * @author HuangJingNa
    	 * @param username 
    	 * @date 2019年12月20日 下午2:50:11
    	 *
    	 * @return
    	 */
    	public static boolean checkUsername(String username) {
    		boolean flag = true;
    		if(StringUtils.isEmpty(username)) {
    			return !flag;
    		}
    		if(!username.matches("[0-9a-zA-Z]{6,16}")) {
    			return !flag;
    		}
    		return flag;
    	}
    	/**
    	 * 	校验密码数据
    	 * @author HuangJingNa
    	 * @date 2019年12月20日 下午3:28:00
    	 *
    	 * @param password
    	 * @return
    	 */
    	public static boolean checkPassword(String password) {
    		boolean flag = true;
    		if(StringUtils.isEmpty(password)) {
    			return !flag;
    		}
    		if(!password.matches("[0-9a-zA-Z]{6,20}")) {
    			return !flag;
    		}
    		return flag;
    	}
    
    }
    

    响应消息封装工具类

    响应返回的数据Result

    package cn.kooun.common.result;
    
    import lombok.Getter;
    import lombok.Setter;
    import lombok.ToString;
    
    /**
     * 	通用响应数据模型
     * @author HuangJingNa
     * @date 2019年12月20日 下午2:57:50
     *
     */
    @Setter
    @Getter
    @ToString
    public class Result {
    	/*
    	 * {
    	 * 	status: "success/error",
    	 * 	message: "友好提示消息",
    	 * 	result: "业务数据",
    	 *  jump: "跳转标记=> index(首页),login(登录页)"
    	 * }
    	 */
    	/**成功状态*/
    	public static final String STATUS_SUCCESS = "success";
    	/**错误状态*/
    	public static final String STATUS_ERROR = "error";
    	/**登录页跳转*/
    	public static final String JUMP_LOGIN = "login";
    	/**首页跳转*/
    	public static final String JUMP_INDEX = "index";
    	
    	
    	/**响应状态*/
    	private String status;
    	/**响应消息*/
    	private String message;
    	/**响应数据*/
    	private Object result;
    	/**跳转标识*/
    	private String jump;
    }
    

    工具类

    package cn.kooun.common.result;
    
    import cn.kooun.common.factory.ErrorResultFactory;
    import cn.kooun.common.factory.SuccessResultFactory;
    
    /**
     * 	业务响应标准类
     * @author HuangJingNa
     * @date 2019年12月20日 下午2:54:48
     *
     */
    public class ResultUtils {
    	/**
    	 * 	业务成功响应
    	 * @author HuangJingNa
    	 * @date 2019年12月20日 下午2:56:45
    	 *
    	 * @param string
    	 * @return
    	 */
    	public static Object success(String message) {
    		SuccessResult successResult = SuccessResultFactory.getInstance();
    		successResult.setMessage(message);
    		return successResult;
    	}
    	/**
    	 * 	业务成功响应
    	 * @author HuangJingNa
    	 * @date 2019年12月20日 下午2:56:45
    	 *
    	 * @param string
    	 * @return
    	 */
    	public static Object success(String message, String jump) {
    		SuccessResult successResult = SuccessResultFactory.getInstance();
    		successResult.setMessage(message);
    		successResult.setJump(jump);
    		return successResult;
    	}
    	/**
    	 * 	业务错误响应
    	 * @author HuangJingNa
    	 * @date 2019年12月20日 下午3:30:09
    	 *
    	 * @param string
    	 * @return
    	 */
    	public static Object error(String message) {
    		ErrorResult errorResult = ErrorResultFactory.getInstance();
    		errorResult.setMessage(message);
    		return errorResult;
    	}
    	/**
    	 * 	业务成功响应
    	 * @author HuangJingNa
    	 * @date 2019年12月20日 下午7:57:51
    	 *
    	 * @param string
    	 * @param jumpIndex
    	 * @param ticket
    	 * @return
    	 */
    	public static Object success(
    			String message,
    			String jump, 
    			Object result) {
    		SuccessResult successResult = SuccessResultFactory.getInstance();
    		successResult.setMessage(message);
    		successResult.setJump(jump);
    		successResult.setResult(result);
    		return successResult;
    	}
    }
    

    成功数据封装

    package cn.kooun.common.result;
    
    /**
     * 	成功业务封装数据
     * @author HuangJingNa
     * @date 2019年12月20日 下午3:01:58
     *
     */
    public class SuccessResult extends Result{
    	{
    		this.setStatus(Result.STATUS_SUCCESS);
    	}
    }
    

    错误数据封装

    package cn.kooun.common.result;
    
    /**
     * 	错误业务封装数据
     * @author HuangJingNa
     * @date 2019年12月20日 下午3:01:58
     *
     */
    public class ErrorResult extends Result{
    	{
    		this.setStatus(Result.STATUS_ERROR);
    	}
    }
    

    由于要多次创建对象,则使用工厂模式

    抽象工厂

    package cn.kooun.common.factory;
    
    /**
     * 	响应结果抽象工厂
     * @author HuangJingNa
     * @date 2019年12月20日 下午3:11:37
     *
     */
    public interface Factory<T> {
    	/**
    	 *	 创建具体实例
    	 * @author HuangJingNa
    	 * @date 2019年12月20日 下午3:12:50
    	 *
    	 * @return
    	 */
    	T newInstance();
    }
    

    成功响应实例工厂

    package cn.kooun.common.factory;
    
    import cn.kooun.common.result.SuccessResult;
    
    /**
     * 	成功响应数据工厂
     * @author HuangJingNa
     * @date 2019年12月20日 下午3:31:15
     *
     */
    public class SuccessResultFactory implements Factory<SuccessResult> {
    	//懒汉式
    	private static SuccessResultFactory successResultFactory;
    	static{
    		if(successResultFactory == null) {
    			successResultFactory = new SuccessResultFactory();
    		}
    	}
    	
    	/**
    	 * 	创建具体实例
    	 */
    	public SuccessResult newInstance() {
    		return new SuccessResult();
    	}
    
    	/**
    	 * 	创建具体实例
    	 */
    	public static SuccessResult getInstance() {
    		return new SuccessResultFactory().newInstance();
    	}
    }
    

    失败响应实例工厂

    package cn.kooun.common.factory;
    
    import cn.kooun.common.result.ErrorResult;
    
    /**
     * 	错误响应数据工厂
     * @author HuangJingNa
     * @date 2019年12月20日 下午3:31:07
     *
     */
    public class ErrorResultFactory implements Factory<ErrorResult> {
    	private static ErrorResultFactory errorResultFactory;
    	static{
    		if(errorResultFactory == null) {
    			errorResultFactory = new ErrorResultFactory();
    		}
    	}
    	
    	/**
    	 * 	创建具体实例
    	 */
    	public ErrorResult newInstance() {
    		return new ErrorResult();
    	}
    
    	/**
    	 * 	创建具体实例
    	 */
    	public static ErrorResult getInstance() {
    		return new ErrorResultFactory().newInstance();
    	}
    }
    

    三、使用逆向工程生成pojo类和mapper接口及mapper.xml文件

    逆向工程的生成:https://www.jianshu.com/p/c61f0bf1efe0
    数据库创建表通常都有的字段封装到一个基础表类中(BaseTable),要实现序列化,便于客户端使用json数据(要求实现序列化以及拥有序列化id)响应

    package cn.kooun.pojo.table.base;
    
    import java.io.Serializable;
    import java.util.Date;
    
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    
    import lombok.Getter;
    import lombok.Setter;
    import lombok.ToString;
    
    /**
     * 	基础表
     *	需要实现序列化,给与一个序列化id
     * @author HuangJingNa
     * @date 2019年12月20日 下午2:30:37
     *
     */
    @Setter
    @Getter
    @ToString
    public class BaseTable implements Serializable{
    	
    	//由于createTime和updateTime每次创建对象的时候需要赋值
    	//可以使用构造代码块,避免每次创建对象时都需要set
    	{
    		this.setCreateTime(new Date());
    		this.setUpdateTime(new Date());
    	}
    
    	private static final long serialVersionUID = 8533571383425561865L;
    	
    	@Id
    	@GeneratedValue(strategy=GenerationType.IDENTITY,generator="Mysql")
    	private String id;
    	
    	//@Column(name = "create_time")//告诉通用mapper此变量对应表的字段名
    	//这里开启了驼峰命名,可以省略以上步骤
    	private Date createTime;
    	
    	private Date updateTime;
    }
    

    pojo类:User.java

    package cn.kooun.pojo.table;
    
    import javax.persistence.Table;
    
    import cn.kooun.pojo.table.base.BaseTable;
    import lombok.Getter;
    import lombok.Setter;
    import lombok.ToString;
    
    /**
     * 	用户表
     * @author HuangJingNa
     * @date 2019年12月20日 下午2:32:09
     * 	1.通过lombok日志包可以通过注解动态生成get&set方法,但是需要注明是哪一张表,方便映射
     * 	2.开启驼峰命名,可以在类和数据库中将两个单词通过_连接,改为小驼峰命名,
     * 	    同时可以省略注解@Column(name = "create_time")
     * 	3.主键需要注明,以及自动增长
     */
    @Setter
    @Getter
    @ToString
    //@Data  //@Setter+@Getter+@ToString等的集合体
    @Table(name = "u_user")
    public class User extends BaseTable{
    	private static final long serialVersionUID = -2649200110993098831L;
    	/**账号名称*/
    	private String username;
    	/**账号密码*/
    	private String password;
    	/**账号类型*/
    	private Integer type;
    	/**账号昵称*/
    	private String nickName;
    
    }
    

    mapper接口:UserMapper.java

    package cn.kooun.mapper;
    
    import org.apache.ibatis.annotations.Param;
    import org.apache.ibatis.annotations.Select;
    
    import cn.kooun.pojo.table.User;
    import tk.mybatis.mapper.common.Mapper;
    /**
     * 	用户mapper
     * 	1.需要继承通过Mapper的泛型类,可以获取其本身拥有的增删改查操作
     * @author HuangJingNa
     * @date 2019年12月20日 下午3:44:22
     *
     */
    public interface UserMapper extends Mapper<User>{
    	/**
    	 *	 判断该用户是否存在
    	 * @author HuangJingNa
    	 * @date 2019年12月20日 下午3:44:02
    	 *
    	 * @param username
    	 * @return
    	 */
    	@Select("SELECT " + 
    			"	CASE COUNT(u.id) WHEN 0 THEN 0 ELSE 1 END" + 
    			" FROM u_user u" + 
    			" WHERE u.username = #{username}")
    	boolean isExistUserNameByUsername(@Param("username")String username);
    }
    

    mapper.xml文件:UserMapper.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="cn.kooun.mapper.UserMapper">
      
    </mapper>
    
  • 相关阅读:
    vue 重定向
    vue 通过插槽分发内容
    vue 表单输入绑定 checkbox
    jq enter键发送
    vue footer点击变色
    vue computed和methods 计算属性和侦听器
    实时监听input输入情况
    关于Input输入框蓝色外框的操作
    鼠标悬浮指针变手
    鼠标悬浮样式
  • 原文地址:https://www.cnblogs.com/nadou/p/14000976.html
Copyright © 2020-2023  润新知