IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> 项目1在线交流平台-2.开发交流社区注册登录模块-7.上传文件-账号设置 -> 正文阅读

[系统运维]项目1在线交流平台-2.开发交流社区注册登录模块-7.上传文件-账号设置

参考牛客网高级项目教程

1. 账号设置功能需求

在这里插入图片描述

在这里插入图片描述

  • 点击账户设置,能够跳转到账户设置页面

    • 有上传头像
    • 修改密码功能
  • 点击上传文件,能够从本地查找图片文件

    • 点击立即上传,将图片上传到服务器,并跳转到首页
    • 在首页中,显示新的图片头像
  • 点击修改密码的立即保存,将账户数据库密码进行更新,并跳转到首页

2. 上传文件模块开发

2.1 账号设置页面显示

1)Controller层处理新请求

@Controller
@RequestMapping("/user")
public class UserController {
    // 显示账号设置页面
    @RequestMapping(value = "/setting", method = RequestMethod.GET)
    public String getUserSetting(){
        return "/site/setting";
    }
}

2)View视图层处理模板页面

  • 处理动态url,测试结果:

    在这里插入图片描述

2.2 上传头像

1)配置

  • 先配置设置上传的文件储存在哪里

    • 先储存在本地
    • 上线后,放在linux里
    # 上传文件保存的位置
    community.path.upload=E:/javaWeb/data/upload
    

2)service层,更改用户头像

  • 有关用户的操作,dao层已经处理好了,暂时不需要动

  • 上传头像后,用户头像需要更改,因此,需要在service层修改业务

    // 更改用户头像
    public int updateHeader(int userId, String headerUrl) {
        return userMapper.updateHeader(userId, headerUrl);
    }
    

3)Controller层处理上传请求

  • 1.使用MultipartFile接受用户上传文件,并将文件重命名后保存到服务端指定位置
  • 2.更新数据库,将用户更改的头像数据更新
  • 3.判断操作是否正确,
    • 不正确,返回用户设置页面,并显示错误提示信息
    • 正确,重定向到首页,显示更新后的用户头像
1.将上传的文件保存到服务端
MultipartFile
  • 多组件文档,spring框架下的一个包,封装了很多api,方便操作文件流的上传处理

    • MultipartFile是一个接口,并继承自InputStreamSource
    • 我们在使用MultipartFile作为参数传递的时候
      • 可以将MultipartFile声明为一个数组,这样就能支持多文件传输,
      • 如果只需要传输一个文件,则去掉数组就好了
  • 因此,controller方法中,将MultipartFile作为参数传入

    // 处理文件上传请求
    @RequestMapping(path = "/upload", method = RequestMethod.POST)
    public String uploadHeader(MultipartFile multipartFile, Model model) {
        
        return "redirect:/index";
    }
    
  • 通过MultipartFile接受上传的文件,要先判空

getOriginalFilename()
  • 注意不是getName()

  • 先读取文件名,存入本地前,为防止用户上传文件名重复,需重命名:随机字符串.后缀

    // 对上传的文件进行处理
    // 先读取文件名,存入本地前,为防止用户上传文件名重复,需重命名:随机字符串.后缀
    String filename = multipartFile.getName();
    
substring(filename.lastIndexOf(’.’))
  • 重命名需要后缀,截器后缀名.png

  • 同样,要判空,如果没有后缀,说明图片格式不正确

    // 读取后缀,并验证后缀名是否合法
        String suffix = filename.substring(filename.lastIndexOf('.')); // .字符开始往后
        if(StringUtils.isBlank(suffix)) {
            model.addAttribute("error", "文件格式不正确!");
            return "/site/setting";
        }
        filename = CommunityUtil.generateUUID() + suffix; // 重命名
    
new File(address)
  • 要将上传文件储存到指定位置,定义好指定路径位置的空文件准备接受

    // 定义文件存放的地址
        String address = uploadPath + "/" + filename;
        File dest = new File(address); // 指定地址要存放接受图片的空文件
    
transferTo(dest)
  • 将上传文件写入到指定路径文件中,此方法有重载,也可以写到指定路径中

    // 将上传文件写入到指定路径文件中
        try {
            multipartFile.transferTo(dest);
        } catch (IOException e) {
           logger.error("上传文件失败!" + e.getMessage());
            throw new IllegalArgumentException("上传文件失败,服务器发生异常!", e);
        }
    
2.更新数据库
  • 上传头像成功后,要将用户头像的数据更改

  • 最后重定向到首页,展示新的用户信息

    // 上传头像成功后,要将用户头像的数据更改
        // 要给新的用户头像一个web能访问的url地址
        // http://localhost:8080/community/user/header/xxx.png
        String headerUrl = domain + contextPath + "/user/header" + "/" + filename;
        User user = hostHolder.getUser();
        userService.updateHeader(user.getId(), headerUrl);
        
        return "redirect:/index";
    
  • 完整代码如下:

    // 处理文件上传请求
    @RequestMapping(path = "/upload", method = RequestMethod.POST)
    public String uploadHeader(MultipartFile multipartFile, Model model) {
        // 先判断上传的文件是否为空
        if(multipartFile == null) {
            model.addAttribute("error", "您还没有选择图片!");
            return "/site/setting";
        }
        
        // 对上传的文件进行处理
        // 先读取文件名,存入本地前,为防止用户上传文件名重复,需重命名:随机字符串.后缀
        String filename = multipartFile.getName();
        // 读取后缀,并验证后缀名是否合法
        String suffix = filename.substring(filename.lastIndexOf('.')); // .字符开始往后
        if(StringUtils.isBlank(suffix)) {
            model.addAttribute("error", "文件格式不正确!");
            return "/site/setting";
        }
        filename = CommunityUtil.generateUUID() + suffix;
        
        // 定义文件存放的地址
        String address = uploadPath + "/" + filename;
        File dest = new File(address); // 指定地址要存放接受图片的空文件
        // 将上传文件写入到指定路径文件中
        try {
            multipartFile.transferTo(dest);
        } catch (IOException e) {
           logger.error("上传文件失败!" + e.getMessage());
            throw new IllegalArgumentException("上传文件失败,服务器发生异常!", e);
        }
        
        // 上传头像成功后,要将用户头像的数据更改
        // 要给新的用户头像一个web能访问的url地址
        // http://localhost:8080/community/user/header/xxx.png
        String headerUrl = domain + contextPath + "/user/header" + "/" + filename;
        User user = hostHolder.getUser();
        userService.updateHeader(user.getId(), headerUrl);
        
        return "redirect:/index";
    }
    

4)Controller处理访问headerUrl请求

  • 目的是将上一步设定的用户web访问的url路径能够在浏览器中显示出来

  • 因此,需要处理这个请求

    • 获取用户头像请求,访问路径即之前设置的路径
    • 服务端一段从内存文件里读,一端写给浏览器
  • 如果单独访问url请求,本质上也是向浏览器下载文件

     /** 获取用户头像请求,访问路径即之前设置的路径,服务端一段从内存文件里读,一端写给浏览器*/
        @RequestMapping(value = "/header/{filename}", method = RequestMethod.GET)
        public void getHeader(@PathVariable("filename") String filename,
                                HttpServletResponse response) {
            // 1. 获取服务器存放路径的文件
            filename = uploadPath + "/" + filename;
            // 2. 因response要向浏览器响应图片,需要类型,故需要读取后缀
            String suffix = filename.substring(filename.lastIndexOf('.'));
            // 3. 向浏览器响应图片
            response.setContentType("image/" + suffix); // image/.png,也可以识别
            try (
                    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) {
                logger.error("读取头像失败: " + e.getMessage());
            }
        }
    

5)处理模板页面

表单头部处理

enctype=“multipart/form-data”
  • 要添加能够支持multipart类接受文件的支持

    <form class="mt-5" method="post"  enctype="multipart/form-data" th:action="@{/user/upload}">
    
  • 添加错误信息

    <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>
    

注意事项:

  • 1.MultipartFile类对像命名不能为multipartFile,否则接收不到上传的文件

    • pring-boot自带的org.springframework.web.multipart.MultipartFile
      和Multipart产生冲突
  • 2.MultipartFile获取文件的名称是getOriginalFilename()方法,不是getName()方法

    • getOriginalFileName方法获取的是文件的完整名称,包括文件名称+文件拓展名
    • getName方法获取的是前后端约定的传入文件的参数的名称,即自己定义的类名headerImage
  • 3.@Value("${community.path.upload}"),

    • 一定不要忘记${}

测试结果

在这里插入图片描述

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-03-08 22:59:52  更:2022-03-08 23:00:44 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/16 3:41:40-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码