Http协议+请求响应+分层解耦
HTTP协议
请求协议
GET /brand/findAll?name=oppo&status=active,inactive HTTP/1.1POST /brand HTTP/1.1
请求行:请求数据第一行(请求方式,资源路径,协议)
请求头:第二行开始,格式Key:Value
HOST:请求的主机名
user-Agent:浏览器版本,IE浏览器的标识类似Mozilla/4.0
Accept:表浏览器能接收的资源类型,如text/,imagin/
Accept-Language:浏览器偏好的语言,服务器可以据此返回不同语言的页面
Accept-Encoding:表浏览器可以支持的压缩类型,如.qzip
Content-Tupe:求主体的类型
Content-Length:主体的大小(字节)
请求体:POST请求,存放请求参数
**请求方式-GET:**请求参数在请求行中,没有请求体,如:/brand/findAll…,GET请求大小是有限制的。
**请求方式-POST:**请求参数在请求体中,POST请求大小是没有限制的
GET大多数是查询,
POST是新增,所以才会有请求体
响应协议
响应行:响应数据第一行(协议,状态码,描述)- HTTP/1.1 200 ok
响应头:第二行开始,格式Key:Value
响应体:最后一部分,存放响应数据
响应格式
- 1xx (信息响应 - Informational):请求已被接收,继续处理。
- 例子:
100 Continue
,表示客户端应该继续发送请求的其余部分。
- 例子:
- 2xx (成功响应 - Success):请求已被成功处理、理解和接受。
- 例子:
200 OK
,最常见的成功状态码。201 Created
,表示请求成功并创建了新资源。
- 例子:
- 3xx (重定向 - Redirection):需要采取进一步措施来完成请求。
- 例子:
301 Moved Permanently
,表示请求的资源已永久移动到新位置。
- 例子:
- 4xx (客户端错误 - Client Error):请求包含语法错误或无法完成。
- 例子:
404 Not Found
,找不到请求的资源。400 Bad Request
,请求语法有误。403 Forbidden
,服务器拒绝访问。
- 例子:
- 5xx (服务器错误 - Server Error):服务器在处理请求时发生错误。
- 例子:
500 Internal Server Error
,服务器内部发生未知错误。502 Bad Gateway
,服务器作为网关或代理,从上游服务器收到无效响应。
- 例子:
Content-Type:表响应内容的类型
Content-Length:表响应内容的长度
Content-Encoding:表响应压缩算法.qzip
Set-Cookie:告诉浏览器当前页面所在的域设置Cookie
最常见的响应格式:
200:OK
404:Not Found,请求资源不存在
500:服务器发生不可预期错误
重定向(请求响应)
客户端浏览器要去访问A服务器上的资源,但是A服务器上的资源移动到B上,所以A会向客户端传输3XX(B),浏览器会自动请求响应B,A和B有可能是同一台服务器,只是资源的位置不一样。
协议解析
概念:超文本传输协议,规定了浏览器和服务器之间的数据传输的规则。浏览器:客户端内部已经内置解析HTTP协议的程序
服务器:在服务器端,通过Java程序来接受客户端(浏览器)发起的请求,并获取请求数据,参考HTTP协议的响应数据格式,给浏览器响应对应的数据。
Tomcat
=web服务器是一个软件程序,对HTTP协议的操作进行封装,使得程序员不必直接对协议进行操作,让web开发更加便捷,主要功能:“提供网上信息浏览服务”
nginx和Tomcat都可以作为web服务器,但是Tomcat可以运行Java的servlet等Java程序,而nginx不行,一般nginx会做动静分离,对于后端请求会被转发到Tomcat上
概念:
+ Tomcat是Apache软件基金会一个核心项目,是一个开源免费的轻量级web服务器,支持Servlet、jsp少量JavaEE规范。 + 也被称为web容器,Servlet容器,Servlet程序需要依赖于Tomcat才能运行JavaEE:企业版,指Java企业级开发的技术规范总和,包含13项技术规范。
JAVASE:Java标准版
JAVAME:Java小型版
JAVAEE:Java企业版
web服务器
+ 对HTTP协议操作进行封装,简化web程序开发 + 部署web项目,对外提供网上信息浏览服务 + SpringBoot已经部署起步依赖
+ spring-boot-starter-web + spring-boot-stater-text内嵌Tomcat服务器
基于springboot开发的web应用程序,内置了Tomcat服务器,当启动类运行时,会自动启动内签的Tomcat服务器。如何在Servlet类中获取请求的数据呢,前端浏览器发出请求,会携带Http的请求参数,web服务器负责请求数据的解析,DispatchServlet会对请求数据进行解析,会将解析后的所有请求信息,封装到一个对象当中(HttpServletRequest),然后我们的应用程序会从从这个对象当中获取数据,处理完之后,会根据Http协议响应数据的格式,给浏览器相应数据(HttpServletResponse)
请求(HttpServletRequest):获取请求数据
响应(HttpServletResponse):获取响应数据
BS架构:Browser/Server,浏览器/服务器架构模式,客户端只需要浏览器,应用程序的逻辑和数据都存储在服务器当中(比如:京东,淘宝,天猫网页版)
CS架构:Client/Server,客户端/服务器(开发,维护麻烦,体验感不错)
请求响应
postman请求
postman是一款功能强大的网页调试与发送网页Http请求的Chrome插件作用,作用:常用于接口调试简单参数
原始方式(繁琐,手动类型转换)
在原始的web程序中,获取请求参数,需要通过HttpServletRequest对象手动获取SpringBoot方式
参数简单:参数名和形参变量名相同,定义形参即可接收参数,如果方法形参名称与请求名称不匹配,可以使用@RequestParam完成映射public String simpleParam(@RequestParam(name="name")String username,Integer age){
}
注:@RequestParam中的required属性默认为true,代表该参数必须传递,如果不传递就报错,如果该参数是可以选择的,可将required属性设置为false
简单实体对象:
请求参数名与形参对象属性名相同,定义pojo接收。复杂实体对象:
请求参数名与形参对象属性名相同,按照层次结构关系,可接收嵌套pojo属性参数。数组集合参数
数组参数:请求参数与形参数组名称相同且请求为多个,定义数组类型参即可接收参数。集合参数:请求参数名与形参集合名称相同且请求参数为多个@RequestParam绑定参数关系
日期参数:使用@DateTimeFormat注解完成日期参数格式转换
JSON参数
服务端如何接收JSON参数:JSON数据键名与形参对象属性名相同,定义pojo类型形参即可接收参数,需要使用@ResquestBody标识
路径参数
路径参数:通过请求VRL直接传递参数,使用{...}来标识该路径参数,需要使用@PathVariable获取路径参数。@RequestMapping:指定某方法的请求路径
单个路径访问("/Path/{id})
多个路径访问(“/path/{id}/{name}”)
响应数据
@ResponseBody
类型:方法注解,类注解位置:Controller方法上/类上
作用:将方法返回值响应,如果返回值类型是实体对象/集合,将会转换为JSON格式响应。
说明@RestController=@Controller+@ResponseBody
如果一个类设置了@RestController,就代表当前类下所有的方法,他的返回值都会作为一个相应数据,如果是一个对象或集合,它会先转JSON,然后再来响应。
统一响应结果
@ResponseBody
位置:Controller类上/方法上作用:将方法返回值响应,若返回值是实体类/集合,转JSON格式响应
统一响应结果
Result(code,msg,data)
例子:获取员工数据,返回统一响应结果,在页面渲染展示
步骤- 在pom.xml文件中引入dom4j的依赖,用于解析xml文件
- 引入资料中提供的解析xml的工具类Parservtils,对应的实体类Emp,xml文件emp,xml
- 引入资料中提供的静态页面文件,放在resoures下的static目录下
- 编写Controller程序,处理请求
SpringBoot项目的静态资源(html,css,js等前端资源)默认存放目录为:classpath:/static,classpath:/public,classpath:/resources。
三层结构
- 复用性强
- 便于维护
- 利于拓展
Controller:控制层,接收前端发送的请求,对请求进行处理并响应数据。
Service:业务逻辑层,处理具体的业务逻辑。
Dao:数据访问层(Data,Access,Object)(持久层)负责数据访问操作,包括数据的增,删,改,查。
最终Service逻辑处理的数据,调用Dao来获取。
分层解耦
内聚:软件中各个功能模块内部的功能联系。耦合:衡量软件中各个层、模块之间的依赖,关联程度。
在项目中我们强调高内聚,低耦合,尽可能解除耦合(比如在员工管理的Service当中,仅仅存放员工相关的逻辑处理)。
层与层之间的解耦操作。
定义一个容器,将Service类对象存放在容器里。
- 控制反转:IOC(Inversion of Control)对象的创建控制权由程序自身转移到外部(容器),这种思想称为控制反转。
- 依赖注入:DI(Dependency Injection)容器为应用程序提供运行时,所依赖的资源,称之为依赖注入。
- Bean对象:IOC容器中创建,管理对象,称之为Bean。
IOC&DI入门
1. Service及Dao层的实现类,交给IOC容器管理。 2. 为Controller及Service注入运行时,依赖的对象。 3. 运行测试。加上@Autowired,程序在运行的时候,IOC容器自动会为其提供该类型的类对象,并且赋值给这个变量。
Bean的声明
要把某个对象交给IOC容器管理,需要在对应的类上加上如下注解之一。@Component:声明Bean的基础注解(可以替代下面注解)
@Controller:标注在控制器类上(衍生)
@Service:在业务类上(衍生)
@Repository:在数据访问类上(由于与MyBatis整合,用的少)
Bean组件扫描
前面声明Bean的四大注解,要想生效,还需要被组件扫描注解。@ComponentScan扫描
@ComponentScan注解虽然没有显示配置,但是实际上已经包含在了启动类声明注解@SpringBootApplication中,要默认扫描的范围是启动类所在的包及其子包。
DI注解
@Autowired注解,默认是按照类型进行,如果存在多个相同类型的Bean,会出现错误。通过一下几个案例来解决
假设现在有两个实现类userServiceImpl,userServiceMock,都继承了UserService接口。
@Primary(优先级)想要哪个先运行就写在哪个类的@Service上面。
// UserServiceImpl.java - 标记为首选的Bean
@Service
@Primary // 标记这个Bean为首选
public class UserServiceImpl implements UserService {@Overridepublic void registerUser(String username) {System.out.println("使用 UserServiceImpl: 用户 " + username + " 已成功注册!");}
}
@Qualifier(“empServiceA”)
// UserController.java
@RestController
public class UserController {@Autowired@Qualifier("userServiceImpl") // 指定注入名为 "userServiceImpl" 的Beanprivate UserService userService;// ... 省略其他代码
}
@Resource(name = “empServiceB”)
// UserController.java
@RestController
public class UserController {// 明确指定注入名为 "userServiceMock" 的Bean@Resource(name = "userServiceMock")private UserService userService;// ... 省略其他代码
}
@Resource与@Autowired区别
- @Autowired是Spring框架提供的注解,而@Resource是jdk提供的注解。
- @Autowired默认是按照类型注入,而@Resource默认按照名称注入