当前位置:网站首页>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/upload5. 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边栏推荐
猜你喜欢

Win11 computer off for a period of time without operating network how to solve

倍增和稀疏表

TCP三次握手、四次挥手

刷卡芯片CI520可直接PIN对PIN替换CV520支持SPI通讯接口

What should I do if Windows 10 cannot connect to the printer?Solutions for not using the printer

Yolov5 official code reading - prior to transmission

Codeforces Round #605 (Div. 3)

FP7195转模拟调光技术解决智能家居调光频闪和电感噪音的原理

基于矩阵计算的线性回归分析方程中系数的估计

Win11电脑一段时间不操作就断网怎么解决
随机推荐
What is Win10 God Mode for?How to enable God Mode in Windows 10?
Win11 system cannot find dll file how to fix
Please make sure you have the correct access rights and the repository exists.问题解决
Cmd Markdown 公式指导手册
What should I do if Windows 10 cannot connect to the printer?Solutions for not using the printer
win10 system update error code 0x80244022 how to do
FP5139电池与适配器供电DC-DC隔离升降压电路反激电路电荷泵电路原理图
Failed to install using npx -p @storybook/cli sb init, build a dedicated storybook by hand
背包问题-动态规划-理论篇
Win10 computer can't read U disk?Don't recognize U disk how to solve?
win10系统更新错误代码0x80244022怎么办
ASR6601牛羊定位器芯片GPS国内首颗支持LoRa的LPWAN SoC
Fast advanced TypeScript
jest test, component test
Mysql connection error solution
2021-10-14
Please make sure you have the correct access rights and the repository exists. Problem solved
深入理解Golang之Map
How to update Win11 sound card driver?Win11 sound card driver update method
发布模块到npm应该怎么操作?及错误问题解决方案