网页后端开发(基础3--Springboot框架)
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默认是按照名称注入