springboot项目整合注册功能模块开发实战
wiselee/ 人气:0工程简介
准备工作:
项目所用到的html界面以及sql文件链接如下:
百度网盘获取地址:
链接: http://pan.baidu.com/s/1CcbQWP8RNqyy3ieib1osLg?pwd=t1qu 提取码: t1qu
第一步:注册功能的实现
1.1持久层的设计
1.1.1规范需要执行的SQL语句
1.用户的注册工作,相当于在做数据的插入操作
insert into t_user (username,password) values (?,?)
2.在用户的注册是首先需要查询当前的用户名是否存在,如果存在则不能进行注册,相当于一个查询语句
select * from t_user where username = ?
1.1.2设计接口和抽象方法
定义mapper接口,在项目的目录结构下首先创建一个mapper包,在这个包下根据不同的功能模块来创建mapper接口
1.创建一个userMapper 需要考虑上述的两个注意点
package com.cy.store.mapper; import com.cy.store.pojo.User; /** * 用户模块的持久化层接口 */ public interface UserMapper { /** * 插入用户的数据->用来实现注册功能 * @param user * @return 受到影响的行数(增删改查 ) */ Integer insert(User user); /** * 根据用户名查询用户的数据 * @param username * @return 如果找到了则返回相对应的用户信息,找不到返回null */ User findByUsername(String username); }
1.1.3 编写映射
1.定义xml映射文件,与对应的接口进行关联.所有饿映射文件需要放置在resource目录下,一般为了方便管理,一般在这个目录下创建一个mapper文件夹,然后在找这个文件夹存放相应的mapper 文件
2.创建接口的对应的映射文件,规则:和接口的名称保持一致即可,创建一个UserMapper.xml
1.1.4 单元测试
1.每个独立的层编写完毕需要编写单元测试方法,来测试当前的功能, 在test包下创建一个mapper包
包:test-com.cy.store.mapper.UserMapperTest
package com.cy.store.mapper; import com.cy.store.pojo.User; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; /** * @PROJECT_NAME: store * @DESCRIPTION: * @USER: 28416 * @DATE: 2022/11/2 16:43 */ @Slf4j @SpringBootTest public class UserMapperTest { /** * 在mapper方法上加上这个注解: @Repository */ @Autowired private UserMapper userMapper; /** * @Dat 2022年11月2日17:25:41 * 测试成功 */ @Test public void insert(){ User user = new User(); user.setUsername("tom"); user.setPassword("123456"); Integer insert = userMapper.insert(user); log.info("插入返回的值:{}",insert); } /** * @Date 2022年11月2日17:27:25 * @return 查询的结果为:User(uid=1, username=tom, password=123456, salt=null, phone=null, email=null, gender=null, avatar=null, isDelete=null) * 测试成功 */ @Test public void testFindByUsername(){ User tom = userMapper.findByUsername("tom"); log.info("查询的结果为:{}",tom); } }
1.2注册功能-业务层
1.2.1 规划异常
1.runtimeException异常,作为这个异常的子类,然后在定义具体的异常类型来继承这个异常,业务层异常的基类
serviceException异常,这个异常继承RuntimeException异常,以此建立异常的机制。
2.用户在进行注册时候可能会产生用户名被占用的错误,抛出一个异常 UsernameDuplicatedException
3.正在执行数据插入操作的时候,服务器、数据库宕机。处于正在执行插入的过程中,所产生的异常InsertException
1.2.2 设计接口和抽象方法
1.在service包下创建一个IUserService
2.设计一个实现类的包
3.实现类中重写 注册方法实现完全的用户注册逻辑
@Override public void reg(User user) { //调用findByUsernam 方法 判断用户名是否被注册过 String username = user.getUsername(); User byUsername = userMapper.findByUsername(username); if (byUsername != null){ throw new UsernameDuplicatedException("用户名被占用"); } Integer insert = userMapper.insert(user); if (insert != 1){ throw new InsertException("在用户注册中产生了位置的异常"); } }
1.2.3 在单元测试中创建UserServiceTest类 进行相应的注册逻辑进行测试
package com.cy.store.service; import com.cy.store.pojo.User; import com.cy.store.service.ex.ServiceException; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; /** * @PROJECT_NAME: store * @DESCRIPTION: * @USER: 28416 * @DATE: 2022/11/2 18:15 */ @SpringBootTest public class UserServiceTest { @Autowired private IUserService userService; /** * @Date 2022年11月2日19:25:39 * @return UsernameDuplicatedException * @return 测试用户注册的功能 成功返回1 or 返回自定义的exception * / * */ @Test public void reg(){ try { User user = new User(); user.setUsername("Lux"); user.setPassword("123456"); userService.reg(user); System.out.println("ok"); } catch (ServiceException e) { //获取异常的类名 System.out.println(e.getClass().getSimpleName()); //打印错误信息 System.out.println(e.getMessage()); } } }
1.3控制层
1.3.1 创建响应
1.状态码、状态描述信息、数据,这部分功能封装在一个类中,将这类方法作为方法返回值,返回给前端浏览器 com.cy.store.StoreApplication
1.3.2. 设计请求
依据当前的业务功能模块进行请求的设计
请求的路径: /user/reg
请求参数: User user
请求类型: Post
响应结果:JsonResult<void>
1.3.3 处理请求
1.创建一个控制层的对应的类 UserController com.cy.store.controller.UserController
try { userService.reg(user); voidJsonResult.setState(200); voidJsonResult.setMessage("用户注册成功"); } catch (UsernameDuplicatedException e) { voidJsonResult.setState(4000); voidJsonResult.setMessage("用户名被占用"); } catch (InsertException e) { voidJsonResult.setState(5000); voidJsonResult.setMessage("注册时发生未知的异常"); }
业务逻辑过于复杂 进行简化
1.3.4 控制层优化设计
在控制层抽离一个父类,在这个父类中统一的处理关于异常的相关操作,编写一个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.web.bind.annotation.ExceptionHandler; /** * @PROJECT_NAME: store * @DESCRIPTION: * @USER: 28416 * @DATE: 2022/11/2 20:34 * * 用来表示控制层类的基类 * */ public class BaseController { public static final int OK = 200; //表示操作成功的状态码 //请求处理方法,这个方法的返回值就是需要传递给前端的数据 //当项目中产生异常时,会被拦截到此方法 这个方法此时充当的就是请求处理方法 方法的返回值直接给到前端 @ExceptionHandler(ServiceException.class) // 主要用于统一处理抛出的异常 public JsonResult<Void> handleException(Throwable e){ JsonResult<Void> result = new JsonResult<>(e); if (e instanceof UsernameDuplicatedException){ result.setState(4000); result.setMessage("用户名已经被占用"); }else if (e instanceof InsertException){ result.setState(5000); result.setMessage("注册时发生未知的异常"); } return result; } }
修改后的controller - userController 的代码如下;
@RestController @RequestMapping("users") public class UserController extends BaseController{ @Autowired private IUserService userService; /** * 原先的代码 * * @RequestMapping("reg") public JsonResult<Void> reg(User user){ //创建结果响应对象 JsonResult<Void> voidJsonResult = new JsonResult<>(); try { userService.reg(user); voidJsonResult.setState(200); voidJsonResult.setMessage("用户注册成功"); } catch (UsernameDuplicatedException e) { voidJsonResult.setState(4000); voidJsonResult.setMessage("用户名被占用"); } catch (InsertException e) { voidJsonResult.setState(5000); voidJsonResult.setMessage("注册时发生未知的异常"); } return voidJsonResult; }**/ /** * 优化以后的代码 * @param user * @return */ @RequestMapping("reg") public JsonResult<Void> reg(User user) { userService.reg(user); return new JsonResult<>(OK); } }
妙不可言!!!!!!!!!!
1.4前端页面的设计
1.在register页面中编写发送请求的方法,后端接收方法为reg,当检测中点击事件后触发请求--》 点击事件
选择对应的按键(%(“选择器”)),再去添加点击的事件,$.ajax()函数发送异步请求额
2.JQuery封装了一个函数,称为$.ajax()函数,通过对象调用ajax函数,可以异步的加载一个请求,依靠的是JAVAScript提供的一个xhr(xmlHttpResponse),封装了这个对象
3.ajax()使用方法: 需要传递一个方法体作为一个方法的参数使用:一对大括号被称为方法体.ajax接收多个参数,参数之间要求使用","进行分割,每一组参数之间使用":"进行分割
。参数的组成部分一个是参数的名称(不能随意更改),参数的值要求是用字符串来标识。参数的声明顺序没有要求 。语法结构如下:
$.ajax({ url: "", type: "", dataType: "", success: function() { }, error:function() { } });
4.ajax函数参数的含义
url : 标识请求的地址(url地址)。不能包括列表部分的内容 例如: url:"localhost:8080/users/reg"
type: 请求类型(GET 和 POST 请求类型) 例如: type:"POST"
data: 向指定的请求url地址提交的数据: 例如: data:"username="tom"&password="123456""
dataType:提交的数据的类型 例如:"json"
success:当服务器正常响应客户端时,将会自动调用success方法,并且将服务器返回的数据以参数的形式传递给这个方法的参数上
error:当服务器异常响应客户端时,将会自动调用error方法,并且将服务器返回的数据以参数的形式传递给这个方法的参数上
5.js代码可以独立声明在一个js的文件里或者声明在一个script标签中
注册功能实现完成
加载全部内容