vue前端專案編譯
技術標籤: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> </
-
例如:
以上程式碼中配置的就是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 System Customization Logback logback-spring.xml
,logback-spring.groovy
,logback.xml
orlogback.groovy
Log4j2 log4j2-spring.xml
orlog4j2.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,'[',''),']','')}"> </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
二.國際化
-
編寫中英文對照配置檔案
注: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則需要做如下配置:
配置前:
#配置自定義異常資訊顯示
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
- 使用配置檔案來修改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
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.啟動客戶端程式碼