JavaWeb篇——Web工作流程、请求响应

Web

Web:全球广域网,也称为万维网,能够通过浏览器访问的网站

Web的工作流程

SpringBootWeb入门

  • 在创建SpringBoot项目后,添加web相关依赖
  • 创建请求处理类HelloConrtoller和请求处理方法hello

HTTP协议

概念: 超文本传输协议(Hyper Text Transfer Protocol),规定了浏览器与服务器之间数据传输的规则

一次请求的请求和响应

特点:

  1. 基于TCP协议:面向连接,安全(需要经历三次握手四次挥手)

  2. 基于请求-响应模型的:一次请求对应一次响应

  3. HTTP协议是无状态的协议:对于事务处理没有记忆能力。每次请求-响应都是独立的。

    • 缺点:多次请求间不能共享数据。
    • 优点:速度快

HTTP-请求数据格式

请求头信息

请求方式GET和POST的区别

请求方式 区别
GET 请求参数在请求行中,没有请求体,如:/brand/findAll?name=OPPO&status=1。GET请求大小是有限制的。
POST 请求参数在请求体中,POST请求大小是没有限制的。

HTTP-相应格式

响应头格式

常见响应码

HTTP协议解析

客户端可以根据响应的内容转换为具体的数据

那在服务器端如何解析http的数据,并且给浏览器响应数据呢?

按照tcp网络编程,可以使用socket/server socket接收浏览器发送的请求,按照字符串的规则解析,并按照输出流给出固定格式的字符串

如下:

Web服务器-Tomcat

Web服务器:

  • 对HTTP协议操作进行封装,简化web程序开发
  • 部署web项目,对外提供网上信息浏览服务

Tomcat:

  • 一个轻量级的web服务器,支持servlet、jsp等少量JavaEE规范
  • 也被称为web容器、servlet容器
  • 官网:tomcat.apache.org/

Tomcat入门程序解析(内嵌tomcat)

  • 起步依赖: springboot官网提供的用来简化配置的,用一个依赖相当于整块业务开发的全部依赖,原理是maven传递

起步依赖的版本都有父工程统一管理

  • 内嵌tomcat服务器:基于Springboot开发的web应用程序,内置了tomcat服务器,当启动类运行时,会自动启动内嵌的tomcat服务器。

    运行启动类启动springboot的过程中,会自动将内嵌的tomcat也启动起来,并且默认占用tomcat的端口号8080。

    在浏览器访问地址时,就会访问到内嵌的tomcat,并且访问到部署在tomcat内部的程序,拿到响应结果

请求响应

在浏览器输入地址会将请求打到对应Web服务器上,Tomcat可以识别HTTP协议的请求数据,并响应数据给浏览器。开发将具体业务逻辑写在各个Controller层中,但Tomcat不能识别编写的controller,它识别Servlet,SpringBoot底层提供了一个核心的前端控制器DispatcherServlet

Servlet中有两个对象:HttpServletRequest和HttpServletResponse

Tomcat将请求的数据转成HttpServletRequest数据,并根据HttpServletResponse对象设置的响应信息来响应数据给浏览器

  • 请求(HttpServletRequest):获取请求数据
  • 响应(HttpServletResponse):设置响应数据
  • BS架构:Browser/Server,浏览器/服务器架构模式。客户端只需要浏览器,应用程序的逻辑和数据都存储在服务端。不需要单独下载,维护方便,体验一般
  • CS架构:Client/Server,客户端/服务器架构模式。是需要下载客户端的,开发、维护麻烦,体验不错

请求

简单参数

  1. 原始方式获取请求参数

    • Controller方法形参中声明HttpServletRequest对象
    • 调用对象的getParameter(参数名)
  1. SpringBoot接收简单参数

    • 请求参数名与方法形参变量名相同
    • 会自动进行类型转换
  2. @RequestParam注解

    • 方法形参名称与请求参数名称不匹配,通过该注解完成映射
    • 该注解的required属性默认是true,代表请求参数必须传递

实体参数

请求参数名与形参对象属性名相同,即可直接通过POJO接收

复杂实体对象:请求参数名与形参对象属性名相同,按照对象层次结构关系即可接收嵌套POO属性参数。

数组集合参数

  • 数组:请求参数名与形参中数组变量名相同,可以直接使用数组封装

  • 集合:请求参数名与形参中集合变量名相同,通过@RequestParam绑定参数关系,如果不加注解,会自动转为数组形式

日期参数

使用@DateTimeFormat注解完成日期参数格式转换

JSON参数

JSON数据键名与形参对象属性名相同,定义POJO类型形参即可接收参数,需要使用@RequestBody表示

路径参数

通过请求URL直接传递参数,使用{...}来标识该路径参数,需要使用@PathVariable获取路径参数

响应

@ResponseBody

  • 类型:方法注解、类注解
  • 位置:Controller方法上/类上
  • 作用:将方法返回值直接响应,如果返回值类型是实体对象/集合,就会转换为JSON格式响应
  • 说明:@RestController=@Controller+@ResponseBody

统一响应结果

分层解耦

三层架构

  • controller:控制层,接受前端发送的请求,对请求进行处理,并响应数据
  • service:业务逻辑层,处理具体的业务逻辑
  • dao:数据访问层/持久层Data Access Object,负责数据访问操作,包括数据的增、删、改、查

分层解耦

  • 控制反转:Inversion Of Control,简称lOC。对象的创建控制权由程序自身转移到外部(容器),这种思想称为控制反转
  • 依赖注入:Dependency Injection,简称Dl。容器为应用程序提供运行时所依赖的资源,称之为依赖注入。
  • Bean对象:IOC容器中创建、管理的对象,称之为bean
IOC详解

要把某个对象交给IOC容器管理,需要在对应的类上加上如下注解之一

注解 说明 位置
@Component 声明bean的基础注解 不属于以下三类时,用此注解
@Controller @Component的衍生注解 标注在控制器类上
@Service @Component的衍生注解 标注在业务类上
@Repository @Component的衍生注解 标注在数据访问类上(由于与mybatis整合,用的比较少)
  • 声明bean的时候,可以通过value属性指定bean的名字,如果没有指定,默认为类名首字母小写。
  • 使用以上四个注解都可以声明bean,但是在springboot集成web开发中,声明控制器bean只能用@Controller。
Bean组件扫描
  • 声明bean的四大注解想要生效,还需要被组件扫描注解@ComponentScan扫描
  • 在SpringBoot启动类中@SpringBootApplication注解中包含了@ComponentScan,默认扫描的范围时启动类所在包及其子包
DI详解

使用@Autowired注解实现注入。如果同类型的bean存在多个,可以使用:

  • @Primary
  • @Autowired+@Qualifier("bean的名称")
  • @Resource(name="bean的名称")

@Resource与@Autowired区别

  • @Autowired是spring框架提供的注解,而@Resource是JDK提供的注解。
  • @Autowired默认是按照类型注入,而@Resource默认是按照名称注入。

登录校验

会话技术

  • 会话: 用户打开浏览器,访问web服务器的资源,会话建立,直到有一方断开连接,会话结束。在一次会话中可以包含多次请求和响应

  • 会话跟踪: 一种维护浏览器状态的方法,服务器需要识别多次请求是否来自于同一浏览器,以便在同一次会话的多次请求间共享数据

  • 会话跟踪方案

    • 客户端会话跟踪技术:Cookie
    • 服务端会话跟踪技术:Session
    • 令牌技术

会话跟踪方案对比

JWT

  • 场景:登录认证

    • 登陆成功后,生成令牌
    • 后续每个请求,都要携带JWT令牌,系统在每次请求处理之前,先校验令牌,通过后,再处理

生成JWT后,将JWT返回给前端,前端会将token存入到浏览器的本地存储空间中,该存储空间不论是移动端还是客户端都有

过滤器Filter

  • 概念:Filter过滤器,是JavaWeb三大组件(Servlet、Filter、Listener)之一。
  • 过滤器可以把对资源的请求拦截下来,从而实现一些特殊的功能。
  • 过滤器一般完成一些通用的操作,比如:登录校验、统一编码处理、敏感字符处理等。

入门使用:

  • 定义Filter:定义一个类,实现Filter接口,并重写其所有方法。
  • 配置Filter:Filter类上加@WebFilter注解,配置拦截资源的路径。引导类上加@ServletComponentScan开启Servlet组件支持。
java 复制代码
/**
 * Filter 属于JavaWeb三大组件之一
 * 并非SpringBoot提供的功能
 * 要想在SpringBoot中使用JavaWeb的组件,需要在启动类添加注解@ServletComponentScan
 * @ServletComponentScan:该注解表示开启了对servlet组件的支持
 */
​
@WebFilter(urlPatterns = "/*")//拦截请求的路径 /*表示拦截所有
public class DemoFilter implements Filter {
​
    //初始化方法,只调用一次
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("init 初始方法执行了");
    }
​
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("拦截到了请求");
        //放行
        filterChain.doFilter(servletRequest, servletResponse);
    }
​
    //销毁方法,只调用一次
    @Override
    public void destroy() {
        System.out.println("destroy 销毁方法执行了");
    }
}

Filter执行流程

请求------>放行前逻辑------>放行------>资源------>放行后逻辑

Filter拦截路径

过滤器链

  • 介绍:一个wb应用中,可以配置多个过滤器,这多个过滤器就形成了一个过滤器链。
  • 顺序:注解配置的Filter,优先级是按照过滤器类名(字符串)的自然排序。

登录校验Filter流程

ini 复制代码
@Slf4j
@WebFilter(urlPatterns = "/*")
public class LoginCheckFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) request;
        //1.获取请求url
        String url = req.getRequestURL().toString();
        System.out.println(url);
        //2.判断url是否包含login关键字,如果包含,就放行,走登录逻辑
        if (url.contains("login")){
            log.info("登录操作,放行。。。");
            chain.doFilter(request, response);
            return;
        }
        //3.获取请求头中的令牌
        String jwt = req.getHeader("token");
        //4.判断令牌是否存在,不存在则返回错误信息
        if (!StringUtils.hasLength(jwt)){
            log.info("请求头token为null,返回未登陆的信息");
            Result notLogin = Result.error("NOT_LOGIN");
            //手动转换对象------>json,使用阿里巴巴的fastJSON
            String jsonString = JSONObject.toJSONString(notLogin);
            resp.getWriter().write(jsonString);
            return;
        }
        //5.解析token,如果解析失败,返回错误结果
        try {
            JwtUtils.parseJWT(jwt);
        }catch (Exception e){
            log.info("解析令牌失败");
            Result notLogin = Result.error("NOT_LOGIN");
            //手动转换对象------>json,使用阿里巴巴的fastJSON
            String jsonString = JSONObject.toJSONString(notLogin);
            resp.getWriter().write(jsonString);
            return;
        }
        //6.放行
        log.info("令牌合法,放行");
        chain.doFilter(request, response);
    }
}

拦截器Intercrptor

  • 概念:是一种动态拦截方法调用的机制,类似于过滤器。Spring框架中提供的,用来动态拦截控制器方法的执行。
  • 作用:拦截请求,在指定的方法调用前后,根据业务需要执行预先设定的代码。

入门使用

定义拦截器

java 复制代码
@Slf4j
@Component //将其交给IOC容器管理
public class LoginCheckInterceptor implements HandlerInterceptor {
    //目标资源方法运行前运行, 返回true: 放行, 放回false, 不放行
    @Override
    public boolean preHandle(HttpServletRequest req, HttpServletResponse resp, Object handler) throws Exception {
        System.out.println("preHandle ... ");
        return true;
    }
​
    //目标资源方法运行后运行
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle ...");
    }
​
    //视图渲染完毕后运行, 最后运行
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion...");
    }
}

注册拦截器

typescript 复制代码
@Configuration //配置类
public class WebConfig implements WebMvcConfigurer {
​
    @Autowired
    private LoginCheckInterceptor loginCheckInterceptor;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginCheckInterceptor).addPathPatterns("/**");
    }
}

拦截器-拦截路径

拦截器-执行流程

Filter和Interceptor的区别

  • 接口规范不同:过滤器需要实现Filter接口,而拦截器需要实现HandlerInterceptor接口。
  • 拦截范围不同:过滤器Filter会拦截所有的资源,而Interceptor只会拦截Spring环境中的资源。
相关推荐
java156550579705 分钟前
Docker Compose一键部署Spring Boot + Vue项目
java
isolusion9 分钟前
Springboot配置嵌入式服务器
服务器·spring boot·后端
玉红7779 分钟前
Erlang语言的数据结构
开发语言·后端·golang
陶然同学13 分钟前
【黑马头条】day20—xxl-job
java·数据库·redis·项目
陶然同学30 分钟前
【黑马头条训练营】day02-黑马头条-App端文章展示
java·数据库·spring cloud·微服务·项目
smile_life_31 分钟前
Tomcat调优相关理解
java·tomcat·tomcat调优
m0_7482548833 分钟前
JavaWeb项目打包、部署至Tomcat并启动的全程指南(图文详解)
java·tomcat
sunnyday042633 分钟前
Mybatis-Plus updateById 方法更新无效及空值处理
java·开发语言·mybatis
薄荷糖yh34 分钟前
tomcat窗口闪退,以及在eclipse上面运行不出来
java·eclipse·tomcat
java1565505797036 分钟前
在【IntelliJ IDEA】中配置【Tomcat】【2023版】【中文】【图文详解】
java·tomcat·intellij-idea