功能分析
从本地上传头像文件,而对于上传文件需要注意的是这个请求必须要是 POST 请求,在服务器端呢,接收文件的话 SpringMVC 给我们提供了 MultipartFile 类来处理上传文件。
而我们更改用户头像,第一步肯定是要进行上传头像,头像存放的位置呢可以是本地的服务器,也可以是云服务端,这里我们先暂时存到本地;第二部就是获取头像,因为上传上的头像,在后续其他地方我们需要继续使用。
开发步骤
properties文件配置
要想上传文件,首先我们要定义文件最终要存放在哪里。
community.path.upload=E:/ChatFiles
因为我们上传文件,是将这个文件存放到服务器中并不是存放到数据库中,所以数据访问层不需要进行开发
业务层
我们上传头像文件之后,最终是需要更新用户的 HeaderUrl,所以我们需要提供对应的方法。
UserService 类:
public int updateHeader(int userId, String headerUrl) {
return userMapper.updateHeader(userId, headerUrl);
}
视图层
在视图层我们首先需要让用户能够访问到对应的账号设置页面。
然后就是对应的头像上传的代码开发,通过 MultipartFile 来处理。
上传完,我们也需要给外界提供一个访问头像的请求方法。
UserController 类:
package com.spring.community2.controller;
import com.spring.community2.annotation.LoginRequired;
import com.spring.community2.entity.User;
import com.spring.community2.service.UserService;
import com.spring.community2.util.CommunityUtil;
import com.spring.community2.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;
import java.util.Map;
/**
* @ClassName UserController
* @Author ruizhou
* @Date 2020/5/23 20:34
**/
@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;
@LoginRequired
@RequestMapping(path = "/setting", method = RequestMethod.GET)
public String getSettingPage() {
return "/site/setting";
}
// MultipartFile来接受这个图片文件,多个文件声明数组即可
@LoginRequired
@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);
// 将headerImage里面的数据写入到该文件里面
try {
// 存储文件
headerImage.transferTo(dest);
} catch (IOException e) {
logger.error("上传文件失败:" + e.getMessage());
throw new RuntimeException("上传文件失败,服务器发生异常" + e);
}
// 更新当前用户头像的路径(web路径),等会读取的时候就需要按这个路径来处理
// http://localhost:8080/community/user/header/***.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 httpServletResponse) {
// 服务器存放路径
fileName = uploadPath + "/" + fileName;
// 文件的后缀
String suffix = fileName.substring(fileName.lastIndexOf('.'));
// 响应图片
httpServletResponse.setContentType("image/" + suffix);
// 通过字节流输出头像
try (
OutputStream os = httpServletResponse.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());
}
}
}
实现效果
点击文件上传头像文件。
更改前用户头像。
更改后用户头像。