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环境中的资源。
相关推荐
松仔log1 小时前
JetPack——Paging3+Room
android·java·zoom
㳺三才人子6 小时前
初探 Flask
后端·python·flask·html
星栈独行6 小时前
我在 Rust 全栈项目里用 JWT 做无状态认证
开发语言·后端·rust·前端框架·开源·github·web
Lei活在当下6 小时前
先用起来,再理解,关于协程Coroutine应该知道的事
android·java·jvm
Java爱好狂.6 小时前
Java程序员体系化学习路线(2026最新版)
java·后端·java面试·java架构师·java程序员·java八股文·java学习路线
陈随易7 小时前
Redis 8.8发布,一定要更新
前端·后端·程序员
tongluowan0077 小时前
以ReentrantLock为例解释AQS的工作流程
java·模板方法模式·aqs·reentrantlock
装不满的克莱因瓶7 小时前
SpringBoot 如何将 lib 目录中jar包打包进最终的jar包里面
spring boot·后端·maven·jar·mvn
ltl8 小时前
Transformer 原论文实验结果:为什么 28.4 BLEU 足以改写路线图
后端
身如柳絮随风扬8 小时前
Java 项目打包与部署完全指南:JAR vs WAR,从构建到运行
java·firefox·jar