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:\Users\lily\AppData\Local\Temp\tomcat.8080.4074473235196648822\work\Tomcat\localhost\community\community.path.upload\1c0208b7cd0c47d3898b698545693ae1.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;

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

 

 

 

posted @ 2021-06-02 18:08  白清欢  阅读(245)  评论(0编辑  收藏  举报