主頁 > 後端開發 > Spring Boot

Spring Boot

2022-04-29 06:24:39 後端開發

Spring Boot

1 Spring Boot入門

1.1 Spring Boot特性:
  • 能夠快速創建基于 Spring 的應用程式
  • 能夠直接使用 java main 方法啟動內嵌的 Tomcat 服務器運行 Spring Boot 程式,不需 要部署 war 包檔案
  • 提供約定的 starter POM 來簡化 Maven 配置,讓 Maven 的配置變得簡單
  • 自動化配置,根據專案的 Maven 依賴配置,Spring boot 自動配置 Spring、Spring mvc 等
  • 提供了程式的健康檢查等功能
  • 基本可以完全不使用 XML 組態檔,采用注解配置
1.2 SpringMvc常用注解:
1.2.1 @Controller
  • Spring MVC 的注解,處理 http 請求
1.2.2 @RestController
  • Spring 4 后新增注解,是@Controller 注解功能的增強 是 @Controller 與@ResponseBody 的組合注解 如果一個 Controller 類添加了@RestController,那么該 Controller 類下的所有方法都相當 于添加了@ResponseBody 注解 用于回傳字串或 json 資料
1.2.3 @RequestMapping(常用)
  • 支持 Get 請求,也支持 Post 請求
1.2.4 @GetMapping
  • RequestMapping 和 Get 請求方法的組合 只支持 Get 請求 Get 請求主要用于查詢操作
1.2.5 @PostMapping
  • RequestMapping 和 Post 請求方法的組合 只支持 Post 請求 Post 請求主要用戶新增資料
1.2.6 @PutMapping
  • RequestMapping 和 Put 請求方法的組合 只支持 Put 請求 Put 通常用于修改資料
1.2.7 @DeleteMapping
  • RequestMapping 和 Delete 請求方法的組合 只支持 Delete 請求 通常用于洗掉資料

    • /**
      * 該案例主要演示了使用 Spring 提供的不同注解接收不同型別的請求
      */
      //RestController 注解相當于加了給方法加了@ResponseBody 注解,所以是不能跳轉頁面的,
      只能回傳字串或者 json 資料
      @RestController
      public class MVCC
      ontroller {
           @GetMapping(value = "https://www.cnblogs.com/query")
           public String get() 
      	{
           return "@GetMapping 注解,通常查詢時使用";
           }
      
           @PostMapping(value = "https://www.cnblogs.com/add")
           public String add() 
      	{
           return "@PostMapping 注解,通常新增時使用";
           }
      
           @PutMapping(value = "https://www.cnblogs.com/modify")
           public String modify() 
      	{
           return "@PutMapping 注解,通常更新資料時使用";
           }
      
           @DeleteMapping(value = "https://www.cnblogs.com/remove")
           public String remove() 
      	{
           return "@DeleteMapping 注解,通常洗掉資料時使用";
       	}
      }
      
1.2.8 @ResponseBody
  • 不加這個注解可以回傳一個自定義html頁面
  • 加這個注解回傳return后面的東西,
1.2 Spring Boot四大核心:
  • 自動配置
  • 起步依賴
  • Actuator
  • 命令列界面
1.3 核心組態檔
  • 在SpringBoot中核心組態檔一般只有一個,如果這兩種核心組態檔同時存在,那專案會優先讀取application.properties中的組態檔,

  • application.properties
    • 設定內嵌tomcat內嵌埠號:

      • server.port=9090
        
    • 設定背景關系根

      • server.servlet.context-path=/txzmy
        
    • 修改前

    • 修改后:

  • application.yml(.yaml)
    • 設定內嵌tomcat埠號和背景關系根:

    • 在使用這種方式時,先洗掉application.properties,后新建一個file,核心檔案的命名必須以application開頭,這種方式類似與python的縮進,

    • server:
        port: 9090
        servlet:
          context-path: /txzmy
      
1.4 多環境下配置核心檔案
  • 作業中的四種環境:開發環境,測驗環境,準生產環境,生產環境,在不同的環境下同一個網頁的訪問網址不同,核心檔案配置不同,

  • 添加其他環境下的核心組態檔必須以application-開頭,

    • #主核心組態檔
      #激活使用的組態檔
      #等號后面只需要跟已定的核心組態檔的名稱
      spring.profiles.active=dev
      
  • 三種不同檔案型別的核心組態檔寫法相似,

1.5 自定義配置
1.5.1 獲取自定義配置:
  • 我們可以在核心組態檔或者其他檔案里設定一些值,通過注解@value可以訪問到這些值,

    • #主核心組態檔
      #激活使用的組態檔
      spring.profiles.active=dev
      
      
      #設定自定義的值
      schoolName=CTGU
      stuName=tx
      
      
      #方法類
      package com.txzmy.springboot;
      
      import org.springframework.beans.factory.annotation.Value;
      import org.springframework.stereotype.Controller;
      import org.springframework.web.bind.annotation.RequestBody;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.ResponseBody;
      import org.springframework.web.bind.annotation.RestController;
      
      @Controller
      public class Index {
          @Value("${schoolName}")
          public String schoolName;
      
          @Value("${stuName}")
          public String stuName;
      
          @RequestMapping(value = "https://www.cnblogs.com/hello")
      
          public @ResponseBody String hello()
          {
              return "hello,"+stuName+" from "+schoolName;
          }
      
      }
      
      
    • 通過域名http://localhost:7070/dev/hello訪問結果:hello,tx from CTGU

1.5.2 將自定義配置映射到物件
  • 在用@Value時我們只能一個一個的取值,我們可以通過@Component和@ConfigurationProperties將檔案中的值映射到物件中,配置物件必須有統一的前綴,直接上代碼:

    • #主核心組態檔
      #激活使用的組態檔
      spring.profiles.active=dev
      
      
      #設定自定義的值
      school.Name=CTGU
      school.stuName=tx
      
      
      
      //被映射的類
      #package com.txzmy.springboot;
      import org.springframework.boot.context.properties.ConfigurationProperties;
      import org.springframework.stereotype.Component;
      
      //將拿到的值交給spring容器管理
      @Component  
      //@ConfigurationProperties必須有個前綴,即上面設定的自定義值的前綴,后面可以不帶這個前綴,
      @ConfigurationProperties(prefix = "school")
      public class school {
          private String Name;
          private String stuName;
          public String getName() {
              return Name;
          }
          public void setName(String name) {
              Name = name;
          }
          public String getStuName() {
              return stuName;
          }
          public void setStuName(String stuName) {
              this.stuName = stuName;
          }
      }
      
      
      //方法類
      package com.txzmy.springboot;
      
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.beans.factory.annotation.Value;
      import org.springframework.stereotype.Controller;
      import org.springframework.web.bind.annotation.RequestBody;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.ResponseBody;
      import org.springframework.web.bind.annotation.RestController;
      @Controller
      public class Index {
          @Autowired
          public school school;
          @RequestMapping(value = "https://www.cnblogs.com/hello")
      
          public @ResponseBody String hello()
          {
              return "hello,"+school.getStuName()+" from "+school.getName();
          }
      
      }
      
      
      
    • 運行結果:hello,tx from CTGU

1.6 SpringBoot集成JSP
1.6.1 創建存放JSP檔案的檔案夾:
  • 在專案main檔案夾下新建一個檔案夾->在file選單欄中選擇Project Structure->選擇Modules->在旁邊的專案檔案了選中剛剛創建的檔案夾(用來存放JSP檔案的檔案夾)->點擊右邊中間的+號,再次選中剛剛創建的檔案夾,最后apply再ok就完成了,
1.6.2 添加SpringBoot內嵌的Tomcat對JSp的決議依賴:
  • <!-- 引入SpringBoot內嵌的Tomcat對JSp的決議依賴,不添加決議不了-->
    <!-- 在這里我們僅僅展示JSP頁面,只添加下面一個依賴-->
    
            <dependency>
                <groupId>org.apache.tomcat.embed</groupId>
                <artifactId>tomcat-embed-jsper</artifactId>
            </dependency>
    
1.6.3 指定JSP編譯的路徑及檔案夾專案:
  • <build>
    
        <!--
        Springboot專案默認推薦使用的前端引擎是thymeleaf
        現在我們要使用springboot集成jsp,手動指定jsp最后編譯的路徑
        而且springboot集成jsp編譯jsp的路徑是springboot規定好的位置
        MFTA-TNF /resources
        -->
        <resources>
            <resource>
            <!-- 源檔案夾-->
                <directory>src/main/webapp</directory>
            <!--指定編譯到META-INF/reserous-->
                <targetPath>META-INF/reserous</targetPath>
            <!--指定源檔案夾的那個檔案要編譯-->
                <includes>
                    <include>*.*</include>
                </includes>
            </resource>
        </resources>
    
    
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
    
1.6.4 在核心組態檔里配置視圖決議器:
  • 核心組態檔:application.properties

  • #配置視圖決議器
    #配置前綴
    spring.mvc.view.prefix=/
    #配置后綴
    spring.mvc.view.suffix=/jsp
    
    • @Controller
      public class Index {
      
          @RequestMapping(value = "https://www.cnblogs.com/hello")
          public  ModelAndView hello()
          {
              ModelAndView mv = new ModelAndView();
              mv.addObject("message","Hello SpringBoot");
              mv.setViewName("hello");
              return  mv;
          }
      
      
      }
      

2 Spring Boot框架Web開發:

2.1 集成Mybatis:
2.1.1 添加起步依賴:
  • <!--mysql驅動-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    
    <!--MyBatis整合SpringBoot框架的起步依賴-->
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
    </dependency>
    
2.1.2 關于MySQL的安裝參考推薦:
  • ? https://www.jb51.net/article/193731.htm
2.1.3 逆向工程:
  • Mybatis提供的逆向工程可以生成物體bean,映射檔案,DAO介面:

  • 需要添加的組態檔:

    • 在專案的根目錄下添加GeneratorMapper.xml檔案,檔案具體內容如下:

      • <?xml version="1.0" encoding="UTF-8"?>
        <!DOCTYPE generatorConfiguration
                PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
                "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
        <generatorConfiguration>
            <!-- 指定連接資料庫的 JDBC 驅動包所在位置,指定到你本機的完整路徑 -->
            <classPathEntry location="D:/mysql-downloads/mysql-connector-java-5.1.49/mysql-connector-java-5.1.49/mysql-connector-java-5.1.49.jar"/>
            <!-- 配置 table 表資訊內容體,targetRuntime 指定采用 MyBatis3 的版本 -->
            <context id="txzmy" targetRuntime="MyBatis3">
                <!-- 抑制生成注釋,由于生成的注釋都是英文的,可以不讓它生成 -->
                <commentGenerator>
                    <property name="suppressAllComments" value="https://www.cnblogs.com/txzmy/p/true" />
                </commentGenerator>
                <!-- 配置資料庫連接資訊 -->
                <jdbcConnection driver
        
                                connectionURL="jdbc:mysql://localhost:3306"
                                userId="root"
                                password="Tx110304..">
                </jdbcConnection>
                <!-- 生成 model 類,targetPackage 指定 model 類的包名, targetProject 指定
               生成的 model 放在 eclipse 的哪個工程下面-->
                <javaModelGenerator targetPackage="comzmy.model"
                                    targetProject="src/main/java">
                    <property name="enableSubPackages" value="https://www.cnblogs.com/txzmy/p/false" />
                    <property name="trimStrings" value="https://www.cnblogs.com/txzmy/p/false" />
                </javaModelGenerator>
                <!-- 生成 MyBatis 的 Mapper.xml 檔案,targetPackage 指定 mapper.xml 檔案的
               包名, targetProject 指定生成的 mapper.xml 放在 eclipse 的哪個工程下面 -->
                <sqlMapGenerator targetPackage="comzmy.mapper"
                                 targetProject="src/main/java">
                    <property name="enableSubPackages" value="https://www.cnblogs.com/txzmy/p/false" />
                </sqlMapGenerator>
                <!-- 生成 MyBatis 的 Mapper 介面類檔案,targetPackage 指定 Mapper 介面類的包
               名, targetProject 指定生成的 Mapper 介面放在 eclipse 的哪個工程下面 -->
                <javaClientGenerator type="XMLMAPPER"
                                     targetPackage="comzmy.mapper" targetProject="src/main/java">
                    <property name="enableSubPackages" value="https://www.cnblogs.com/txzmy/p/false" />
                </javaClientGenerator>
                <!-- 資料庫表名及對應的 Java 模型類名 -->
                <table tableName="student" domainObjectName="Student"
                       enableCountByExample="false"
                       enableUpdateByExample="false"
                       enableDeleteByExample="false"
                enableSelectByExample="false"
                selectByExampleQueryId="false"/>
            </context>
        </generatorConfiguration>
        
    • 在專案檔案pom.xml中添加依賴:

      • <!--MyBatis 集成 SpringBoot 框架起步依賴-->
           <dependency>
               <groupId>org.mybatis.spring.boot</groupId>
               <artifactId>mybatis-spring-boot-starter</artifactId>
               <version>2.0.1</version>
           </dependency>
           <!--MySQL 驅動-->
           <dependency>
               <groupId>mysql</groupId>
               <artifactId>mysql-connector-java</artifactId>
           </dependency>
        </dependencies>
        <build>
            <!--指定配置資源的位置-->
            <resources>
                <resource>
                    <directory>src/main/java</directory>
                    <includes>
                        <include>**/*.xml</include>
                    </includes>
                </resource>
            </resources>
            <plugins>
                <!--mybatis 代碼自動生成插件-->
                <plugin>
                    <groupId>org.mybatis.generator</groupId>
                    <artifactId>mybatis-generator-maven-plugin</artifactId>
                    <version>1.3.6</version>
                    <configuration>
                        <!--組態檔的位置-->
                        <configurationFile>GeneratorMapper.xml</configurationFile>
                        <verbose>true</verbose>
                        <overwrite>true</overwrite>
                    </configuration>
                </plugin>
        
            </plugins>
        
    • 在application.properties檔案中配置資料庫的相關資訊:

      • #配置內嵌 Tomcat 埠號
        server.port=9090
        #配置專案背景關系根
        server.servlet.context-path=/txzmy
        #配置資料庫的連接資訊
        #注意這里的驅動類有變化
        spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
        spring.datasource.url=jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8
        spring.datasource.username=root
        spring.datasource.password=Tx110304..
        
    • 在右側maven結構中選擇Plugins->mybatis-generator->mybatis-generator:generate.雙擊mybatis-generator:generate.

2.2 Spring Boot實作RESTful
2.2.1 認識RESTful:
  • REST(英文:Representational State Transfer,簡稱 REST) 一種互聯網軟體架構設計的風格,但它并不是標準,它只是提出了一組客戶端和服務器 互動時的架構理念和設計原則,基于這種理念和原則設計的介面可以更簡潔,更有層次,REST 這個詞,是 Roy Thomas Fielding 在他 2000 年的博士論文中提出的, 任何的技術都可以實作這種理念,如果一個架構符合 REST 原則,就稱它為 RESTFul 架 構 ,
  • 比如我們要訪問一個 http 介面:http://localhost:8080/boot/order?id=1021&status=1 采用 RESTFul 風格則 http 地址為:http://localhost:8080/boot/order/1021/1
2.2.2 Spring Boot開發RESTful:
  • Spring boot 開發 RESTFul 主要是幾個注解實作:

    • @PathVariable
      • 獲取 url 中的資料,該注解是實作 RESTful最主要的一個注解,
    • @PostMapping
      • 接收和處理 Post 方式的請求 ,
    • @DeleteMapping
      • 接收 delete 方式的請求,可以使用 GetMapping 代替 ,
    • @PutMapping
      • 接收 put 方式的請求,可以用 PostMapping 代替,
    • @GetMapping
      • 接收 get 方式的請求,
  • pom.xml添加內容:

    • <dependencies>
       <!--SpringBoot 框架 web 專案起步依賴-->
       <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-web</artifactId>
       </dependency>
       <!--MyBatis 集成 SpringBoot 框架起步依賴-->
       <dependency>
       <groupId>org.mybatis.spring.boot</groupId>
       <artifactId>mybatis-spring-boot-starter</artifactId>
       <version>2.0.1</version>
       </dependency>
       <!--MySQL 驅動-->
       <dependency>
       <groupId>mysql</groupId>
       <artifactId>mysql-connector-java</artifactId>
       </dependency>
      </dependencies>
      <build>
       <!--指定配置資源的位置-->
       <resources>
       <resource>
       <directory>src/main/java</directory>
       <includes>
       <include>**/*.xml</include>
       </includes>
       </resource>
       </resources>
       <plugins>
       <!--mybatis 代碼自動生成插件-->
       <plugin>
       <groupId>org.mybatis.generator</groupId>
       <artifactId>mybatis-generator-maven-plugin</artifactId>
       <version>1.3.6</version>
       <configuration>
       <!--組態檔的位置-->
       <configurationFile>GeneratorMapper.xml</configurationFile>
       <verbose>true</verbose>
       <overwrite>true</overwrite>
       </configuration>
       </plugin>
       <plugin>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-maven-plugin</artifactId>
       </plugin>
       </plugins>
      </build>
      
      
  • application.yml 核心組態檔:

    • server:
       port: 8090 #設定 Tomcat 內嵌埠號
       servlet:
       context-path: / #設定背景關系根
      #配置資料源
      spring:
       datasource:
       driver-class-name: com.mysql.cj.jdbc.Driver
       url: 
      jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=UTF-8&useJDBC
      CompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8
       username: root
       password: Tx110304..
      
      
2.3 SpringBoot集成Redis:
2.3.1 認識Reids:(源于百度百科)
  • redis是一個key-value存盤系統,和Memcached類似,它支持存盤的value型別相對更多,包括string(字串)、list(鏈表)、set(集合)、zset(sorted set --有序集合)和hash(哈希型別),這些資料型別都支持push/pop、add/remove及取交集并集和差集及更豐富的操作,而且這些操作都是原子性的,在此基礎上,redis支持各種不同方式的排序,與memcached一樣,為了保證效率,資料都是快取在記憶體中,區別的是redis會周期性的把更新的資料寫入磁盤或者把修改操作寫入追加的記錄檔案,并且在此基礎上實作了master-slave(主從)同步,

    Redis 是一個高性能的key-value資料庫, redis的出現,很大程度補償了memcached這類key/value存盤的不足,在部 分場合可以對關系資料庫起到很好的補充作用,它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客戶端,使用很方便, [1]

    Redis支持主從同步,資料可以從主服務器向任意數量的從服務器上同步,從服務器可以是關聯其他從服務器的主服務器,這使得Redis可執行單層樹復制,存盤可以有意無意的對資料進行寫操作,由于完全實作了發布/訂閱機制,使得從資料庫在任何地方同步樹時,可訂閱一個頻道并接收主服務器完整的訊息發布記錄,同步對讀取操作的可擴展性和資料冗余很有幫助,

2.3.2 添加依賴:
  • 在Pom.xml添加操作redis資料型別的依賴:

    <!--SpringBoot集成Redis的起步依賴-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
            </dependency>
    
  • 在SpringBoot核心組態檔中添加Redis的 配置(配置連接資訊):

    #redis連接資訊
    spring.redis.host=
    sring.redis.port=
    sring.redis.password=
    
2.3.3 相關類:
  • RestController類:

    @RestController
    public class RedisController {
     @Autowired
     private StudentService studentService;
     @GetMapping(value = "https://www.cnblogs.com/springboot/allStudentCount")
     public Object allStudentCount(HttpServletRequest request) {
     Long allStudentCount = studentService.queryAllStudentCount();
     return "學生總人數:" + allStudentCount;
     }
    }
    
  • StudentService 介面:

    public interface StudentService {
     /**
     * 獲取學生總人數
     * @return
     */
     Long queryAllStudentCount();
    }
    
    
  • 在 StudentServiceImpl 中注入 RedisTemplate 并修改根據 id 獲取學生的方法:

    @Service
    public class StudentServiceImpl implements StudentService {
     @Autowired
     private StudentMapper studentMapper;
     @Autowired
     private RedisTemplate<Object,Object> redisTemplate;
     @Override
     public Long queryAllStudentCount() {
     //設定 redisTemplate 物件 key 的序列化方式
     redisTemplate.setKeySerializer(new StringRedisSerializer());
     //從 redis 快取中獲取總人數
     Long allStudentCount = (Long) 
    redisTemplate.opsForValue().get("allStudentCount");
     //判斷是否為空
     if (null == allStudentCount) {
     //去資料庫查詢,并存放到 redis 快取中
     allStudentCount = studentMapper.selectAllStudentCount();
     
    redisTemplate.opsForValue().set("allStudentCount",allStudentCount,15, 
    TimeUnit.SECONDS);
     }
     return allStudentCount;
     }
    }
    
    
  • StudentMapper 介面:

    public interface StudentMapper {
     /**
     * 獲取學生總人數
     * @return
     */
     Long selectAllStudentCount();
    }
    
    
  • StudentMapper 映射檔案:

    <!--獲取學生總人數-->
    <select id="selectAllStudentCount" resultType="java.lang.Long">
     select
     count(*)
     from
     t_student
    </select>
    
    
  • 啟動類 Application:

    • 在 SpringBoot 啟動類上添加掃描資料持久層的注解并指定掃描包:

      @SpringBootApplication
      @MapperScan(basePackages = "com.txzmy.mapper")//掃描資料持久層
      public class Application {
       public static void main(String[] args) {
       SpringApplication.run(Application.class, args);
       }
      }
      
2.4 集成dubbo:
2.4.1. 準備作業

創建一個Maven空專案,作為專案的父工程,此工程的子專案基于Spring Boot 2.0.5 實作

img

在父工程的pom.xml引入之后要創建的子工程

    <modules>
        <module>gmall-interface</module>
        <module>user-service-provider</module>
        <module>order-service-consumer</module>
    </modules>

可以提前看一下工程結構

img

下面分別來實作子工程:(子工程的實作方式都是在gmall工程下新建Module)

img

2.4.2. 公共API

專案中共用的介面和POJO類,代碼和之前一樣,這里不再展開

img

2.4.3. 服務提供者

工程結構如下

img

引入依賴

<!-- 引入公共API,以實作其介面 -->
        <dependency>
            <groupId>com.zang</groupId>
            <artifactId>gmall-interface</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <!-- 引入spring-boot-starter以及dubbo和curator的依賴 -->
        <dependency>
            <groupId>com.alibaba.boot</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>0.2.0</version>
        </dependency>
        <!-- Spring Boot相關依賴 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

需要注意的是,根據jdk和Spring Boot版本的不同,dubbo-spring-boot-starter的版本需要有根據的選擇

img

dubbo提供了@Service注解,可將類宣告為提供方,省去了大量配置的麻煩

import com.alibaba.dubbo.config.annotation.Service;
import com.zang.gmall.bean.UserAddress;
import com.zang.gmall.service.UserService;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.List;

@Service   //屬于Dubbo的@Service注解,非Spring  作用:暴露服務
@Component
public class UserServiceImpl implements UserService {

    @Override
    public List<UserAddress> getUserAddressList(String userId) {
    //省略
}}

通過屬性配置的方式設定application.properties

#當前服務/應用的名字
dubbo.application.name=user-service-provider
#注冊中心的協議和地址
dubbo.registry.protocol=zookeeper
dubbo.registry.address=127.0.0.1:2181
#通信規則(通信協議和介面)
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880
#連接監控中心
dubbo.monitor.protocol=registry
#開啟包掃描,可替代 @EnableDubbo 注解
##dubbo.scan.base-packages=com.zang.gmall

springboot容器根據配置啟動服務提供方,這里需要添加 @EnableDubbo 注解

import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

// 開啟基于注解的dubbo功能(主要是包掃描@DubboComponentScan)
// 也可以在組態檔中使用dubbo.scan.base-package來替代   @EnableDubbo
@EnableDubbo

@SpringBootApplication
public class UserServiceProviderApplication {

    public static void main(String[] args) {
        SpringApplication.run(UserServiceProviderApplication.class, args);
    }
}

提供方順利啟動

img

2.4.4. 服務消費者

消費者工程在初始化時設定為web專案,結構如下

img

引入和服務提供方同樣的依賴,除此之外,添加springboot web模塊的依賴,

    <!-- springboot web模塊 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

dubbo提供了@Reference注解,可替換@Autowired注解,用于引入遠程服務

import com.alibaba.dubbo.config.annotation.Reference;
import com.zang.gmall.bean.UserAddress;
import com.zang.gmall.service.OrderService;
import com.zang.gmall.service.UserService;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class OrderServiceImpl implements OrderService {

    @Reference
    UserService userService;

    @Override
    public List<UserAddress> initOrder(String userId) {
  //代碼省略
   }}

組態檔application.properties

#避免和監控中心埠沖突,設為8081埠訪問
server.port=8081  

dubbo.application.name=order-service-consumer
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.monitor.protocol=registry

啟動類同樣加上@EnableDubbo注解

import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@EnableDubbo
@SpringBootApplication
public class OrderServiceConsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderServiceConsumerApplication.class, args);
    }
}

為查看呼叫是否成功,新增控制層用于訪問

import com.zang.gmall.bean.UserAddress;
import com.zang.gmall.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;

@Controller
public class OrderController {

    @Autowired
    OrderService orderService;

    @ResponseBody   //以json格式回傳
    @RequestMapping("/initOrder")
    public List<UserAddress> initOrder(@RequestParam("uid") String userId){

       return orderService.initOrder(userId);
    }

}
2.4.5. 測驗呼叫

啟動消費方,在瀏覽器訪問

img

呼叫成功

img

附:springboot也允許參考xml檔案配置,方法是在啟動類中加入如下注解

//@EnableDubbo
//引入配置資訊
@ImportResource(locations="classpath:provider.xml")
@SpringBootApplication
public class UserServiceProviderApplication {
//略
}

3 Spring Boot下的非Web程式:

3.1 創建一個非Web程式:
3.1.1 方式一:
  • 直接在 main 方法中,根據 SpringApplication.run()方 法獲取回傳的 Spring 容器物件,再獲取業務 bean 進行呼叫:

    • //Application.java檔案
          
          
      package com.txzmy;
      import com.txzmy.TestInterface1.UserService;
      import org.springframework.boot.SpringApplication;
      import org.springframework.boot.autoconfigure.SpringBootApplication;
      import org.springframework.context.ConfigurableApplicationContext;
      @SpringBootApplication
      public class Application {
          public static void main(String[] args) {
              /**
               * SpringBoot 程式啟動后,回傳值是 ConfigurableApplicationContext,它也是一個
               Spring 容器物件
               * 它其它相當于原來 Spring 中啟動容器 ClassPathXmlApplicationContext context =
               new ClassPathXmlApplicationContext("");
               */
              //獲取 SpringBoot 程式啟動后的 Spring 容器
              ConfigurableApplicationContext context =
                      SpringApplication.run(Application.class, args);
              //從 Spring 容器中獲取指定 bean 的物件
              UserService userService = (UserService)
                      context.getBean("userServiceImpl");
              //呼叫業務 bean 的方法
              String sayHello = userService.SayHello();
              System.out.println(sayHello);
          }
      
      }
      
      
      //UserService介面
      
      
      
      package com.txzmy.TestInterface1;
      public interface UserService 
      {
           String SayHello();
      }
      
      
      //UserServiceImpl介面實作類
      
      
      package com.txzmy.TestAchieve;
      
      import com.txzmy.TestInterface1.UserService;
      import org.springframework.stereotype.Service;
      
      @Service
      public class UserServiceImpl implements UserService {
          @Override
          public String SayHello() {
              return "Hello";
          }
      }
      
      
      
    • 運行結果:

    • 注意:

      • 在getBean方法中,如果介面實作類的名稱首字母是大寫,則在getBean方法的引數中首字母必須換為小寫,解決“No bean named 'UserServiceImpl' available”報錯,
3.1.2 方式二:
  • Spring boot 的入口類實作 CommandLineRunner 介面,

    • //Application.java檔案
      
      package com.txzmy;
      
      //import javafx.application.Application;
      import com.txzmy.TestInterface1.UserService;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.boot.CommandLineRunner;
      import org.springframework.boot.SpringApplication;
      import org.springframework.boot.autoconfigure.SpringBootApplication;
      import org.springframework.context.ConfigurableApplicationContext;
      @SpringBootApplication
      public class Application implements CommandLineRunner {
      
          @Autowired
          private UserService userService;
          @Override
      //    重寫CommandLineRunner中的run方法
          public void run(String... args) throws Exception
          {
              System.out.println(userService.SayHello());
          }
      
          public static void main(String[] args) {
              SpringApplication.run(Application.class);
          }
      
      }
      
      
      //介面類和介面實作類和上面相同
      
    • 運行結果:

  • @SpringBootApplication
    public class Application {
     public static void main(String[] args) {
     SpringApplication springApplication = new SpringApplication(Application.class);
     //關閉啟動 logo 的輸出
     springApplication.setBannerMode(Banner.Mode.OFF);
     springApplication.run(args);
     }
    }
    
  • 在 src/main/resources 放入 banner.txt 檔案,該檔案名字不能隨意,檔案中的內容就是要輸出 的 logo ;
  • 可 以 利 用 網 站 生 成 圖 標 : https://www.bootschool.net/ascii 或 者 http://patorjk.com/software/taag/,將生成好的圖示文字粘貼到 banner.txt 檔案中,然后將關 閉 logo 輸出的陳述句注釋,啟動看效果,

4 Spring Boot 使用攔截器:

4.1 使用攔截器的步驟:
  • 定義一個攔截器,實作HandlerInterceptor介面,

    • package com.txzmy.interceptor;
      
      import com.txzmy.model.User;
      import org.springframework.web.servlet.HandlerInterceptor;
      import org.springframework.web.servlet.ModelAndView;
      
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      
      public class UserInterceptor implements HandlerInterceptor {
          @Override
          public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
      
      
              System.out.println("進入攔截器-----------------");
              //撰寫業務中攔截的規則
              //從session中獲取用戶的資訊
              User user = (User)request.getSession().getAttribute("user");
      
              //判斷用戶是否登錄
              if(null==user)
              {
                  response.sendRedirect(request.getContextPath()+"/user/error");
                  return false;
              }
              return true;
      
          }
      
          @Override
          public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
      
          }
      
          @Override
          public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
      
          }
      }
      
      
  • 創建一個配置類(即:在SpringMvc組態檔中使用MVC:攔截器標簽),

    • package com.txzmy.config;
      
      import com.txzmy.interceptor.UserInterceptor;
      import org.springframework.context.annotation.Configuration;
      import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
      import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
      
      @Configuration
      //定義此類為組態檔(即相當于之前的xml組態檔)
      public class InterceptorConfig implements WebMvcConfigurer {
          @Override
          //攔截器注冊類,需要我們把自己定義的攔截器注冊進去
          public void addInterceptors(InterceptorRegistry registry) {
      
              //定義需要攔截的和不需要攔截的String容器
              //要攔截user下面的所有的訪問請求,必須用戶登錄后才可以訪問
              String[] addPathPatterns={
                  "/user/**"
              };
              //要排除的路徑,排除的路徑說明用戶不需要登陸也可以訪問
              String[] excludePathPatterns={
                  "/user/out","/user/error","/user/login"
              };
              registry.addInterceptor(new UserInterceptor()).addPathPatterns(addPathPatterns).excludePathPatterns(excludePathPatterns);
          }
      }
      
      
  • 請求頁面類:

    • package com.txzmy.web;
      
      import com.txzmy.model.User;
      import org.springframework.stereotype.Controller;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.ResponseBody;
      
      import javax.servlet.http.HttpServletRequest;
      
      @Controller
      @RequestMapping("/user")
      public class UserController {
      
          @RequestMapping(value = "https://www.cnblogs.com/login")
          public @ResponseBody Object login(HttpServletRequest request)
          {
              //將用戶資訊放到session中
              User user=new User();
              user.setId(1001);
              user.setName("張滿月");
              request.getSession().setAttribute("user",user);
      
              return "login success";
      
          }
      
          //該請求需要用戶登錄后才可以訪問
          @RequestMapping(value = "https://www.cnblogs.com/center")
          public @ResponseBody Object center()
          {
              return "Center Message";
          }
      
          //該請求不需要用戶可以訪問
          @RequestMapping(value = "https://www.cnblogs.com/out")
          public @ResponseBody Object out()
          {
              return "out Message";
          }
      
          //如果用戶未登錄訪問了需要登陸才可以訪問的資料,會跳轉至該請求
          @RequestMapping(value = "https://www.cnblogs.com/error")
          public @ResponseBody Object error()
      
          {
              return "error";
          }
      
      }
      
      
  • 用戶類:

    • package com.txzmy.model;
      
      public class User {
      
          private int id;
          private  String name;
      
      
          public int getId() {
              return id;
          }
      
          public void setId(int id) {
              this.id = id;
          }
      
          public String getName() {
              return name;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      }
      
      

5 Spring Boot中使用Servlet:

5.1 Servlet:
5.1.1 認識Servlet:
  • Java Servlet 是運行在 Web 服務器或應用服務器上的程式,它是作為來自 Web 瀏覽器或其他 HTTP 客戶端的請求和 HTTP 服務器上的資料庫或應用程式之間的中間層,使用 Servlet,您可以收集來自網頁表單的用戶輸入,呈現來自資料庫或者其他源的記錄,還可以動態創建網頁.
5.1.2 Servlet 任務:
  • 讀取客戶端(瀏覽器)發送的顯式的資料,這包括網頁上的 HTML 表單,或者也可以是來自 applet 或自定義的 HTTP 客戶端程式的表單,
  • 讀取客戶端(瀏覽器)發送的隱式的 HTTP 請求資料,這包括 cookies、媒體型別和瀏覽器能理解的壓縮格式等等,
  • 處理資料并生成結果,這個程序可能需要訪問資料庫,執行 RMI 或 CORBA 呼叫,呼叫 Web 服務,或者直接計算得出對應的回應,
  • 發送顯式的資料(即檔案)到客戶端(瀏覽器),該檔案的格式可以是多種多樣的,包括文本檔案(HTML 或 XML)、二進制檔案(GIF 影像)、Excel 等,
  • 發送隱式的 HTTP 回應到客戶端(瀏覽器),這包括告訴瀏覽器或其他客戶端被回傳的檔案型別(例如 HTML),設定 cookies 和快取引數,以及其他類似的任務,
5.2 兩種使用Servlet的方式:
5.2.1 方式一 通過注解方式實作:
  • MyServlet.java

    • package com.example.demo.Servlet;
      
      import javax.servlet.ServletException;
      import javax.servlet.annotation.WebServlet;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import java.io.IOException;
      
      //定義訪問的地址
      @WebServlet(urlPatterns = "/myServlet")
      public class MyServlet extends HttpServlet
      {
          @Override
          protected void doGet(HttpServletRequest request, HttpServletResponse
                  response) throws ServletException, IOException {
              response.getWriter().print("My SpringBoot Servlet");
              response.getWriter().flush();
              response.getWriter().close();
          }
      
          @Override
          protected void doPost(HttpServletRequest request, HttpServletResponse
                  response) throws ServletException, IOException {
              doGet(request, response);
          }
      }
      
      
      
  • Application.java

    • package com.example.demo;
      
      import org.springframework.boot.SpringApplication;
      import org.springframework.boot.autoconfigure.SpringBootApplication;
      import org.springframework.boot.web.servlet.ServletComponentScan;
      
      @SpringBootApplication
      //開啟Spring配置
      @ServletComponentScan(basePackages = "com.example.demo.Servlet")
      //指定要掃描的Servlet
      public class DemoApplication {
      
          public static void main(String[] args) {
              SpringApplication.run(DemoApplication.class, args);
          }
      
      }
      
      
5.2.2 方式二 通過 SpringBoot 的配置類實作(組件注冊)
  • ServletConfiguration.java

    • package com.example.demo.Servlet;
      
      import org.springframework.boot.web.servlet.ServletRegistrationBean;
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.Configuration;
      
      @Configuration
      public class ServletConfiguration {
      
          //@Bean 是一個方法級別上的注解,主要用在配置類里
          /*
           * 相當于一個<beans>
           * <bean id="" />
           * </beans>
           * */
      
          @Bean
          public ServletRegistrationBean servletRegistrationBean()
          {
              //將自定義 servlet 注冊到注冊 Servlet 類中,并指定訪問路徑
              ServletRegistrationBean servletRegistrationBean = new
                      ServletRegistrationBean(new MyServlet(), "/MyServlet");
              return servletRegistrationBean;
          }
      
      }
      
      
  • MyServlet.java

    • package com.example.demo.Servlet;
      
      import javax.servlet.ServletException;
      import javax.servlet.annotation.WebServlet;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import java.io.IOException;
      
      public class MyServlet extends HttpServlet
      {
          @Override
          protected void doGet(HttpServletRequest request, HttpServletResponse
                  response) throws ServletException, IOException {
              response.getWriter().print("My SpringBoot Servlet2222");
              response.getWriter().flush();
              response.getWriter().close();
          }
      
          @Override
          protected void doPost(HttpServletRequest request, HttpServletResponse
                  response) throws ServletException, IOException {
              doGet(request, response);
          }
      }
      
  • application.java不變

6 Spring Boot中使用過濾器Filter

6.1 過濾器的作用:
  • Filter 過濾器它是 JavaWeb 的三大組件之一,三大組件分別是:Servlet 程式、Listener 監聽器、Filter 過濾器
  • Filter 過濾器它是 JavaEE 的規范,也就是介面
  • Filter 過濾器它的作用是:攔截請求,過濾回應,
6.2 創建Filter的兩種方法:
6.2.1 方式一 通過注解方式實作:
  • MyFilter.java

    • @WebFilter(urlPatterns = "/springboot/myFilter")
      //設定過濾的訪問路徑
      public class MyFilter implements Filter {
       @Override
       public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, 
      FilterChain filterChain) throws IOException, ServletException {
       System.out.println("-------------您已進入過濾器---------------");
       filterChain.doFilter(servletRequest,servletResponse);
       }
      }
      
      
  • Application檔案

    • import org.springframework.boot.SpringApplication;
      import org.springframework.boot.autoconfigure.SpringBootApplication;
      import org.springframework.boot.web.servlet.ServletComponentScan;
      
      @ServletComponentScan(basePackages = "com.demo.filter")
      @SpringBootApplication
      public class Application {
       public static void main(String[] args) {
       SpringApplication.run(Application.class, args);
       }
      
      
  • 結果:通過 .../springboot/myFilter...的訪問路徑全部無法訪問,

6.2.2 方式二 通過 Spring Boot 的配置類實作:
  • FilterConfiguration.java

    • package com.example.demo.Filter;
      
      import org.springframework.boot.web.servlet.FilterRegistrationBean;
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.Configuration;
      
      import javax.servlet.FilterRegistration;
      
      @Configuration
      public class FilterConfiguration {
          @Bean
          public FilterRegistrationBean myFilterRegistration (){
      
              //注冊過濾器
              FilterRegistrationBean filterRegistrationBean
                      =new FilterRegistrationBean(new MyFilter());
              //添加過濾路徑
              filterRegistrationBean.addUrlPatterns("/User/*");
              return filterRegistrationBean;
          }
      }
      
      
  • MyFilter.java

    • package com.example.demo.Filter;
      
      import javax.servlet.*;
      import java.io.IOException;
      
      public class MyFilter implements Filter {
          @Override
          public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
              System.out.println("get access to filter");
              filterChain.doFilter(servletRequest,servletResponse);
          }
      }
      
      
  • userController.java

    • package com.example.demo.Filter;
      
      import org.springframework.stereotype.Controller;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.ResponseBody;
      
      @Controller
      public class userController {
          @RequestMapping(value = "https://www.cnblogs.com/User/one")
          public @ResponseBody String one()
          {
              return "one";
          }
      
          @RequestMapping(value = "https://www.cnblogs.com/two")
          public @ResponseBody String two()
          {
              return "two";
          }
      }
      

7 Spring Boot 專案配置字符編碼:

7.1 目的:
  • 解決網頁中的中文亂碼問題,不需要用戶手動更改瀏覽器的encoding,
7.2 兩種配置字符編碼的方式:
7.2.1 方式一: 使用傳統的 Spring 提供的字符編碼過濾器
  • MyServlet.java

    • package com.example.demo.Servlet;
      
      import javax.servlet.ServletException;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import java.io.IOException;
      
      public class MyServlet extends HttpServlet {
      
          @Override
          protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              doGet(req,resp);
          }
      
          @Override
          protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
             resp.getWriter().println("張滿月:Hello,demo");
             //設定瀏覽器編碼格式
              resp.setContentType("text/html;character=utf-8");
              resp.getWriter().flush();
              resp.getWriter().close();
          }
      }
      
      
  • 配置類:

    • package com.example.demo.Servlet;
      
      import org.springframework.boot.web.servlet.FilterRegistrationBean;
      import org.springframework.boot.web.servlet.ServletRegistrationBean;
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.Configuration;
      import org.springframework.web.filter.CharacterEncodingFilter;
      
      @Configuration
      //定義此類為配置類
      public class SystemConfiguration {
          @Bean
          public ServletRegistrationBean servletRegistrationBean()
          {
              ServletRegistrationBean servletRegistrationBean=new ServletRegistrationBean(new MyServlet(),"/Servlet/MyServlet");
      
              return servletRegistrationBean;
      
          }
      
          @Bean
          public FilterRegistrationBean filterRegistrationBean()
          {
              //設定字符編碼過濾器
              //CharacterEncoding 是由 Spring 提供的一個字符編碼過濾器,之前是配置在web.xml 檔案中
              CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
              //強制使用指定字符編碼
              characterEncodingFilter.setForceEncoding(true);
              //設定指定字符編碼
              characterEncodingFilter.setEncoding("utf-8");
              //創建過濾器注冊 bean
              FilterRegistrationBean filterRegistrationBean=new FilterRegistrationBean();
              //設定字符編碼過濾器
              filterRegistrationBean.setFilter(characterEncodingFilter);
              //設定字符編碼過濾器路徑
              filterRegistrationBean.addUrlPatterns("/*");
              return filterRegistrationBean;
      
          }
      }
      
      
  • application.properties

    • #關閉 springboot 的 http 字符編碼支持
      #只有關閉該選項后,spring 字符編碼過濾器才生效
      server.servlet.encoding.enabled=false
      
  • 不設定解碼方式中文可能會亂碼,

7.2.2 方式二:在 application.properties 中配置字符編碼(推薦)
  • 核心組態檔application.properties:

    • #設定請求回應的字符編碼
      spring.http.encoding.enabled=true
      spring.http.encoding.force=true
      spring.http.encoding.charset=UTF-8
      
  • MyServlet.java

    • package com.example.demo.Servlet;
      
      import javax.servlet.ServletException;
      import javax.servlet.annotation.WebServlet;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import java.io.IOException;
      
      @WebServlet("/ServletDemo")
      public class MyServlet extends HttpServlet {
      
          @Override
          protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              doGet(req,resp);
          }
      
          @Override
          protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
             resp.getWriter().println("張滿月:Hello,demo");
             //設定瀏覽器編碼格式
              resp.setContentType("text/html;character=utf-8");
              resp.getWriter().flush();
              resp.getWriter().close();
          }
      }
      
      
  • 在主類中定義掃描路徑:

    • @SpringBootApplication
      @ServletComponentScan(basePackages = "com.example.demo.Servlet")
      public class DemoApplication {
      
          public static void main(String[] args) {
              SpringApplication.run(DemoApplication.class, args);
          }
      
      }
      
  • 未設定前:

    • 網頁顯示結果:????Hello,demo
  • 設定后:

    • 網頁顯示結果:張滿月:Hello,demo

8 Spring Boot 打包與部署:

8.1 Spring Boot打war包部署:
8.1.1 準備:
  • 將SpringBoot的專案的打包方式設定為war:

    • <groupId>com.example</groupId>  
      <artifactId>demo</artifactId>  
      <version>1.0.0</version>  
      <packaging>war</packaging>
      
  • 移除內嵌的tomcat模塊,但是為了我們在本機測驗方便,我們還需要引入它,所以配置如下:

    • <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>  
      <dependency>  
              <groupId>org.springframework.boot</groupId>  
              <artifactId>spring-boot-starter-tomcat</artifactId>  
              <scope>provided</scope>  
      </dependency>  
      
  • 添加tomcat-servelt-api依賴:

    • <dependency>  
            <groupId>org.apache.tomcat</groupId>  
            <artifactId>tomcat-servlet-api</artifactId>  
            <version>7.0.42</version>  
            <scope>provided</scope>  
      </dependency>  
      
    • 修改入口方法 繼承一個SpringBootServletInitializer類,并且覆寫configure方法:

      • package com.example;  
          
           import org.springframework.boot.SpringApplication;  
        import org.springframework.boot.autoconfigure.SpringBootApplication;  
        import org.springframework.boot.builder.SpringApplicationBuilder;  
        import org.springframework.boot.web.support.SpringBootServletInitializer;  
        import org.springframework.cache.annotation.EnableCaching;  
          
           @SpringBootApplication  
        @EnableCaching  
        public class SpringDataJpaExampleApplication extends SpringBootServletInitializer {  
          
            @Override  
            protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {  
                return application.sources(SpringDataJpaExampleApplication.class);  
            }  
          
            public static void main(String[] args) {  
                SpringApplication.run(SpringDataJpaExampleApplication.class, args);  
            }  
        }  
        
    • 添加war插件,用來自定義打包以后的war包的名稱:

      • <plugin>  
              <groupId>org.apache.maven.plugins</groupId>  
              <artifactId>maven-war-plugin</artifactId>  
              <configuration>  
                  <warSourceExcludes>src/main/resources/**</warSourceExcludes>  
                  <warName>springboot</warName>  
              </configuration>  
        </plugin>  
        
8.1.2 打包步驟:
  • maven->要打包的專案->Lifecycle->package
  • 打包完成后專案下面會出現一個檔案夾,里面.war檔案就是打包好的檔案,
8.1.3 使用tomcat啟動打好的war包:
  • 將war包復制到本機的tomcat里的webapps檔案夾下,在bin中雙擊startup.bat啟動服務,雙擊shutdown.bat可以關閉服務,
8.1.4 關于startup和shutdown檔案閃退問題:
  • 右鍵startup檔案,編輯,在檔案頭添加:

    • SET JAVA_HOME=D:\java-web-spring\JAVA\ideaIU-2019\jdk1.8.0_31
      SET TOMCAT_HOME=D:\java-web-spring\JAVA\ideaIU-2019\apache-tomcat-9.0.21
      
    • 兩個路徑分別為jdk的路徑和tomcat的路徑,shutdown檔案閃退操作相同,

8.2 SpringBoot打jar包:
8.2.1 準備:
  • 在 pom.xml 檔案中添加 Tomcat 決議 jsp 依賴

    • <!--SpringBoot 專案內嵌 tomcat 對 jsp 的決議包-->
      <dependency>
       <groupId>org.apache.tomcat.embed</groupId>
       <artifactId>tomcat-embed-jasper</artifactId>
      </dependency>
      
  • 在 pom.xml 檔案中添加 resources 配置,以后為了保險起見, 大家在打包的時候,建議把下面的配置都加上:

    • <resource>
       <!--源檔案夾-->
       <directory>src/main/webapp</directory>
       <!--目標檔案夾-->
       <targetPath>META-INF/resources</targetPath>
       <!--包含的檔案-->
       <includes>
       <include>**/*.*</include>
       </includes>
      </resource>
      <!--mybatis 的 mapper.xml-->
      <resource>
       <directory>src/main/java</directory>
       <includes>
       <include>**/*.xml</include>
       </includes>
      </resource>
      <!--src/main/resources 下的所有組態檔編譯到 classes 下面去-->
      <resource>
       <directory>src/main/resources</directory>
       <includes>
       <include>**/*.*</include>
       </includes>
      </resource>
      
  • 修改 application.properties 組態檔:

    • 打jar包也將工程的核心組態檔一起打包,所以在核心組態檔里面設定的埠號起作用,而war包的背景關系根是打包的專案名,

    • #設定內嵌 Tomcat 埠號
      server.port=9090
      #設定專案背景關系根
      server.servlet.context-path=/
      #配置 jsp 的前/后綴
      spring.mvc.view.prefix=/
      spring.mvc.view.suffix=.jsp
      
8.2.2 打包步驟:
  • maven->要打包的專案->Lifecycle->package
  • 打包完成后專案下面會出現一個檔案夾,里面.jar檔案就是打包好的檔案,
8.2.3 啟動打包好的工程:
  • 啟動jar包可以用內置的tomcat啟動:
    • 將jar包復制到某個檔案夾內,在檔案夾檔案路徑欄輸入cmd進入視窗:
    • 在輸入java -jar +打包的專案名字.jar回車即可以啟動專案,
8.3 Spring Boot 部署與運行方式總結:
  • ?在 IDEA 中直接運行 Spring Boot 程式的 main 方法(開發階段)

  • 用 maven 將 Spring Boot 安裝為一個 jar 包,使用 Java 命令運行

    java -jar springboot-xxx.jar

    可以將該命令封裝到一個 Linux 的一個 shell 腳本中(上線部署)

    • 寫一個 shell 腳本(run.sh): #!/bin/sh java -jar xxx.jar
    • 賦權限 chmod 777 run.sh
    • 啟動 shell 腳本: ./run.sh
    • 使用 Spring Boot 的 maven 插件將 Springboot 程式打成 war 包,單獨部署在 tomcat 中運行(上 線部署常用)

9 SpringBoot 集成 logback 日志:

9.1 目的:
  • 做故障定位;
  • 顯示程式運行狀態,
9.2 參考:
  • https://blog.csdn.net/lw1124052197/article/details/110522948

10 Thymeleaf:

10.1 Thymeleaf簡介:
  • Thymeleaf 是一款用于渲染 XML/XHTML/HTML5 內容的模板引擎,它與 JSP,Velocity,FreeMaker 等模板引擎類似,也可以輕易地與 Spring MVC 等 Web 框架集成,與其它模板引擎相比,Thymeleaf 最大的特點是,即使不啟動 Web 應用,也可以直接在瀏覽器中打開并正確顯示模板頁面 ,
10.2 thymeleaf相關的方法:
10.2.1 設定前后綴(在核心組態檔中):
  • #設定themeleaf模板引擎的前后綴
    spring.thymeleaf.prefix=classpath:/templates/
    spring.thymeleaf.suffix=.html
    
10.2.2 開關thymeleaf的快取(在核心組態檔中):
  • #設定快取,默認為開啟,建議在開發階段關閉 thymeleaf 頁面快取,目的實時看到頁面
    spring.thymeleaf.cache=false
    
    • 讓頁面隨原始碼的改動而改變:

      • 關掉thymeleaf快取;

      • 在Run/Debug Configurations視窗中修改On 'Update' action和On frame deactivation為Update resources.

      • 相關實作:

        • //控制類
          @Controller
          public class ThymeleafController {
           @RequestMapping(value = "https://www.cnblogs.com/thymeleaf/index")
           public String index(Model model) {
           model.addAttribute("data","SpringBoot 成功集成 Thymeleaf 模版!");
           return "index";
           }
          }
          
        • //thymeleaf模板
          <body >
           <!--Thymeleaf 前端框架以 Html 為載體-->
           <span th:text="${data}"></span>
           <span th:text="${data}"></span>
           <p th:text="${data}"></p>
           <div th:text="${data}"></div>
          </body>
          </html>
          
          
        • 這樣在thymeleaf模板中修改 內的標簽在網頁上也會相應的動態修改(不用重啟專案程式),

10.3 thymeleaf變數運算式:
10.3.1標準變數運算式:
  • 語法 ${...}

  • 標準變數運算式用于訪問容器(tomcat)背景關系環境中的變數,功能和 EL 中的 ${} 相 同,Thymeleaf 中的變數運算式使用 ${變數名} 的方式獲取 Controller 中 model 其中的資料,

  • 例子:

    • user類

      • package com.example.model;
        
        public class user {
            private int num;
            private  String name;
        
            public int getNum() {
                return num;
            }
        
            public void setNum(int num) {
                this.num = num;
            }
        
            public String getName() {
                return name;
            }
        
            public void setName(String name) {
                this.name = name;
            }
        }
        
        
  • UserController類:

    • package com.example.web;
      
      
      import com.example.model.user;
      import org.springframework.stereotype.Controller;
      import org.springframework.ui.Model;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.ResponseBody;
      import org.springframework.web.servlet.ModelAndView;
      
      import javax.jws.WebParam;
      
      @Controller
      public class UserController {
      
          @RequestMapping(value = "https://www.cnblogs.com/user/detail")
          public String message(Model model)
          {
              user user = new user();
              user.setName("KB");
              user.setNum(24);
              model.addAttribute("user",user);
              return "message";
          }
      }
      
      
      • message.html:

        • <!DOCTYPE html>
          <html lang="en"  xmlns:th="http://www.thymeleaf.org">
          <head>
              <meta charset="UTF-8">
              <title>Title</title>
          </head>
          <body>
          PlayerNum :<div th:text="${user.getNum()}"> message showed:</div><br/>
          PlayerName:<div th:text="${user.getName()}"> message showed:</div>
          PlayerNum :<div th:text="${user.getNum()}"> message showed:</div><br/>
          PlayerName:<div th:text="${user.getName()}"> message showed:</div>
          </body>
          </html>
          
      • 核心組態檔:

        • #設定themeleaf模板引擎的前后綴
          spring.thymeleaf.prefix=classpath:/templates/
          spring.thymeleaf.suffix=.html
          
          #設定快取
          spring.thymeleaf.cache=false
          
          
      • 結果:

        • PlayerNum :

          24

          PlayerName:

          KB

          PlayerNum :

          24

          PlayerName:

          KB

10.3.2 選擇變數運算式:
  • 語法:*{...}

  • 說明:

    • 選擇變數運算式,也叫星號變數運算式,使用 th:object 屬性來系結物件
    • 選擇運算式首先使用 th:object 來系結后臺傳來的 User 物件,然后使用 * 來代表這個對 象,后面 {} 中的值是此物件中的屬性, 選擇變數運算式 *{...} 是另一種類似于標準變數運算式 ${...} 表示變數的方法
    • 選擇變數運算式在執行時是在選擇的物件上求解,而${...}是在背景關系的變數 Model 上求 解,這種寫法比標準變數運算式繁瑣,
  • 示例:

    • <div th:Object="${user}">
          PlayNum   :<span th:text="*{getNum()}"></span><br/>
          PlayerName:<span th:text="*{getName()}"></span>
      </div>
      
      
    • 其他類和上面一樣,

10.3.3 標準變數運算式和選擇變數運算式混合使用
  • 標準變數和選擇變數運算式可以混合使用,也可以不混合使用,使用 th:object 進行對 象的選擇,也可以直接使用 *{...} 獲取資料:

  • 示例:

    • PlayerNum :<div th:text="*{user.getNum()}"> message showed:</div><br/>
      PlayerName:<div th:text="*{user.getName()}"> message showed:</div>
      
10.4 thymeleaf URL路徑運算式:
10.4.1 絕對路徑:
  • 不帶引數:

    • <h1>URL 路徑運算式:@{...}</h1>
      <h2>絕對路徑(沒有引數)</h2>
      <a th:href="https://www.cnblogs.com/txzmy/p/@{http://localhost:8080/thymeleaf/info}">查看:絕對路徑</a>
      
  • 帶引數:

    • <h2>絕對路徑(路徑中有引數)</h2>
      <a th:href="https://www.cnblogs.com/txzmy/p/@{'http://localhost:8080/thymeleaf/user/info?id=' + 
      ${user.id}}">查看用戶資訊:絕對路徑(帶引數)</a>
      
  • 不推薦使用:路徑寫死,

10.4.2 相對路徑:
  • 不帶引數:

    • <h2 style="color: red">實際開發推薦使用:相對路徑(沒有引數)</h2>
      <a th:href="https://www.cnblogs.com/txzmy/p/@{/thymeleaf/info}">查看:相對路徑</a>
      
  • 帶引數:

      • 先請求一個帶有跳轉標簽的網址,點擊click就會再請求一個帶引數的網址,
    • user類:

      • package com.example.model;
        
        public class user {
            private int num;
            private  String name;
        
            public int getNum() {
                return num;
            }
        
            public void setNum(int num) {
                this.num = num;
            }
        
            public String getName() {
                return name;
            }
        
            public void setName(String name) {
                this.name = name;
            }
        }
        
        
    • UserController類:

      • package com.example.web;
        
        
        import com.example.model.user;
        import org.springframework.stereotype.Controller;
        import org.springframework.ui.Model;
        import org.springframework.web.bind.annotation.RequestMapping;
        import org.springframework.web.bind.annotation.ResponseBody;
        import org.springframework.web.servlet.ModelAndView;
        
        import javax.jws.WebParam;
        
        @Controller
        public class UserController {
        
        
        //    public ModelAndView  message( )
        ////    {
        ////        user user = new user();
        ////        user.setNum(30);
        ////        user.setName("SC");
        ////        ModelAndView modelAndView =new ModelAndView();
        ////        modelAndView.setViewName("userInfomation");
        ////        modelAndView.addObject("userNum",user.getNum());
        ////        modelAndView.addObject("userName",user.getName());
        ////        return modelAndView;
        ////    }
        @RequestMapping(value = "https://www.cnblogs.com/user/detail")
            public  String message(Model model)
            {
                user user =new user();
                user.setName("KB");
                user.setNum(24);
                model.addAttribute("user",user);
                return "message";
            }
            @RequestMapping(value = "https://www.cnblogs.com/user/Info")
            public  @ResponseBody String userInfo(int num,String name)
            {
                return "num:"+num+"  Name:"+name;
            }
        
        }
        
        
    • message.html

      • <!DOCTYPE html>
        <html lang="en"  xmlns:th="http://www.thymeleaf.org">
        <head>
            <meta charset="UTF-8">
            <title>Title</title>
        </head>
        <body>
        <a th:href ="https://www.cnblogs.com/txzmy/p/@{/user/Info(num=${user.getNum()},name=${user.getName()})}">click</a>
        </body>
        </html>
        
    • 核心組態檔:

      • #設定themeleaf模板引擎的前后綴
        spring.thymeleaf.prefix=classpath:/templates/
        spring.thymeleaf.suffix=.html
        
        #設定快取
        spring.thymeleaf.cache=false
        
        server.servlet.context-path=/url
        
        
10.5 thymeleaf常見屬性:
10.5.1 th:action:
  • th:action 定義后臺控制器的路徑,類似標簽的 action 屬性,主要結合 URL 運算式,獲 取動態變數;
10.5.2 th:method:
  • 設定請求方法

    • 	<form th:action="@{/user/login}" th:method="post"></form>
      
10.5.3 th:href:
  • 定義超鏈接,主要結合 URL 運算式,獲取動態變數.

    • <a href="http://www.baidu.com">超鏈接百度</a><br/>
      <a th:href="'http://www.baidu.com?id=' + ${user.id}">th:href 鏈接</a>
      
10.5.4 th:src:
  • 用于外部資源引入,比如

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/466954.html

標籤:Java

上一篇:Java中如何產生死鎖呢?

下一篇:自定義持久層框架

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more