设置用户的头像和修改密码功能
1.service层
UserService中添加updateHeader方法和changePassword方法。
package com.gerrard.community.service;
import com.gerrard.community.dao.UserMapper;
import com.gerrard.community.entity.LoginTicket;
import com.gerrard.community.entity.User;
import com.gerrard.community.util.CommunityConstant;
import com.gerrard.community.util.CommunityUtil;
import com.gerrard.community.util.MailClient;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
@Service
public class UserService implements CommunityConstant {
@Autowired
private UserMapper userMapper;
@Autowired
private MailClient mailClient;
@Autowired
private TemplateEngine templateEngine;
@Value("${community.path.domain}")
private String domain;
@Value("${server.servlet.context-path}")
private String contextPath;
@Autowired
private LoginTicketMapper loginTicketMapper;
public User findUserById(int id) {
return userMapper.selectById(id);
}
public Map<String, Object> register(User user) {
Map<String, Object> map = new HashMap<>();
// 空值处理
if (user == null) {
throw new IllegalArgumentException("参数不能为空!");
}
if (StringUtils.isBlank(user.getUsername())) {
map.put("usernameMsg", "账号不能为空!");
return map;
}
if (StringUtils.isBlank(user.getPassword())) {
map.put("passwordMsg", "密码不能为空!");
return map;
}
if (StringUtils.isBlank(user.getEmail())) {
map.put("emailMsg", "邮箱不能为空!");
return map;
}
// 验证账号
User u = userMapper.selectByName(user.getUsername());
if (u != null) {
map.put("usernameMsg", "该账号已存在!");
return map;
}
// 验证邮箱
u = userMapper.selectByEmail(user.getEmail());
if (u != null) {
map.put("emailMsg", "该邮箱已被注册!");
return map;
}
// 注册用户
user.setSalt(CommunityUtil.generateUUID().substring(0, 5));
user.setPassword(CommunityUtil.md5(user.getPassword() + user.getSalt()));
user.setType(0);
user.setStatus(0);
user.setActivationCode(CommunityUtil.generateUUID());
user.setHeaderUrl(String.format("http://images.nowcoder.com/head/%dt.png", new Random().nextInt(1000)));
user.setCreateTime(new Date());
userMapper.insertUser(user);
// 激活邮件
Context context = new Context();
context.setVariable("email", user.getEmail());
// http://localhost:8080/community/activation/101/code
String url = domain + contextPath + "/activation/" + user.getId() + "/" + user.getActivationCode();
context.setVariable("url", url);
String content = templateEngine.process("/mail/activation", context);
mailClient.sendMail(user.getEmail(), "激活账号", content);
return map;
}
public int activation(int userId, String code) {
User user = userMapper.selectById(userId);
if (user.getStatus() == 1) {
return ACTIVATION_REPEAT;
} else if (user.getActivationCode().equals(code)) {
userMapper.updateStatus(userId, 1);
return ACTIVATION_SUCCESS;
} else {
return ACTIVATION_FAILURE;
}
}
public Map<String, Object> login(String username, String password, int expiredSeconds) {
Map<String, Object> map = new HashMap<>();
// 空值处理
if (StringUtils.isBlank(username)) {
map.put("usernameMsg", "账号不能为空!");
return map;
}
if (StringUtils.isBlank(password)) {
map.put("passwordMsg", "密码不能为空!");
return map;
}
// 验证账号
User user = userMapper.selectByName(username);
if (user == null) {
map.put("usernameMsg", "该账号不存在!");
return map;
}
// 验证状态
if (user.getStatus() == 0) {
map.put("usernameMsg", "该账号未激活!");
return map;
}
// 验证密码
password = CommunityUtil.md5(password + user.getSalt());
if (!user.getPassword().equals(password)) {
map.put("passwordMsg", "密码不正确!");
return map;
}
// 生成登录凭证
LoginTicket loginTicket = new LoginTicket();
loginTicket.setUserId(user.getId());
loginTicket.setTicket(CommunityUtil.generateUUID());
loginTicket.setStatus(0);
loginTicket.setExpired(new Date(System.currentTimeMillis() + expiredSeconds * 1000));
loginTicketMapper.insertLoginTicket(loginTicket);
map.put("ticket", loginTicket.getTicket());
return map;
}
public void logout(String ticket) {
loginTicketMapper.updateStatus(ticket, 1);
}
public LoginTicket findLoginTicket(String ticket) {
return loginTicketMapper.selectByTicket(ticket);
}
public int updateHeader(int userId, String headerUrl) {
return userMapper.updateHeader(userId, headerUrl);
}
//用户修改密码服务
/**
*
* @return
* public Map<String,Object> changePassword(){
*
*
* }
*/
public Map<String,Object> changePassword(int id,String originPassword,String newPassword,String confirmPassword){
//空值处理
Map<String,Object> map=new HashMap<>();
if(StringUtils.isBlank(originPassword)){
map.put("originPasswordMsg","原始密码不能为空!");
return map;
}
if(StringUtils.isBlank(newPassword)){
map.put("newPasswordMsg","新密码不能为空!");
return map;
}
if(StringUtils.isBlank(confirmPassword)){
map.put("confirmPasswordMsg","确认密码不能为空!");
return map;
}
if(!confirmPassword.equals(newPassword)){
map.put("confirmPasswordMsg","两次输入密码不一致,请重新确认");
return map;
}
//验证账号
// User user=userMapper.selectByName(username);
// if(user==null){
// map.put("usernameMsg","该账号不存在!");
// return map;
// }
User user=userMapper.selectById(id);
if(!user.getPassword().equals( CommunityUtil.md5(originPassword+user.getSalt()))){
System.out.println(user.getPassword());
System.out.println(originPassword);
//怪不得,已经加密了,要再处理一下加密
map.put("originPasswordMsg","原始密码错误!");
return map;
}
if(user.getPassword().equals(CommunityUtil.md5(newPassword+user.getSalt()))){
map.put("newPasswordMsg","新密码与原始密码一致,请重新输入新密码!");
return map;
}
userMapper.updatePassword(id,CommunityUtil.md5(newPassword+user.getSalt()));
return map;
}
}
2.修改配置文件
添加上传头像的路径及暴露头像Url地址的根地址:
# community
community.path.domain=http://localhost:8080
community.path.upload=d:/work/data/upload
3.controller层
在controller包中创建UserController类,代码见下。
package com.gerrrard.community.controller;
import com.gerrrard.community.entity.User;
import com.gerrrard.community.service.UserService;
import com.gerrrard.community.util.CommunityUtil;
import com.gerrrard.community.util.HostHolder;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
@Controller
@RequestMapping("/user")
public class UserController {
private static final Logger logger = LoggerFactory.getLogger(UserController.class);
@Value("${community.path.upload}")
private String uploadPath;
@Value("${community.path.domain}")
private String domain;
@Value("${server.servlet.context-path}")
private String contextPath;
@Autowired
private UserService userService;
@Autowired
private HostHolder hostHolder;
@RequestMapping(path = "/setting", method = RequestMethod.GET)
public String getSettingPage() {
return "/site/setting";
}
@RequestMapping(path = "/upload", method = RequestMethod.POST)
public String uploadHeader(MultipartFile headerImage, Model model) {
if (headerImage == null) {
model.addAttribute("error", "您还没有选择图片!");
return "/site/setting";
}
String fileName = headerImage.getOriginalFilename();
String suffix = fileName.substring(fileName.lastIndexOf("."));
if (StringUtils.isBlank(suffix)) {
model.addAttribute("error", "文件的格式不正确!");
return "/site/setting";
}
// 生成随机文件名
fileName = CommunityUtil.generateUUID() + suffix;
// 确定文件存放的路径
File dest = new File(uploadPath + "/" + fileName);
try {
// 存储文件
headerImage.transferTo(dest);
} catch (IOException e) {
logger.error("上传文件失败: " + e.getMessage());
throw new RuntimeException("上传文件失败,服务器发生异常!", e);
}
// 更新当前用户的头像的路径(web访问路径)
// http://localhost:8080/community/user/header/xxx.png
User user = hostHolder.getUser();
String headerUrl = domain + contextPath + "/user/header/" + fileName;
userService.updateHeader(user.getId(), headerUrl);
return "redirect:/index";
}
//暴露一个访问接口给外部
@RequestMapping(path = "/header/{fileName}", method = RequestMethod.GET)
public void getHeader(@PathVariable("fileName") String fileName, HttpServletResponse response) {
// 服务器存放路径
fileName = uploadPath + "/" + fileName;
// 文件后缀
String suffix = fileName.substring(fileName.lastIndexOf("."));
// 响应图片
response.setContentType("image/" + suffix);
try (
FileInputStream fis = new FileInputStream(fileName);
OutputStream os = response.getOutputStream();
) {
byte[] buffer = new byte[1024];
int b = 0;
while ((b = fis.read(buffer)) != -1) {
os.write(buffer, 0, b);
}
} catch (IOException e) {
logger.error("读取头像失败: " + e.getMessage());
}
}
@RequestMapping(path="/updatePassword",method = RequestMethod.POST)
public String uploadPassword(String originPassword,String newPassword,String confirmPassword, Model model){
Map<String,Object> map=userService.changePassword(hostHolder.getUser().getId(),originPassword,newPassword,confirmPassword);
if(map==null || map.isEmpty()){
model.addAttribute("msg","修改密码成功!");
model.addAttribute("target","/index");
return "/site/operate-result";
}else {
model.addAttribute("originPasswordMsg", map.get("originPasswordMsg"));
model.addAttribute("newPasswordMsg", map.get("newPasswordMsg"));
model.addAttribute("confirmPasswordMsg", map.get("confirmPasswordMsg"));
return "/site/setting";
}
}
}
3.1更换头像
uoload方法:用户在setting页面点击上传头像按钮后,转到uploadHeader方法,先对输入进行合法性判断,包含判断用户是否选择图片,文件的格式正不正确,如果非法则转回setting页面;通过合法性判断后,生成随机文件名,再确定本地存放路径存储至本地;最后通过hostHolder获取到用户,确定“暴露用户头像的url地址”,并更新user MySQL的headerUrl字段,最后重定向至index页面。
getHeader方法:暴露headerUrl给外部,通过headerUrl即可访问到本地图片,即将本地图片地址映射为headerUrl地址。
3.2修改密码
用户修改密码操作的逻辑与登录/注册功能逻辑类似,这里不再赘述。
4.View层
index.html:添加转到修改用户信息页面的请求链接。
setting.html:
引入th库,修改资源地址,顶部复用:
内容动态更改:
修改头像:
更改密码:
5.功能测试
修改头像:
本地文件查看:
数据库headerurl地址变更:
通过headerurl暴露的地址浏览器下载访问:
修改密码:
修改密码成功后跳转回首页: