【编程不良人】快速入门SpringMVC学习笔记03---文件上传、文件下载、springmvc与Ajax集成

【编程不良人】快速入门SpringMVC学习笔记03---文件上传、文件下载、springmvc与Ajax集成,第1张

1. 文件上传

配套视频:https://www.bilibili.com/video/BV1WD4y1D7kz?p=11

                  https://www.bilibili.com/video/BV1WD4y1D7kz?p=12

文件上传:  指将用户本地计算机中的文件上传到服务器上。

1.1 新建maven-webapp工程,添加java、resources目录

1.2 pom.xml引入依赖
  
  
    org.springframework
    spring-core
    4.3.2.RELEASE
  
  
    org.springframework
    spring-context
    4.3.2.RELEASE
  
  
    org.springframework
    spring-context-support
    4.3.2.RELEASE
  
  
    org.springframework
    spring-jdbc
    4.3.2.RELEASE
  
  
    org.springframework
    spring-aop
    4.3.2.RELEASE
  
  
    org.springframework
    spring-beans
    4.3.2.RELEASE
  
  
    org.springframework
    spring-expression
    4.3.2.RELEASE
  
  
    org.springframework
    spring-aspects
    4.3.2.RELEASE
  
  
    org.springframework
    spring-tx
    4.3.2.RELEASE
  
  
    org.springframework
    spring-web
    4.3.2.RELEASE
  
  
    org.springframework
    spring-webmvc
    4.3.2.RELEASE
  
  
  
    javax.servlet
    servlet-api
    2.5
    provided
  
  
    jstl
    jstl
    1.2
  
  
    commons-fileupload
    commons-fileupload
    1.4
  
  
    com.alibaba
    fastjson
    1.2.62
  
  
    com.fasterxml.jackson.core
    jackson-databind
    2.9.0
  

1.3 配置web.xml

    Archetype Created Web Application
  ​
    
    
      charset
      org.springframework.web.filter.CharacterEncodingFilter
      
        encoding
        UTF-8
      
    
    
      charset
      /*
    
  ​
    
    
      springmvc
      org.springframework.web.servlet.DispatcherServlet
      
      
        contextConfigLocation
        classpath:springmvc.xml
      
    
    
      springmvc
      /
    
  
1.4 引入springmvc.xml
  
  
      
      
  ​
      
      
  ​
      
      
          
          
      
  ​
      
      
  ​
      
      
          
          
      

1.5 开发上传页面upload.jsp
  
  <%@page contentType="text/html; UTF-8" pageEncoding="UTF-8" isELIgnored="false" %>
  
  
  
      
      
      
      测试文件上传
  
  
      文件上传
      
                   

1.6 开发控制器FileController
  package com.study.controller;
  ​
  import org.apache.commons.io.FilenameUtils;
  import org.springframework.stereotype.Controller;
  import org.springframework.web.bind.annotation.RequestMapping;
  import org.springframework.web.multipart.MultipartFile;
  ​
  import javax.servlet.http.HttpServletRequest;
  import java.io.File;
  import java.io.IOException;
  import java.time.LocalDate;
  import java.util.UUID;
  ​
  /**
   * @ClassName FileController
   * @Description TODO
   * @Author Jiangnan Cui
   * @Date 2022/4/24 9:24
   * @Version 1.0
   */
  @Controller
  @RequestMapping("file")
  public class FileController {
  ​
      /**
       * @MethodName upload
       * @Description 测试文件上传
       * @param: img
       * @return: java.lang.String
       * @Author Jiangnan Cui
       * @Date 2022/4/24 9:34
       */
      @RequestMapping("upload")
      public String upload(MultipartFile img, HttpServletRequest request) throws IOException {
          //获取上传文件属性
          System.out.println("文件原始名称为:" + img.getOriginalFilename());
          System.out.println("文件大小:" + img.getSize());
          System.out.println("文件类型:" + img.getContentType());
  ​
          //1.根据upload相对路径获取部署到服务之后的绝对路径
          //获取上传路径
          String realPath = request.getSession().getServletContext().getRealPath("/upload");
          System.out.println("上传路径为:" + realPath);
  ​
          //2.修改文件原始名称
          //获取原始文件名称
          String originalFileName = img.getOriginalFilename();
          //获取原始文件后缀 FilenameUtils为工具类,里面提供了一些静态方法
          String extension = FilenameUtils.getExtension(originalFileName);
          //设置新文件名
          String newFileName = UUID.randomUUID().toString().replace("-","") + "." + extension;
          System.out.println("文件新名称为: " + newFileName);
  ​
          //3.生成当天日期目录
          LocalDate now = LocalDate.now();
          //realPath:父路径,now.toString():子路径
          File dateDir = new File(realPath, now.toString());
          if(!dateDir.exists())
              dateDir.mkdirs();
          System.out.println("日期目录为:" + dateDir.getName());
  ​
          //4.上传文件到服务器中对应日期的目录中
          //dateDir:存放文件的日期目录,newFileName:新文件名
          img.transferTo(new File(dateDir,newFileName));
          return "index";
      }
  }
  ​
1.7 部署到tomcat服务器上进行测试

访问路径:http://localhost:8888/springmvc02/upload.jsp,选择文件后进行上传

上传成功后跳转到index.jsp页面:

控制台输出文件信息、target目录下出现upload本地上传的文件:

1.8 总结

springmvc中文件上传流程:

springmvc中文件上传细节处理:

2. 文件下载

配套视频:【编程不良人】继spring之后快速入门springmvc,面对SpringMVC不用慌_哔哩哔哩_bilibili

【编程不良人】继spring之后快速入门springmvc,面对SpringMVC不用慌_哔哩哔哩_bilibili

文件下载:即将服务器上的文件下载到当前用户访问的计算机。

2.1 完善upload.jsp页面
  文件下载
  
       
  •       a.txt 在线打开               附件下载    
  •    
  •       b.rar 在线打开        附件下载    
  •    
  •       c.png 在线打开        附件下载    
  •    
  •       自我介绍.txt 在线打开        附件下载    

添加测试文件:

 

2.2 完善控制器FileController
  
  /**
   * @MethodName download
   * @Description 测试文件下载
   * @param: openStyle 文件打开方式
   * @param: fileName 文件名
   * @param: request
   * @param: response
   * @Author Jiangnan Cui
   * @Date 2022/4/25 16:27
   */
  @RequestMapping("download")
  public void download(String openStyle, String fileName, HttpServletRequest request, HttpServletResponse response) throws IOException {
      //三目表达式 若不设置打开方式,即openStyle为null时,说明文件可以在线打开
      //         若设置了文件打开方式,即openStyle不为null,说明文件可以以压缩包进行下载
      openStyle = openStyle == null ? "inline":"attachment";
      System.out.println("下载文件的名称为:" + fileName);
      //1.根据下载相对目录获取下载目录在服务器部署之后的绝对目录
      String realPath = request.getSession().getServletContext().getRealPath("/download");
      System.out.println("绝对路径:" + realPath);
      //2.通过文件输入流读取文件                               文件路径     文件名
      FileInputStream fis = new FileInputStream(new File(realPath, fileName));
      //3.解决流乱码问题
      response.setContentType("text/plain;charset=UTF-8");
      //4.判断是在线打开还是下载附件                   openStyle:attachment 附件下载、online 在线打开
      response.setHeader("content-disposition",openStyle + ";fileName=" + URLEncoder.encode(fileName,"UTF-8"));
      //5.获取响应输出流
      ServletOutputStream sos = response.getOutputStream();
  ​
      //6.处理下载流赋值
      //流 *** 作使用Utils工具类:1. *** 作io流用IOUtils;2. *** 作file用FileUtils
      IOUtils.copy(fis,sos);
      IOUtils.closeQuietly(fis);//优雅关闭,安静关流
      IOUtils.closeQuietly(sos);
  ​
  ​
      /*//传统写法:流 *** 作读写
      int len;
      byte[] b = new byte[1024];
      while(true){
          len = fis.read(b);
          if(len == -1)//读到末尾
              break;
          sos.write(b,0,len);
      }
      //释放资源
      fis.close();
      sos.close();*/
  }

       注意:下载时必须设置响应的头信息,指定文件以何种方式保存,另外,下载文件的控制器不能存在返回值,代表响应只用来下载文件信息。

2.3 启动服务器进行测试

访问路径:http://localhost:8888/springmvc02/upload.jsp

若文件可以在线打开,点击“在线打开”后,文件在浏览器页面上进行显示;

文件不能在线打开,则点击“在线打开”后文件会以附件形式下载;

点击“附件下载”后文件均可以以附件形式进行下载

       注意:若发生HTTP状态 500错误-内部服务器错误---找不到对应文件,说明文件没有部署上去,点击右侧maven中的clean进行清缓存处理,重新启动服务,若target目录下出现所有文件,则说明部署成功!

2.4 总结

3.springmvc与Ajax的集成(@ResponseBody注解使用)

配套视频:【编程不良人】继spring之后快速入门springmvc,面对SpringMVC不用慌_哔哩哔哩_bilibili

  • Ajax:异步处理、局部更新数据、在处理响应的时候只认json格式的字符串

  • fastjson:阿里巴巴提供的转json格式工具

  • springmvc提供的@ResponseBody注解:为了进一步方便控制器与ajax集成,springmvc提供了@responseBody注解用在方法的返回值上,代表可以将方法的返回值转换为json格式字符串并响应到前台,省去了通过第三方工具转换json的过程。

3.1 引入相关依赖
  
  
  
    com.fasterxml.jackson.core
    jackson-databind
    2.9.0
  

3.2 开发实体类
  
  package com.study.entity;
  ​
  import com.fasterxml.jackson.annotation.JsonFormat;
  ​
  import java.util.Date;
  ​
  /**
   * @ClassName User
   * @Description TODO
   * @Author Jiangnan Cui
   * @Date 2022/4/26 11:51
   * @Version 1.0
   */
  public class User {
      private String id;
      private String name;
      private Integer age;
      @JsonFormat(pattern = "yyyy-MM-dd") //json日期格式转换(jackson依赖提供)
      private Date bir;
  ​
      @Override
      public String toString() {
          return "User{" +
                  "id='" + id + '\'' +
                  ", name='" + name + '\'' +
                  ", age=" + age +
                  ", bir=" + bir +
                  '}';
      }
  ​
      public User() {
      }
  ​
      public User(String id, String name, Integer age, Date bir) {
          this.id = id;
          this.name = name;
          this.age = age;
          this.bir = bir;
      }
  ​
      public String getId() {
          return id;
      }
  ​
      public void setId(String id) {
          this.id = id;
      }
  ​
      public String getName() {
          return name;
      }
  ​
      public void setName(String name) {
          this.name = name;
      }
  ​
      public Integer getAge() {
          return age;
      }
  ​
      public void setAge(Integer age) {
          this.age = age;
      }
  ​
      public Date getBir() {
          return bir;
      }
  ​
      public void setBir(Date bir) {
          this.bir = bir;
      }
  }
  ​
3.3 开发控制器
  package com.study.controller;
  ​
  import com.alibaba.fastjson.JSONObject;
  import com.study.entity.User;
  import org.springframework.stereotype.Controller;
  import org.springframework.web.bind.annotation.RequestMapping;
  import org.springframework.web.bind.annotation.ResponseBody;
  ​
  import javax.servlet.http.HttpServletResponse;
  import java.io.IOException;
  import java.util.*;
  ​
  /**
   * @ClassName JSonController
   * @Description TODO
   * @Author Jiangnan Cui
   * @Date 2022/4/26 11:42
   * @Version 1.0
   */
  @Controller
  @RequestMapping("json")
  public class JsonController {
      /**
       * @MethodName test
       * @Description 测试@ResponseBody注解  
       * @return: java.util.Map 
       * @Author Jiangnan Cui
       * @Date 2022/4/26 12:11
       */
      @RequestMapping("test")
      @ResponseBody
      public Map test(){
          Map map = new HashMap<>();
          map.put("message","测试成功");
          return map;
      }
  ​
      /**
       * @MethodName findAll
       * @Description 使用阿里fastjson转换json
       * @param: response
       * @Author Jiangnan Cui
       * @Date 2022/4/26 12:05
       */
      @RequestMapping("findAll")
      public void findAll(HttpServletResponse response) throws IOException {
          //1.收集数据
          //2.调用业务
          List users = new ArrayList<>();
          users.add(new User(UUID.randomUUID().toString(),"熊大",20,new Date()));
          users.add(new User(UUID.randomUUID().toString(),"熊二",10,new Date()));
          users.add(new User(UUID.randomUUID().toString(),"光头强",50,new Date()));
          //fastjson
          String s = JSONObject.toJSONStringWithDateFormat(users, "yyyy-MM-dd");
          response.setContentType("application/json;charset=UTF-8");
          response.getWriter().println();
      }
  ​
      /**
       * @MethodName showAll
       * @Description 使用springmvc提供的注解@ResponseBody,将控制器方法的返回值转为json,并响应给前台
       * @return: java.util.List
       * @Author Jiangnan Cui
       * @Date 2022/4/26 12:06
       */
      @RequestMapping("showAll")
      public @ResponseBody List showAll(){
          //1.收集数据
          //2.调用业务
          List users = new ArrayList<>();
          users.add(new User(UUID.randomUUID().toString(),"熊大",20,new Date()));
          users.add(new User(UUID.randomUUID().toString(),"熊二",10,new Date()));
          users.add(new User(UUID.randomUUID().toString(),"光头强",50,new Date()));
          return users;
      }
  }
  ​
3.4 开发json.jsp页面
  
  <%@page contentType="text/html; UTF-8" pageEncoding="UTF-8" isELIgnored="false" %>
  
  
  
      
      
      
      测试springmvc与ajax集成
      
      
  
  
      
  
  

3.5 启动服务器进行测试

访问路径:http://localhost:8888/springmvc02/json/test

访问路径:http://localhost:8888/springmvc02/json.jsp

访问路径:http://localhost:8888/springmvc02/json/findAll

访问路径:http://localhost:8888/springmvc02/json/showAll

3.6 总结

4.SpringMVC中拦截器

配套视频:【编程不良人】继spring之后快速入门springmvc,面对SpringMVC不用慌_哔哩哔哩_bilibili

4.1 作用

       类似于javaweb中的Filter,用来对控制器请求进行拦截,可以将多个Controller中执行的共同代码放入拦截器中执行,减少Controller类中代码的冗余。

4.2 特点
  • 拦截器器只能拦截Controller的请求,不能拦截jsp、静态资源等相关请求

  • 拦截器可中断用户的请求轨迹

  • 请求先经过拦截器,之后还会经过拦截器

4.3 自定义拦截器
  package com.study.interceptors;
  ​
  import org.springframework.web.method.HandlerMethod;
  import org.springframework.web.servlet.HandlerInterceptor;
  import org.springframework.web.servlet.ModelAndView;
  ​
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletResponse;
  ​
  /**
   * @ClassName MyInterceptor
   * @Description 自定义拦截器
   * @Author Jiangnan Cui
   * @Date 2022/4/26 15:37
   * @Version 1.0
   */
  public class MyInterceptor implements HandlerInterceptor {
      //执行顺序:1、2、3、4
      //1.请求会最先进入拦截器中的preHandler方法,执行preHandler方法中内容
      //return true表示放行请求;false表示中断请求
      @Override
      public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
          System.out.println(((HandlerMethod)o).getMethod().getName());
          System.out.println("===========1=============");
  //        //强制用户登录
  //        Object user = httpServletRequest.getSession().getAttribute("user");
  //        if(user==null){
  //            //重定向到登录页面
  //            httpServletResponse.sendRedirect(httpServletRequest.getContextPath() + "/login.jsp");
  //            return false;
  //        }
          return true;
      }
  ​
      //3.当控制器方法执行结束以后,会返回拦截器中,执行拦截器中的postHandler方法
      @Override
      public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
          System.out.println(modelAndView);
          System.out.println("===========3=============");
      }
  ​
      //4.postHandler执行完成之后响应请求,在响应请求完成后,会执行afterCompletion方法
      @Override
      public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
          if(e!=null){
              System.out.println(e.getMessage());
          }
          System.out.println("===========4=============");
      }
  }
  ​
4.4 开发控制器
  /**
   * @MethodName testInterceptor
   * @Description 测试拦截器
   * @return: java.lang.String
   * @Author Jiangnan Cui
   * @Date 2022/4/26 15:47
   */
  @RequestMapping("interceptor")
  public String testInterceptor(){
      System.out.println("===========2=============");
      throw new RuntimeException("程序出错啦!");
  //        return "index";//此处的ModelAndView只有view,即index
  }

4.5 springmvc.xml中配置拦截器
  
  
  
      
      
          
          
          
          
          
          
      
  

注意:/*代表拦截所有请求路径

4.6 启动服务测试拦截器

访问路径:http://localhost:8888/springmvc02/json/interceptor

控制台输出结果:

(1)正常执行时

  
  testInterceptor
  ===========1=============
  ===========2=============
  ModelAndView: reference to view with name 'index'; model is {}
  ===========3=============
  ===========4=============

(2)出错时

  
  testInterceptor
  ===========1=============
  ===========2=============
  程序出错啦!
  ===========4=============

访问路径:http://localhost:8888/springmvc02/json/findAll

 控制台输出结果:

  
  findAll
  ===========1=============
  null
  ===========3=============
  ===========4=============

访问路径:http://localhost:8888/springmvc02/json/showAll

控制台无输出结果

4.7 总结

5.SpringMVC全局异常处理

配套视频:【编程不良人】继spring之后快速入门springmvc,面对SpringMVC不用慌_哔哩哔哩_bilibili

5.1 作用

       当控制器中某个方法在运行过程中突然发生运行时异常时,为了增加用户体验不能出现500错误代码,应该给用户良好展示错误界面,全局异常处理就能更好解决这个问题。

5.2 控制器
  /**
   * @MethodName testInterceptor
   * @Description 测试拦截器
   * @return: java.lang.String
   * @Author Jiangnan Cui
   * @Date 2022/4/26 15:47
   */
  @RequestMapping("interceptor")
  public String testInterceptor(){
      System.out.println("===========2=============");
      throw new UserNameNotFoundException("保存失败,请稍后再试......");
      //throw new RuntimeException("程序出错啦......");
      //return "index";//此处的ModelAndView只有view,即index
  }

5.3 自定义异常
  
  package com.study.exceptions;
  ​
  /**
   * @ClassName UserNameNotFoundException
   * @Description 自定义异常
   * @Author Jiangnan Cui
   * @Date 2022/4/26 19:31
   * @Version 1.0
   */
  public class UserNameNotFoundException extends RuntimeException{
      public UserNameNotFoundException(String message) {
          super(message);
      }
  }
  ​
5.4 全局异常处理开发
  package com.study.handlerexception;
  ​
  import com.study.exceptions.UserNameNotFoundException;
  import org.springframework.web.servlet.HandlerExceptionResolver;
  import org.springframework.web.servlet.ModelAndView;
  ​
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletResponse;
  ​
  /**
   * @ClassName GlobalExceptionResolver
   * @Description TODO
   * @Author Jiangnan Cui
   * @Date 2022/4/26 19:22
   * @Version 1.0
   */
  public class GlobalExceptionResolver implements HandlerExceptionResolver {
      /**
       * @MethodName resolveException
       * @Description 用来处理发生异常时的方法
       * @param: httpServletRequest 当前请求对象
       * @param: httpServletResponse 当前请求对应的响应对象
       * @param: o 当前请求的方法对象
       * @param: e 当前出现异常时的异常对象
       * @return: org.springframework.web.servlet.ModelAndView
       * @Author Jiangnan Cui
       * @Date 2022/4/26 19:24
       */
      @Override
      public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
          System.out.println("进入全局异常处理器获取的异常信息为:" + e.getMessage());
          ModelAndView modelAndView = new ModelAndView();
          //基于不同业务异常跳转到不同页面
          if(e instanceof UserNameNotFoundException){
              modelAndView.setViewName("redirect:/login.jsp");
          }else{
              modelAndView.setViewName("redirect:/error.jsp");//相当于 return "error"
          }
          //modelAndView中model默认放入request作用域,如果使用redirect跳转,model中数据会自动拼接到跳转url
          modelAndView.addObject("msg",e.getMessage());
          return modelAndView;
      }
  }
  ​
5.5 springmvc.xml配置全局异常处理
  
  
  

5.6 jsp页面

login.jsp

  
  <%@page contentType="text/html; UTF-8" pageEncoding="UTF-8" isELIgnored="false" %>
  
  
  
      
      
      
      用户登录
  
  
      用户登录界面
      登录失败:${param.msg}!
  
  

error.jsp

  
  <%@page contentType="text/html; UTF-8" pageEncoding="UTF-8" isELIgnored="false" %>
  
  
  
      
      
      
      全局错误页面
  
  
      系统出现错误: ${param.msg}!
  
  

5.7 启动服务进行测试

访问路径:http://localhost:8888/springmvc02/json/interceptor

 控制台输出结果:

  
  testInterceptor
  ===========1=============
  ===========2=============
  null
  进入全局异常处理器获取的异常信息为:保存失败,请稍后重试......
  ===========4=============
5.8 总结

【SpringMVC完结】

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/785773.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-04
下一篇 2022-05-04

发表评论

登录后才能评论

评论列表(0条)

保存