在编程的世界里,有一群人,他们眼中的代码不仅仅是冰冷的命令,更是一首首悠扬的乐章;他们不仅仅是写代码的工程师,更是创造者和艺术家。他们就是那些品味Java人生的程序员。
一、WEB运行原理
Web的运行原理涉及多个层面,包括客户端、服务器、网络通信等。
-
客户端请求:
- 用户在浏览器地址栏输入URL,或者通过点击链接、提交表单等方式触发页面请求。
- 浏览器将用户请求封装成HTTP请求,包括请求的资源(如HTML、CSS、JavaScript文件等)和目标服务器的地址。
-
域名解析与服务器连接:
- 浏览器通过域名系统(DNS)将域名解析成对应的IP地址。
- 浏览器与目标服务器建立TCP连接。这个过程通常包括三次握手。
补充:DNS服务器
DNS(Domain Name System,域名系统)是互联网中用于将域名转换为对应 IP 地址的系统。DNS服务器是运行 DNS 服务的计算机服务器,它负责存储和管理域名与 IP 地址之间的映射关系,并对外提供域名解析服务。以下是DNS服务器的主要功能和工作原理:
功能:
域名解析: DNS服务器将用户输入的域名转换为对应的 IP 地址,使用户能够通过便于记忆的域名访问互联网资源。
IP地址逆解析: DNS服务器还可以执行反向 DNS 查询,即通过给定的 IP 地址查找对应的域名。
缓存功能: DNS服务器通常会缓存已解析的域名与 IP 地址的映射关系,以提高查询效率并减轻网络负载。
负载均衡: 一些大型网站会配置多个 DNS 服务器,并使用负载均衡技术来分担流量,提高网站的可用性和性能。
工作原理:
域名解析请求: 当用户在浏览器中输入一个域名时,操作系统会向本地 DNS 服务器发送 DNS 查询请求。
本地DNS解析: 如果本地 DNS 服务器缓存中存在所请求的域名与 IP 地址的映射关系,则直接返回结果;否则,本地 DNS 服务器将向根域名服务器发送查询请求。
递归查询: 根域名服务器返回顶级域名服务器(TLD)的 IP 地址,本地 DNS 服务器再向 TLD 服务器发送查询请求。
迭代查询: TLD 服务器返回对应的权威域名服务器的 IP 地址,本地 DNS 服务器继续向权威域名服务器发送查询请求。
查询结果返回: 权威域名服务器返回所请求域名的 IP 地址,本地 DNS 服务器将结果缓存并返回给用户。
缓存更新: 本地 DNS 服务器将查询结果缓存起来,以备将来的使用。
DNS服务器通过分层的结构、缓存机制和分布式部署,实现了高效、可靠的域名解析服务,是互联网中不可或缺的基础设施之一。
注意:通常情况下,普通用户无需自己搭建 DNS 服务器。互联网服务提供商(ISP)或其他网络设备通常会提供默认的 DNS 服务器,用户设备在连接到互联网时会自动获取这些 DNS 服务器的信息。这样,用户就能够通过这些 DNS 服务器进行域名解析,访问互联网上的各种服务。
-
HTTP请求:
- 浏览器向服务器发送HTTP请求,请求页面所需的各种资源。
- 请求头中包含有关请求的信息,如浏览器类型、支持的编码方式等。
-
服务器处理请求:
- 服务器接收到请求后,根据请求的资源类型和路径,调用相应的处理程序(如Web服务器、应用服务器等)。
- 服务器处理请求,可能涉及到数据库查询、业务逻辑处理等。
-
生成HTTP响应:
- 服务器生成HTTP响应,包括状态码、响应头和响应体。
- 响应头包含有关响应的信息,如响应的内容类型、过期时间等。
-
数据传输:
- 服务器将HTTP响应通过TCP连接传输给客户端。
- 在传输过程中,可能会使用TLS/SSL进行加密,形成HTTPS连接。
-
浏览器渲染:
- 浏览器接收到响应后,开始解析HTML文件。
- 解析过程中,发现引用的外部资源(CSS、JavaScript等),则再次向服务器请求这些资源。
-
页面渲染:
- 浏览器根据HTML、CSS、JavaScript等资源,渲染页面。
- JavaScript可能会触发对服务器的AJAX请求,动态更新页面内容。
-
用户交互:
- 用户与页面交互,触发事件,可能导致新的HTTP请求(如通过表单提交)。
-
连接关闭:
二、SpringBoot后参数接收
上述我们简单了解了WEB运行原理, 浏览器可以向服务器发送url请求,那么后端服务器接收到请求以后便可以去解析url一方面可以解析出里面的映射路径同时还可以去解析请求头、请求参数等相关信息。
浏览器发送的请求中所请求的参数在SpringBoot后端接收的方式也有所不同,对此SpringBoot提供了对应的注解帮助我们去实现前后端数据的交互。
2.1 @RequestParm注解
@RequestParm注解可以在后端用于参数的获取,该注解的原理是基于request.getParameter的形式来获取参数,对此它既可以处理GET请求也可以用于处理POST请求。
@RequestParm注解有两个属性即value和required,其中value用来指定要传入值的id名称(即请求参数的key对应,也是表单属性的name的值对应),required用来指示参数是否必须绑定,默认为true即请求参数必须携带该参数,不携带将报错。
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestParam {
@AliasFor("name")
String value() default "";
@AliasFor("value")
String name() default "";
boolean required() default true;
String defaultValue() default "\n\t\t\n\t\t\n\ue000\ue001\ue002\n\t\t\t\t\n";
}
下面我们将通过案例来认识该注解。
@RestController
@Slf4j
public class TestController {
@GetMapping("/test1")
public ResponseResult parmTest(@RequestParam("name") String name){
log.info(name);
return ResponseResult.okResult();
}
}
如果我们发送请求的时候name参数给忽略来看一下效果。
我们可以看到如果我们不去传参name那么就会报错,这是因为@RequestParm注解的required属性默认值为true,对此我们在发送请求的时候就必须上传这个name参数。
下面我们将@RequestParm注解的required属性的值改为false。
@RestController
@Slf4j
public class TestController {
@GetMapping("/test1")
public ResponseResult parmTest(@RequestParam(value = "name",required = false) String name){
log.info(name);
return ResponseResult.okResult();
}
}
我们可以从上述运行结果中看到required的值改为false以后name参数不上传也不会报错。
注意:对于该注解需要注意的是当前端以application/json格式上传即使用JSON字符串,后台使用@RequestParam是无法一一对应来获取参数的,对此此类情况下就不能使用该注解进行参数的获取 ,并且改注解一般用于GET请求,因为我们现在在开发的时候POT类型请求前端一般都是使用application/json格式上传JSON字符串。
2.2 @PathVariable注解
@PathVariable是spring3.0的一个新功能:接收请求路径中占位符的值,这里的所谓占位符就是将请求参数放在请求路径中成为路径的一部分,通过@PathVariable来获取路径中的参数,从而获取其中的参数值。
我们在RESTful详解一文中曾说过若一些参数名非常敏感,建议可以使用 参数路径方式,可以隐藏参数名。对于参数路径中的参数解析就需要使用PathVariable注解。
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PathVariable {
@AliasFor("name")
String value() default "";
@AliasFor("value")
String name() default "";
boolean required() default true;
}
下面我们使用一下改注解。
@RestController
@Slf4j
public class TestController {
@GetMapping("/test1/SR_{id}/info")
public ResponseResult parmTest(@PathVariable("id") int id){
log.info(String.valueOf(id));
return ResponseResult.okResult();
}
}
2.3 @RequestBody注解
使用@RequestBody 该注解,前端请求只能为POST,因为该注解是从请求体中获得对象的,且请求头中的Content-type一般为application/json方式。所以使用该注解能够接收JSON格式的数据,并且能把接收到的JSON 数据绑定到JAVA对象中。复杂对象包括List,实体类,Map对象等。
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestBody {
boolean required() default true;
}
下面我们来使用一下这个注解。
@RestController
@Slf4j
public class TestController {
@PostMapping(value = "/test1",consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseResult parmTest(@RequestBody User user){
log.info(user.getAccount());
return ResponseResult.okResult();
}
}
需要注意的是,在GET请求中,不能使用@RequestBody。因为往GET请求里加body是不符合规范的,不保证所有的实现都支持,所以在ajax里注意请求方式如果用 get 后端参数不能用@RequestBody 来接收它。同时当前端以application/x-www-form-urlencoded格式上传数据时,后台可以使用@RequestParam或者不使用任何注解来获取参数,后台不可以使用@RquestBody来获取参数,使用的话会报错误。
2.4 不使用注解
SpringBoot在接收参数的时候也可以考虑不使用任何注解只是需要将参数进行一一对应即可。
@RestController
@Slf4j
public class TestController {
@GetMapping(value = "/test1")
public ResponseResult parmTest(String name,int age){
log.info(name);
log.info(String.valueOf(age));
return ResponseResult.okResult();
}
}
2.5 HttpServletRequest对象
HttpServletRequest对象是Java Servlet API 中的一部分,用于表示客户端发起的HTTP请求。在Web应用程序中,通过HttpServletRequest对象可以获取有关客户端请求的各种信息,包括请求方法、请求头、请求参数、请求URI等。
HttpServletRequest对象提供的常用方法如下所示:
- getMethod():获取请求的 HTTP 方法,如 GET、POST 等。
- getRequestURI():获取请求的 URI,不包括查询字符串部分。
- getQueryString():获取请求的查询字符串部分。
- getParameter(String name):获取指定名称的请求参数的值。
- getParameterNames():获取所有请求参数的名称的枚举。
- getHeader(String name):获取指定名称的请求头的值。
- getHeaderNames():获取所有请求头的名称的枚举。
- getRemoteAddr():获取客户端的IP地址。
@RestController
@Slf4j
public class TestController {
@GetMapping(value = "/test1")
public ResponseResult parmTest(HttpServletRequest request){
log.info(request.getParameter("name"));
log.info(request.getParameter("age"));
return ResponseResult.okResult();
}
}
那么到此为止我们就了解了SpringBoot如何去接收url请求发送过来的请求参数,学完之后是不是就很简单了。如果大家想要了解更多的知识点,大家可以在评论区讲一下,后面会进行一个更新。
更多内容请查看下期内容。