首页 > 其他分享 >Spring MVC (文件上传下载)

Spring MVC (文件上传下载)

时间:2023-12-27 22:22:45浏览次数:41  
标签:控制器 String Spring 上传下载 视图 MVC 处理器 new 前端

 

1. 介绍

  1)三层架构:

    表现层(UI):负责数据展示;
    业务层(BLL):负责业务处理;
    数据层(DAL):负责数据操作;

 

  2)MVC

    SpringMVC(Model-View-Controller)是Spring的一部分,基于Java的Web框架,用于开发Web应用框架。

    提供一种模型(Model)-视图(View)-控制器(Controller)的架构模式,用于构建灵活,可维护性和可扩展性的Web应用。

 

    •  Model(模型):数据模型,用于封装数据;

    •  View(视图):页面视图,用于展示数据;

    •  Controller(Handle 处理器):处理用户交互的调度器,用于根据用户需求处理程序逻辑;

 

    SpringBoot只是提供了一种更快更优的Spring方式,并不是Spring的增强版。
    Spring约定:简化配置。

 

2. 创建SpringMVC 步骤(上传文件与下载文件)

  1)后端:新建MavenWeb项目

     

 

   如下:

   

  2)后端:导入Maven依赖(pom.xml)

    <dependencies>
        <!-- Servlet 坐标 -->
        <dependency>
            <groupId>jakarta.servlet</groupId>
            <artifactId>jakarta.servlet-api</artifactId>
            <version>5.0.0</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>

        <!-- servlet3.1规范的坐标 -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
        <!--jsp坐标-->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.1</version>
            <scope>provided</scope>
        </dependency>
        <!--spring的坐标-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.1.9.RELEASE</version>
        </dependency>
        <!--spring web的坐标-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>5.1.9.RELEASE</version>
        </dependency>
        <!--springmvc的坐标-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.1.9.RELEASE</version>
        </dependency>


        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.4</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.3</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.3.2</version>
            </plugin>
        </plugins>
    </build>

  注:导入后背景有黄色高亮的是有漏洞的,但不影响;

 

  3)后端:创建controller层 -- > FileController类

  文件上传:

 1     // 文件上传
 2     //  @RequestMapping(value = "/upload", method = RequestMethod.POST)  等价于 @PostMapping()
 3     @PostMapping(value = "upload")
 4     @ResponseBody
 5     public String fileUpload(MultipartFile[] uploadFile) {
 6         for (MultipartFile file : uploadFile) {
 7             //获取原始文件名
 8             String originalFilename = file.getOriginalFilename();
 9 
10 
11             try {
12                 //  生成UUID
13                 //  修正文件名出现乱码 防止文件名重复造成覆盖
14                 originalFilename = new String(originalFilename.getBytes("ISO-8859-1"), "UTF-8");
15             } catch (UnsupportedEncodingException e) {
16                 throw new RuntimeException(e);
17             }
18             System.out.println("文件名:" + originalFilename);
19             // UUID随机
20             String newFile = UUID.randomUUID().toString() + "_" + originalFilename;
21 
22             // 指定文件上传路径
23             // Windows版--方式
24             String serverWin = "E:\\Chrom\\Download\\pictures\\";
25             
26             //  Linux版--方式
27             //  String serverLinux = "/home";
28 
29             File fileWin = new File(serverWin);
30             // 文件夹是否存在
31             if (!fileWin.exists()) {
32                 fileWin.mkdir();
33             }
34             try {
35                 // 文件与文件夹
36                 file.transferTo(new File(serverWin + newFile));
37             } catch (IOException e) {
38                 throw new RuntimeException(e);
39             }
40         }
41         return "success";
42     }

   

  文件下载:

    // 文件下载
    @GetMapping(value = "download")
    public ResponseEntity<byte[]> download(HttpServletRequest httpServletRequest, String filename) {
        // 指定文件下载目录
        // 文件在服务器的目录
        String fileDownloadWin = "E:\\Chrom\\Download\\pictures\\";

        // 指定文件下载名称
        File file = new File(fileDownloadWin + File.separator + filename);
        HttpHeaders httpHeaders = new HttpHeaders();
        filename = getFilename(httpServletRequest, filename);
        httpHeaders.setContentDispositionFormData("attachment", filename);
        httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        try {
            return new ResponseEntity<>(FileUtils.readFileToByteArray(file), httpHeaders, HttpStatus.OK);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

 

 

  工具类:(解决不同浏览器版本兼容问题)

    /**
     * 工具类 解决 不同浏览器的版本兼容
     * @param request
     * @param filename
     * @return
     * @throws UnsupportedEncodingException
     */
    private String getFilename(HttpServletRequest request,String filename){
        //判断是不是IE内核的关键字
        String[] IEBrowerKeyWords = {"MSIE","Trident","Edge"};
        String keywords = request.getHeader("User-Agent");
        for (String keyWord : IEBrowerKeyWords) {
            if(keywords.contains(keyWord)){  //判断是否为IE浏览器
                try {
                    return URLEncoder.encode(filename,"UTF-8");
                } catch (UnsupportedEncodingException e) {
                    throw new RuntimeException(e);
                }
            }
        }
        // 其他浏览器编码格式ISO-8859-1
        try {
            return new String(filename.getBytes("UTF-8"),"ISO-8859-1");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }

 

   @ResponseBody 注解:将方法的返回值通过适当的转换器转换为指定的格式之后,写入到 response 对象的 body 区,通常用来返回 JSON、XML 数据。

 

  4)后端:创建spring-mvc.xml配置文件(本质就是spring的配置件)

    <bean id="multipartResolver"
          class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    </bean>

    <!--注解开发-->
    <context:component-scan base-package="com.bei"/>

 

  5)后端:web.xml中配置前端控制器

    <servlet>
        <servlet-name>DispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath*:spring-mvc.xml</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>DispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

 

  6)后端:配置tomcat

   

     

 

  7)前端:使用JQuery编写上传方法

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>文件上传</title>
    <!-- 导入JQuery -->
    <script type="text/javascript" src="./jquery-1.11.3.min.js"></script>
</head>

<body>

    <!-- 请求路径 -->
    <form action="http://localhost:8080/upload" method="post" enctype="multipart/form-data">
        上传文件:&nbsp;&nbsp;<input type="button" value="添加文件" onclick="add()" />
        <div id="file" style="margin-top: 10px;" value="文件上传区域">

        </div>
        <input id="submit" type="submit" value="上传" style="display: none;margin-top: 10px;" />
    </form>
</body>

<script>
    function add() {
        var innerdiv = "<div>";
            // name='uploadFile' 一定是 上传方法内的参
        innerdiv += "<input type='file' name='uploadFile'>" +
            "<input type='button' value='删除' onclick='remove(this)'>";
        innerdiv += "</div>";
        $("#file").append(innerdiv);
        $("#submit").css("display", "block");
    }
    function remove(obj) {
        $(obj).parent().remove();
        if ($("#file div").length == 0) {
            $("#submit").css("display", "none");
        }
    }
</script>

  

  8)前端:使用JQuery编写下载方法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>下载</title>
</head>
<body>
    <!-- 请求路径  ?  文件名 -->
    <a href="http://localhost:8080/downloadThree?fileName=小可莉.mp4">小可莉.mp4</a>
</body>
</html>

 

3. 工作流程分析

 

  1)服务器启动

 

    • 加载web.xml中DispatcherServlet;

    • 读取spring-mvc.xml中的配置,加载所有com.xx 包中所有标记为bean的类;

    • 读取bean中方法上方标注@RequestMapping的内容;

 

  2)处理请求

 

    • DispatcherServlet配置拦截所有请求 /  ;

    • 使用请求路径与所有加载的@RequestMapping的内容进行比对;

    • 执行对应的方法;

    • 根据方法的返回值在webapp目录中查找对应的页面并展示;

 

  3)web三大组件有 处理器映射,处理器适配器, 视图解析器

    •  dispatcherServlet 前置控制器,负责接收并处理所有的web请求,根据handlerMapping(处理器映射)找到具体的Controller(处理器),由controller完成具体的处理逻辑。
    •  HandlerMapping(处理器映射器):负责处理web请求和具体的Controller之间的映射关系匹配。
    • HandlerAdapter(处理器适配器) 通过 HandlerAdapter 对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。 主要处理方法参数、相关注解、数据绑                                                         定、消息转换、返回值、调用视图解析器等等。
    •  Controller(处理器):DispatherServlet的次级控制器,web请求的具体处理者。DispatherServlet获得handlerMapping的返回结果后,调用controller的处理方法处理当前的业务请求,处理完成后返                                                         回ModelAndView对象。
    •  ViewResolver( 视图解析器):用来处理视图名与具体的view实例之间的映射对应关系。根据ModelAndView中的视图名查找相应的View实现类,然后将查找的结果返回给DispatcherServlet,                                                                 DispatcherServlet最终会将ModelAndView中的模型数据交给返回的View处理最终的视图渲染工作。

 

 

  Springmvc架构原理解析:

      第一步:发起请求到前端控制器(DispatcherServlet);

      第二步:前端控制器请求HandlerMapping查找 Handler,可以根据xml配置、注解进行查找;

      第三步:处理器映射器HandlerMapping向前端控制器返回Handler;

      第四步:前端控制器调用处理器适配器去执行Handler;

      第五步:处理器适配器去执行Handler;

      第六步:Handler执行完成给适配器返回ModelAndView;

      第七步:处理器适配器向前端控制器返回ModelAndView ModelAndView是springmvc框架的一个底层对象,包括 Model和view;

      第八步:前端控制器请求视图解析器去进行视图解析 根据逻辑视图名解析成真正的视图(jsp);

      第九步:视图解析器向前端控制器返回View;

      第十步:前端控制器进行视图渲染,视图渲染将模型数据(在ModelAndView对象中)填充到request域;

      第十一步:前端控制器向用户响应结果。

 

 

4. 请求参数的绑定

    1)默认类型:

      直接放在参数上就可以使用的数据,HttpServletRequest;

    2)简单类型:

      直接将简单类型的数据放在方法里,如果前端参数和后端参数名字一样,自动匹配;

      名字不一样:@RequsetParam(“前端的值”) 就可以将前传的值和后端参数映射;

    3 对象 :

      前端的参数要和对象的属性名称必须、一定一致,会自动封装。

    4 对象嵌套:

      参数和对象的属性名称一致,前端参数对象子属性必须(子对象.属性);

    5 自定义数据的绑定:

      ① 编写转换器类,作用是将前端的数据类型转换成后端的数据类型,继承converter;

      ② 配置文件中,添加转化器驱动。

    6 数组:

      前端数组中是简单类型的数据,前端数组中的name要和后端数组名称一致;

    7 集合:

      后端接受的对象是含有List<对象>属性的,那么前端的name值格式要和后端list属性名称一致,而且用索引的格式 list[0].属性(list集合里对象的属性名称)。

 

  

 



标签:控制器,String,Spring,上传下载,视图,MVC,处理器,new,前端
From: https://www.cnblogs.com/warmNest-llb/p/17931560.html

相关文章

  • Spring Boot2.x 集成 Eureka 与 Feign
    参考https://blog.csdn.net/m0_37959155/article/details/122521406https://blog.csdn.net/Shnywe/article/details/123682758https://www.cnblogs.com/yxth/p/10845640.htmlhttps://juejin.cn/post/6973680096011878407本文完整代码下载注意事项Feign集成了Hystrix......
  • spring MVC 后端 接收 前端 批量添加的数据(简单示例)
    <%@pagecontentType="text/html;charset=UTF-8"language="java"%><html><head>  <title>Title</title></head><body><scriptsrc="${pageScope.request.ContextPath}/js/jquery-3.3.1.min.js&qu......
  • 基于Spring Boot2.x 集成 Spring Cloud Gateway
    参考https://blog.csdn.net/DCTANT/article/details/108125229(boot与cloud的版本关系)https://blog.csdn.net/yuanchangliang/article/details/109579705https://blog.csdn.net/qq_38380025/article/details/102968559本文代码下载环境环境版本说明windows1......
  • 面试官:说说MVCC的执行原理?
    MVCC(Multi-VersionConcurrencyControl)是一种并发控制机制,用于解决数据库并发访问中,数据一致性问题。它通过在读写操作期间保存多个数据版本,以提供并发事务间的隔离性,从而避免了传统的锁机制所带来的资源争用和阻塞问题。所谓的一致性问题,就是在并发事务执行时,应该看到那些数......
  • Taurus .Net Core 微服务开源框架:Admin 插件【4-7】 - 配置管理-Mvc【Plugin-Metric
    前言:继上篇:Taurus.NetCore微服务开源框架:Admin插件【4-6】-配置管理-Mvc【Plugin-Doc接口测试及文档】本篇继续介绍下一个内容:系统配置节点:Mvc- Plugin-Metric接口调用次数统计:配置界面如下:1、Metric.IsEnable:配置当前接口统计插件是否可用打开开关时,可以通......
  • Spring Boot学习随笔- 后端实现全局异常处理(HandlerExceptionResolver),前后端解决跨域
    学习视频:【编程不良人】2021年SpringBoot最新最全教程第十七章、异常处理异常处理作用:用来解决整合系统中任意一个控制器抛出异常时的统一处理入口传统方式传统单体架构下的处理方式配置全局异常处理类@ComponentpublicclassGlobalExceptionResolverimplementsHand......
  • Spring/SpringBoot 参数校验
    目录基础设施搭建1.相关依赖2.实体类案例校验参数注解JSR提供的校验注解:HibernateValidator提供的校验注解:实践案例......
  • springboot 中,ApplicationRunner、InitializingBean、@PostConstruct 执行顺序
    划水。。。ApplicationRunner、InitializingBean、@PostConstruct执行顺序InitializingBean是Spring提供的一个接口,它只有一个方法afterPropertiesSet(),该方法会在容器初始化完成后被调用。ApplicationRunner是SpringBoot提供的一个接口,它有一个方法run(),该方法会在......
  • springboot注解表达式
    ("execution(*com.aop..*.*(..))")1、execution():表达式主体2、第一个*号:表示返回类型,*号表示所有的类型3、.包名:表示需要拦截的包名,后面的两个句点表示当前包和当前包的所有子包4、第二个*号:表示类名,号表示所有的类5、.*(..):最后这个星号表示方法名,号表示所有的方法,后......
  • SpringBoot内置Tomcat启动原理
    SpringBoot内置Tomcat启动原理当依赖Spring-boot-starter-web依赖时会在SpringBoot中添加:ServletWebServerFactoryAutoConfigurationservlet容器自动配置类该自动配置类通过@Import导入了可用(通过@ConditionalOnClass判断决定使用哪一个)的一个Web容器工厂在内嵌Tomc......