1. 程式人生 > 其它 >理想國Python基礎教程之常用容器

理想國Python基礎教程之常用容器

技術標籤:javaspring boot

SpringBoot

appliaction.propertise中的配置

1.修改Tomcat的埠號

server.port=8181

原理初識

pom.xml

  • 啟動器 : springboot啟動的場景

  •       <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </
    dependency
    >
  • 例如:

    以上程式碼中配置的就是web 環境下的所有依賴,當需要其他功能時只需匯入對應的啟動器即可

自動裝配原理

  • SpringBoot啟動的時候載入主配置類,通過註解(@EnableAutoConfiguration)開啟了自動配置功能 ,
  • 每一個這樣的 xxxAutoConfiguration類都是容器中的一個元件,都加入到容器中;用他們來做自動配置,
  • 一旦配置類生效,那麼這個配置類就會給容器中新增各種元件;這些元件的屬性是從對應的properties類中獲取的,這些類裡面的每一個屬性又是通過(@ConfigurationProperties(prefix = “spring.http.encoding”))註解和配置檔案繫結的,所以配置檔案中配置的內容就可以新增到元件的屬性之中,從而實現自動裝配

yaml基礎語法

語法:以空格來控制層級關係,只要是左對齊的都是一個層級下的,鍵值之間必須加空格

1.字面量(字串,布林型別,數字)

注:字串,在編寫的過程中不用加上單引號或者雙引號

雙引號(""):不會轉義特殊字元,會按照本身想表達的意思輸出,比如: “name”: “zhangsna \n lisi” 輸出:zhangsna

​ 換行 lisi

單引號(’’):會轉義特殊字元,比如: “name”: “zhangsna \n lisi” 輸出:zhangsna \n lisi

server:
  port: 8081

注:等同於 server.port=8081

2.物件,Map

student:
 name: zhangsna
 age: 18

注:等同於 student.name=zhangsna student.age=18

行內寫法

student: {name: zhangsnag,age: 18}

3.陣列,List,Set

age:
  - 1
  - 2
  - 3

行內寫法

age: [1,2,3]

注: 在上述資料的儲存過程中,無論是哪種資料都嚴格控制空格的位置和數量,不同的空格數量表示的含義是不同的

給屬性賦值

  • 1.通過yaml

例:

注:@ConfigurationProperties(prefix = “配置檔案中的物件名稱”),表示的當前這個類的屬性值是通過yaml 中的配置獲得的,且這個類必須交由spring管理之後才能配置,該註解支援鬆散繫結


@Component
@ConfigurationProperties(prefix = "person")//person表示yaml中的 person
public class Person {
    private  String name;
    private Integer  age;
    private  String  [] aihao;
    private Map<String,Object> map;

    public Person() {
    }
}

appliaction.yaml

#對應的是@ConfigurationProperties(prefix = "person")中的 person
person:
 name: 張三
 aihao: [抽菸,喝酒]
 map: {k1: 1,k2: 2}

注:yaml的鍵必須和屬性名稱相同,否則無法注入

  • 2.通過properties

例:

appaliaction.properties

person.name=張勝男
person.aihao=抽菸,喝酒
person.map.k1=1
person.map.k1=2
@PropertySource("classpath:application.properties")//引入配置的properties,可載入多個。名字不一
public class Person {
    @Value("張三")//給name屬性賦值
    private  String name;
    @Value("#{22*1}")//將運算結果賦值給age
    private Integer  age;
     @Value("${person.aihao}")//獲取properties檔案中key為person.aihao的值,注入到aihao屬性中
    private  String  [] aihao;
    private Map<String,Object> map;

@ImportResource&@PropertySource註解

@PropertySource("classpath:person.properties")//引入配置的properties,使其生效,可載入多個,如上
@ImportResource("classpath:spring-mvc.xml")//載入spring的配置檔案,使其生效,可載入多個

yaml佔位符表示式

例:(隨機的值,很多,此處省略)

person:
 uuid: ${random.uuid} #隨機一個uuid賦值給person的屬性
 age: ${random.int} #隨機一個int型別的數字賦值給屬性
 ming: 小張
 name: ${person.ming:小明} #假如person.ming不存在,則賦值為  小明 若存在則賦值為 小張
 aihao: [展示那,試試]
 map: {k1: 1,k2: 2}

配置類

例:

@Configuration //標註這是一個配置類,相當於一個applicationContext.xml
public class UserConfig implements WebMvcConfigurer {
    
    //將國際換轉換元件新增進去
    @Bean//該註解相當於之前的<bean></bean>,其id預設為方法名稱 getLocaleResolver
    public LocaleResolver getLocaleResolver(){
        return  new IndexLocaleResolver();//自定義的一個元件
    }
}

application.yml中的配置

  • 配置thymeleaf關閉快取:
#關閉模板引擎的快取
spring:
  thymeleaf:
    cache: false
  • 配置Tomcat的埠號
server:
  port: 8081
  • 配置專案虛擬路徑,即本來訪問的url是:http://localhost:8080/login

​ 配置以後為:http://localhost:8080/wf/login,即,多了一層

server:
  servlet:
    context-path: /wf

JSR303常用資料校驗

例:

@Validated //標註這個類會受到資料校驗,如果校驗不通過,會丟擲異常
public class Person {
    @Valid //表示當前方法或屬性需要進行資料校驗,校驗不通過則丟擲異常
    @Email//校驗當前屬性的值是否為郵箱的格式
    private String email;

常用校驗註解:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-eHgNq1Ar-1609398539483)(D:\學習必備\筆記\SpringBoot\img\jsr303.png)]

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-hGsQAWzR-1609398539483)(D:\學習必備\筆記\SpringBoot\img\jsr303Two.png)]

注:在使用jsr303資料校驗的時候需要匯入依賴

 <dependency>
        <groupId>javax.validation</groupId>
        <artifactId>validation-api</artifactId>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-validator -->
    <dependency>
        <groupId>org.hibernate.validator</groupId>
        <artifactId>hibernate-validator</artifactId>
    </dependency>

appliaction.yml的配置檔案優先順序

預設狀態

在4個檔案同時配置時,使用的yml檔案的優先級別順序將會按照圖中執行

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-7ruy4nRQ-1609398539485)(D:\學習必備\筆記\SpringBoot\img\image-20200826201311050.png)]

1.路徑對應的是:file:/config/ (專案的根目錄下的config資料夾中)

2.路徑對應的是:file:/ (專案的根目錄下)

3.路徑對應的是:classpath:/config/ (類路徑下的config資料夾中)

4.路徑對應的是:classpath:/ (類路徑下)

可通過以下配置進行指定

spring:
  config:
    location: 檔案路徑

注:這些配置檔案會按照優先順序進行覆蓋,但是並不代表只會載入某一個,他們會進行互補配置,也就是說,無論檔案的優先順序如何,這些配置檔案的都會被載入一遍,然後進行互補配置,比如使用的是B檔案,那麼就會將A檔案中有的B沒有的載入到B中,從而互補

Profile指定啟用

1.properties形式

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-FceRuDx6-1609398539485)(D:\學習必備\筆記\SpringBoot\img\image-20200826202356447.png)]

例:

在appliaction.properties中配置如下

spring.profiles. active=test #表示當前使用的是appliaction-test.properties

注:在改變時只需要寫 - 後面的名稱 如上述事例中的 dev 或test

2.yaml的形式

例:

在appliaction.yml中配置如下

server:
 port: 8081 #配置伺服器埠號
spring:
 profiles:
  active: test #即將使用的yml名稱

--- #一條分割線表示是一個yml
server:
   port: 8082 #配置伺服器埠號
spring:
 profiles: test  #配置當前yml名稱
---
server:
 port: 8083 #配置伺服器埠號
spring:
 profiles: dev  #配置當前yml名稱

注:使用yml的方式配置多個不同的檔案無需建立多個,只用在一個裡面以分割線,分割,即表示多個appliaction.yml

日誌使用

slf4j(日誌門面)+logback(日誌實現)

例:

import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.test.context.SpringBootTest;


@SpringBootTest
class SpringbootIntegrationApplicationTests {
    //獲取一個日誌記錄器
    Logger logger= LoggerFactory.getLogger(getClass());//括號中即為需要被記錄的類
    //日誌的輸出級別如下,由低到高
    @Test
    void contextLoads() {
        logger.trace("這是trace");
        logger.debug("這是debug");
        logger.info("這是info");
        logger.warn("這是warn");
        logger.error("這是error");

    }

}

注:日誌的預設輸出級別為info,所以大於等於info級別的日誌都會輸出

日誌級別:TRACE < DEBUG < INFO < WARN < ERROR < FATAL

  • 配置日誌輸出級別
logging:
  level:
    com: # com.wf為需要被記錄的包,trace為最低級別,如果配置的是最低級別,那麼只要比他高的級別都會輸出
      wf: trace

配置日誌儲存路徑(預設是在控制檯)

方式一

注:如果沒加路徑則會在專案根目錄下建立springboot.log來儲存日誌,加上路徑則會按照路徑儲存

logging:
  file:
   # name: springboot.log
   name: C:\demo\springboot.log # 按照路徑儲存日誌

方式二

logging:
  file:
    path: E:\demo\springboot.log #按照此路徑儲存日誌

注:二者設定其一就可,若都設定,則方式一生效

  • 配置日誌輸出格式

    在控制檯輸出的格式:

logging:
  pattern:
    console: "%boldMagenta(%d{yyyy-MM-dd HH:mm:ss})  [%p]  %highlight(%C:%L)  : %m %n"

​ 在檔案中輸出的格式:

logging:
  pattern:
    file: "%boldMagenta(%d{yyyy-MM-dd HH:mm:ss})  [%p]  %highlight(%C:%L)  : %m %n"
  • 格式解析:

志輸出格式:**
%d表示日期時間,
%thread表示執行緒名,
%-5level:級別從左顯示5個字元寬度
%logger{50} 表示logger名字最長50個字元,否則按照句點分割。
%msg:日誌訊息,
​ %n是換行符**

  • 指定配置

    注:當使用表格中的這些日誌實現時,若需要新增自己的日誌配置,則配置檔案的名稱應該按照表格右邊的約定編寫,這樣就可以直接使用了

    Logging SystemCustomization
    Logbacklogback-spring.xml, logback-spring.groovy, logback.xml or logback.groovy
    Log4j2log4j2-spring.xml or log4j2.xml
    JDK (Java Util Logging)logging.properties

    區別:

    logback.xml:直接就被日誌框架識別了;

    logback-spring.xml:日誌框架就不直接載入日誌的配置項,由SpringBoot解析日誌配置,可以使用SpringBoot的高階Profile功能,建議使用

    例:

    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-mfwRWkVq-1609398539488)(D:\學習必備\筆記\SpringBoot\img\image-20200829100032467.png)]

    當使用的是開發環境時,日誌的輸出是一種格式,當不是開發環境時,日誌的輸出是另一種格式

    可使用以下標籤在logback-spring.xml中進行配置,不同環境下的狀態

    <springProfile name="staging">
        <!-- configuration to be enabled when the "staging" profile is active -->
      	可以指定某段配置只在某個環境下生效
    </springProfile>
    

    配置示例:

    <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
            <layout class="ch.qos.logback.classic.PatternLayout">
                <!--name=dev表示如果使用的是開發環境,那麼日誌的輸出格式就是帶---》的這種-->
                <springProfile name="dev">
                    <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} ----> [%thread] ---> %-5level %logger{50} - %msg%n</pattern>
                </springProfile>
                 <!--name=dev表示如果使用的不是開發環境,那麼日誌的輸出格式就是帶===的這種-->
                <springProfile name="!dev">
                    <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} ==== [%thread] ==== %-5level %logger{50} - %msg%n</pattern>
                </springProfile>
            </layout>
        </appender>
    

    若使用的是logback.xml還想使用profile指定環境,那麼程式就會報如下錯誤:

    no applicable action for [springProfile]
    

靜態資源的處理

注:假如在標註序號的資料夾下同時存在相同名稱的檔案,那麼使用的預設順序將會按照序號選擇

可以通過以下程式碼指定資料夾

spring:
 mvc:
  static-path-pattern: 

templates資料夾相當於webapp資料夾下的WEB-INF,只能通過controller才能訪問該資料夾下的資源

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-wFTj4dnQ-1609398539490)(D:\學習必備\筆記\SpringBoot\img\image-20200827111057754.png)]

thymeleaf模板引擎

依賴:

<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf-spring5</artifactId>
</dependency>
<dependency>
    <groupId>org.thymeleaf.extras</groupId>
    <artifactId>thymeleaf-extras-java8time</artifactId>
</dependency>

html宣告的約束:

<html xmlns:th="http://www.thymeleaf.org">

thymeleaf語法

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-g937qc8T-1609398539492)(D:\學習必備\筆記\SpringBoot\img\2018-02-04_123955.png)]

表示式:

Simple expressions:(表示式語法)
    Variable Expressions: ${...}:獲取變數值;OGNL;
    		1)、獲取物件的屬性、呼叫方法
    		2)、使用內建的基本物件:
    			#ctx : the context object.
    			#vars: the context variables.
                #locale : the context locale.
                #request : (only in Web Contexts) the HttpServletRequest object.
                #response : (only in Web Contexts) the HttpServletResponse object.
                #session : (only in Web Contexts) the HttpSession object.
                #servletContext : (only in Web Contexts) the ServletContext object.
                
                ${session.foo}
            3)、內建的一些工具物件:
#execInfo : information about the template being processed.
#messages : methods for obtaining externalized messages inside variables expressions, in the same way as they would be obtained using #{…} syntax.
#uris : methods for escaping parts of URLs/URIs
#conversions : methods for executing the configured conversion service (if any).
#dates : methods for java.util.Date objects: formatting, component extraction, etc.
#calendars : analogous to #dates , but for java.util.Calendar objects.
#numbers : methods for formatting numeric objects.
#strings : methods for String objects: contains, startsWith, prepending/appending, etc.

將如下集合遍歷,並去掉[] 左右括號
例:
private List<String> postno;
    user.postno 指的是被遍歷出來的user物件,對應的就是上面這個集合,直接寫,可以自己遍歷
    遍歷後去掉左右的括號
 <td th:text="${#strings.replace(#strings.replace(user.postno,'[',''),']','')}">&nbsp;</td>

    
    
    字串的比較即check資料回顯:
    存在如下集合:private List<String> role;
    注:此處需要先去空格在進行字串的比較否則比對永遠不成功
    
<input type='checkbox'  th:each="role :${session.loginUser.role}" th:if="${#strings.trim(role)} eq 'ROLE_SystemAdministrator'" th:checked="${#strings.trim(role)} eq 'ROLE_SystemAdministrator'"  name='resourceIdList' id='cb_45' onclick='doChecked("li_45", this.checked)'/>
    

#objects : methods for objects in general.
#bools : methods for boolean evaluation.
#arrays : methods for arrays.
#lists : methods for lists.
#sets : methods for sets.
#maps : methods for maps.
#aggregates : methods for creating aggregates on arrays or collections.
#ids : methods for dealing with id attributes that might be repeated (for example, as a result of an iteration).

    Selection Variable Expressions: *{...}:選擇表示式:和${}在功能上是一樣;
    	補充:配合 th:object="${session.user}:
   <div th:object="${session.user}">
    <p>Name: <span th:text="*{firstName}">Sebastian</span>.</p>
    <p>Surname: <span th:text="*{lastName}">Pepper</span>.</p>
    <p>Nationality: <span th:text="*{nationality}">Saturn</span>.</p>
    </div>
    
    Message Expressions: #{...}:獲取國際化內容
    Link URL Expressions: @{...}:定義URL;
    		@{/order/process(execId=${execId},execType='FAST')}
    Fragment Expressions: ~{...}:片段引用表示式
    		<div th:insert="~{commons :: main}">...</div>
 關係運算符
且(and) 或 ||

Literals(字面量)
      Text literals: 'one text' , 'Another one!' ,…
      Number literals: 0 , 34 , 3.0 , 12.3 ,…
      Boolean literals: true , false
      Null literal: null
      Literal tokens: one , sometext , main ,…
Text operations:(文字操作)
    String concatenation: +
    Literal substitutions: |The name is ${name}|
Arithmetic operations:(數學運算)
    Binary operators: + , - , * , / , %
    Minus sign (unary operator): -
Boolean operations:(布林運算)
    Binary operators: and , or
    Boolean negation (unary operator): ! , not
Comparisons and equality:(比較運算)
    Comparators: > , < , >= , <= ( gt , lt , ge , le )
    Equality operators: == , != ( eq , ne )
Conditional operators:條件運算(三元運算子)
    If-then: (if) ? (then)
    If-then-else: (if) ? (then) : (else)
    Default: (value) ?: (defaultvalue)
Special tokens:
    No-Operation: _  假如三元運算子後面沒有操作,那麼就可以寫一個_代替
                                 
   迴圈計數 iterStat

注:[[……]]表示的是th:text,而[(……)]表示的是th:utext,如果想要html程式碼被解析,那麼就應該使用th:utext

寫專案時遇到的一個坑:

在controller中使用Model儲存一個User物件

@GetMapping("/saveUI/{id}")
public String saveUI(@PathVariable String id,Model model){
   
        //查詢即將修改的user資訊
        model.addAttribute("updateUser",OperationUserService.selectUserAll(new User(id)));
    return "/System_User/saveUI";
}

物件被解析後的字串如下:

[User{id='c07e2f5748104e21ada578276f7196dd', logname='lm', password='ICy5YqxZB1uWSwcVLSNLcA==', name='劉敏', sex='女', phone='13444342223', email='[email protected]', deptno=Dept{id='fc465c1d79544435b0735a4d3adbd280', name='研發部', number='12', rank=0, superiors=null, superiorsId='null'remark='研發專案}, userno=3, postno=[開發], remark='實習生', deptSerial='12', picture='tu.jpeg'}]

在使用thymeleaf獲取時發現,無法直接根據Model中的key去獲取,直接獲取會是一個集合型別,獲取方式如下:

<div class="Description"  th:text="${updateUser.get(0).id}" >

${updateUser}獲取到的是Model中儲存的元素,如上述的json,但是直接 用.來獲取user的屬性的話會報如下錯,

EL1008E: Property or field ‘id’ cannot be found on object of type ‘java.util.ArrayList’ - maybe not public or not valid?

應該先獲取集合中的位置,在獲取屬性

thymeleaf實現資料回顯

select :(th:selected)

 <option th:selected="${updateUser!=null} and ${updateUser.get(0).deptno.name}==${dept.name}"  th:each="dept :${DeptList}"  th:value="${dept.number}" th:text="${dept.name}"></option>

radio: (th:checked)

<input type="RADIO"  th:checked="${updateUser} !=null ?(${updateUser.get(0).sex}==''?true:false):''" name="sex" value="" id="female"/><label for="female"></label>

thymeleaf空物件處理

例:

這裡的if並不能起到判斷為空的作用,所以需要新增 ?的方式進行處理

<option   th:each="post :${updateUser?.get(0)?.post}" th:text="${post.name}"  selected="selected"  th:value="${post.postno}"></option>

注:var name = [[${session?.user?.name}]],裡面新增?號的作用就是判斷是不是null,只要其中一級是null,返回值就是null,就不會在獲取後面的屬性了==,注意在使用?的時候就不要在使用th:if了,會衝突==

其他語法詳情參見此文件:

https://www.jianshu.com/p/d1370aeb0881

thymeleaf靜態資原始檔的路徑編寫

例:

現存在如下資料夾:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-AEJcicE1-1609398539494)(D:\學習必備\筆記\SpringBoot\img\image-20200827213230752.png)]

index.html的資源路徑編寫示例:

<link rel="stylesheet" type="text/css" th:href="@{/css/style.css}">

<script type="text/javascript"   th:src="@{/js/jquery-1.7.2.min.js}"></script>
<script type="text/javascript" th:src="@{/js/all.js}"></script>

注:在@{}標籤中編寫的是url,括號中的內容以 /開頭表示的是專案根路徑,因為css資料夾存在於static資料夾中所以可以被掃描到,無需再次編寫

thymeleaf公共頁面元素抽取

1、抽取公共片段

     在footer.html中有如下片段
<div th:fragment="copy" id="ccc"> <!--給引入的模板編寫一個--->
被引入的內容
</div>

2、引入公共片段
<!--此處的footer是映入模板的html名稱,copy是引入的模板名稱-->
<!--因為thymeleaf會走檢視解析器,所以footer無需寫全路徑名(footer.html),只需要寫footer即可-->

方式一:~{templatename::fragmentname}:模板名::片段名
<div th:insert="~{footer :: copy}"></div>

方式二:~{templatename::selector}:模板名::選擇器
<div th:insert="~{footer :: #ccc}"></div>

3、預設效果:
insert的公共片段在div標籤中
如果使用th:insert等屬性進行引入,可以不用寫~{}:
行內寫法可以加上:[[~{}]];[(~{})];

三種引入公共片段的th屬性:

th:insert:將公共片段整個插入到宣告引入的元素中(將內容插入到本身的基礎之上)

th:replace:將宣告引入的元素替換為公共片段(將本身全部替換為內容)

th:include:將被引入的片段的內容包含進這個標籤中(只引入內容)

引入元素時傳遞引數:

<!--引入左邊導航欄,並傳遞一個引數-->
<div th:replace="~{commons/part :: #reight(activuri='list')}"></div>


<!--引數的使用-->
<a class="nav-link"
   
   					<!--用三元運算子判斷接收的引數是否為list,然後設定class屬性-->
   
                   th:class="${activuri=='list'?'nav-link active':'nav-link'}"
   
   
   
                   th:href="@{/emp/selectAll}">
                    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-users">
                        <path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path>
                        <circle cx="9" cy="7" r="4"></circle>
                        <path d="M23 21v-2a4 4 0 0 0-3-3.87"></path>
                        <path d="M16 3.13a4 4 0 0 1 0 7.75"></path>
                    </svg>
                    員工列表
                </a>

擴充套件SpringMvc配置

一.歡迎頁面

@Configuration //宣告這是一個配置類
public class UserConfig implements WebMvcConfigurer {

    /**
     * 配置一個檢視控制
     * @param registry
     */
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        //當訪問路徑為 / 或者為 /login 時,跳轉到index.html介面
        registry.addViewController("/").setViewName("index");
        registry.addViewController("/login").setViewName("index");
    }
}

全面接管SpringMvc:

注:該註解表示,SpringMvc所有的自動裝配全部失效,需要自行配置

@EnableWebMvc

二.國際化

  1. 編寫中英文對照配置檔案

    注:login.properties表示的是預設顯示,login_en_US.properties表示的是英文,

    login_zh_CN.properties表示的是中文

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-AdJ4yJEI-1609398539495)(D:\學習必備\筆記\SpringBoot\img\image-20200829200557212.png)]

配置示例:

login.properties(預設)

login.title=請登入
login.remember=記住我
login.userName=使用者名稱
login.userPas=密碼
login.btn=登入

login_en_US.properties(英文)

login.title=Please sign in   
login.remember=Remember me
login.userName=Username
login.userPas=Password
login.btn=Sign in

login_zh_CN.properties(中文)

login.title=請登入
login.remember=記住我
login.userName=使用者名稱
login.userPas=密碼
login.btn=登入

注:中文的值對應英文的值,英文的值來自於頁面

2.LocaleResolver自定義元件配置

package com.wf.compont;

import org.springframework.util.StringUtils;
import org.springframework.web.servlet.LocaleResolver;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;

public class MyLocaleResolver implements LocaleResolver {
    @Override
    public Locale resolveLocale(HttpServletRequest request) {
        //獲取引數,此處獲取的是中英文切換超連結點選傳入的引數
        //即:中文:?l=zh_CN   英文:?l=en_US
        String l = request.getParameter("l");
        Locale locale=Locale.getDefault();//獲取預設的配置,假如沒有傳入引數就使用預設
        //判斷引數是否為空
        if(!StringUtils.isEmpty(l)){
            //將傳入的語言和國家進行拆分  zh為語言 CN為國家
            String [] target=l.split("_");
            //傳入語言,國家
            locale=new Locale(target[0],target[1]);
        }
        return locale;
    }

    @Override
    public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {

    }
}

3.將自定義元件新增到配置檔案中

注: @Bean相當於 其方法名必須是方法返回值的駝峰命名規則,其等同於 是標籤中的id值,所以不符合規則的話,將會導致無法注入

package com.wf.config;

import com.wf.compont.MyLocaleResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MyWebConfig implements WebMvcConfigurer {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("index");
        registry.addViewController("index.html").setViewName("index");
    }

    //將自己編寫的元件,進行配置
    @Bean//相當於<bean></bean>
    public LocaleResolver localeResolver(){ //注:!!!此處的方法名相當於<bean ></bean>中的id
        //應該為駝峰命名規則下的方法返回值名稱,不然配置不會生效
        return new MyLocaleResolver();
    }

}

4.啟用peoperties

application.yml

spring:
  messages:
    basename: I18n.login #I18n資料夾下的login.properties

5.前端使用(部分)

  <input type="checkbox" value="remember-me">[[#{login.remember}]]  <!--獲取配置檔案中的login.remember項-->
     </label>
</div>
<button class="btn btn-lg btn-primary btn-block" type="submit" th:text="#{login.btn}" >Sign in</button>
<p class="mt-5 mb-3 text-muted">© 2017-2018</p>

<!--切換中英文-->
<a class="btn btn-sm" th:href="@{/index.html(l='zh_CN')}">中文</a>
<a class="btn btn-sm" th:href="@{/index.html(l='en_US')}">English</a>

三.攔截器

自定義攔截器:

package com.wf.compont;


import com.wf.pojo.User.User;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * 配置攔截器
 */
public class MyHandlerInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        HttpSession session = request.getSession();
        User user = (User)session.getAttribute("user");
        if(user!=null){
            return true;
        }else{
            //攔截請求,提示錯誤資訊
            request.setAttribute("mss","非法登入");
            //返回登入介面
            request.getRequestDispatcher("/index.html").forward(request,response);
            return false;
        }
    }
}

攔截器配置:

注:此處的靜態資源的排除如下 .excludePathPatterns("/asserts/**") 將asserts目錄下的所有資源都排除

檔案目錄:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-FiUQ9wfQ-1609398539498)(D:\學習必備\筆記\SpringBoot\img\image-20200829231140472.png)]

package com.wf.config;

import com.wf.compont.MyHandlerInterceptor;
import com.wf.compont.MyLocaleResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MyWebConfig implements WebMvcConfigurer {
    //配置檢視對映
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("index");
        registry.addViewController("/index.html").setViewName("index");
        registry.addViewController("/main.html").setViewName("dashboard");
    }

    //將自己編寫的國際化元件,進行配置
    @Bean
    public LocaleResolver localeResolver(){
        return new MyLocaleResolver();
    }

    //配置攔截器

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //攔截所有,排除最後三個,和靜態資源
        registry.addInterceptor(new MyHandlerInterceptor()).addPathPatterns("/**").excludePathPatterns("/asserts/**","/","/index.html","/login/verify");
    }


}

四.錯誤頁面

1)、有模板引擎的情況下;error/狀態碼; 【將錯誤頁面命名為 錯誤狀態碼.html(400.html) 放在模板引擎資料夾裡面的 error資料夾下】,發生此狀態碼的錯誤就會來到 對應的頁面;

可以使用4xx和5xx作為錯誤頁面的檔名來匹配這種型別的所有錯誤,精確優先(優先尋找精確的狀態碼.html);

​ 頁面能獲取的資訊;

​ timestamp:時間戳

​ status:狀態碼

​ error:錯誤提示

​ exception:異常物件

​ message:異常訊息

​ errors:JSR303資料校驗的錯誤都在這裡

例:

顯示部分錯誤資訊:

<main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
					<h1>[[${timestamp}]]</h1>
					<h1>[[${status}]]</h1>
					<h1>[[${error}]]</h1>
					<h1>[[${message}]]</h1>
				</main>

檔案目錄如下:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-61uIcK75-1609398539501)(D:\學習必備\筆記\SpringBoot\img\image-20200830194042678.png)]

當發生404錯誤時,就會返回此頁面

2)、沒有模板引擎(模板引擎找不到這個錯誤頁面),靜態資原始檔夾下找,即,在static資料夾下的error去找

3)、以上都沒有錯誤頁面,就是預設來到SpringBoot預設的錯誤提示頁面;

五.自定義異常

注:springboot2.3.2版本中若要自己的Exception可以列印,massage則需要做如下配置:

配置前:

20200811190847181
#配置自定義異常資訊顯示
server:
  error:
    include-exception: true
    include-message: always

配置後:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-bglDNQK8-1609398539503)(D:\學習必備\筆記\SpringBoot\img\20200811191336943.png)]

自定義異常類:

package com.wf.Exception;

public class UserNotExistException extends RuntimeException {
    public UserNotExistException() {
        super("使用者不存在");
    }
}

讓捕獲到的異常轉發到/error進行自適應響應效果處理

package com.wf.controller;

import com.wf.Exception.UserNotExistException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

@ControllerAdvice
public class MyExceptionHandler {

    @ExceptionHandler(UserNotExistException.class)
    public String handleException(Exception e, HttpServletRequest request){
        Map<String,Object> map = new HashMap<>();
        //傳入自己的錯誤狀態碼  4xx 5xx,否則就不會進入定製錯誤頁面的解析流程
     
        request.setAttribute("javax.servlet.error.status_code",500);
        map.put("code","user.notexist");
        map.put("message",e.getMessage());
        //轉發到/error
        return "forward:/error";//在error資料夾下有一個500.html
    }
}

六.伺服器相關配置

springboot預設伺服器是tomcat

  1. 使用配置檔案來修改Servlet容器的配置
#配置自定義異常資訊顯示(顯示異常物件,顯示異常資訊)
server:
  error:
    include-exception: true
    include-message: always
#修改Tomcat的埠號
  port: 8081
#配置tomcat的字符集
  tomcat:
    uri-encoding: utf-8
#配置專案訪問路徑
  servlet:
    context-path: /wf

​ 2.使用嵌入式的Servlet容器的定製器;來修改Servlet容器的配置

@Bean
    public WebServerFactoryCustomizer<ConfigurableWebServerFactory> webServerFactoryCustomizer(){
        return new WebServerFactoryCustomizer<ConfigurableWebServerFactory>() {
            @Override
            public void customize(ConfigurableWebServerFactory factory) {
                factory.setPort(8081);//修改埠號
            }
        };
    }

springboot中註冊Servlet三大元件【Servlet、Filter、Listener】

可通過ServletRegistrationBean,FilterRegistrationBean,ServletListenerRegistrationBean實現

切換伺服器

使用jetty伺服器(優點:支援持久連線,可用來做聊天系統)

<!-- 引入web模組 -->
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
   <exclusions>
      <exclusion>
         <artifactId>spring-boot-starter-tomcat</artifactId>
         <groupId>org.springframework.boot</groupId>
      </exclusion>
   </exclusions>
</dependency>

<!--引入其他的Servlet容器-->
<dependency>
   <artifactId>spring-boot-starter-jetty</artifactId>
   <groupId>org.springframework.boot</groupId>
</dependency>

使用Undertow伺服器(優點:支援高併發)

<!-- 引入web模組 -->
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
   <exclusions>
      <exclusion>
         <artifactId>spring-boot-starter-tomcat</artifactId>
         <groupId>org.springframework.boot</groupId>
      </exclusion>
   </exclusions>
</dependency>

<!--引入其他的Servlet容器-->
<dependency>
   <artifactId>spring-boot-starter-undertow</artifactId>
   <groupId>org.springframework.boot</groupId>
</dependency>

Druid資料來源整合

匯入依賴:

<!--配置log4j日誌監控-->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>
<!-- 配置druid資料來源 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.23</version>
</dependency>

application.yml連線池配置

spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql://localhost:3306/sys?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
    initialSize: 5
    minIdle: 5
    maxActive: 20
    maxWait: 60000
    timeBetweenEvictionRunsMillis: 60000
    minEvictableIdleTimeMillis: 300000
    validationQuery: SELECT1FROMDUAL
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    filters: stat,wall,log4j
    logSlowSql: true

整合Druid資料來源

package com.wf.config;


import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.springframework.boot.context.properties.ConfigurationProperties;
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 javax.sql.DataSource;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

@Configuration
public class DruidConfig {

    @ConfigurationProperties(prefix = "spring.datasource")
    @Bean
    public DataSource druid(){
        return  new DruidDataSource();
    }

    //配置Druid的監控
    //1、配置一個管理後臺的Servlet
    @Bean
    public ServletRegistrationBean statViewServlet(){
        ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
        Map<String,String> initParams = new HashMap<>();

        initParams.put("loginUsername","admin");
        initParams.put("loginPassword","123456");
        initParams.put("allow","");//預設就是允許所有訪問
        initParams.put("deny","192.168.15.21");

        bean.setInitParameters(initParams);
        return bean;
    }


    //2、配置一個web監控的filter
    @Bean
    public FilterRegistrationBean webStatFilter(){
        FilterRegistrationBean bean = new FilterRegistrationBean();
        bean.setFilter(new WebStatFilter());

        Map<String,String> initParams = new HashMap<>();
        initParams.put("exclusions","*.js,*.css,/druid/*");

        //設定這些資源不被過濾
        bean.setInitParameters(initParams);
		//設定需要過濾的資源
        bean.setUrlPatterns(Arrays.asList("/*"));


        return  bean;
    }
}

springboot整合mybatis

1、匯入依賴

      <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <!--資料庫連線-->
         <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!-- 配置druid資料來源 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.23</version>
        </dependency>
        <!--mybatis -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.3</version>
        </dependency>

2.配置資料來源

spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql://localhost:3306/sys?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8
    driver-class-name: com.mysql.cj.jdbc.Driver
#配置連線池資訊
    type: com.alibaba.druid.pool.DruidDataSource
    initialSize: 5
    minIdle: 5
    maxActive: 20
    maxWait: 60000
    timeBetweenEvictionRunsMillis: 60000
    minEvictableIdleTimeMillis: 300000
    validationQuery: SELECT1FROMDUAL
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    filters: stat,wall,log4j
    logSlowSql: true
#配置實體類別名
mybatis:
  type-aliases-package: com.wf.pojo
#配置sqlmapper檔案路徑
  mapper-locations: classpath:mybatis/mapper/*.xml

sqlmapper.xml配置檔案的存放目錄:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-ysFn25n0-1609398539504)(D:\學習必備\筆記\SpringBoot\img\image-20200831160821976.png)]

3.配置springboot掃描dao介面

注:可以用兩種方式,掃描dao

@Mapper

@MapperScan(“com.wf.Dao”)

例:

@Mapper  //使該介面被掃描
@Repository
public interface OpectionStudent {
    List<Student> selectAll();
}
@MapperScan("com.wf.Dao")//要被掃描的dao介面,在springboot啟動口配置
@SpringBootApplication
public class SpringbootMybatisApplication {

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

}

springboot-security(許可權控制)

整合示例:

1.匯入依賴

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

2.自定義Security策略(WebSecurityConfigureAdaper)

靜態資源結構如下:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-ci0vzM5u-1609398539506)(D:\學習必備\筆記\SpringBoot\img\image-20200902105331509.png)]

3.使用者認證授權,及登出(cookies,session資料的銷燬):

package com.wf.config;

import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@EnableWebSecurity  //開啟webSecurity模式
public class SucerityConfig extends WebSecurityConfigurerAdapter {
    //定製請求的授權規則
    @Override
    protected void configure(HttpSecurity http) throws Exception {
       http.authorizeRequests()
               //當請求為‘/’時,所有人都可以訪問
               .antMatchers("/").permitAll()//首頁所有人都可以訪問
               //當請求為/level1/**時,只有vip1的身份才能訪問,以下類同
               .antMatchers("/level1/**").hasRole("vip1")
               .antMatchers("/level2/**").hasRole("vip2")
               .antMatchers("/level3/**").hasRole("vip3");
        //如果沒有登入,也沒有許可權,那麼就會跳轉到登入介面
       http.formLogin();
        http.csrf().disable();//關閉防止跨站請求攻擊

       //設定登出請求,刪除cookie,移出session
     //  http.logout().deleteCookies("remove").invalidateHttpSession(true);
        //登出成功之後跳轉到首頁
        http.logout().logoutSuccessUrl("/");
    }

    //定義認證規則
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                //設定使用者許可權,加密後的密碼,和對應可以訪問的許可權
                .passwordEncoder(new BCryptPasswordEncoder())
                //張三 使用者的密碼為 123 他只能訪問上述程式碼中vip1中的內容
                .withUser("zhangsan").password(new BCryptPasswordEncoder().encode("123")).roles("vip1")
                .and()
                .withUser("lisi").password(new BCryptPasswordEncoder().encode("123")).roles("vip2","vip1")
                .and()
                .withUser("wangwu").password(new BCryptPasswordEncoder().encode("123")).roles("vip3","vip1","vip2");

    }
}

注:對應的登出請求,前端傳送的url應該如下

<a th:href="@{/logout}">登出</a>

頁面控制,選擇顯示:

1.匯入依賴:


<dependency>
    <groupId>org.thymeleaf.extras</groupId>
    <artifactId>thymeleaf-extras-springsecurity4</artifactId>
    <version>3.0.4.RELEASE</version>
</dependency>

2.匯入名稱空間

<html xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/99/xhtml/thymeleaf-extras-springsecurity4">

頁面程式碼:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1 align="center">歡迎光臨武林祕籍管理系統</h1>
<h2 align="center">遊客您好,如果想檢視武林祕籍 </h2>

<!--如果使用者沒有登入-->
<div sec:authorize="not isAuthenticated()">
	<p><a th:href="@{/login}">請登入</a></p>
</div>
    
    
<!--如果使用者已經登入  isAuthenticated 驗證已經登入過了-->
<div sec:authorize="isAuthenticated()">
	使用者名稱:<span sec:authentication="name"></span>
<p><a th:href="@{/logout}">登出</a></p>
</div>
    
    
    <!--判斷此次登陸是否包含vip的內容-->
<hr>
<div sec:authorize="hasRole('vip1')">
<h3>普通武功祕籍</h3>
<ul>
	<li><a th:href="@{/level1/1}">羅漢拳</a></li>
	<li><a th:href="@{/level1/2}">武當長拳</a></li>
	<li><a th:href="@{/level1/3}">全真劍法</a></li>
</ul>
</div>
    
    
    
<div sec:authorize="hasRole('vip2')">
<h3>高階武功祕籍</h3>
<ul>
	<li><a th:href="@{/level2/1}">太極拳</a></li>
	<li><a th:href="@{/level2/2}">七傷拳</a></li>
	<li><a th:href="@{/level2/3}">梯雲縱</a></li>
</ul>
    
    
</div>
<div sec:authorize="hasRole('vip3')">
<h3>絕世武功祕籍</h3>
<ul>
	<li><a th:href="@{/level3/1}">葵花寶典</a></li>
	<li><a th:href="@{/level3/2}">龜派氣功</a></li>
	<li><a th:href="@{/level3/3}">獨孤九劍</a></li>
</ul>
</div>
    
    
</body>
</html>

自定義登入介面,及表單資料的提交:

package com.wf.config;

import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@EnableWebSecurity  //開啟webSecurity模式
public class SucerityConfig extends WebSecurityConfigurerAdapter {
    //定製請求的授權規則
    @Override
    protected void configure(HttpSecurity http) throws Exception {
       http.authorizeRequests()
               //當請求為‘/’時,所有人都可以訪問
               .antMatchers("/").permitAll()//首頁所有人都可以訪問
               //當請求為/level1/**時,只有vip1的角色才能訪問,以下類同
               .antMatchers("/level1/**").hasRole("vip1")
               .antMatchers("/level2/**").hasRole("vip2")
               .antMatchers("/level3/**").hasRole("vip3");
        //如果沒有登入,也沒有許可權,那麼就會跳轉到登入介面

        ///userlogin是跳轉的url
        //tologin表單提交地址
        http.formLogin().loginPage("/userlogin").//指定自己的登入介面
            usernameParameter("userName").//修改登入表單預設input框中的name屬性值(預設:username)
            passwordParameter("password")//修改登入表單預設input密碼框中的name屬性值(預設:password)
       .loginProcessingUrl("/tologin")
          .defaultSuccessUrl("/") //登入成功後去的地址
            ;//登入的表單提交地址

        http.csrf().disable();//關閉防止跨站請求偽造

        http.rememberMe().rememberMeParameter("remeber");//記住我,建立一個cookies和session儲存當前登入使用者


       //設定登出請求,刪除cookie,移出session
     //  http.logout().deleteCookies("remove").invalidateHttpSession(true);
        //登出成功之後跳轉到首頁
        http.logout().logoutSuccessUrl("/");//登出成功後去的路徑
        
        
       // .exceptionHandling()
		//.accessDeniedPage("/error") 配置無許可權訪問403 錯誤頁面路徑 (自定義403錯誤頁面)

    }

    //定義認證規則,指定正確的賬號密碼
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                //設定使用者許可權,加密後的密碼,和對應可以訪問的許可權
                .passwordEncoder(new BCryptPasswordEncoder())
                //張三 使用者的密碼為 123 他只能訪問上述程式碼中vip1中的內容
                .withUser("zhangsan"). //設定使用者名稱
            password(new BCryptPasswordEncoder().encode("123")).//設定密碼
            roles("vip1")//設定角色
            // .hasAuthority()  //設定使用者具備的許可權
                .and()
                .withUser("lisi").password(new BCryptPasswordEncoder().encode("123")).roles("vip2","vip1")
                .and()
                .withUser("wangwu").password(new BCryptPasswordEncoder().encode("123")).roles("vip3","vip1","vip2");

    }
}

==注:在新增角色前字串的字首必須手動的加上ROLE_作為區分是角色控值還是許可權控制如果不加,那麼就會預設為是許可權控制,這樣就會和宣告的角色控制不對應從而導致不生效

對應前端程式碼:
login.html (其表單提交地址為:/tologin)

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
	</head>
	<body>
		<center>
		<div style="background-color: royalblue;">
			<form action="/tologin" method="post">
				使用者名稱:<input type="text" name="userName"/><br>
				密碼:<input type="password" name="password"><br>
				<input type="checkbox" name="remeber" />記住我
			<input type="submit" value="登入"/><br>
			</form>
		</div>
		<div>
		</div>
	</center>
	</body>
</html>

​ 用於跳轉到自定義登入介面的controller:(/userlogin)

/**
 * 登陸頁
 * @return
 */
@GetMapping("/userlogin")
public String loginPage() {
   return "login";
}

springboot-shiro(許可權控制)

1.匯入依賴:

<dependencies>
	<!--shiro配置-->
    <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-spring</artifactId>
        <version>1.6.0</version>
    </dependency>
  
    <!-- springboot-shiro配置-->
    <dependency>
        <groupId>com.github.theborakompanioni</groupId>
        <artifactId>thymeleaf-extras-shiro</artifactId>
        <version>2.0.0</version>
    </dependency>
    
    
    
    
  <!--資料來源配置-->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.23</version>
    </dependency>
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.1.3</version>
    </dependency>
    <!--配置log4j日誌監控-->
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <groupId>org.junit.vintage</groupId>
                <artifactId>junit-vintage-engine</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

2.applictaion.yml配置:

#關閉模板引擎的快取
spring:
  thymeleaf:
    cache: false
#配置資料來源
  datasource:
    username: root
    password: root
    url: jdbc:mysql://localhost:3306/springboottest?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8
    driver-class-name: com.mysql.cj.jdbc.Driver
    #配置連線池資訊
    type: com.alibaba.druid.pool.DruidDataSource
    initialSize: 5
    minIdle: 5
    maxActive: 20
    maxWait: 60000
    timeBetweenEvictionRunsMillis: 60000
    minEvictableIdleTimeMillis: 300000
    validationQuery: SELECT1FROMDUAL
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    filters: stat,wall,log4j
    logSlowSql: true
#配置實體類別名
mybatis:
  type-aliases-package: com.wf.bean
#配置SQLmapper.xml檔案位置
  mapper-locations: classpath:mapper/*.xml

index.html

<!DOCTYPE html>

<html xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.thymeleaf.org/thymeleaf-extras-shiro">
<head>
    <meta charset="UTF-8">
    <title>首頁</title>
</head>
<body>
<h1>首頁</h1>

<div th:if="${session.loginUser==null}">
    <a th:href="@{/tologin}">登入</a>
</div>

<span th:text="${msg}"></span>
<br>
<hr>
<div shiro:hasPermission="user:add">
    <a th:href="@{/user/add}">add</a>
</div>
<div shiro:hasPermission="user:update">
<a th:href="@{/user/update}">update</a>
</div>
</body>
</html>

配置類:

package com.wf.config;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.catalina.User;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Hashtable;
import java.util.LinkedHashMap;
import java.util.Map;

@Configuration
public class ShiroConfig {

    @Bean(name = "getShiroFilterFactoryBean")
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("getDefaultWebSecurityManager") DefaultWebSecurityManager dWSM) {
        ShiroFilterFactoryBean sffb = new ShiroFilterFactoryBean();
        /*
        anon:無需認證就可以訪問,比如對靜態資源的排除
        authc:必須認證之後才可以訪問
        user:必須擁有記住我功能才能訪問
        perms:擁有對某個資源的許可權才能訪問
        role:擁有某個角色許可權才能訪問
         */

       //設定安全管理器
        sffb.setSecurityManager(dWSM);
        Map<String,String> map=new LinkedHashMap<>();
        //此處的key為請求的地址
        map.put("/user/add","perms[user:add]");
        map.put("/user/update","perms[user:update]");
//        map.put("/user/add","authc");
//        map.put("/user/update","authc");
         //退出系統的controller
        map.put("/logout","logout");
          map.put("/**","authc"); // 對所有請求進行認證
        sffb.setFilterChainDefinitionMap(map);
        // /tologin 為跳轉到登入介面的url,設定假如當前沒有許可權,那麼就會自動跳轉到自定義的登入介面
        sffb.setLoginUrl("/tologin");
         //已經授權後去的頁面
        sffb.setSuccessUrl("/index");
        //設定未授權的url跳轉頁面
        sffb.setUnauthorizedUrl("/tonoUnautorize");
        return sffb;
    }

    //建立安全管理器
    @Bean(name = "getDefaultWebSecurityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm) {
        DefaultWebSecurityManager dwsm = new DefaultWebSecurityManager();
        //關聯許可權物件
        dwsm.setRealm(userRealm);
        return dwsm;
    }


    //建立許可權物件
    @Bean(name = "userRealm")
    public UserRealm userRealm() {
        return new UserRealm();
    }

    //裝配shiro和thymeleof
    @Bean
    public ShiroDialect getShiroDialect(){
        return new ShiroDialect();
    }

}

許可權配置:

package com.wf.config;

import com.wf.bean.User;
import com.wf.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;

public class UserRealm extends AuthorizingRealm {
    @Autowired
    UserService userService;

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //對使用者進行授權
        SimpleAuthorizationInfo sai=new SimpleAuthorizationInfo();
        Subject subject = SecurityUtils.getSubject();
        User user = (User)subject.getPrincipal();
        //給指定角色設定許可權  這裡的許可權就相當於是perms[user:add] 括號中的字串
        sai.addStringPermission(user.getPerms());

        return sai;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {


        UsernamePasswordToken token= (UsernamePasswordToken) authenticationToken;
        String name=token.getUsername();//獲取使用者名稱
        User u=new User();//建立一個當前登入物件
        char[] password = token.getPassword();//從表單中獲取的密碼
        String pas = new String(password);//轉化為字串後的密碼
        u.setName(name);//設定從表單中獲取的名稱
        u=userService.queryUser(u);//查詢資料庫使用者

        //認證使用者名稱是否正確
        if(u==null){
            return  null;
        }
        //將登入的當前使用者存入session中
        Subject subject = SecurityUtils.getSubject();
        Session session = subject.getSession();
        session.setAttribute("loginUser",u);

       //認證密碼
        return new SimpleAuthenticationInfo(u,pas,"");
    }
}

使用Shiro預設退出系統:(可自定義退出,但是需要繼承LogoutFilter,並重寫preHandle)

package com.wf.oa.controller;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

import javax.servlet.http.HttpSession;

@Controller
public class ExitSystem {

    @GetMapping("/logout")
    public String esc(HttpSession session){
        Subject subject = SecurityUtils.getSubject();
        subject.logout();//清除 cookie session 中的資料
        return "loginUI"; //返回至登入介面
    }
}

springboot整合swagger

一.基本資訊配置

1、匯入依賴

   <!-- swagger依賴 -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>
<!--UI介面的依賴-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>

2.配置文件生成內容

package com.wf.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.service.ApiInfo;

import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.ArrayList;

@Configuration
@EnableSwagger2
public class SwaggerConfig {

   @Bean
    public Docket docket(){
        return  new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo());
    }
    public ApiInfo apiInfo(){

        //作者資訊
        Contact contact=new Contact("王飛","http://www.baidu.com","[email protected]");

        return  new ApiInfo(
        "我的swagger文件", //標題
                "美好生活嚮往未來", //描述
                "v1.0",//版本
                "http://www.baidu.com",//組織地址
                contact,//作者資訊
                "Apache 2.0",
                "http://www.apache.org/licenses/LICENSE-2.0",
                new ArrayList<>()
      );
    }

}

3.啟動appliaction類:

注:需要在appliaction啟動類上新增 @ComponentScan({ “com.wf.config” })註解,掃描器配置類,否在會存在

swagger2無限彈窗Unable to infer base url. This is common when using dynamic servlet registra…

@ComponentScan({ "com.wf.config" })//掃描文件配置類
@SpringBootApplication
public class SwaggerApplication {

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

}

二.swagger2無限彈窗解決方案

(Unable to infer base url. This is common when using dynamic servlet registra…)

在使用swagger時出現如下異常:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-l2c999OP-1609398539507)(D:\學習必備\筆記\SpringBoot\img\image-20200904184701418.png)]

解決方案為:

在application啟動類上新增 @ComponentScan({ “com.wf.config” })註解

還可參照如下原因:

①swaager配置檔案忘記加@EnableSwagger2註解

②在application啟動類中未定義@EnableSwagger2註解

③在swaager配置檔案中添加註解@ComponentScan({ “com...mapper” })

④在application啟動類中添加註解@ComponentScan({ “com...mapper” })

三.配置掃描介面,及開關

package com.wf.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;

import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.ArrayList;

@Configuration
@EnableSwagger2
public class SwaggerConfig {

    /**
     * RequestHandlerSelectors 配置要掃描介面的方式
     * basePackage 指定要掃描的包
     * RequestHandlerSelectors.any() 掃描全部
     * RequestHandlerSelectors.none() 全部不掃描
     * RequestHandlerSelectors.withClassAnnotation(); 掃描一個類上的註解,引數是一個註解的反射物件
     * RequestHandlerSelectors.withMethodAnnotation(); 掃描方法上的註解
     */
   @Bean
    public Docket docket(){

        return  new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .enable(true)//是否啟用,swagger 預設為true,表示啟用狀態,false表示不啟用,瀏覽器將無法訪問
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.wf.controller"))
                .paths(PathSelectors.ant("/login/**"))
                .build()
                ;
    }
    public ApiInfo apiInfo(){

        //作者資訊
        Contact contact=new Contact("王飛","http://www.baidu.com","[email protected]");

        return  new ApiInfo(
        "我的swagger文件", //標題
                "美好生活嚮往未來", //描述
                "v1.0",//版本
                "http://www.baidu.com",//組織地址
                contact,//作者資訊
                "Apache 2.0",
                "http://www.apache.org/licenses/LICENSE-2.0",
                new ArrayList<>()
      );
    }

}

四.swagger不同環境下的狀態切換

例:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-aa8kedpV-1609398539508)(D:\學習必備\筆記\SpringBoot\img\image-20200904201606038.png)]

實現如下需求:

在開發環境時啟用swagger在專案部署之後就不在使用swagger

在主配置中指定當前使用的環境為application-dev.yml:

spring.profiles.active=dev

改寫如下程式碼:

 @Bean
    public Docket docket(Environment environment){
       //設定要顯示swagger的環境,指定後當前的swagger只會在Dev環境下生效
        
       Profiles profiles=Profiles.of("dev");//此處的引數為可變長引數,所以可以指定多個
       //判斷當前環境是否為指定環境
       boolean b = environment.acceptsProfiles(profiles);
        /*
        .enable(b)將引數賦值給enable()方法,如果是當前指定環境那就設定swagger可用,如果不是,那就不可用
         */
       return  new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .enable(b)//是否啟用,swagger 預設為true,啟用狀態,false表示不啟用,瀏覽器將無法訪問
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.wf.controller"))
                .paths(PathSelectors.ant("/login/**"))
                .build()
                ;
    }

五.分組及介面註釋

1.分組

 .groupName("分組一")

例:

    @Bean
    public Docket docket1(Environment environment){
        return  new Docket(DocumentationType.SWAGGER_2).groupName("分組四");
    }
    @Bean
    public Docket docket2(Environment environment){
        return  new Docket(DocumentationType.SWAGGER_2).groupName("分組二");
    }
    @Bean
    public Docket docket3(Environment environment){
        return  new Docket(DocumentationType.SWAGGER_2).groupName("分組三");
    }

效果:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-tEF8t1GL-1609398539512)(D:\學習必備\筆記\SpringBoot\img\image-20200904204523851.png)]

2.介面註釋

常用文件生成註解:

@ApiModel("使用者實體類")  //標註在類上
@ApiModelProperty("使用者名稱") //標註在屬性上
@ApiOperation("這是getUser方法") //標註在方法之上
@ApiParam("使用者名稱引數") //標註在引數上

注:使用時應該在application啟動類上標註文件註解被掃描的位置,否則不會生效

會顯示:No operations defined in spec!

例:

application啟動類:

@ComponentScan({ "com.wf.controller" ,"com.wf.config"})
@SpringBootApplication
public class SwaggerApplication {

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

}

使用:

package com.wf.bean;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

@ApiModel("使用者實體類")
public class User {
    @ApiModelProperty("使用者名稱")
private  String name;
    @ApiModelProperty("密碼")
private  String sex;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }
}

六.swagger線上介面測試

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-rrK8oHOF-1609398539514)(D:\學習必備\筆記\SpringBoot\img\image-20200904214209604.png)]

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-Zwa8u61R-1609398539517)(D:\學習必備\筆記\SpringBoot\img\image-20200904214335067.png)]

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-0IFg9I5c-1609398539519)(D:\學習必備\筆記\SpringBoot\img\image-20200904214434188.png)]

springboot非同步任務

@Async  //從執行緒池中重新開啟一個執行緒完成當前任務,放置在需要非同步的方法之上
@EnableAsync //開啟非同步任務,放置在application啟動類上

例:

@GetMapping("/getUser")
@ResponseBody
@Async  //表示當前方法的執行會被分配一個新的執行緒去執行
public User getUser2( String name){//標註引數
    return new User();
}
@SpringBootApplication
@EnableAsync //表示開啟非同步任務
public class SwaggerApplication {

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

}

springboot郵件傳送

1.匯入啟動器

<!--配置郵件傳送的啟動器-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
</dependency>

2.獲取授權碼

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-BJNOTcZq-1609398539521)(D:\學習必備\筆記\SpringBoot\img\image-20200905093248098.png)]

點選設定——》點選賬戶

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-fYVekuGU-1609398539523)(D:\學習必備\筆記\SpringBoot\img\image-20200905093410192.png)]

點選開啟

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-ZP8Lwf23-1609398539524)(D:\學習必備\筆記\SpringBoot\img\image-20200905093610048.png)]

填寫資訊

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-f00TuzAi-1609398539527)(D:\學習必備\筆記\SpringBoot\img\image-20200905093830222.png)]

3.配置資訊

application.properties:

#發起人的賬號
[email protected]
#發起人的授權碼
spring.mail.password=vvmfrnrxsncfddej
#傳送的伺服器    smtp.163.com (163郵箱)
spring.mail.host=smtp.qq.com
#開啟加密驗證
spring.mail.properties.mail.smtl.ssl.enable=true

注:步驟2中獲取到的授權碼,對應配置的就是檔案中的第二部分

4.編寫郵件

簡單型別的郵件:

@SpringBootTest
class SwaggerApplicationTests {
  @Autowired
  JavaMailSenderImpl javaMailSender;

    @Test
    void contextLoads() {
        SimpleMailMessage message=new SimpleMailMessage();
        message.setSubject("簡單郵件");//設定郵件的通知
        message.setText("內容啥的");//設定郵件的文字內容
        message.setTo("[email protected]");//傳送給誰
        message.setFrom("[email protected]");//由誰傳送
        javaMailSender.send(message);
    }


}

攜帶檔案傳送:

    @Test
    void contextLoads2() throws MessagingException {
        //一個複雜的郵件
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        //組裝
        MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
        helper.setSubject("簡單郵件22");//通知
        helper.setText("<p style='color: red'>內容啥的22</p>",true);//傳送文字內容,並設定字型顏色
        //傳送附件,檔案
        helper.addAttachment("1241269186.jpeg",new File("D:\\學習必備\\1241269186.jpeg"));
        helper.setTo("[email protected]");//傳送給誰
        helper.setFrom("[email protected]");//由誰傳送
        javaMailSender.send(mimeMessage);
    }

springboot定時任務

@EnableScheduling //開啟定時任務,放置在application啟動類上
@Scheduled(cron = "0/2 * * * * ?") //為當前任務設定定時,放置在需要執行定時任務的方法上
@Lazy(false) //設定bean的延時載入,避免因為springboot啟動時載入bean 而導致的任務失效,放置在需要執行定時任務的類上
@ComponentScan(value = "com.wf.service",lazyInit = true) //掃描這個包下的註解,並設定延時載入,避免springboot的定時任務失效,放置在application啟動類上

例:

application啟動類:

@SpringBootApplication
@EnableScheduling
@ComponentScan(value = "com.wf.service",lazyInit = true)
public class SwaggerApplication {

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

}

任務:

@Service
@Lazy(false) //設定bean的延時載入
public class SchedulingService {

    @Scheduled(cron = "0/2 * * * * ?")//該任務每隔兩秒執行一次
    public void hello(){
        System.out.println("你好呀~~");
    }
}

常用cron表示式:

​ ( 1)0/2 * * * * ? 表示每2秒 執行任務

(1)0 0/2 * * * ? 表示每2分鐘 執行任務

(1)0 0 2 1 * ? 表示在每月的1日的凌晨2點調整任務

(2)0 15 10 ? * MON-FRI 表示週一到週五每天上午10:15執行作業

(3)0 15 10 ? 6L 2002-2006 表示2002-2006年的每個月的最後一個星期五上午10:15執行作

(4)0 0 10,14,16 * * ? 每天上午10點,下午2點,4點

(5)0 0/30 9-17 * * ? 朝九晚五工作時間內每半小時

(6)0 0 12 ? * WED 表示每個星期三中午12點

(7)0 0 12 * * ? 每天中午12點觸發

(8)0 15 10 ? * * 每天上午10:15觸發

(9)0 15 10 * * ? 每天上午10:15觸發

(10)0 15 10 * * ? 每天上午10:15觸發

(11)0 15 10 * * ? 2005 2005年的每天上午10:15觸發

(12)0 * 14 * * ? 在每天下午2點到下午2:59期間的每1分鐘觸發

(13)0 0/5 14 * * ? 在每天下午2點到下午2:55期間的每5分鐘觸發

(14)0 0/5 14,18 * * ? 在每天下午2點到2:55期間和下午6點到6:55期間的每5分鐘觸發

(15)0 0-5 14 * * ? 在每天下午2點到下午2:05期間的每1分鐘觸發

(16)0 10,44 14 ? 3 WED 每年三月的星期三的下午2:10和2:44觸發

(17)0 15 10 ? * MON-FRI 週一至週五的上午10:15觸發

(18)0 15 10 15 * ? 每月15日上午10:15觸發

(19)0 15 10 L * ? 每月最後一日的上午10:15觸發

(20)0 15 10 ? * 6L 每月的最後一個星期五上午10:15觸發

(21)0 15 10 ? * 6L 2002-2005 2002年至2005年的每月的最後一個星期五上午10:15觸發

(22)0 15 10 ? * 6#3 每月的第三個星期五上午10:15觸發

springboot整合dubbo即zookeepre

dubbo:一個基於java實現的高效能 RPC通訊框架(RPC類比於http)

zookeepre:服務的註冊與發現

1.匯入依賴

<!--配置dubbo-->
<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo-spring-boot-starter</artifactId>
    <version>2.7.3</version>
</dependency>
<!--配置zkclient -->
<dependency>
    <groupId>com.github.sgroschupf</groupId>
    <artifactId>zkclient</artifactId>
    <version>0.1</version>
</dependency>

<!--因為jar衝突問題所以需要排除一些依賴-->
<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-framework</artifactId>
    <version>2.12.0</version>
</dependency>
<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-recipes</artifactId>
    <version>2.12.0</version>
</dependency>
<!--日誌會衝突~-->
<!--引入zookeeper -->
<dependency>
    <groupId>org.apache.zookeeper</groupId>
    <artifactId>zookeeper</artifactId>
    <version>3.4.14</version>
    <!--排除這個sLf4j-Log4j12-->
    <exclusions>
        <exclusion>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
        </exclusion>
    </exclusions>
</dependency>

2.配置檔案

此處以A作為被訪問者,服務端,提供方法

B作為訪問者。客戶端,呼叫方法,

先寫服務端

application.properties:

#服務應用名稱
dubbo.application.name=mytest-02
#註冊中心地址 zookeeper
dubbo.registry.address=zookeeper://127.0.0.1:2181
#配置掃描包
dubbo.scan.base-packages=com.wf
server.port=8081

客戶端:

#服務應用名稱
dubbo.application.name=mytest-02
#註冊中心地址 zookeeper
dubbo.registry.address=zookeeper://127.0.0.1:2181
server.port=8082

服務端提供的方法:

注:此處的@Service註解的包是org.apache.dubbo.config.annotation.Service; 不是spring中的,標註@Component的作用在於交給spring管理

public interface myservice {
    public  String hello();
}
package com.wf.serviceImpl;

import com.wf.service.myservice;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.stereotype.Component;


@Service
@Component
public class myserviceImpl  implements myservice {
    public  String hello(){
        return "hellow";
    }
}

客戶端:

注:這裡的這個藉口必須名稱,全路徑名和服務端相同,否則無法呼叫

public interface myservice {
    public  String hello();
}
package com.wf.serviceImpl;

import com.wf.service.myservice;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.stereotype.Service;

@Service
public class MyserviceOneImpl {

    @Reference //宣告使用的是別的地方的介面
    myservice myservice;
    public void show() {
        String hello = myservice.hello();
        System.out.println("資料:-----》"+hello);
    }
}

3.啟動測試:

1.D:\apache-zookeeper-3.6.1-bin\apache-zookeeper-3.6.1-bin\bin目錄下雙擊zkServer.cmd檔案開啟服務

2.執行服務端程式,啟動application主類,將方法註冊到服務中

3.C:\Windows\System32\cmd.exe目錄下的dubbo-admin-0.0.1-SNAPSHOT.jar (cmd 執行命令:java -jar 名稱.jar)

4。訪問localhost:7001/ 賬戶密碼為root root

5.點選服務治理–提供著 若存在如下資訊,可點選檢視,那就表示註冊成功

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-6Z4kTFb9-1609398539531)(D:\學習必備\筆記\SpringBoot\img\image-20200905190611162.png)]

6.啟動客戶端程式碼

artifactId>zkclient
0.1

org.apache.curator curator-framework 2.12.0 org.apache.curator curator-recipes 2.12.0 org.apache.zookeeper zookeeper 3.4.14 org.slf4j slf4j-log4j12 ```

2.配置檔案

此處以A作為被訪問者,服務端,提供方法

B作為訪問者。客戶端,呼叫方法,

先寫服務端

application.properties:

#服務應用名稱
dubbo.application.name=mytest-02
#註冊中心地址 zookeeper
dubbo.registry.address=zookeeper://127.0.0.1:2181
#配置掃描包
dubbo.scan.base-packages=com.wf
server.port=8081

客戶端:

#服務應用名稱
dubbo.application.name=mytest-02
#註冊中心地址 zookeeper
dubbo.registry.address=zookeeper://127.0.0.1:2181
server.port=8082

服務端提供的方法:

注:此處的@Service註解的包是org.apache.dubbo.config.annotation.Service; 不是spring中的,標註@Component的作用在於交給spring管理

public interface myservice {
    public  String hello();
}
package com.wf.serviceImpl;

import com.wf.service.myservice;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.stereotype.Component;


@Service
@Component
public class myserviceImpl  implements myservice {
    public  String hello(){
        return "hellow";
    }
}

客戶端:

注:這裡的這個藉口必須名稱,全路徑名和服務端相同,否則無法呼叫

public interface myservice {
    public  String hello();
}
package com.wf.serviceImpl;

import com.wf.service.myservice;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.stereotype.Service;

@Service
public class MyserviceOneImpl {

    @Reference //宣告使用的是別的地方的介面
    myservice myservice;
    public void show() {
        String hello = myservice.hello();
        System.out.println("資料:-----》"+hello);
    }
}

3.啟動測試:

1.D:\apache-zookeeper-3.6.1-bin\apache-zookeeper-3.6.1-bin\bin目錄下雙擊zkServer.cmd檔案開啟服務

2.執行服務端程式,啟動application主類,將方法註冊到服務中

3.C:\Windows\System32\cmd.exe目錄下的dubbo-admin-0.0.1-SNAPSHOT.jar (cmd 執行命令:java -jar 名稱.jar)

4。訪問localhost:7001/ 賬戶密碼為root root

5.點選服務治理–提供著 若存在如下資訊,可點選檢視,那就表示註冊成功

[外鏈圖片轉存中…(img-6Z4kTFb9-1609398539531)]

6.啟動客戶端程式碼