当前位置:网站首页>3. User upload avatar
3. User upload avatar
2022-08-02 15:31:00 【Caviar :P】
还是三层架构,Consider first the data access layer,There is nothing to do with this layer,Because the avatar is saved to the hard disk and not saved to the database;The business layer needs to be updated after uploading the avatarheadurl,The server needs to provide a function to change the avatar path;That's it for uploading filescontrollerIt's better to implement it in the presentation layer.因为啊MultipartFileis an object belonging to the presentation layer,if passed toserviceCoupling occurs,不太合适.
First upload the avatar and have a path to store the avatar,This path cannot be fixed,Because developing locally is definitely not the same as deploying to a server,Currently stored locally,will be stored later云服务器上.在application.propertiesAdd the avatar upload path.
1. 大体思路
①The user clicks on the home page【账号设置】按钮,getSettingPage()会返回静态资源【/site/setting】,进入到设置页面,执行UserController的控制器方法;
②我们点击【上传头像】按钮后,发送【/user/upload】,执行UserController的控制器方法uploadHeader():Null values are handled first,然后用substringSplit out the file suffix,png或者jpg等等.If there is no suffix, it will prompt that the file format is incorrect.Rename user-uploaded images,Generated using what was written beforeuuidmethod plus the suffix of the split file.将文件存储到我们在配置文件中设置的路径下,并更新当前user的headerUrl属性为指定格式的路径;
③当我们需要访问头像(即user的headerUrl属性)时,控制器方法getHeader()会根据headerUrl,将对应目录下的头像复制出来.
2. 用户控制器-上传头像
这里用到的是Spring MVC的multipartFile,Avatars are stored and retrieved directly in controller层操作.新建一个UserController.Set the class's access path to /user.
转载:初步理解MultipartFile - 简书 (jianshu.com)
MultipartFile是SpringMVC提供简化上传操作的工具类.
在不使用框架之前,都是使用原生的HttpServletRequest来接收上传的数据,文件是以二进制流传递到后端的,然后需要我们自己转换为File类.使用了MultipartFile工具类之后,我们对文件上传的操作就简便许多了.
MultipartFile主要是用表单的形式进行文件上传,在接收到文件时,可以获取文件的相关属性,比如文件名、文件大小、文件类型等等.
- 第一个方法,Used to return to the personal settings page,Returns the template path directly.
- Then upload the avatar method,Here two objects are obtained from the container,一个是MultiparFile,That is, the avatar file passed from the browser,一个是model,Used for model return information.
- Null values are handled first,然后用substringSplit out the file suffix,png或者jpg等等.If there is no suffix, it will prompt that the file format is incorrect.Rename user-uploaded images,Generated using what was written beforeuuidmethod plus the suffix of the split file.
- Then create a new file in the file storage location we specified,The filename uses the generated name,并记录异常,将异常向上抛出,for subsequent processing.然后从hostHolderto get the current user,更新头像路径.
package com.nowcoder.mycommunity.controller;
@Controller
@RequestMapping("/user")
public class UserController {
private static final Logger logger = LoggerFactory.getLogger(UserController.class);
//注入文件的上传路径
@Value("${community.path.upload}")
private String uploadPath;
//注入域名
@Value("${mycommunity.path.domin}")
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 (
//此为java7写法,这里面声明的变量会自动加finally,在里面自动关闭
//而输出流会被SpringMVC自动关闭
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) {
e.printStackTrace();
}
}
}
3. 更新用户头像方法
在UserService类中添加方法
还是从dao层向controller开发,Because the avatar exists directly locally,not saved to the database,这里不涉及dao层.
serviceThe layer is mainly dealt withuser表里的headUrl,这个方法在userMapper里写过,直接调用就可以.
//更新用户头像
public int updateHeader(int userId, String headurl){
return userMapper.updateHeader(userId, headurl);
}
4. 配置文件
添加文件的上传存储路径.
# 上传资源存放的位置
community.path.upload=e:/nowcoder/data/upload
5. html
①首页index.html:进入【账号设置】.
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item text-center" href="site/profile.html">个人主页</a>
<a class="dropdown-item text-center" th:href="@{/user/setting}">账号设置</a>
<a class="dropdown-item text-center" th:href="@{/logout}">退出登录</a>
<div class="dropdown-divider"></div>
<span class="dropdown-item text-center text-secondary" th:utext="${loginUser.username}">nowcoder</span>
</div>
②账号设置页面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">
<!-- name需要与控制器方法中形参名相同 -->
<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
边栏推荐
- 倍增和稀疏表
- Detailed explanation of Golang garbage collection mechanism
- 刷卡芯片CI520可直接PIN对PIN替换CV520支持SPI通讯接口
- mysql的索引结构为什么选用B+树?
- Please make sure you have the correct access rights and the repository exists.问题解决
- 一篇文章彻底理解Redis的持久化:RDB、AOF
- Use libcurl to upload the image of Opencv Mat to the file server, based on two methods of post request and ftp protocol
- 背包问题-动态规划-理论篇
- MATLAB绘图函数ezplot入门详解
- Win10 cannot directly use photo viewer to open the picture
猜你喜欢
随机推荐
What should I do if Windows 10 cannot connect to the printer?Solutions for not using the printer
轻量化AlphaPose
13.56MHZ刷卡芯片CI521兼容cv520/ci520支持A卡B卡MIFARE协议
Redis的线程模型
MATLAB绘图命令fimplicit绘制隐函数图形入门详解
日常-笔记
一篇文章彻底理解Redis的持久化:RDB、AOF
BLE蓝牙5.2-PHY6222系统级芯片(SoC)智能手表/手环
Daily - Notes
Win10无法连接打印机怎么办?不能使用打印机的解决方法
pygame draw arc
FP5207电池升压 5V9V12V24V36V42V大功率方案
Spark及相关生态组件安装配置——快速回忆
Mapreduce环境详细搭建和案例实现
发布模块到npm应该怎么操作?及错误问题解决方案
推开机电的大门《电路》(一):电压,电流,参考方向
Win11 system cannot find dll file how to fix
FP6293电池升压5V-12V大电流2APWM模式升压方案
FP5139电池与适配器供电DC-DC隔离升降压电路反激电路电荷泵电路原理图
win10 system update error code 0x80244022 how to do