首页 > 其他分享 >十七:Spring Boot (2)-- spring-boot-starter-web 应用

十七:Spring Boot (2)-- spring-boot-starter-web 应用

时间:2024-11-08 15:47:02浏览次数:3  
标签:web 请求 -- Spring springframework org public 跨域

目录

1. spring-boot-starter-web 简介

1.1 作用与功能:

1.2 引入方式:

1.3 包含的核心依赖:

2. 自动配置原理

3. 内嵌 Servlet 容器

3.1 默认 Tomcat 配置:

3.2 替换容器(Jetty 或 Undertow):

4. 构建 RESTful Web 服务:

4.1 什么是 RESTful Web 服务

4.2 创建 REST 控制器

5. 自动处理 JSON:

6. 静态资源支持

7. Web 配置定制(通过 WebMvcConfigurer)

7.1 注册拦截器(Interceptor)

7.2 配置静态资源处理

7.2.1 addResourceHandlers(ResourceHandlerRegistry registry) 方法

7.2.2 registry.addResourceHandler("/assets/**")

7.2.3 addResourceLocations("classpath:/static/assets/")

7.3 配置视图解析器(ViewResolver)

7.3.1 pom.xml 加两个引用 支持jsp 的

7.3.2 配置视图解析器

7.3.3 创建jsp页面

7.3.4 写controller 一定用@Controller

7.3.4 浏览器访问 乱码 无所谓 只要能请求到 就没大问题

7.3.5 工作原理

7.4 CORS 配置(跨域资源共享)

7.4.1 ​​​​​​​什么是跨域?

7.4.2 为什么会有跨域问题?

7.4.3 同源策略(Same-Origin Policy)​​​​​​​

7.4.4 跨域的场景​​​​​​​

7.4.5 浏览器的跨域限制

7.4.6 跨域的解决方案

​​​​​​​7.4.6.1 CORS(跨域资源共享)

7.4.6.2 JSONP(仅限 GET 请求)

7.4.6.3 服务器端代理(推荐)

7.5 消息转换器(Message Converters)

7.8 定制异常处理(@ExceptionHandler)(不推荐)

8. 支持文件上传与下载

​​​​​​​8.1 文件上传

8.1.1 配置文件上传的基本设置

8.1.2 实现文件上传接口

8.1.3 上传目录配置

8.1.4 上传多个文件

8.2 文件下载

8.2.1 实现文件下载接口

8.2.2 设置响应头部以下载文件


  • 1. spring-boot-starter-web 简介

    • 1.1 作用与功能

      • spring-boot-starter-web 是 Spring Boot 的一个启动器(starter),用于构建 Web 应用,它自动配置了多种常见的 Web 组件,尤其适合构建 RESTful Web 服务。

    • 1.2 引入方式

      • Maven:在 pom.xml 中添加:
        • <dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-web</artifactId>
          </dependency>
          
      • Gradle:在 build.gradle 中添加:
        • implementation 'org.springframework.boot:spring-boot-starter-web'
          
    • 1.3 包含的核心依赖

      • ​​​​​Spring MVC:构建 Web 应用的基础框架,提供了控制器、视图解析等功能。

      • 内嵌 Servlet 容器(Tomcat):提供一个内嵌的默认 Servlet 容器,简化部署。

      • Jackson:用于 JSON 数据的序列化和反序列化。

      • Spring Boot 自动配置:自动配置 DispatcherServlet,自动配置 Spring MVC 相关的功能。

  • 2. 自动配置原理

    • DispatcherServlet 自动配置
      • Spring Boot 会自动配置 DispatcherServlet,它是 Spring MVC 的核心,用于路由请求到适当的控制器方法。

    • Spring MVC 相关的自动配置
      spring-boot-starter-web 自动配置了 Spring MVC 所需的 MessageConverter、视图解析器等,简化了手动配置。

    • Tomcat 自动配置
      默认情况下,spring-boot-starter-web 使用 Tomcat 作为嵌入式容器,你可以通过配置改变容器(如使用 Jetty 或 Undertow)。

  • 3. 内嵌 Servlet 容器

    • 3.1 默认 Tomcat 配置

      • 默认内嵌容器是 Tomcat,并且默认端口是 8080

      • 可以通过 application.propertiesapplication.yml 修改端口:

        • server.port=8081
    • 3.2 替换容器(Jetty 或 Undertow)

      • 如果你不想使用 Tomcat,可以排除它并使用 Jetty 或 Undertow:

      • 排除 Tomcat:

        • <dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-web</artifactId>
              <scope>provided</scope>
          </dependency>
          
      • 添加 Jetty 或 Undertow:

        • <dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-jetty</artifactId>
          </dependency>
          
  • 4. 构建 RESTful Web 服务:

    • 4.1 什么是 RESTful Web 服务

      •         REST(Representational State Transfer)是一种通过 HTTP 协议与 Web 服务交互的架构风格。RESTful Web 服务遵循一系列约定,通常使用 HTTP 方法(如 GET、POST、PUT、DELETE)来进行资源的创建、查询、更新和删除操作。每个资源通常由一个 URL 唯一标识,且资源的数据通常以 JSON 返回。
    • 4.2 创建 REST 控制器

      •         在 Spring Boot 中,构建 RESTful 服务的核心是 @RestController 注解。@RestController 是一个结合了 @Controller@ResponseBody 注解的注解,表示该类是一个控制器,且返回的内容会自动以 JSON 或 XML 格式返回(根据客户端请求的 Accept 头)。

      • package com.example.demo.controller;
        
        import org.springframework.web.bind.annotation.GetMapping;
        import org.springframework.web.bind.annotation.RequestMapping;
        import org.springframework.web.bind.annotation.RestController;
        
        @RestController
        @RequestMapping("/api")
        public class HelloController {
        
            @GetMapping("/hello")
            public String hello() {
                return "Hello, World!";
            }
        }
        
      • @RestController:表示该类是一个 REST 控制器,返回数据会被自动序列化为 JSON 格式。

      • @RequestMapping("/api"):为所有请求添加一个基础路径 /api

      • @GetMapping("/hello"):处理 GET 请求,当客户端访问 /api/hello 时,返回 "Hello, World!"

      • @PostMapping:处理 HTTP POST 请求,用于创建新用户。

      • @PutMapping:处理 HTTP PUT 请求,用于更新用户信息。

      • @DeleteMapping:处理 HTTP DELETE 请求,用于删除用户。

  • 5. 自动处理 JSON:

    • spring-boot-starter-web 默认集成了 Jackson 序列化和反序列化,自动将 Java 对象与 JSON 数据进行转换。

    • 你可以使用 @RequestBody 注解接收请求体中的 JSON 数据,使用 @ResponseBody 返回 JSON 数据。

  • 6. 静态资源支持

    • 默认情况下,Spring Boot 会从 /static/public/resources/META-INF/resources 目录提供静态资源。

    • 可以将静态文件(如 HTML、CSS、JavaScript、图片等)放入这些目录中,Spring Boot 会自动提供访问。

    • 自定义静态资源路径

      • 可以通过配置文件修改静态资源的根目录

      • spring.resources.static-locations=classpath:/custom-static/
        
  • 7. Web 配置定制(通过 WebMvcConfigurer

    • 在开发 Spring Web 应用时,WebMvcConfigurer 是一个非常常用的接口,它提供了一种灵活的方式来定制 Spring MVC 的行为。

    • 7.1 注册拦截器(Interceptor)

      • package com.lirui.springbootmoduledemo.config;
        
        
        import org.springframework.context.annotation.Configuration;
        import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
        import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
        
        @Configuration
        public class WebConfig  implements WebMvcConfigurer {
            @Override
            public void addInterceptors(InterceptorRegistry registry) {
                // 注册一个拦截器
                registry.addInterceptor(new WebInterceptor())
                        // 设置拦截路径
                        .addPathPatterns("/api/**")
                        // 排除不需要拦截的路径
                        .excludePathPatterns("/api/login", "/api/register");
            }
        }
        
        package com.lirui.springbootmoduledemo.config;
        
        import org.springframework.web.servlet.HandlerInterceptor;
        import org.springframework.web.servlet.ModelAndView;
        
        import javax.servlet.http.HttpServletRequest;
        import javax.servlet.http.HttpServletResponse;
        
        public class WebInterceptor  implements HandlerInterceptor {
        
            @Override
            public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
                // 这里可以做一些拦截前的校验或操作
                System.out.println("preHandle: 请求即将到达Controller");
        
                // 返回true表示继续处理请求,false表示请求被拦截,不会继续执行
                return true; // 如果返回false,请求会被拦截,后续不会执行
            }
        
            @Override
            public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
                // 请求处理之后,视图渲染之前调用
                System.out.println("postHandle: 请求已处理,视图渲染之前");
            }
        
            @Override
            public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
                // 请求处理完后,视图渲染完毕后调用(通常用于清理资源)
                System.out.println("afterCompletion: 请求完成后,视图渲染之后");
            }
        }
        

    • 7.2 配置静态资源处理

      • package com.lirui.springbootmoduledemo.config;
        
        
        import org.springframework.context.annotation.Configuration;
        import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
        import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
        import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
        
        @Configuration
        public class WebConfig  implements WebMvcConfigurer {
            @Override
            public void addInterceptors(InterceptorRegistry registry) {
                // 注册一个拦截器
                registry.addInterceptor(new WebInterceptor())
                        // 设置拦截路径
                        .addPathPatterns("/api/**")
                        // 排除不需要拦截的路径
                        .excludePathPatterns("/api/login", "/api/register");
            }
        
            @Override
            public void addResourceHandlers(ResourceHandlerRegistry registry) {
                // 配置 /assets/** 请求,映射到 classpath:/static/assets/ 文件夹
                registry.addResourceHandler("/assets/**")
                        .addResourceLocations("classpath:/static/assets/");
        
                // 配置 /images/** 请求,映射到 classpath:/static/images/ 文件夹
                registry.addResourceHandler("/images/**")
                        .addResourceLocations("classpath:/static/images/");
            }
        
        }
        

      • 7.2.1 addResourceHandlers(ResourceHandlerRegistry registry) 方法

        • addResourceHandlers 是 Spring MVC 提供的一个方法,用于配置静态资源的处理方式。ResourceHandlerRegistry 用来注册静态资源的访问路径和实际的资源位置。

        • addResourceHandlers 方法允许你定义一组 资源处理器(Resource Handlers),这些处理器负责处理静态资源请求并返回相应的资源。通过配置,Spring MVC 能够自动映射 URL 路径到实际的文件存放位置,从而提供静态文件的访问功能。

      • 7.2.2 registry.addResourceHandler("/assets/**")

        • registry.addResourceHandler("/assets/**")

        • addResourceHandler("/assets/**") 指定了一个 资源请求的映射路径,即用户访问 /assets/ 路径下的任何 URL(匹配 /assets/**)时,都会交给 Spring MVC 来处理。

          • ** 是一种通配符,表示匹配 /assets/ 后面所有的路径(包括子目录)。

          • 例如,访问 http://localhost:8080/assets/img/logo.png 或者 http://localhost:8080/assets/css/style.css 都会被映射到对应的静态资源文件。

      • 7.2.3 addResourceLocations("classpath:/static/assets/")

        • addResourceLocations("classpath:/static/assets/") 指定了 静态资源文件的实际存储路径classpath:/static/assets/ 是资源文件所在的路径。

        • classpath: 表示资源位置在类路径中。Spring Boot 默认会将静态资源放在 src/main/resources/static 目录下。所以如果你的静态文件在 src/main/resources/static/assets/ 目录下,路径应该设置为 classpath:/static/assets/

        • 这样,当用户请求 /assets/** 路径时,Spring 会在 classpath:/static/assets/ 目录中查找对应的文件。

    • 7.3 配置视图解析器(ViewResolver)

      • 感觉很少会用到来
      • 7.3.1 pom.xml 加两个引用 支持jsp 的

        •         <dependency>
                      <groupId>org.apache.tomcat.embed</groupId>
                      <artifactId>tomcat-embed-jasper</artifactId>
                  </dependency>
                  <dependency>
                      <groupId>javax.servlet</groupId>
                      <artifactId>javax.servlet-api</artifactId>
                      <scope>provided</scope>
                  </dependency>
      • 7.3.2 配置视图解析器

        • package com.lirui.springbootmoduledemo.config;
          
          
          import org.springframework.context.annotation.Configuration;
          import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
          import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
          import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
          import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
          
          @Configuration
          public class WebConfig implements WebMvcConfigurer {
              @Override
              public void addInterceptors(InterceptorRegistry registry) {
                  // 注册一个拦截器
                  registry.addInterceptor(new WebInterceptor())
                          // 设置拦截路径
                          .addPathPatterns("/api/**")
                          // 排除不需要拦截的路径
                          .excludePathPatterns("/api/login", "/api/register");
              }
          
              @Override
              public void addResourceHandlers(ResourceHandlerRegistry registry) {
                  // 配置 /assets/** 请求,映射到 classpath:/static/assets/ 文件夹
                  registry.addResourceHandler("/assets/**")
                          .addResourceLocations("classpath:/static/assets/");
          
                  // 配置 /images/** 请求,映射到 classpath:/static/images/ 文件夹
                  registry.addResourceHandler("/images/**")
                          .addResourceLocations("classpath:/static/images/");
              }
          
              @Override
              public void configureViewResolvers(ViewResolverRegistry registry) {
                  // 配置 JSP 视图解析器
                  registry.jsp().prefix("/WEB-INF/views1/").suffix(".jsp");
              }
          
          }
          
      • 7.3.3 创建jsp页面

          • <!DOCTYPE html>
            <html lang="en">
            <head>
                <meta charset="UTF-8">
                <meta name="viewport" content="width=device-width, initial-scale=1.0">
                <title>hello</title>
            </head>
            <body>
            <h1>欢迎</h1>
            <h1>欢迎</h1>
            <h1>欢迎</h1>
            <h1>欢迎</h1>
            </body>
            </html>
            
      • 7.3.4 写controller 一定用@Controller

        • package com.lirui.springbootmoduledemo.controller;
          
          import org.springframework.stereotype.Controller;
          import org.springframework.web.bind.annotation.GetMapping;
          import org.springframework.web.bind.annotation.RequestMapping;
          import org.springframework.web.bind.annotation.RestController;
          
          @Controller
          @RequestMapping("/api")
          public class HelloController {
          
              @GetMapping("/hello")
              public String hello() {
                  return "Hello, World!";
              }
          
              @GetMapping("/helloJSP")
              public String home() {
                  // 返回 index.jsp 视图
                  return "hello";
              }
          
          }
      • 7.3.4 浏览器访问 乱码 无所谓 只要能请求到 就没大问题

      • 7.3.5 工作原理

        • 当 Spring MVC 中的控制器(Controller)返回一个视图名称时(比如 "hello"),视图解析器会根据配置的 prefixsuffix 来构造最终的 JSP 文件路径。

          • 控制器返回视图名称:hello
          • 视图解析器会去 WEB-INF/views/ 目录下查找名为hello.jsp的文件。
          • 如果文件存在,Spring 会将该 JSP 文件渲染到响应中,返回给客户端。
    • 7.4 CORS 配置(跨域资源共享)

      • 7.4.1 ​​​​​​​什么是跨域?

        • ​​​​​​​**跨域(Cross-Origin)**是指浏览器在不同的域、协议、端口之间进行资源请求的行为。简单来说,当一个网页试图从不同的域名、端口号或协议(如 http://example.comhttps://example.com)加载资源时,就涉及到“跨域”问题。

      • 7.4.2 为什么会有跨域问题?

        • ​​​​​​​浏览器出于安全考虑,采用了 同源策略(Same-Origin Policy),即一个网页只能访问同一来源(同协议、同域名、同端口)的资源。这是为了防止恶意网站通过脚本获取用户的敏感数据或做其他恶意操作。

      • 7.4.3 同源策略(Same-Origin Policy)​​​​​​​

        • 协议httphttps
        • 域名:如 example.com
        • 端口:如 8080
        • 同源策略要求这三者必须完全相同才能进行资源的访问和交互。例如,https://example.comhttp://example.com 是不同的源,因为协议不同;http://example.com:8080http://example.com:9090 是不同的源,因为端口不同。
      • 7.4.4 跨域的场景​​​​​​​

        • 不同的域

          • 网站 A(https://site-a.com)想要访问网站 B(https://site-b.com)的资源。
        • 不同的协议

          • 网站 A(http://site.com)想要访问网站 B(https://site.com)的资源,协议不同。
        • 不同的端口

          • 网站 A(http://site.com:8080)想要访问网站 B(http://site.com:9090)的资源,端口不同。
      • 7.4.5 浏览器的跨域限制

        • ​​​​​​​​​​​​​​浏览器出于安全原因,限制了网页脚本对跨域资源的访问。比如,如果你的网页在 http://localhost:3000 上,试图去请求 http://api.example.com 上的资源,浏览器会默认阻止这种请求,称为 跨域请求(Cross-Origin Request)

          跨域请求的类型

          跨域请求可以分为两种类型:

          • 简单请求(Simple Request)

            • 请求方法是 GETPOSTHEAD

            • 请求头只包括浏览器内置的标准头部(如 Content-Type 设置为 application/x-www-form-urlencodedmultipart/form-datatext/plain)。

          • 复杂请求(Preflighted Request)

            • 请求方法是 PUTDELETE 或自定义的方法,或者请求头包含了非标准的自定义头部(例如 AuthorizationX-Custom-Header 等)。

            • 在这种情况下,浏览器会先发送一个 预检请求(Preflight Request),以确认服务器是否允许实际的请求。

      • 7.4.6 跨域的解决方案

        • ​​​​​​​7.4.6.1 CORS(跨域资源共享)
          • CORS(Cross-Origin Resource Sharing) 是一种浏览器和服务器之间的协议,它允许服务器声明哪些源(域、协议、端口)可以访问其资源。

          • 当浏览器发起跨域请求时,浏览器会自动添加一些 CORS 相关的头部信息:

            • Origin:表示请求发起的源(域、协议、端口)。

            • Access-Control-Allow-Origin:服务器响应的头部,表示允许哪些源可以访问资源。

          • CORS 预检请求: 当浏览器发起一个复杂的跨域请求时(例如,方法是 PUTDELETE 或请求头包含自定义头),浏览器会先发起一个 OPTIONS 请求,即 预检请求(Preflight Request),询问服务器是否允许跨域请求。如果服务器返回适当的响应头,则允许实际请求的发送。

          • CORS 响应头

            • Access-Control-Allow-Origin:允许访问的源,* 表示所有域都可以访问,或者可以指定特定的域(如 http://example.com)。

            • Access-Control-Allow-Methods:允许的 HTTP 方法(如 GET, POST, PUT, DELETE)。

            • Access-Control-Allow-Headers:允许的请求头。

            • Access-Control-Allow-Credentials:是否允许带上身份凭证(如 Cookies)。

            • Access-Control-Max-Age:预检请求的有效时间,表示浏览器在多长时间内不需要再次发送预检请求。

          •    @Override
                public void addCorsMappings(CorsRegistry registry) {
                    // 配置全局跨域
                    registry.addMapping("/**")
                            .allowedOrigins("http://example.com") // 允许来自 example.com 的跨域请求
                            .allowedMethods("GET", "POST") // 允许的请求方法
                            .allowedHeaders("*"); // 允许所有请求头
                }
        • 7.4.6.2 JSONP(仅限 GET 请求)
          • 在早期,浏览器没有支持 CORS 机制时,开发者常用 JSONP 来绕过跨域限制。JSONP 是通过 <script> 标签的跨域特性来发送请求的,但它只支持 GET 请求,不支持发送其他类型的请求,如 POST

        • 7.4.6.3 服务器端代理(推荐)
          • 一种常见的解决跨域问题的方式是通过设置 代理服务器。前端应用发送请求到同源的代理服务器,由代理服务器转发请求到实际的跨域资源服务器。代理服务器和跨域服务器之间的请求不受浏览器的同源策略限制。

    • 7.5 消息转换器(Message Converters)

      • ​​​​​​​Spring MVC 使用 HttpMessageConverter 来将请求和响应的主体内容转换成 Java 对象或从 Java 对象转换为响应的格式(如 JSON、XML)。你可以定制消息转换器来支持自定义的序列化方式。

      • @Override
        public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
            // 创建 Jackson 转换器
            MappingJackson2HttpMessageConverter jacksonConverter = new MappingJackson2HttpMessageConverter();
            
            // 创建 ObjectMapper 并进行配置
            ObjectMapper objectMapper = new ObjectMapper();
            
            // 排除 null 字段
            objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
            
            // 设置日期格式
            objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
            
            // 可以通过 Jackson 的 MixIn 来定制序列化规则
            objectMapper.addMixIn(SomeClass.class, SomeClassMixIn.class);
        
            // 设置 ObjectMapper 到 Jackson 转换器
            jacksonConverter.setObjectMapper(objectMapper);
            
            // 添加到转换器列表
            converters.add(jacksonConverter);
        }
    • 7.8 定制异常处理(@ExceptionHandler)(不推荐)

      • ​​​​​​​
        @Configuration
        public class WebConfig implements WebMvcConfigurer {
            @Override
            public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
                // 定制异常处理
                resolvers.add(new MyCustomExceptionResolver());
            }
        }
  • 8. 支持文件上传与下载

    • ​​​​​​​8.1 文件上传

      • 8.1.1 配置文件上传的基本设置

        • 在 Spring Boot 中,文件上传的功能默认已经启用。但是,你可以在 application.propertiesapplication.yml 中配置一些上传限制(如文件大小)。
        • # 最大上传文件大小
          spring.servlet.multipart.max-file-size=10MB
          # 最大请求数据大小
          spring.servlet.multipart.max-request-size=10MB
          
      • 8.1.2 实现文件上传接口

        • @RestController
          @RequestMapping("/api/files")
          public class FileUploadController {
          
              @Value("${file.upload-dir}")
              private String uploadDir;  // 用于存储文件的目录
          
              // 文件上传接口
              @PostMapping("/upload")
              public ResponseEntity<String> uploadFile(@RequestParam("file") MultipartFile file) {
                  try {
                      // 获取文件名
                      String fileName = file.getOriginalFilename();
                      // 将文件存储到指定目录
                      Path path = Paths.get(uploadDir, fileName);
                      Files.copy(file.getInputStream(), path, StandardCopyOption.REPLACE_EXISTING);
                      return ResponseEntity.ok("文件上传成功:" + fileName);
                  } catch (IOException e) {
                      e.printStackTrace();
                      return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                              .body("文件上传失败:" + e.getMessage());
                  }
              }
          }
          
      • 8.1.3 上传目录配置

        • 你可以在 application.properties 文件中指定文件上传的目录。例如:
        • # 文件存储路径
          file.upload-dir=./uploads
          
      • 8.1.4 上传多个文件

        • @PostMapping("/uploadMultiple")
          public ResponseEntity<String> uploadMultipleFiles(@RequestParam("files") List<MultipartFile> files) {
              for (MultipartFile file : files) {
                  // 保存每个文件
                  try {
                      String fileName = file.getOriginalFilename();
                      Path path = Paths.get(uploadDir, fileName);
                      Files.copy(file.getInputStream(), path, StandardCopyOption.REPLACE_EXISTING);
                  } catch (IOException e) {
                      e.printStackTrace();
                      return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                              .body("部分文件上传失败:" + e.getMessage());
                  }
              }
              return ResponseEntity.ok("所有文件上传成功");
          }
          
    • 8.2 文件下载

      • 8.2.1 实现文件下载接口

        • 下载文件的实现比较简单,通常使用 HttpServletResponse 来将文件内容写入响应流中,浏览器会自动处理并触发文件下载。

        • @RestController
          @RequestMapping("/api/files")
          public class FileDownloadController {
          
              @Value("${file.upload-dir}")
              private String uploadDir;  // 文件存储目录
          
              // 文件下载接口
              @GetMapping("/download/{fileName}")
              public ResponseEntity<Resource> downloadFile(@PathVariable String fileName) {
                  try {
                      // 获取文件路径
                      Path filePath = Paths.get(uploadDir).resolve(fileName).normalize();
                      // 如果文件不存在,抛出异常
                      Resource resource = new FileSystemResource(filePath);
                      if (!resource.exists()) {
                          throw new FileNotFoundException("文件未找到:" + fileName);
                      }
                      // 返回文件资源并设置下载的 Content-Disposition
                      return ResponseEntity.ok()
                              .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"")
                              .body(resource);
                  } catch (Exception e) {
                      e.printStackTrace();
                      return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
                  }
              }
          }
          
      • 8.2.2 设置响应头部以下载文件

        • 通过 Content-Disposition 响应头可以让浏览器以下载的形式处理文件而不是直接显示内容。上述代码中已经设置了这个头部:

        • .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"")
          

标签:web,请求,--,Spring,springframework,org,public,跨域
From: https://blog.csdn.net/pasaxiaorui/article/details/143618571

相关文章

  • 虚假新闻检测:CSV格式数据集的预处理与模型选择
    ✅作者简介:2022年博客新星第八。热爱国学的Java后端开发者,修心和技术同步精进。......
  • Linux 终端控件:实时时刻表
    为了看几点才能讨论所以设计的,因此这里面有一个自带的机房时间表,你直接跑就行写得很naive,因为没找到Linux有啥API接口因此你需要在终端里跑如果用Vscode推荐分一个终端挂着否则可以单开一个终端然后置顶终端各种部件和时刻详细信息都提供了快捷修改接口,设置项全都放在......
  • 案例:三次锁定(下)
    第二步:    在 Form1.cs 中完成以下代码usingDome16_三次锁定.service;usingDome16_三次锁定.service.serviceimpl;usingSystem;usingSystem.Collections.Generic;usingSystem.ComponentModel;usingSystem.Data;usingSystem.Drawing;usingSystem.Li......
  • 案例: 三次锁定(上)
    输入错了三次禁止登录,15分钟后才能继续.用数据库记录ErrorTimes,最后出错时间uLoginTime数据导入第一步:    在App.config中添加连接字符串<connectionStrings> <addname="conStr"connectionString="DataSource=WINGEL;InitialCatalog=People;Trust......
  • 90后斩获多家名企offer的小哥哥,做对了什么?
    我本人的上一份工作,职级是高级测试开发工程师,平时的工作是以功能项目测试为主,接口自动化、web自动化、性能测试工作中都有涉及,接口自动化框架已经可以独立负责搭建并维护,性能测试也是公司内自己独立负责,可以支持公司内各种压测活动的进行。我的短板是自动化框架的搭建,不是特别的......
  • Python介绍和基础运用
    python之基本介绍(1)什么是python?python是一门编程语言python是一门面向对象,解释型的动态类型的编程语言,guidovanrossunm(吉多*范罗苏姆),在1989年发明,第一个公开发行版本与1991年;guidovanrossunm(吉多*范罗苏姆)是荷兰计算机程序员(2)什么是面向对象?python中一切皆......
  • 数据源及分层开发
    数据源及分层开发文章目录数据源及分层开发1.使用Tomcat数据源1.1连接池工作原理1.2Tomcat配置数据源步骤2.使用JavaBean传递数据3.JSP动作标签jsp:useBeanjsp:include%@include%4.分层开发4.1传统的MVC架构4.2后端三层架构如何来做系统分层确定层次定义接口遵循设计......
  • AI巨头下场!Computer use横空出世! 揭秘实在Agent和Claude能力有啥区别?|实在Agent研究
    从Claude发布了像人一样操作电脑的能力之后,一直有小伙伴问我,实在Agent和Claude的computeruse能力有什么异同点。废话不多说,我们直接测试一波。AI巨头下场!揭秘实在Agent和Claude能力有啥区别?第一步、安装。目前Claude的computeruse,需要通过代码来部署,且需要提前充值;而实......
  • vue页签
    效果:快来学习:Vue3CompositionAPI和scriptsetup语法CompositionAPI:Vue3引入的CompositionAPI相比Vue2的OptionsAPI提供了更灵活的代码组织方式。使用setup函数,可以将组件的所有功能和逻辑集中在一起,方便复用。scriptsetup语法:Vue3的<scriptsetu......
  • 数学建模_BP神经网络预测新数据模型(多输入单输出)回归预测模型+Matlab代码包教会使用
    基于BP神经网络新数据预测的多输入单输出回归预测模型简介这段代码实现了一个BP神经网络BackpropagationNeuralNetwork用于回归预测任务,并包含新数据的预测功能。该模型通过多层前馈神经网络学习输入特征与目标变量之间的非线性映射关系,并使用反向传播算法优化权重和偏置......