问答平台(2),账号设置

上传文件

  • 请求:必须是POST请求
  • 表单:enctype = “multipart/form-data”
  • Spring MVC:通过MultipartFile处理上传文件,在表现层保存文件,业务层只更新路径。

开发步骤

  • 访问账号设置页面

表现层

1
2
3
4
5
// UserController.java
@RequestMapping(path = "/setting", method = RequestMethod.GET)
public String getSettingPage(Model model) {
return "/site/setting";
}

页面

1
2
3
<!-- setting.html -->
<!-- 头部: 复用 -->
<!-- js: 引入 -->
1
2
3
4
<!-- index.html -->
<!-- 头部 -->
<!-- 功能 -->
<a class="dropdown-item text-center" th:href="@{/user/setting}">账号设置</a>
  • 上传头像

业务层

1
2
3
4
// UserService.java
public int updateHeader(int userId, String headerUrl) {
return userMapper.updateHeader(userId, headerUrl);
}

表现层

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
// UserController.java
/*
读取文件后缀名,与随机字符串拼接,表示服务器本地存入的文件名。
然后进行存储,更新数据库里面的header_url字段。
*/
@Controller
@RequestMapping("/user")
public class UserController implements CommunityConstant {

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(Model model) {
return "/site/setting";
}

@RequestMapping(path = "/upload", method = RequestMethod.POST)
public String uploadHeader(MultipartFile headerImage, Model model) {
if (headerImage == null) {
model.addAttribute("error", "您还没有选择图片!");
return "/site/setti00ng";
}

// 读取文件后缀
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";
}
}
  • 获取头像

表现层

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// UserController.java
@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 (
OutputStream os = response.getOutputStream();
FileInputStream fis = new FileInputStream(fileName);
) {
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());
}
}

页面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<!-- setting.html -->
<!-- 内容 -->
<!-- 上传头像 -->
<h6 class="text-left text-info border-bottom pb-2">上传头像</h6>
<!--上传到本地-->
<form class="mt-5" method="post" enctype="multipart/form-data" th:action="@{/user/upload}">
<div class="form-group row mt-4">
<label for="head-image" class="col-sm-2 col-form-label text-right">选择头像:</label>
<div class="col-sm-10">
<div class="custom-file">
<input type="file" th:class="|custom-file-input ${error!=null?'is-invalid':''}|"
id="head-image" name="headerImage" lang="es" required="">
<label class="custom-file-label" for="head-image" data-browse="文件">选择一张图片</label>
<div class="invalid-feedback" th:text="${error}">
上传图片出错!
</div>
</div>
</div>
</div>
<div class="form-group row mt-4">
<div class="col-sm-2"></div>
<div class="col-sm-10 text-center">
<button type="submit" class="btn btn-info text-white form-control">立即上传</button>
</div>
</div>
</form>

修改用户密码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// UserController.java
@RequestMapping(path = "/updatePassword", method = RequestMethod.POST)
public String updatePassword(String oldPassword, String newPassword, String confirmPassword, Model model) {
User user = hostHolder.getUser();
// 检查原密码
if(StringUtils.isBlank(oldPassword)) {
model.addAttribute("oldPasswordMsg", "原密码不能为空!");
return "/site/setting";
}
// 检查新密码和确认密码
if(StringUtils.isBlank(newPassword) || StringUtils.isBlank(confirmPassword)) {
model.addAttribute("passwordMsg", "密码不能为空!");
return "/site/setting";
}
if(!newPassword.equals(confirmPassword)) {
model.addAttribute("passwordMsg", "两次密码不一致,请重新输入!");
return "/site/setting";
}

Map<String, Object> map = userService.updatePassword(user.getId(), oldPassword, newPassword);
if(map.containsKey("updateSuccess")) {
System.out.println("updateSuccess");
return "/site/login";
} else {
model.addAttribute("usernameMsg",map.get("usernameMsg"));
model.addAttribute("oldPasswordMsg", map.get("oldPasswordMsg"));
return "/site/setting";
}
}

参考资料


问答平台(2),账号设置
https://lcf163.github.io/2020/05/01/问答平台(2),账号设置/
作者
乘风的小站
发布于
2020年5月1日
许可协议