(3)Springboot2核心功能

二 Web开发

(接上文)

2.7 文件上传

  1. 页面
<form method="post" action="/upload" enctype="multipart/form-data">
    <input type="file" name="file"><br>
    <input type="submit" value="提交">
</form>

  1. java
/**
     * MultipartFile 自动封装上传过来的文件
     */
    @PostMapping("/upload")
    public String upload(@RequestParam("email") String email,
                         @RequestParam("username") String username,
                         @RequestPart("headerImg") MultipartFile headerImg,
                         @RequestPart("photos") MultipartFile[] photos) throws IOException {

        log.info("上传的信息:email={},username={},headerImg={},photos={}",
                email,username,headerImg.getSize(),photos.length);

        if(!headerImg.isEmpty()){
            //保存到文件服务器,OSS服务器; 使用SpringBoot之后,上传功能也如此精简了
            String originalFilename = headerImg.getOriginalFilename();
            headerImg.transferTo(new File("H:\\cache\\"+originalFilename));
        }
        if(photos.length > 0){
            for (MultipartFile photo : photos) {
                if(!photo.isEmpty()){
                    String originalFilename = photo.getOriginalFilename();
                    photo.transferTo(new File("H:\\cache\\"+originalFilename));
                }
            }
        }
        return "main";
    }
  1. 自动配置原理

文件上传自动配置类-MultipartAutoConfiguration-MultipartProperties

  • 自动配置好了 StandardServletMultipartResolver 【文件上传解析器】
  • 原理步骤
    • 1.请求进来使用文件上传解析器判断(isMultipart)并封装(resolveMultipart,返回MultipartHttpServletRequest)文件上传请求
    • 2.参数解析器解析请求中的文件内容封装成MultipartFile
    • 3.将request中文件信息封装为一个Map;MultiValueMap<String, MultipartFile>
    • 4.使用FileCopyUtils实现文件流的拷贝
@PostMapping("/upload")
public String upload(@RequestParam("email") String email,
					 @RequestParam("username") String username,
					 @RequestPart("headerImg") MultipartFile headerImg,
					 @RequestPart("photos") MultipartFile[] photos)

2.8 错误处理 (TODO)

1、默认规则

  • 默认情况下,Spring Boot提供/error处理所有错误的映射
  • 对于机器客户端,它将生成JSON响应,其中包含错误,HTTP状态和异常消息的详细信息。
  • 对于浏览器客户端,响应一个“ whitelabel”错误视图,以HTML格式呈现相同的数据

2.9 Web原生组件注入(Servlet、Filter、Listener)

第一种方式: 使用Servlet API (推荐)

  • @ServletComponentScan(basePackages = "com.atguigu.admin") :指定原生Servlet组件都放在那里
  • @WebServlet(urlPatterns = "/my"):效果:直接响应,没有经过Spring的拦截器?
  • @WebFilter(urlPatterns={"/css/*","/images/*"})
  • @WebListener

第二种方式: 使用XXRegistrationBean

//注意:保证依赖的组件始终是单实例的!!!
// 十分重要!!!
@Configuration(proxyBeanMethods = true)
public class ServletConfiguration {

    @Bean
    public ServletRegistrationBean<MyServlet> servletRegistrationBean() {
        return new ServletRegistrationBean<>(new MyServlet(), "/myServlet2");
    }

    @Bean
    public FilterRegistrationBean<MyFilter> filterFilterRegistrationBean() {
        MyFilter myFilter = new MyFilter();
        FilterRegistrationBean<MyFilter> bean = new FilterRegistrationBean<MyFilter>();
        bean.setFilter(myFilter);
        bean.setUrlPatterns(Collections.singletonList("/myFilter2"));

        return bean;
    }

    @Bean
    public ServletListenerRegistrationBean<MyListener> servletListenerRegistrationBean() {
        return new ServletListenerRegistrationBean<>(new MyListener());
    }
}

扩展: DispatchServlet 如何注册进来

  • 容器中自动配置了 DispatcherServlet 属性绑定到 WebMvcProperties;对应的配置文件配置项是 spring.mvc
  • 通过 ServletRegistrationBean<DispatcherServlet>DispatcherServlet 配置进来。
  • 默认映射的是 / 路径

Tomcat-Servlet
多个Servlet都能处理到同一层路径,精确匹配原则,比如
A: /my/
B: /my/1
因此, 当同时存在 /my 和 /my/1 的URL 时, /my1 会首先命中; 这就意味着 下图中的 /my 会由Tomcat处理, 而 不会经过 dispatcherServlet, 这会让 /my不能被Spring捕获,那些拦截器可能会不起作用
在这里插入图片描述

2.10 servlet web server

2.10.1 如何切换

  • 默认支持的webServer
    • Tomcat, Jetty, or Undertow
    • ServletWebServerApplicationContext 容器启动寻找ServletWebServerFactory 并引导创建服务器
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>

2.10.2 嵌入式servlet web server启动原理

  • SpringBoot应用启动发现当前是Web应用。web场景包-导入tomcat starter
  • web应用会创建一个web版的ioc容器 ServletWebServerApplicationContext
  • ServletWebServerApplicationContext 启动的时候寻找 ServletWebServerFactory(Servlet 的web服务器工厂—> Servlet 的web服务器)
  • SpringBoot底层默认有很多的WebServer工厂:TomcatServletWebServerFactory, JettyServletWebServerFactory, or UndertowServletWebServerFactory
  • 底层直接会有一个自动配置类:ServletWebServerFactoryAutoConfiguration
  • ServletWebServerFactoryAutoConfiguration导入了ServletWebServerFactoryConfiguration(配置类)
  • ServletWebServerFactoryConfiguration 配置类 根据动态判断系统中到底导入了那个Web服务器的包。(默认是web-starter导入tomcat包),容器中就有 TomcatServletWebServerFactory
  • TomcatServletWebServerFactory 创建出Tomcat服务器并启动;TomcatWebServer 的构造器拥有初始化方法initializethis.tomcat.start();
  • 内嵌服务器,就是手动把启动服务器的代码调用(tomcat核心jar包存在)

2.10.3 如何定制自己的Servlet Web

  • 实现WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>
    • 把配置文件的值和 ServletWebServerFactory 进行绑定
  • 修改配置文件 server.xxx
  • 直接自定义 ConfigurableServletWebServerFactory

xxxxxCustomizer:定制化器,可以改变xxxx的默认规则.

@Component
public class CustomizationBean implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {

    @Override
    public void customize(ConfigurableServletWebServerFactory server) {
        server.setPort(9000);
    }

}

2.11 ServletWebServer定制原理

2.11.1 定制化的常见方式

  1. 方式一:修改配置文件
  2. 方式二: xxxxxCustomizer
  3. 方式三: 编写自定义的配置类 xxxConfiguration+ @Bean替换、增加容器中默认组件;视图解析器
  4. Web应用 编写一个配置类实现 WebMvcConfigurer 即可定制化web功能 + @Bean给容器中再扩展一些组件
@Configuration
public class AdminWebConfig implements WebMvcConfigurer
  • @EnableWebMvc + WebMvcConfigurer ——@Bean 可以全面接管SpringMVC,所有规则全部自己重新配置;实现定制和扩展功能; 原理如下:
    • 1、WebMvcAutoConfiguration 默认的SpringMVC的自动配置功能类。静态资源、欢迎页…
    • 2、一旦使用 @EnableWebMvc@Import(DelegatingWebMvcConfiguration.class)
    • 3、DelegatingWebMvcConfiguration 的只保证SpringMVC最基本的使用, 不会把静态资源的处理也加上. 它会:
      • 把系统所有的 WebMvcConfigurer (不管是一个类多个@Bean, 还是多个类)拿过来。所有功能的定制都是这些 WebMvcConfigurer合起来一起生效
      • 自动配置了一些非常底层的组件,RequestMappingHandlerMapping这些组件依赖的组件都是从容器中获取
      • public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport
    • 4、WebMvcAutoConfiguration 里面的配置要能生效 必须 @ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
    • 5、@EnableWebMvc 会导致 WebMvcAutoConfiguration不生效。

2.11.2 原理分析套路

场景starter - xxxxAutoConfiguration - 导入xxx组件 - 绑定xxxProperties – 绑定配置文件项

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值