Netty+SpringBoot+FastDFS+Html5實現聊天App,項目介紹。
Netty+SpringBoot+FastDFS+Html5實現聊天App,項目github鏈接。
本章完整代碼
本節主要講解聊天App PigChat中關於用戶信息處理,以及文件服務器FastDFS的相關操作。
包含以下內容:
(1)註冊與登錄功能
(2)文件服務器的配置
(3)上傳用戶頭像
(4)設置用戶暱稱
(5)用戶二維碼的生成與上傳
註冊與登錄功能
自定義一個工具類IMoocJSONResult,是後端響應前端的數據結構。
包含下面三個屬性:
// 響應業務狀態
private Integer status;
// 響應消息
private String msg;
// 響應中的數據
private Object data;
提供錯誤響應與正常響應的方法:
public static IMoocJSONResult ok(Object data) {
return new IMoocJSONResult(data);
}
public static IMoocJSONResult ok() {
return new IMoocJSONResult(null);
}
public static IMoocJSONResult errorMsg(String msg) {
return new IMoocJSONResult(500, msg, null);
}
public static IMoocJSONResult errorMap(Object data) {
return new IMoocJSONResult(501, "error", data);
}
public static IMoocJSONResult errorTokenMsg(String msg) {
return new IMoocJSONResult(502, msg, null);
}
public static IMoocJSONResult errorException(String msg) {
return new IMoocJSONResult(555, msg, null);
}
根據數據庫所建的表創建對應的pojo包與mapper包,數據庫建表詳情
創建UserController方法,寫入進行註冊於登錄處理的registOrLogin接口。
【0】前端傳入Users對象,首先判斷前端傳入的Users對象是否爲空。
【1】然後通過userService的queryUsernameIsExist方法根據傳入的用戶名在數據庫中進行查詢。
【1.1】若該用戶存在則進行登錄,通過userService的queryUserForLogin方法判斷前端傳入的用戶名與密碼試湊匹配,若匹配則登錄成功,否則登錄失敗。
【1.2】若該用戶不存在則記性註冊,根據前端傳入的信息構建Users對象,通過userService的saveUser將其保存入數據庫中。
【2】最後構造UsersVO對象,返回給前端。
注意:密碼需要使用MD5工具類進行加密後再保存到數據庫中。
/**
* @Description: 用戶註冊/登錄
*/
@PostMapping("/registOrLogin")
public IMoocJSONResult registOrLogin(@RequestBody Users user) throws Exception {
// 0. 判斷用戶名和密碼不能爲空
if (StringUtils.isBlank(user.getUsername())
|| StringUtils.isBlank(user.getPassword())) {
return IMoocJSONResult.errorMsg("用戶名或密碼不能爲空...");
}
// 1. 判斷用戶名是否存在,如果存在就登錄,如果不存在則註冊
boolean usernameIsExist = userService.queryUsernameIsExist(user.getUsername());
Users userResult = null;
if (usernameIsExist) {
// 1.1 登錄
userResult = userService.queryUserForLogin(user.getUsername(),
MD5Utils.getMD5Str(user.getPassword()));
if (userResult == null) {
return IMoocJSONResult.errorMsg("用戶名或密碼不正確...");
}
} else {
// 1.2 註冊
user.setNickname(user.getUsername());
user.setFaceImage("");
user.setFaceImageBig("");
user.setPassword(MD5Utils.getMD5Str(user.getPassword()));
userResult = userService.saveUser(user);
}
// 2.構造UsersVO對象
UsersVO userVO = new UsersVO();
BeanUtils.copyProperties(userResult, userVO);
return IMoocJSONResult.ok(userVO);
}
文件服務器的配置
在linux中配置好文件服務器FastDFS後,需要在項目中添加如下配置:
(1)在Application同目錄下創建FastdfsImporter
package com.imooc;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableMBeanExport;
import org.springframework.context.annotation.Import;
import org.springframework.jmx.support.RegistrationPolicy;
import com.github.tobato.fastdfs.FdfsClientConfig;
/**
* 導入FastDFS-Client組件
*
* @author tobato
*
*/
@Configuration
@Import(FdfsClientConfig.class)
// 解決jmx重複註冊bean的問題
@EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)
public class FastdfsImporter {
// 導入依賴組件
}
(2)在application.properties中添加如下配置:
fdfs.soTimeout=1501
fdfs.connectTimeout=601
fdfs.thumbImage.width=80
fdfs.thumbImage.height=80
# 192.168.1.70爲Linux虛擬機的ip地址
fdfs.trackerList[0]=192.168.1.70:22122
啓動服務命令:
/usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf
/usr/bin/fdfs_storaged /etc/fdfs/storage.conf
#查看服務啓動情況(23000/22122端口)
netstat -lnp |grep fdfs
cd /usr/local/nginx/sbin
./nginx
上傳用戶頭像
在UserController中添加上傳用戶頭像的uploadFaceBase64接口。
【1】前端傳入UserBO對象,首先獲取前端傳來的base64字符串,並通過文件工具類FileUtils的base64ToFile方法將其轉換成文件對象保存在本地。
【2】將文件對象轉換成MultipartFile,並通過fastDFSClient的uploadBase64方法將其上傳到文件服務器fastDFS中,打印出服務器返回的路徑,我們可以通過這個路徑訪問這張圖片。
【3】對返回的路徑進行切割後得到縮略圖的路徑。
【4】更新數據庫中用戶頭像信息。
/**
* @Description: 上傳用戶頭像
*/
@PostMapping("/uploadFaceBase64")
public IMoocJSONResult uploadFaceBase64(@RequestBody UsersBO userBO) throws Exception {
// 1. 獲取前端傳過來的base64字符串, 然後轉換爲文件對象再上傳
String base64Data = userBO.getFaceData();
// 在本地存儲圖片的路徑
String userFacePath = "C:\\" + userBO.getUserId() + "userface64.png";
FileUtils.base64ToFile(userFacePath, base64Data);
// 2.上傳文件到fastdfs
MultipartFile faceFile = FileUtils.fileToMultipart(userFacePath);
String url = fastDFSClient.uploadBase64(faceFile);
System.out.println(url);
// "dhawuidhwaiuh3u89u98432.png"
// "dhawuidhwaiuh3u89u98432_80x80.png"
// 3.獲取縮略圖的url
String thump = "_80x80.";
String arr[] = url.split("\\.");
String thumpImgUrl = arr[0] + thump + arr[1];
// 4.更新用戶頭像
Users user = new Users();
user.setId(userBO.getUserId());
user.setFaceImage(thumpImgUrl);
user.setFaceImageBig(url);
Users result = userService.updateUserInfo(user);
return IMoocJSONResult.ok(result);
}
設置用戶暱稱
在UserController添加設置用戶暱稱的setNickname接口。
/**
* @Description: 設置用戶暱稱
*/
@PostMapping("/setNickname")
public IMoocJSONResult setNickname(@RequestBody UsersBO userBO) throws Exception {
Users user = new Users();
user.setId(userBO.getUserId());
user.setNickname(userBO.getNickname());
Users result = userService.updateUserInfo(user);
return IMoocJSONResult.ok(result);
}
用戶二維碼的生成與上傳
在UserServiceImpl中引入相關工具類與組件
//二維碼工具類
@Autowired
private QRCodeUtils qrCodeUtils;
//上傳文件到fsatDFS需要的組件
@Autowired
private FastDFSClient fastDFSClient;
在UserServiceImpl保存用戶信息的saveUser方法中需要爲每一個用戶生成一個唯一的二維碼。
【1】通過二維碼工具類qrCodeUtils的createQRCode方法爲每個用戶生成一個唯一的二維碼,第一個參數爲生成的二維碼存儲的路徑,第二個參數爲二維碼中保存的信息,然後將文件轉成MultipartFile對象,方便上傳操作。
【2】通過fastDFSClient的uploadQRCode方法將二維碼圖片上傳到文件服務器中。
@Transactional(propagation = Propagation.REQUIRED)
@Override
public Users saveUser(Users user) {
//生成唯一的id
String userId = sid.nextShort();
// 1.爲每個用戶生成一個唯一的二維碼
//本地用來存儲生成的二維碼圖片的路徑
String qrCodePath = "C://user" + userId + "qrcode.png";
// 掃描二維碼後得到的信息:zhuzhu_qrcode:[username]
qrCodeUtils.createQRCode(qrCodePath, "zhuzhu_qrcode:" + user.getUsername());
MultipartFile qrCodeFile = FileUtils.fileToMultipart(qrCodePath);
//2.上傳文件
String qrCodeUrl = "";
try {
qrCodeUrl = fastDFSClient.uploadQRCode(qrCodeFile);
} catch (IOException e) {
e.printStackTrace();
}
user.setQrcode(qrCodeUrl);
user.setId(userId);
userMapper.insert(user);
return user;
}