• Java Web 项目学习(二)账号设置


    MultipartFile 只能封装单个文件。 可以处理上传的文件。但是上传的文件可以不采用MultipartFile 的方式。可以采用其他方式处理。

    表单的处理必须要用 enctype=“multipart.form-data”。并采用post提交

    访问设置界面

    • 在UserController中设置访问链接,
      @Controller
      @RequestMapping("/user")
      public class UserController {
          @RequestMapping(path = "/setting", method = RequestMethod.GET)
          public String getSettingPage(){
              return "/site/setting";
          }
      }
    • 修改对应HTML,(setting和对应index的header)
      <a class="dropdown-item text-center" th:href="@{/user/setting}">账号设置</a>

     

    上传获取头像

    • 在配置application.properties文件中配置上传资源时存放的路径。
      community.path.upload=D:/Project/workspace/file
    • 考虑数据访问层DAO(暂时不需要动)

    • Service业务层

      • 更新用户的headerUrl
            /**
             * 更新用户头像
             */
            public int updateHeaderUrl(int userId, String url){
                return userMapper.updateHeader(userId,url);
            }
    • Controller

      • 上传头像。上传存储的路径、服务器路径、项目路径、获取当前对象hostHoder

        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
            UserService userService ;
            @Autowired
            HostHolder hostHolder; //取当前的用户对象
        
        
          /**
             * 处理上传文件的请求
             */
            @RequestMapping(path = "/upload", method = RequestMethod.POST)
            public String uploadHeader (MultipartFile headerImg, Model model){
                if(headerImg ==null){
                    model.addAttribute("error","您还未选择上传图片");
                    return "/site/setting";
                }
                //为了避免覆盖,文件名要加一个随机字符。同时要保证后缀名不变,因此需要先得到后缀名,暂存一下、
                String filename = headerImg.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 {
                    headerImg.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 headUrl =domain + contextPath + "/user/header/"+ filename;
                userService.updateHeaderUrl(user.getId(),headUrl);
        
                return "redirect:/index";
        
            }

        上传图像的过程(MultipartFile 上传文件):

        • 判空

        • 判合法

        • 上传

          • 获取图片的后缀名, 修改图片名保证唯一。

          • 获取当前用户对象 ,设置图片上传路径。

          • 调Service上传
      • 获取头像

           /**
             * 获取头像
             */
            @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 (
                        OutputStream os =   response.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());
                }
            }

        放在try()内的留,Java编译器会自动创建finnal帮我们关闭。
        FileInputStream 创建文件的输入流,用来读文件filename。进行批量输出,而不是按照字节输出来提高效率。 所以从 fis---->buffer---->os(respond)

        • 获取头像过程
          • 服务器路径解析
          • 文件名后缀解析
          • 设置respose的输出格式
          • 从文件中读数据到缓冲区,再到response对象中。
      • 处理对应HTML

        <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">
                         <input type="file" th:class="|custom-file-input ${error==null?'':'is-invalid'}|"
                                id="head-image" name="headerImg" 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>

     遇错:

    There was an unexpected error (type=Internal Server Error, status=500).
    上传文件失败,服务器发生异常!
    java.lang.RuntimeException: 上传文件失败,服务器发生异常!
    Caused by: java.io.IOException: java.io.FileNotFoundException: C:UserslilyAppDataLocalTemp	omcat.8080.4074473235196648822workTomcatlocalhostcommunitycommunity.path.upload1c0208b7cd0c47d3898b698545693ae1.jpg (系统找不到指定的路径。)

    原因是因为写 忘记加${} ,

      @Value("community.path.upload")
        private String uploadPath;
        @Value("community.path.domain")
        private String domain;
        @Value("server.servlet.context-path")
        private String contextPath;

    修改后 成功。

        @Value("${community.path.upload}")
        private String uploadPath;
        @Value("${community.path.domain}")
        private String domain;
        @Value("${server.servlet.context-path}")
        private String contextPath;

    如果没有建立对应的文件夹,也会报找不到路径的错。需要手动创建对应目录。

     

  • 相关阅读:
    xpath教程-逐层检索和全局检索 转
    xpath教程-通过ID和Class检索 转
    minianaconda3安装
    爬取表情
    进程线程(转)
    centos 安装docker方法2
    关于Dockerfile
    根据指定规则生成游戏选项编码实战
    分布式对象存储 读书笔记
    muduo 的windows下的编译
  • 原文地址:https://www.cnblogs.com/codinghard/p/14842329.html
Copyright © 2020-2023  润新知