• 小白学习spring第四天


    第三章:SpringMVC

    第1节:基本概念

    1.1 三层架构和MVC
    		我们的开发架构一般都是基于两种形式,一种是 C/S 架构,也就是客户端/服务器,另一种是 B/S 架构,也就是浏览器服务器。在 JavaEE 开发中,几乎全都是基于 Browser/S 架构的开发。那么在 B/S 架构中,系统标准的三层架构
    包括:表现层(web)、业务层(service)、持久层(dao)。三层架构在我们的实际开发中使用的非常多,所以我们课程中的案例也都是基于三层架构设计的。
          
    三层架构中,每一层各司其职,接下来我们就说说每层都负责哪些方面:
    (1)表现层(表示层,web):也就是我们常说的web层。它负责接收客户端请求,向客户端响应结果,通常客户端使用http协议请求web 层,web 需要接收 http 请求,完成 http 响应。
    表现层包括展示层和控制层:控制层负责接收请求,展示层负责结果的展示。	
    (2)业务层:也就是我们常说的 service 层。它负责业务逻辑处理,和我们开发项目的需求息息相关。	
    (3)持久层(Dao data access  object):也就是我们是常说的 dao 层。负责数据持久化,和数据库做交互。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    1.2 SpringMVC概述
    1.2.1 介绍
    		SpringMVC是一个基于Java的实现了MVC设计模式的请求驱动类型的轻量级Web框架,通过把ModelViewController分离,将web层进行职责解耦,把复杂的web应用分成逻辑清晰的几部分,简化开发,减少出错,方便组内开发人员之间的配合。
    
    百科介绍:
    		Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。使用 Spring 可插入的 MVC 架构,从而在使用Spring进行WEB开发时,可以选择使用SpringSpring MVC框架或集成其他MVC开发框架,如Struts1(现在一般不用)Struts 2(一般老项目使用)等等。
    
    总结: 
    		springmvc 是应用web层的 基于MVC设计模式的轻量级的web框架。 对Servlet封装,支持restful风格。
    官网: 
    	https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#spring-web
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    springMVC位于三层架构中的表现层,作用是接收请求响应数据,响应的数据通过视图、模板展示给用: 
    数据访问层:  Mybatis DButils JdbcTemplate Jdbc | Mybatis-plus | mapper Hibernate JPA  
    业务层:    spring框架: IOC提供对象, 声明式事务~ 
    表现层:    springMVC Servlet | Struts2(很少)  Struts1 
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    1.2.2 优势
    1)清晰的角色划分。
    (2)分工明确,而且扩展点相当灵活,可以很容易扩展,虽然几乎不需要。 
    (3)POJO 就可以充当控制器,屏蔽了繁琐的servlet的API
    (4)和 Spring 其他框架无缝集成,是其它 Web 框架所不具备的。 
    (5)可适配,通过 HandlerAdapter 可以支持任意的类作为处理器。 
    (6)可定制性,HandlerMappingViewResolver 等能够非常简单的定制。 
    (7)功能强大的数据验证、格式化、绑定机制。 
    		………………还有比如RESTful风格的支持、简单的文件上传、约定大于配置的契约式编程支持、基于注解的零配
    置支持等等。
    
    约定优于配置, 配置优于编码~ 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    第2节:使用

    2.1 入门案例
    2.1.1 需求分析
    构建页面index.jsp发起请求,在服务器端处理请求,控制台打印处理请求成功,跳转success.jsp成功页面;
    
    • 1
    2.1.2 添加依赖
    注意:  maven war   工程打包方式war。 
    <dependency>
        <groupId>org.springframeworkgroupId>
        <artifactId>spring-webmvcartifactId>
        <version>5.2.5.RELEASEversion>
    dependency>
    
    <dependency>
        <groupId>org.springframeworkgroupId>
        <artifactId>spring-contextartifactId>
        <version>5.2.5.RELEASEversion>
    dependency>
    
    总结: springmvc: webmvc web
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    2.1.3 配置web.xml
    <servlet>
        <servlet-name>springmvc01servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
        <init-param>
            <param-name>contextConfigLocationparam-name>
            <param-value>classpath:springmvc.xmlparam-value>
        init-param>
    servlet>
    <servlet-mapping>
        <servlet-name>springmvc01servlet-name>
        <url-pattern>/url-pattern>
    servlet-mapping>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    2.1.4 配置springmvc.xml
     	
        <context:component-scan base-package="com.offcn.controller">context:component-scan>
        
    	
       <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">bean>
    
        
        <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">bean>
    
        
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/">property>
            <property name="suffix" value=".jsp">property>
        bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    2.1.5 构建页面发起请求
    <a href="/hello/test1">helloa>
    
    • 1
    2.1.6 编写控制器并使用注解配置
    @Controller //必须开启注解扫描
    @RequestMapping("hello")
    public class HelloController {
        @RequestMapping("test1")
        public String test1(){
            System.out.println("正在处理请求");
            return "success";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    2.1.7 启动服务器测试
    pom.xml文件中服务器插件配置:
     <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.tomcat.mavengroupId>
                    <artifactId>tomcat7-maven-pluginartifactId>
                    <version>2.2version>
                    <configuration>
                        
                        <uriEncoding>utf-8uriEncoding>
                        
                        <path>/path>
                        
                        <port>8888port>
                    configuration>
                plugin>
            plugins>
        build>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    2.2 执行过程及原理分析
    		浏览器发送请求,被DispatcherServlet捕获,DispatcherServlet没有直接处理请求,而是将请求交给HandlerMapping处理器映射器,处理器映射器根据请求路径去controller控制层中匹配对应的执行器,并将匹配结果返回给DispatcherServlet,由DispacherServlet调用HandlerAdapter处理器适配器来执行控制层执行器方法;
    执行器方法执行后的返回结果,由DispatcherServlet交给视图解析器ViewResolver来处理,找到对应的结果视图,渲染视图,并将结果响应给浏览器。
    
    http://localhost:8080/xxx/servlet
    (1)客户端浏览器发出请求, 到达DispatcherServlet前端控制器。 springmvc 框架提供的。  
    (2)DispatcherServlet 将请求交给了 处理器映射器,进行路径映射。映射结果交给前端控制器。 
    (3)请求到达处理器适配器,可以进行数据类型的转换等操作,最后达到Handler。【后端处理器,自定义的 Servlet(4)后端处理器处理完毕之后, 将结果经过处理器适配器最终交给 前端控制器。 
    (5)经过视图解析器: 数据解析到 view 对象当中。  交给了前端控制器
    (6)前端控制器将view对象 交给模板引擎,进行试图渲染。 最终生成静态页面,响应给用户。 
    
    以下组件: 
    一个中心是三个基本点: 不需要自己开发,springmvc提供的
    一个中心: DispatcherServlet 
    三个基本点: 处理器映射器  处理器适配器  试图解析器
    Handler后端处理器:程序员自己开发~ 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    在这里插入图片描述

    第3节:常用组件介绍

    3.1 DispatcherServlet
    		用户请求到达前端控制器,它就相当于 mvc 模式中的 controller,dispatcherServlet 是整个流程控制的中心,由它调用其它组件处理用户的请求,dispatcherServlet 的存在降低了组件之间的耦合性。 
    		DispatcherServlet本质上就是servlet web.xml当中。 该组件是springMVC 提供的, 无所编写,只需配制。
    
    • 1
    • 2
    3.2 HandlerMapping
    		HandlerMapping 负责根据用户请求找到 Handler 即处理器,SpringMVC提供了不同的映射器实现不同的映射方式: 
    该组件: springMVC提供的。 无需编写
    
    • 1
    • 2
    3.3 Handler
    它就是我们开发中要编写的具体业务控制器。由 DispatcherServlet 把用户请求转发到 Handler。由Handler 对具体的用户请求进行处理。 
    等价于之前编写的Servlet。后端逻辑处理 【程序员编写】
    
    • 1
    • 2
    3.4 HandlAdapter
    通过 HandlerAdapter 对处理器进行执行, 适配器主要进行数据类型类转换等操作~  
    该组件: 无需编写, 只需配置~ 
    
    • 1
    • 2
    3.5 View Resolver
    		View Resolver 负责将处理结果(ModelAndView)生成 View 对象,将view对象返回给前端控制器。 
    注意: 组件springmvc提供的, 如果不使用,可以不用配置。  
          如果要使用,自行配置试图解析器~ 
    
    
    • 1
    • 2
    • 3
    • 4
    3.6 View:视图渲染
    SpringMVC 框架提供了很多的 View 视图类型的支持,包括:jsp、freemarkerView、pdfView,FreeMark ,thymeleaf 等。我们最常用的视图就是 jsp。之后的学习, 我们会学习静态模板技术~  
    view对象的数据渲染到页面上。 
    
    总结: 
    springmvc 基于组件开发: 
    DispatcherServlet: 一个中心
    三个基本点:
        处理器映射器: 
        处理器适配器: 
        试图解析器: 
        
    后端处理器: 类似与servlet, 程序员自定义。 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    3.7 特殊标签说明
    		在 SpringMVC 的各个组件中,处理器映射器、处理器适配器、视图解析器称为 SpringMVC 的三大组件。使用  自动加载 RequestMappingHandlerMapping(处理映射器)和RequestMappingHandlerAdapter ( 处 理 适 配 器 ),可 用 在 SpringMVC.xml 配 置 文 件 中 使 用替代处理映射器和适配器的配置(一般开发中都需要该标签)。注意:我们只需要编写处理具体业务的控制器以及视图。
        
     
    标签相当于以下配置:
     
     
    
        
     
     
    
    
        
     
     
     
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    第4节:请求参数绑定【重点】

    4.1 绑定说明
    4.1.1 绑定的机制
    我们都知道,表单中请求参数都是基于 key=value 的。SpringMVC绑定请求参数的过程是通过把表单提交请求参数,作为控制器中方法参数进行绑定的。
    
    获得前端页面提交的参数:
    request.getParameter("username");
    String [] values = request.getParameterValues("hobby");
    request.getParameterMap(); => Map集合
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    4.1.2 支持的数据类型
    简单类型参数:包括基本类型和 String 类型
    POJO 类型参数:包括实体类,以及关联的实体类
    数组和集合类型参数:包括 List 结构和 Map 结构的集合(包括数组)
    
    • 1
    • 2
    • 3
    4.1.3 使用要求
    如果是基本类型或者 String 类型:要求我们的参数名称必须和控制器中方法的形参名称保持一致。(严格区分大小写)
    如果是 POJO 类型,或者它的关联对象:要求表单中参数名称和 POJO 类的属性名称保持一致。并且控制器方法的参数类型是 POJO 类型。
    如果是集合类型,有两种方式:
    (1)第一种:要求集合类型的请求参数必须在 POJO 中。在表单中请求参数名称要和 POJO 中集合属性名称相同。给 List 集合中的元素赋值,使用下标。给 Map 集合中的元素赋值,使用键值对。
    (2)第二种:接收的请求参数是 json 格式数据。需要借助一个注解实现。 @RequestBody注解
    
    • 1
    • 2
    • 3
    • 4
    • 5
    4.2 参数绑定示例
    4.2.1 基本类型和 String 类型作为参数
    1)页面定义请求:
    <form action="/hello/test2" method="post">
        用户名:<input name="userName" type="text">
        年龄:<input name="age" type="text">
        <input type="submit" value="提交">
    </form>2)执行器方法绑定参数:
     @RequestMapping("test2")
        public String test2(String userName,int age){
            System.out.println("用户名:"+userName);
            System.out.println("年龄:"+age);
            return "main";
        }
    注意: 参数提交的名称和方法形式参数的名称保持一致。 否则封装失败~  ,并且能够进行数据类型的转换。 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    4.2.2 POJO 类型作为参数
    1)页面定义请求:
    <form action="/hello/test3" >
        用户名:<input name="pname" type="text">
        年龄:<input name="age" type="text">
        车名称:<input name="car.cname" type="text">
        车价格:<input name="car.cprice" type="text">
        <input type="submit" value="提交">
    </form>2)执行器方法绑定参数:
     @RequestMapping("test3")
        public String test3(Person person){
            System.out.println(person);
            return "main";
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    4.2.3 POJO 类中包含集合类型参数(了解)
    集合类型,不能直接绑定在方法的形式参数上。 
    (1)页面定义请求:
    <form action="/hello/test4" >
        用户名:<input name="pname" type="text">
        年龄:<input name="age" type="text">
        车名称:<input name="car.cname" type="text">
        车价格:<input name="car.cprice" type="text">
        list集合车1:车名称<input name="carList[0].cname" type="text">
        list集合车1:车价格<input name="carList[0].cprice" type="text">
        list集合车2:车名称<input name="carList[1].cname" type="text">
        list集合车2:车价格<input name="carList[1].cprice" type="text">
        set集合车1:车名称<input name="carSet[0].cname" type="text">
        set集合车1:车价格<input name="carSet[0].cprice" type="text">
        set集合车2:车名称<input name="carSet[1].cname" type="text">
        set集合车2:车价格<input name="carSet[1].cprice" type="text">
        map集合车1:车名称<input name="map['x'].cname" type="text">
        map集合车1:车价格<input name="map['x'].cprice" type="text">
        map集合车2:车名称<input name="map['y'].cname" type="text">
        map集合车2:车价格<input name="map['y'].cprice" type="text">
        <input type="submit" value="提交">
    </form>2)执行器方法绑定参数:
      @RequestMapping("test4")
        public String test4(Person person){
            System.out.println(person);
            return "main";
        }
    
    注意: set集合:---【了解】 
     (1)set集合必须创建 :new HashSet<>();2)set集合提供set 和get 方法
     (3)在构造器当中明确set集合当中添加的元素个数
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    4.2.4 数组类型参数(重点)
    1)页面定义请求:
    <form action="/hello/test5" >
        爱好1<input name="hobbies" type="text">
        爱好2<input name="hobbies" type="text">
        爱好3<input name="hobbies" type="text">
        <input type="submit" value="提交">
    </form>2)执行器方法绑定参数:
       @RequestMapping("test5")
        public String test5(String[] hobbies){
            for(String hobby:hobbies){
                System.out.println(hobby);
            }
            return "main";
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    4.2.5 使用 ServletAPI 对象作为方法参数
    1)引入servletAPI的依赖jar包:(注意jar包作用范围provided:不参与项目部署)
    		 <!--web: servlet ,jsp, jstl -->
        <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>javax.servlet-api</artifactId>
          <version>3.1.0</version>
          <scope>provided</scope>
        </dependency>
    
        <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>jsp-api</artifactId>
          <version>2.0</version>
          <scope>provided</scope>
        </dependency>
    
        <dependency>
          <groupId>jstl</groupId>
          <artifactId>jstl</artifactId>
          <version>1.2</version>
        </dependency>2)执行器方法绑定参数:
        @RequestMapping("test6")
        public void test6(HttpServletRequest request, HttpServletResponse response,HttpSession session) throws ServletException, IOException {
            System.out.println("我在请求转发");
            request.getRequestDispatcher("/hello/test1").forward(request,response);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    4.2.6 请求参数乱码问题
    tomacat 对 GET 和 POST 请求处理方式是不同的:
    (1)GET 请求的编码问题,要改 tomcat 的 server.xml配置文件:【了解】
      
        
    	<Connector connectionTimeout="20000" port="8080"protocol="HTTP/1.1" redirectPort="8443" URIEncoding="UTF-8"/>
    
     使用的方式:  在配置tomcat插件的时候,指定一个tomcat字符集编码。 
     <uriEncoding>utf-8uriEncoding>
      
    (2)POST 请求的编码问题,要在web.xml文件中配置编码过滤器:
        <filter>
            <filter-name>characterEncodingFilterfilter-name>
            <filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
            <init-param>
                <param-name>encodingparam-name>
                <param-value>utf-8param-value>
            init-param>
        filter>
        <filter-mapping>
            <filter-name>characterEncodingFilterfilter-name>
            <url-pattern>/*url-pattern>
        filter-mapping>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    4.2.7 静态资源访问
    (1)将静态资源交给默认的DefaultServlet处理:在springMVC.xml配置文件中加如下配置:
    	<mvc:default-servlet-handler>mvc:default-servlet-handler>
    (2)指定静态资源的访问路径:在springMVC.xml配置文件中加如下配置:
    	<mvc:resources location="/css/" mapping="/css/**"/>
    	<mvc:resources location="/images/" mapping="/images/**"/>
    	<mvc:resources location="/js/" mapping="/js/**"/>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    4.3 自定义参数类型转换器
    4.3.1 使用场景
    SpringMVC不能自动识别参数转换为我们需要的数据类型,浏览器报400错误,类型转换异常;
    
    默认支持的类型: yyyy/MM/dd  
    如果需要使用自定义的类型:此时就需要类型转换器
    开发步骤: 
    (1)开发一个类型转换器  implements Converter<String, Date>2)将自定义的类型转换器配置在工厂当中: 
    (3)在注解当中引用工厂: <mvc:annotation-driven conversion-service="serviceFactoryBean" /> 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    4.3.2 使用步骤
    1)定义类型转换器;
    public class MyDateConverter implements Converter<String, Date> {
        @Override
        public Date convert(String source) {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
            Date date = null;
            try {
                date=simpleDateFormat.parse(source);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            return date;
        }
    }2)配置类型转换器;
     <bean id="formattingConversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
            <property name="converters">
                <bean class="com.offcn.util.MyDateConverter"></bean>
            </property>
        </bean>3)引用类型转换器;	
     引用自定义的类型转换器: 
     <mvc:annotation-driven conversion-service="formattingConversionService" />
    
         
    <form action="/hello/test7" >
        入职日期:<input name="hireDate" type="date">
        <input type="submit" value="提交">
    </form>
    
     @RequestMapping("test7")
        public String test7(Date hireDate){
            System.out.println(hireDate);
            return "main";
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    4.4 参数绑定默认类型
    参数绑定:默认类型:Map<String,Object> ModelAndView  Model ModelMap 类型,能够给前台传递。
    
    • 1
    @RequestMapping(path="hello01")
        public ModelAndView modelAndView(User user, Map<String,String> map){
            System.out.println(user);
            ModelAndView mav = new ModelAndView();
            map.put("username",user.getUsername());
            mav.setViewName("success");
            return  mav;
    
    }
    
     @RequestMapping(path="hello01")
        public ModelAndView modelAndView(User user, ModelMap model){
            System.out.println(user);
            ModelAndView mav = new ModelAndView();
            model.addAttribute("username",user.getUsername());
            mav.setViewName("success");
            return  mav;
        }
    
     @RequestMapping("findById")
        public ModelAndView findById(Integer id, Model model){
            Person person = new Person();
            person.setAge(29);
            person.setName("许~");
            person.setBirthday(new Date());
            //视图路径的跳转:
            ModelAndView modelAndView = new ModelAndView();
            modelAndView.setViewName("success");
    
            //存在Model当中: 传递给前台:
            model.addAttribute("person",person);
            return modelAndView;
    
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
  • 相关阅读:
    ubuntu 18.04安装pycharm及编译环境配置
    ssm欢欢宠物医院管理系统的设计与实现毕业设计源码171734
    基于Python网络爬虫的IT招聘就业岗位可视化分析推荐系统
    深入理解Kotlin协程
    vue3.0 实现图片延迟加载 自定义属性
    字符流用户注册案例、字符缓冲流、字符缓冲流特有功能、字符缓冲流操作文件中的数据排序案例
    【Flink读写外部系统】Flink异步访问外部系统_mysql
    LinkedIn领英开发客户方法大全(篇一)
    JS--localStorage设置过期时间的方案(有示例)
    LuatOS-SOC接口文档(air780E)--coremark - 跑分
  • 原文地址:https://blog.csdn.net/sjxxxx_/article/details/127638002