springboot項(xiàng)目整合注冊(cè)功能模塊開發(fā)實(shí)戰(zhàn)
工程簡(jiǎn)介
準(zhǔn)備工作:
項(xiàng)目所用到的html界面以及sql文件鏈接如下:
百度網(wǎng)盤獲取地址:
鏈接: https://pan.baidu.com/s/1CcbQWP8RNqyy3ieib1osLg?pwd=t1qu 提取碼: t1qu
第一步:注冊(cè)功能的實(shí)現(xiàn)
1.1持久層的設(shè)計(jì)
1.1.1規(guī)范需要執(zhí)行的SQL語(yǔ)句
1.用戶的注冊(cè)工作,相當(dāng)于在做數(shù)據(jù)的插入操作
insert into t_user (username,password) values (?,?)
2.在用戶的注冊(cè)是首先需要查詢當(dāng)前的用戶名是否存在,如果存在則不能進(jìn)行注冊(cè),相當(dāng)于一個(gè)查詢語(yǔ)句
select * from t_user where username = ?
1.1.2設(shè)計(jì)接口和抽象方法
定義mapper接口,在項(xiàng)目的目錄結(jié)構(gòu)下首先創(chuàng)建一個(gè)mapper包,在這個(gè)包下根據(jù)不同的功能模塊來(lái)創(chuàng)建mapper接口
1.創(chuàng)建一個(gè)userMapper 需要考慮上述的兩個(gè)注意點(diǎn)
package com.cy.store.mapper;
import com.cy.store.pojo.User;
/**
* 用戶模塊的持久化層接口
*/
public interface UserMapper {
/**
* 插入用戶的數(shù)據(jù)->用來(lái)實(shí)現(xiàn)注冊(cè)功能
* @param user
* @return 受到影響的行數(shù)(增刪改查 )
*/
Integer insert(User user);
/**
* 根據(jù)用戶名查詢用戶的數(shù)據(jù)
* @param username
* @return 如果找到了則返回相對(duì)應(yīng)的用戶信息,找不到返回null
*/
User findByUsername(String username);
}1.1.3 編寫映射
1.定義xml映射文件,與對(duì)應(yīng)的接口進(jìn)行關(guān)聯(lián).所有餓映射文件需要放置在resource目錄下,一般為了方便管理,一般在這個(gè)目錄下創(chuàng)建一個(gè)mapper文件夾,然后在找這個(gè)文件夾存放相應(yīng)的mapper 文件
2.創(chuàng)建接口的對(duì)應(yīng)的映射文件,規(guī)則:和接口的名稱保持一致即可,創(chuàng)建一個(gè)UserMapper.xml
1.1.4 單元測(cè)試
1.每個(gè)獨(dú)立的層編寫完畢需要編寫單元測(cè)試方法,來(lái)測(cè)試當(dāng)前的功能, 在test包下創(chuàng)建一個(gè)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方法上加上這個(gè)注解: @Repository
*/
@Autowired
private UserMapper userMapper;
/**
* @Dat 2022年11月2日17:25:41
* 測(cè)試成功
*/
@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 查詢的結(jié)果為:User(uid=1, username=tom, password=123456, salt=null, phone=null, email=null, gender=null, avatar=null, isDelete=null)
* 測(cè)試成功
*/
@Test
public void testFindByUsername(){
User tom = userMapper.findByUsername("tom");
log.info("查詢的結(jié)果為:{}",tom);
}
}
1.2注冊(cè)功能-業(yè)務(wù)層
1.2.1 規(guī)劃異常
1.runtimeException異常,作為這個(gè)異常的子類,然后在定義具體的異常類型來(lái)繼承這個(gè)異常,業(yè)務(wù)層異常的基類
serviceException異常,這個(gè)異常繼承RuntimeException異常,以此建立異常的機(jī)制。
2.用戶在進(jìn)行注冊(cè)時(shí)候可能會(huì)產(chǎn)生用戶名被占用的錯(cuò)誤,拋出一個(gè)異常 UsernameDuplicatedException
3.正在執(zhí)行數(shù)據(jù)插入操作的時(shí)候,服務(wù)器、數(shù)據(jù)庫(kù)宕機(jī)。處于正在執(zhí)行插入的過程中,所產(chǎn)生的異常InsertException
1.2.2 設(shè)計(jì)接口和抽象方法
1.在service包下創(chuàng)建一個(gè)IUserService
2.設(shè)計(jì)一個(gè)實(shí)現(xiàn)類的包
3.實(shí)現(xiàn)類中重寫 注冊(cè)方法實(shí)現(xiàn)完全的用戶注冊(cè)邏輯
@Override
public void reg(User user) {
//調(diào)用findByUsernam 方法 判斷用戶名是否被注冊(cè)過
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("在用戶注冊(cè)中產(chǎn)生了位置的異常");
}
}1.2.3 在單元測(cè)試中創(chuàng)建UserServiceTest類 進(jìn)行相應(yīng)的注冊(cè)邏輯進(jìn)行測(cè)試
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 測(cè)試用戶注冊(cè)的功能 成功返回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());
//打印錯(cuò)誤信息
System.out.println(e.getMessage());
}
}
}
1.3控制層
1.3.1 創(chuàng)建響應(yīng)
1.狀態(tài)碼、狀態(tài)描述信息、數(shù)據(jù),這部分功能封裝在一個(gè)類中,將這類方法作為方法返回值,返回給前端瀏覽器 com.cy.store.StoreApplication
1.3.2. 設(shè)計(jì)請(qǐng)求
依據(jù)當(dāng)前的業(yè)務(wù)功能模塊進(jìn)行請(qǐng)求的設(shè)計(jì)
請(qǐng)求的路徑: /user/reg
請(qǐng)求參數(shù): User user
請(qǐng)求類型: Post
響應(yīng)結(jié)果:JsonResult<void>
1.3.3 處理請(qǐng)求
1.創(chuàng)建一個(gè)控制層的對(duì)應(yīng)的類 UserController com.cy.store.controller.UserController
try {
userService.reg(user);
voidJsonResult.setState(200);
voidJsonResult.setMessage("用戶注冊(cè)成功");
} catch (UsernameDuplicatedException e) {
voidJsonResult.setState(4000);
voidJsonResult.setMessage("用戶名被占用");
}
catch (InsertException e) {
voidJsonResult.setState(5000);
voidJsonResult.setMessage("注冊(cè)時(shí)發(fā)生未知的異常");
}業(yè)務(wù)邏輯過于復(fù)雜 進(jìn)行簡(jiǎn)化
1.3.4 控制層優(yōu)化設(shè)計(jì)
在控制層抽離一個(gè)父類,在這個(gè)父類中統(tǒng)一的處理關(guān)于異常的相關(guān)操作,編寫一個(gè)BaseController類,在這個(gè)類中,統(tǒng)一的處理異常
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
*
* 用來(lái)表示控制層類的基類
*
*/
public class BaseController {
public static final int OK = 200; //表示操作成功的狀態(tài)碼
//請(qǐng)求處理方法,這個(gè)方法的返回值就是需要傳遞給前端的數(shù)據(jù)
//當(dāng)項(xiàng)目中產(chǎn)生異常時(shí),會(huì)被攔截到此方法 這個(gè)方法此時(shí)充當(dāng)?shù)木褪钦?qǐng)求處理方法 方法的返回值直接給到前端
@ExceptionHandler(ServiceException.class) // 主要用于統(tǒng)一處理拋出的異常
public JsonResult<Void> handleException(Throwable e){
JsonResult<Void> result = new JsonResult<>(e);
if (e instanceof UsernameDuplicatedException){
result.setState(4000);
result.setMessage("用戶名已經(jīng)被占用");
}else if (e instanceof InsertException){
result.setState(5000);
result.setMessage("注冊(cè)時(shí)發(fā)生未知的異常");
}
return result;
}
}修改后的controller - userController 的代碼如下;
@RestController
@RequestMapping("users")
public class UserController extends BaseController{
@Autowired
private IUserService userService;
/**
* 原先的代碼
*
* @RequestMapping("reg")
public JsonResult<Void> reg(User user){
//創(chuàng)建結(jié)果響應(yīng)對(duì)象
JsonResult<Void> voidJsonResult = new JsonResult<>();
try {
userService.reg(user);
voidJsonResult.setState(200);
voidJsonResult.setMessage("用戶注冊(cè)成功");
} catch (UsernameDuplicatedException e) {
voidJsonResult.setState(4000);
voidJsonResult.setMessage("用戶名被占用");
}
catch (InsertException e) {
voidJsonResult.setState(5000);
voidJsonResult.setMessage("注冊(cè)時(shí)發(fā)生未知的異常");
}
return voidJsonResult;
}**/
/**
* 優(yōu)化以后的代碼
* @param user
* @return
*/
@RequestMapping("reg")
public JsonResult<Void> reg(User user) {
userService.reg(user);
return new JsonResult<>(OK);
}
}妙不可言?。。。。。。。。?!
1.4前端頁(yè)面的設(shè)計(jì)
1.在register頁(yè)面中編寫發(fā)送請(qǐng)求的方法,后端接收方法為reg,當(dāng)檢測(cè)中點(diǎn)擊事件后觸發(fā)請(qǐng)求--》 點(diǎn)擊事件
選擇對(duì)應(yīng)的按鍵(%(“選擇器”)),再去添加點(diǎn)擊的事件,$.ajax()函數(shù)發(fā)送異步請(qǐng)求額
2.JQuery封裝了一個(gè)函數(shù),稱為$.ajax()函數(shù),通過對(duì)象調(diào)用ajax函數(shù),可以異步的加載一個(gè)請(qǐng)求,依靠的是JAVAScript提供的一個(gè)xhr(xmlHttpResponse),封裝了這個(gè)對(duì)象
3.ajax()使用方法: 需要傳遞一個(gè)方法體作為一個(gè)方法的參數(shù)使用:一對(duì)大括號(hào)被稱為方法體.ajax接收多個(gè)參數(shù),參數(shù)之間要求使用","進(jìn)行分割,每一組參數(shù)之間使用":"進(jìn)行分割
。參數(shù)的組成部分一個(gè)是參數(shù)的名稱(不能隨意更改),參數(shù)的值要求是用字符串來(lái)標(biāo)識(shí)。參數(shù)的聲明順序沒有要求 。語(yǔ)法結(jié)構(gòu)如下:
$.ajax({
url: "",
type: "",
dataType: "",
success: function() {
},
error:function() {
}
});4.ajax函數(shù)參數(shù)的含義
url : 標(biāo)識(shí)請(qǐng)求的地址(url地址)。不能包括列表部分的內(nèi)容 例如: url:"localhost:8080/users/reg"
type: 請(qǐng)求類型(GET 和 POST 請(qǐng)求類型) 例如: type:"POST"
data: 向指定的請(qǐng)求url地址提交的數(shù)據(jù): 例如: data:"username="tom"&password="123456""
dataType:提交的數(shù)據(jù)的類型 例如:"json"
success:當(dāng)服務(wù)器正常響應(yīng)客戶端時(shí),將會(huì)自動(dòng)調(diào)用success方法,并且將服務(wù)器返回的數(shù)據(jù)以參數(shù)的形式傳遞給這個(gè)方法的參數(shù)上
error:當(dāng)服務(wù)器異常響應(yīng)客戶端時(shí),將會(huì)自動(dòng)調(diào)用error方法,并且將服務(wù)器返回的數(shù)據(jù)以參數(shù)的形式傳遞給這個(gè)方法的參數(shù)上
5.js代碼可以獨(dú)立聲明在一個(gè)js的文件里或者聲明在一個(gè)script標(biāo)簽中
注冊(cè)功能實(shí)現(xiàn)完成


到此這篇關(guān)于springboot項(xiàng)目整合注冊(cè)功能模塊開發(fā)的文章就介紹到這了,更多相關(guān)springboot注冊(cè)模塊內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Visual?Studio?Code配置Tomcat運(yùn)行Java?Web項(xiàng)目詳細(xì)步驟
VS Code是一款非常棒的文本編輯器,具有配置簡(jiǎn)單、功能豐富、輕量簡(jiǎn)潔的特點(diǎn),并且極其適合處理中小規(guī)模的代碼,這篇文章主要給大家介紹了關(guān)于Visual?Studio?Code配置Tomcat運(yùn)行Java?Web項(xiàng)目的詳細(xì)步驟,需要的朋友可以參考下2023-11-11
idea導(dǎo)入項(xiàng)目爆紅問題記錄以及解決
這篇文章主要介紹了idea導(dǎo)入項(xiàng)目爆紅問題記錄以及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07
springcloud?gateway無(wú)法路由問題的解決
gateway網(wǎng)關(guān)的重要作用之一便是進(jìn)行路由轉(zhuǎn)發(fā)工作,下面這篇文章主要給大家介紹了關(guān)于springcloud?gateway無(wú)法路由問題的解決方法,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-05-05
myeclipse中使用maven前常見錯(cuò)誤及解決辦法
這篇文章主要介紹了myeclipse中使用maven前常見錯(cuò)誤及解決辦法 的相關(guān)資料,需要的朋友可以參考下2016-05-05
SpringBoot創(chuàng)建監(jiān)聽器的方法示例
在Java中,監(jiān)聽器(Listener)是一種設(shè)計(jì)模式,它允許對(duì)象在 特定事件 發(fā)生時(shí) 自動(dòng)執(zhí)行某些操作,這種設(shè)計(jì)模式通常用于實(shí)現(xiàn) 發(fā)布-訂閱模型,本文給大家介紹了SpringBoot創(chuàng)建監(jiān)聽器的方法示例,感興趣的通過可以參考一下2024-04-04
關(guān)于mybatis3中幾個(gè)@Provider的使用方式
這篇文章主要介紹了關(guān)于mybatis3中幾個(gè)@Provider的使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07

