Netty+SpringBoot+FastDFS+Html5实现聊天App详解(二)

40次阅读

共计 5516 个字符,预计需要花费 14 分钟才能阅读完成。

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;
}

正文完
 0