0%

Java Web 后端总述

前言

学习了下 Java Web 开发相关的内容

概要

首先,Web 开发分前后端,主流开发模式是前后端分离的

  • 前端:HTML, CSS, JavaScript/TypeScript
    • HTML,CSS 主要是网页展示,详情可以看 https://www.w3school.com.cn/index.html
    • JS 主要处理动态网页相关内容,主要相关的有 BOM(浏览器对象), DOM(HTML文档对象) 以及事件绑定
  • 后端:处理前端请求,返回结果
    • 主要了解 Springboot

在Spring框架的生态中,对web程序开发提供了很好的支持,如:全局异常处理器、拦截器这些都是Spring框架中web开发模块所提供的功能,而Spring框架的web开发模块,我们也称为:SpringMVC

SpringMVC不是一个单独的框架,它是Spring框架的一部分,是Spring框架中的web开发模块,是用来简化原始的Servlet程序开发的。

外界俗称的SSM,就是由:SpringMVC、Spring Framework、Mybatis三块组成。

基于传统的SSM框架进行整合开发项目会比较繁琐,而且效率也比较低,所以在现在的企业项目开发当中,基本上都是直接基于SpringBoot整合SSM进行项目开发的。


前端部分

HTML 和 CSS 就不过多研究了,主要看看 JS

Vue

一个完整的html页面包括了视图和数据,数据是通过请求从后台获取的,那么意味着我们需要将后台获取到的数据呈现到页面上,很明显, 这就需要我们使用DOM操作。正因为这种开发流程,所以我们引入了一种叫做MVVM(Model-View-ViewModel)的前端开发思想,即让我们开发者更加关注数据,而非数据绑定到视图这种机械化的操作。那么具体什么是MVVM思想呢?

MVVM:其实是Model-View-ViewModel的缩写,具体释义如下:

  • Model: 数据模型,特指前端中通过请求从后台获取的数据
  • View: 视图,用于展示数据的页面,可以理解成我们的html+css搭建的页面,但是没有数据
  • ViewModel: 数据绑定到视图,负责将数据(Model)通过JavaScript的DOM技术,将数据展示到视图(View)上

如图所示就是MVVM开发思想的含义:

1668857055058

基于上述的MVVM思想,其中的 Model 可以通过 Ajax 来发起请求从后台获取;ViewModel部分使用 vue 前端框架替代JavaScript的DOM操作,让数据展示到视图的代码开发变得更加的简单。

AJAX

Ajax: 全称Asynchronous JavaScript And XML,异步的JavaScript和XML。其作用有如下2点:

  • 与服务器进行数据交换:通过Ajax可以给服务器发送请求,并获取服务器响应的数据。
  • 异步交互:可以在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术,如:搜索联想、用户名是否可用的校验等等。

Ajax 可以了解下 Axios,是一个对 Ajax 进行封装简化的框架。

部署

前端程序开发完成后是前端的部署,可以使用 nginx 进行部署

nginx: Nginx是一款轻量级的Web服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器。其特点是占有内存少,并发能力强,在各大型互联网公司都有非常广泛的使用。

接口

基于前后端分离开发的模式下的流程如下:

  1. 需求分析:首先我们需要阅读需求文档,分析需求,理解需求。
  2. 接口定义:查询接口文档中关于需求的接口的定义,包括地址,参数,响应数据类型等等
  3. 前后台并行开发:各自按照接口文档进行开发,实现需求
  4. 测试:前后台开发完了,各自按照接口文档进行测试
  5. 前后段联调测试:前段工程请求后端工程,测试功能

接口即前后端接洽的部分,学习课程中介绍了 Yapi 来管理接口文档。

项目管理

项目管理使用 Maven 进行

Apache Maven是一个项目管理和构建工具,它基于项目对象模型(Project Object Model , 简称: POM)的概念,通过一小段描述信息来管理项目的构建、报告和文档。

官网:https://maven.apache.org/

Maven的作用:

  1. 方便的依赖管理
  2. 统一的项目结构
  3. 标准的项目构建流程

image-20231113114402902

SpringBoot

简介

SpringBoot 是后端开发的一个框架,可以快速的构建应用程序,其最大的特点有两个 :

  • 简化配置
  • 快速开发

Web服务器

在网络服务器中,使用的基本协议是 HTTP 协议,但 HTTP 协议解析还是有些繁琐的,但同样有封装好的 Web 服务器可以解决协议解析的问题,例如 TomCat

Tomcat服务器软件是一个免费的开源的web应用服务器。是Apache软件基金会的一个核心项目。由Apache,Sun和其他一些公司及个人共同开发而成。

由于Tomcat只支持Servlet/JSP少量JavaEE规范,所以是一个开源免费的轻量级Web服务器。

JavaEE规范: JavaEE => Java Enterprise Edition(Java企业版)

avaEE规范就是指Java企业级开发的技术规范总和。包含13项技术规范:JDBC、JNDI、EJB、RMI、JSP、Servlet、XML、JMS、Java IDL、JTS、JTA、JavaMail、JAF

因为Tomcat支持Servlet/JSP规范,所以Tomcat也被称为Web容器、Servlet容器。JavaWeb程序需要依赖Tomcat才能运行。

Tomcat的官网: https://tomcat.apache.org/

当然,实际上 SpringBoot 框架中已经集成了 Tomcat 服务器了。

在SpringBoot进行web程序开发时,它内置了一个核心的 Servlet 程序 DispatcherServlet,称之为 核心控制器。 DispatcherServlet 负责接收页面发送的请求,然后根据执行的规则,将请求再转发给后面的请求处理器Controller,请求处理器处理完请求之后,最终再由DispatcherServlet给浏览器响应数据。浏览器发送请求,会携带请求数据,包括:请求行、请求头;请求到达tomcat之后,tomcat会负责解析这些请求数据,然后呢将解析后的请求数据会传递给Servlet程序的HttpServletRequest对象,那也就意味着 HttpServletRequest 对象就可以获取到请求数据。 而Tomcat,还给Servlet程序传递了一个参数 HttpServletResponse,通过这个对象,我们就可以给浏览器设置响应数据 。

三层架构

在我们进行程序设计以及程序开发时,尽可能让每一个接口、类、方法的职责更单一些(单一职责原则)。

单一职责原则:一个类或一个方法,就只做一件事情,只管一块功能。

这样就可以让类、接口、方法的复杂度更低,可读性更强,扩展性更好,也更利用后期的维护。

常见后端的处理逻辑从组成上看可以分为三个部分:

  • 数据访问:负责业务数据的维护操作,包括增、删、改、查等操作。
  • 逻辑处理:负责业务逻辑处理的代码。
  • 请求处理、响应数据:负责,接收页面的请求,给页面响应数据。

按照上述的三个组成部分,可以将代码分为三层:

  • Controller:控制层。接收前端发送的请求,对请求进行处理,并响应数据。
  • Service:业务逻辑层。处理具体的业务逻辑。
  • Dao:数据访问层(Data Access Object),也称为持久层。负责数据访问操作,包括数据的增、删、改、查。

基于三层架构的程序执行流程:

  • 前端发起的请求,由Controller层接收(Controller响应数据给前端)
  • Controller层调用Service层来进行逻辑处理(Service层处理完后,把处理结果返回给Controller层)
  • Serivce层调用Dao层(逻辑处理过程中需要用到的一些数据要从Dao层获取)
  • Dao层操作文件中的数据(Dao拿到的数据会返回给Service层)

分层解耦

三层架构的等之间是有依赖关系的,例如 Controller 必须依赖 Service 处理业务,这不符合高内聚低耦合的软件设计思想,于是引入了 Spring 中两个核心概念

  • 控制反转: Inversion Of Control,简称IOC。对象的创建控制权由程序自身转移到外部(容器),这种思想称为控制反转。
    • 对象的创建权由程序员主动创建转移到容器(由容器创建、管理对象)。这个容器称为:IOC 容器或 Spring 容器
  • 依赖注入: Dependency Injection,简称DI。容器为应用程序提供运行时,所依赖的资源,称之为依赖注入。
    • 程序运行时需要某个资源,此时容器就为其提供这个资源。

IOC容器中创建、管理的对象,称之为:bean对象

简单来说,各个组件只需要定义自身的功能,对于依赖部分只需声明一个接口即可,Spring 会自动为接口注入对应的实例对象

而又依赖关系的对象将实例化的可以将实例化的步骤转移到 Spring 容器,Spring 容器会自动将标注为 Bean 的类进行实例化并注入到依赖模块中,从而实现模块间的解耦

可以视为一个网络,原本是很多计算机之间互相通信(依赖),但是现在有个管理员即 Spring 容器,各个计算机都搭建与管理员的通信信道(控制反转),管理员会负责牵线连接不同计算机之间的通信信道(即依赖注入),这样就不需要各个计算机自己去搭建固定的通信信道,只需向管理员请求通信即可动态的与其他计算机进行通信

数据操作

数据库的操作就不细说了,基本的增删查改是必须要的。但是在后端开发中需要访问修改数据库,这就需要使用 Java 程序操作数据库,一种解决方式是 MyBatis。

  • MyBatis是一款优秀的 持久层 框架,用于简化JDBC的开发。

    • 持久层:指的是就是数据访问层(dao),是用来操作数据库的。

    • 框架:是一个半成品软件,是一套可重用的、通用的、软件基础代码模型。在框架的基础上进行软件开发更加高效、规范、通用、可拓展。

    • JDBC: ( Java DataBase Connectivity ),就是使用Java语言操作关系型数据库的一套API。

  • MyBatis本是 Apache的一个开源项目iBatis,2010年这个项目由apache迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。

  • 官网:https://mybatis.org/mybatis-3/zh/index.html

MyBatis 的功能就是解析代码中的 SQL 语句,然后操作数据库并返回结果,还有个注意点是mybatis中,使用了数据库连接池技术,避免频繁的创建连接、销毁连接而带来的资源浪费,简而言之就是避免每次执行 SQL 语句都要连接、销毁连接数据库的问题,具体解决思路类似线程池。常见的数据库连接池有:

常见的数据库连接池:

  • C3P0
  • DBCP
  • Druid
  • Hikari (springboot默认)

现在使用更多的是:Hikari(Tomcat 自带)、Druid (性能更优越)

登录校验

登录校验指的是我们在服务器端接收到浏览器发送过来的请求之后,首先我们要对请求进行校验。先要校验一下用户登录了没有,如果用户已经登录了,就直接执行对应的业务操作就可以了;如果用户没有登录,此时就不允许他执行相关的业务操作,直接给前端响应一个错误的结果,最终跳转到登录页面,要求他登录成功之后,再来访问对应的数据。

HTTP协议是无状态协议,一次请求都是独立的,下一次请求并不会携带上一次请求的数据,要想解决登录校验的问题,有两个思路:

  1. 在用户登录成功后,需要将用户登录成功的信息存起来,记录用户已经登录成功的标记。
  2. 在浏览器发起请求时,需要在服务端进行统一拦截,拦截后进行登录校验。

程序中所开发的查询功能、删除功能、添加功能、修改功能,都需要使用以上套路进行登录校验。此时就会出现:相同代码逻辑,每个功能都需要编写,就会造成代码非常繁琐。为了简化这块操作,可以使用一种技术:统一拦截技术。

通过统一拦截的技术,可以来拦截浏览器发送过来的所有的请求,拦截到这个请求之后,就可以通过请求来获取之前所存入的登录标记,在获取到登录标记且标记为登录成功,就说明用户已经登录了。

要完成以上操作,会涉及到web开发中的两个技术:

  1. 会话技术
  2. 统一拦截技术

而统一拦截技术现实方案也有两种:

  1. Servlet规范中的Filter过滤器
  2. Spring提供的interceptor拦截器

会话技术

在web开发当中,会话指的就是浏览器与服务器之间的一次连接,我们就称为一次会话,一次会话中可以包含多次请求和响应。

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

会话跟踪技术有两种:

  1. Cookie(客户端会话跟踪技术)
    • cookie 是客户端会话跟踪技术,它是存储在客户端浏览器的,其具体方法为:浏览器第一次发起请求来请求服务器的时候,在服务器端设置一个cookie,用于标志用户相关信息,而后的响应与请求均携带cookie,即可实现会话跟踪
    • cookie 它是 HTP 协议当中所支持的技术,一切都是自动化进行的
    • 优点:HTTP协议中支持的技术(像Set-Cookie 响应头的解析以及 Cookie 请求头数据的携带,都是浏览器自动进行的,是无需手动操作的)
    • 缺点:
      • 移动端APP(Android、IOS)中无法使用Cookie
      • 不安全,用户可以自己禁用Cookie
      • Cookie不能跨域(跨域指通信过程中 协议、IP、端口 的组合标记,任一不同则为不同的域)
  2. Session(服务端会话跟踪技术)
    • 数据存储在储在服务
    • 浏览器在第一次请求服务器的时候,服务器会自动的创建一个会话对象Session 。而每一个会话对象Session ,它有一个ID。服务器端在给浏览器响应数据的时候,它会将 Session 的 ID 通过 Cookie 响应给浏览器。后续的每一次请求当中,都会将 Cookie 的数据获取出来,并且携带到服务端
    • 优点:Session是存储在服务端的,安全
    • 缺点:
      • 服务器集群环境下无法直接使用Session
      • 移动端APP(Android、IOS)中无法使用Cookie
      • 用户可以自己禁用Cookie
      • Cookie不能跨域
  3. 令牌技术
    • 所谓令牌,其实就是一个用户身份的标识,其实本质是一个字符串。
    • 在浏览器发起请求登录成功后,会生成一个令牌作为用户的合法身份凭证。接下来响应数据的时候将令牌响应给前端,前端程序会保存令牌(Cookie或其他存储空间)。在后续的每一次请求当中,都需要将令牌携带到服务端。服务端会校验令牌的有效性。在同一次会话的多次请求之间,可以将共享的数据存储在令牌中
    • 优点:
      • 支持PC端、移动端
      • 解决集群环境下的认证问题
      • 减轻服务器的存储压力(无需在服务器端存储)
    • 缺点:需要自己实现(包括令牌的生成、令牌的传递、令牌的校验)

令牌计技术的一种实现方式:JWT

JWT全称:JSON Web Token (官网:https://jwt.io/)

  • 定义了一种简洁的、自包含的格式,用于在通信双方以json数据格式安全的传输信息。由于数字签名的存在,这些信息是可靠的。

    简洁:是指jwt就是一个简单的字符串。可以在请求参数或者是请求头当中直接传递。

    自包含:指的是jwt令牌,看似是一个随机的字符串,但是我们是可以根据自身的需求在jwt令牌中存储自定义的数据内容。如:可以直接在jwt令牌中存储用户的相关信息。

    简单来讲,jwt就是将原始的json数据格式进行了安全的封装,这样就可以直接基于jwt在通信双方安全的进行信息传输了。

JWT的组成: (JWT令牌由三个部分组成,三个部分之间使用英文的点来分割)

  • 第一部分:Header(头), 记录令牌类型、签名算法等。 例如:{"alg":"HS256","type":"JWT"}

  • 第二部分:Payload(有效载荷),携带一些自定义信息、默认信息等。 例如:{"id":"1","username":"Tom"}

  • 第三部分:Signature(签名),防止Token被篡改、确保安全性。将header、payload,并加入指定秘钥,通过指定签名算法计算而来。

签名的目的就是为了防jwt令牌被篡改,而正是因为jwt令牌最后一个部分数字签名的存在,所以整个jwt 令牌是非常安全可靠的。一旦jwt令牌当中任何一个部分、任何一个字符被篡改了,整个令牌在校验的时候都会失败,所以它是非常安全可靠的。

JWT通过 base64编码将 JSON格式数据转为字符串

JWT令牌最典型的应用场景就是登录认证:

  1. 在浏览器发起请求来执行登录操作,此时会访问登录的接口,如果登录成功之后,我们需要生成一个jwt令牌,将生成的 jwt令牌返回给前端。
  2. 前端拿到jwt令牌之后,会将jwt令牌存储起来。在后续的每一次请求中都会将jwt令牌携带到服务端。
  3. 服务端统一拦截请求之后,先来判断一下这次请求有没有把令牌带过来,如果没有带过来,直接拒绝访问,如果带过来了,还要校验一下令牌是否是有效。如果有效,就直接放行进行请求的处理。

统一拦截技术

Filter
  • Filter表示过滤器,是 JavaWeb三大组件(Servlet、Filter、Listener)之一。
  • 过滤器可以把对资源的请求拦截下来,从而实现一些特殊的功能
    • 使用了过滤器之后,要想访问web服务器上的资源,必须先经过滤器,过滤器处理完毕之后,才可以访问对应的资源。
  • 过滤器一般完成一些通用的操作,比如:登录校验、统一编码处理、敏感字符处理等。
Interceptor
  • Interceptor 表示拦截器,是一种动态拦截方法调用的机制,类似于过滤器。
  • 拦截器是Spring框架中提供的,用来动态拦截控制器方法的执行。

拦截器的作用:

  • 拦截请求,在指定方法调用前后,根据业务需要执行预先设定的代码。

总的流程如下所示,其中Spring的Web环境中提供了一个非常核心的Servlet:DispatcherServlet(前端控制器),所有请求都会先进行到DispatcherServlet,再将请求转给Controller。

image-20231113191220858

全局异常处理

简单来说就是定义一个全局异常处理器统筹处理三层结构中的异常。

怎么样定义全局异常处理器?

  • 定义全局异常处理器非常简单,就是定义一个类,在类上加上一个注解@RestControllerAdvice,加上这个注解就代表我们定义了一个全局异常处理器。
  • 在全局异常处理器当中,需要定义一个方法来捕获异常,在这个方法上需要加上注解@ExceptionHandler。通过@ExceptionHandler注解当中的value属性来指定我们要捕获的是哪一类型的异常。

AOP

AOP英文全称:Aspect Oriented Programming(面向切面编程、面向方面编程),即面向特定方法编程。

AOP的作用:在程序运行期间在不修改源代码的基础上对已有方法进行增强(无侵入性: 解耦)。

AOP的主流实现方式就是动态代理。Spring的AOP是Spring框架的高级技术,旨在管理bean对象的过程中底层使用动态代理机制,对特定的方法进行编程(功能增强)。常见的应用场景如下:

  • 记录系统的操作日志
  • 权限控制
  • 事务管理:我们前面所讲解的Spring事务管理,底层其实也是通过AOP来实现的,只要添加@Transactional注解之后,AOP程序自动会在原始方法运行前先来开启事务,在原始方法运行完毕之后提交或回滚事务

AOP面向切面编程的一些优势:

  • 代码无侵入:没有修改原始的业务方法,就已经对原始的业务方法进行了功能的增强或者是功能的改变

  • 减少了重复代码

  • 提高开发效率

  • 维护方便

核心概念:

  1. 连接点:JoinPoint,可以被AOP控制的方法(暗含方法执行时的相关信息)
  2. 通知:Advice,指哪些重复的逻辑,也就是共性功能(最终体现为一个方法)
    • 就是动态代理做了些什么事情
  3. 切入点:PointCut,匹配连接点的条件,通知仅会在切入点方法执行时被应用
    • 就是筛选条件,指示目标方法是哪些,是一个类似正则的表达式
  4. 切面:Aspect,描述通知与切入点的对应关系(通知+切入点)
  5. 目标对象:Target,通知所应用的对象
--- ♥ end ♥ ---

欢迎关注我呀~