上传头像--功能的实现(基于牛客网项目)
这里的上传图像是存在了个人电脑硬盘上的某一位置,目前并没有存到数据库里(数据访问层没有代码逻辑)
对于服务层Service:
上传头像是用户的行为UserService:
新增 updateHeader 方法,更改指定用户的头像。
public int updateHeader(int userId,String headerUrl){
return userMapper.updateHeader(userId,headerUrl);
}
对于控制层Controller:
创建 UserController:
新增 getSettingPage 方法访问账户设置 setting.html ,并在 index.html 的账号设置按钮关联该链接。
//浏览器通过这个方法可以访问到设置页面
@RequestMapping(path = "/setting", method = RequestMethod.GET)
public String getSettingPages(){
return "/site/setting";
}
新增 uploadHeader 方法更新用户头像,如果上传出现错误将错误信息存在 Model 对象中。
如果没有错误,生成一个文件对象 dest,利用 MultipartFile 接口的 transferTo 方法将用户上传文件导入 dest,
并从 hostHolder 中取出用户,更新用户的头像路径。
//只修改一个用户的头像 参数就用不到数组
@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访问路径)
//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";
}
新增 getHeader 方法获取用户头像,利用文件输入流读取图片数据,利用 HttpServletResponse 的字节输出流再进行输出。
//获取头像 (二进制的数据)
@RequestMapping(path = "/header/{fileName}",method = RequestMethod.GET)
public void getHeader(@PathVariable("fileName")String fileName, HttpServletResponse response){
//@PathVariable从路径中解析filename的参数
//服务器存放的路径
fileName = uploadPath + "/" + fileName ;
//向浏览器输出 文件的后缀
String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
//响应图片
response.setContentType("image/"+suffix);
try( //java7语法 这样写可以自动在finally 关闭
OutputStream os = response.getOutputStream();
FileInputStream fis = new FileInputStream(fileName);
) {
//一次写入1024
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());
}
}
调整 setting.html 的 form 表单, method=“post”,enctype=“multipart/form-data”,并设置提交路径。
附录:
//处理实际问题基本上都会用到日志文件
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;
//注入UserService 主要是为了调用updateHeader()
@Autowired
private UserService userService;
//更新用户的头像 需要知道当前用户是什么
@Autowired
private HostHolder hostHolder;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?