web的服務器資源:
????????靜態資源:服務器上存儲的不會改變的數據,通常不會根據用戶的請求而變化。比如:HTML、CSS、JS、圖片、視頻等(負責頁面展示)
????????動態資源:服務器端根據用戶請求和其他數據動態生成的,內容可能會在每次請求時都發生變化。比如:Spring框架(負責邏輯處理)
????????B/S架構:Browser/Server,瀏覽器/服務器架構模式。客戶端只需瀏覽器,應用程序的邏輯和數據都存在服務器端。(維護方便體驗一般)
SpringBoot Web入門
spring:官網spring.io
spring全家桶:
Spring Framework:spring框架,為依賴注入,事務管理,Web應用程序,數據訪問等等提供核心支持。
Spring Boot:輕量化構建Spring應用程序,并盡可能地快速啟動和運行。
Spring Data:為數據訪問(關系,非關系,map-reduce)提供方法Spring Cloud:為分布式系統的公共模式提供一組工具。對構建和部署微服務非常有用。
Spring Security:spring安全,通過全面且可擴展的身份驗證和授權支持來保護應用程序。spring全家桶是以Spring Framework(spring框架)為核心。
Spring Framework:配置繁瑣,入門難度大。
Spring Boot:簡化配置,快速開發。
Spring? Boot可以幫助我們非常快速的構建應用程序、簡化開發、提高效率。(官方推薦,企業主流)
入門程序
入門程序
????????需求:基于SpringBoot開發一個Web應用,瀏覽器發起請求/hello之后,給瀏覽器返回一個字符串”Hello XX“
????????發起:http://localhost:8080/hello?name=zyx
? ? ? ? 返回:Hello zyx
SpringBootP1Application是啟動項
HelloController是運行的代碼
package com.cyyweb.springbootp1;import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController //標識當前是一個請求處理類
public class HelloController {@RequestMapping("/hello")public String hello(String name){System.out.println("Hello Controller ... hello : " + name);return "Hello " + name + "~";}}
運行結果:
入門程序剖析
依賴:
<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></dependency>
?
spring-boot-starter-web用于web開發
spring-boot-starter-test用于單元測試
HTTP協議
HTTP協議,超文本傳輸協議,規定了瀏覽器和服務器之間數據傳輸的規范。
HTTP協議特點:
1.基于TCP協議:面向連接,安全
2.基于請求-響應模型的:一次請求對應一次響應
3.HTTP協議是無狀態的協議:對于事務處理沒有記憶能力。每次請求-響應都是獨立的
缺點:多次請求間不能共享數據
優點:速度快
HTTP的請求數據
HTTP的請求數據格式
HTTP請求數據的三部分
請求行(請求數據的第一行)
請求頭(key:value)
請求體(與請求頭之間隔了一個空行)
HTTP的請求數據獲取
HTTP協議-請求數據獲取:
?????????Web服務器(Tomcat)對HTTP協議的請求數據進行解析,并進行了封裝(HttpServletRequest),在調用Controler方法的時候傳遞給了該方法。這樣,就使得程序員不必直接對協議進行操作,讓Web開發更加便捷。
HTTP的響應數據
HTTP響應數據格式
示例1:
? ? ? ? 當訪問http://www.baidu.com時,響應307,進行重定向。訪問https://www.baidu.com。
示例2:
????????當訪問網站時,響應404,表示客戶端不存在,或請求不存在的網站,或禁止訪問。
示例3:
? ? ? ? 當訪問網站時,響應500,表示網站代碼報錯。
HTTP響應數據設置
注意:
響應狀態碼 和 響應頭如果沒有特殊要求的話,通常不手動設定。
服務器會根據請求處理的邏輯,自動設置響應狀態碼和響應頭。
SpringBoot Web案例
準備:
1.創建一個SpringBoot工程,并勾選web依賴、lombok
2.引入準備好的用戶數據文件(user.txt),及前端靜態頁面(user.html)
3.定義一個實體類,用來封裝用戶信息
開發服務端程序,接受請求,讀取文本數據并響應。
具體代碼:
//controller包負責接受,請求,響應數據。 @RestController//@RestController=@Controller+@ResponseBody public class UserController {//http://localhost:8080/user.html@RequestMapping("/list")public List<User> list()throws Exception{//1.加載并讀取數據//InputStream in=new FileInputStream("C:\\ANzhuang\\JAVAP\\JavaWeb\\SpringBootWeb01\\src\\main\\resources\\user.txt");InputStream in=this.getClass().getClassLoader().getResourceAsStream("user.txt");ArrayList<String> lines=IoUtil.readLines(in, "UTF-8", new ArrayList<>());//2.解析用戶數據,封裝成對象User->list集合List<User> userList=lines.stream().map(line->{String[] split=line.split(",");Integer id=Integer.parseInt(split[0]);String username=split[1];String password=split[2];String name=split[3];Integer age=Integer.parseInt(split[4]);LocalDateTime updateTime = LocalDateTime.parse(split[5], DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));return new User(id,username,password,name,age,updateTime);//return new User(Integer.parseInt(split[0]),split[1],split[2],split[3],Integer.parseInt(split[4]),null);}).toList();//3返回數據jsonreturn userList;}}
定義實體類:
運行啟動項:
運行結果:
ResponseBody注解的作用
@ResponseBody->作用:將controller返回值直接作為響應體的數據直接響應;返回值是對象/集合->json->響應
1.將controler方法的返回值直接寫入HTTP響應體
2.如果是對象或集合,會先轉為json,再響應
3.@RestControler =@Controller + @ResponseBody
三次架構
三次架構:
controller:控制層,接收前端發送的請求,對請求進行處理,并響應數據
service:業務邏輯層,處理具體的業務邏輯。
dao:數據訪問層(DataAccessObject)(持久層),負責數據訪問操作,包括數據的增、刪、改、查
pojo封裝數據
controller:控制層
service:業務邏輯層
dao:數據訪問層
過程:
pojo封裝數據
controller接受請求,響應數據,調用service
service對數據進行邏輯處理,需要獲取數據調用dao
dao數據的訪問操作(增刪改查),獲取原始數據
運行結果:
?
分層解耦
耦合:衡量軟件中各個層/各個模塊的依賴關聯程度。
內聚:軟件中各個功能模塊內部的功能聯系。軟件設計原則:高內聚低耦合。
controler<-->service<-->dao
控制反轉:Inversion Of Contro,簡稱IOC。對象的創建控制權由程序自身轉移到外部(容器),這種思想稱為控制反轉.
依賴注入:Dependency Injection,簡稱DI。容器為應用程序提供運行時,所依賴的資源,稱之為依賴注入.
Bean對象:IOC容器中創建、管理的對象,稱之為Bean.package com.cyyweb.service.impl;import com.cyyweb.dao.impl.UserDaoImpl; import com.cyyweb.pojo.User; import com.cyyweb.dao.UserDao; import com.cyyweb.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.stereotype.Repository; import org.springframework.stereotype.Service;import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.List;@Service//service層,邏輯處理層 //@Component //將當前類交給IOC容器管理 public class UserServiceImpl implements UserService {@Autowired//應用程序運行時,會自動的查詢該類型的bean對象,并且賦值給該成員變量private UserDao userDao;@Overridepublic List<User> findAll() {//1。調用Dao,獲取數據List<String> lines=userDao.findALl();//2.解析用戶數據,封裝成對象User->list集合List<User> userList=lines.stream().map(line->{String[] split=line.split(",");Integer id=Integer.parseInt(split[0]);String username=split[1];String password=split[2];String name=split[3];Integer age=Integer.parseInt(split[4]);LocalDateTime updateTime = LocalDateTime.parse(split[5], DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));return new User(id,username,password,name,age,updateTime);//return new User(Integer.parseInt(split[0]),split[1],split[2],split[3],Integer.parseInt(split[4]),null);}).toList();//3.返回數據return userList;} }
? ? ? ? 在容器中進行對象的創建,稱為控制反轉。
? ? ? ? 當用戶需要時,通過容器來進行對象的創建,稱為依賴注入。
????????在容器中創建的對象叫Bean
實現分層解耦的思路是什么?
將項目中的類交給IOC容器管理(IOC,控制反轉)
應用程序運行時需要什么對象,直接依賴容器為其提供(DI,依賴注入)
如何將一個類交給IOC容器管理?
Component(注意:是加在實現類上,而非接口上)
?如何從IOC容器中找到該類型的bean,然后完成依賴注入?
@Autowired
IOC詳解
????????注意:聲明bean的時候,可以通過注解的value屬性指定bean的名字,如果沒有指定,默認為類名首字母小寫。
????????前面聲明bean的四大注解,要想生效,還需要被組件掃描注解@ComponentScan掃描。
????????該注解雖然沒有顯式配置,但是實際上已經包含在了啟動類聲明注解@springBootApplication中,默認掃描的范圍是啟動類所在包及其子包。
總結:
1,聲明bean的注解有哪幾個
@Controer
@Service
@Repository
@Component
2,注意事項
在Springboot集成web開發中,聲明控制器bean只能用Controler。
聲明bean的注解要想生效,需要被掃描到,啟動類默認掃描當前包及其子包。
DI詳解
基于@Autowired進行依賴注入的常見方式有如下三種:
1.屬性注入
優點:代碼簡潔、方便快速開發。
缺點:隱藏了類之間的依賴關系、可能會破壞類的封裝性。
@RestController
public class UserController {@Autowiredprivate final UserService userService;}
2.構造函數注入
優點:能清晰地看到類的依賴關系、提高了代碼的安全性。
缺點:代碼繁項、如果構造參數過多,可能會導致構造函臃腫。
注意:如果只有一個構造函數,@Autowired注解可以省略。
@RestController
public class UserController {private final UserService userService;@Autowiredpublic UserController(UserService userService) {this.userService =userService;}
}
3.setter注入
優點:保持了類的封裝性,依賴關系更清晰。
缺點:需要額外編寫setter方法,增加了代碼量。
@Restcontroller
public class Usercontroller {private UserService userService;@Autowiredpublic void setuserService(UserService userService) {this.userService = userService;}
}
Autowired注解,默認是按照類型進行注入的。
如果存在多個相同類型的bean,將會報錯。解決方法:
注:
@Resource與@Autowired區別
@Autowired是Spring框架提供的注解,而Resource是JavaEE規范提供的
@Autowired默認是按照類型注入,而@Resource默認是按照名稱注入