java脚手架系列4--测试用例、拦截器

news2024/11/25 14:10:57

异常处理、拦截器、数据库连接

1 测试用例

单元测试是一个老生常谈的问题,无论是后端对自己的代码质量把的第一道关也好,也是对测试减缓压力。这里就不过多讲述测试用例的重要性,但是有2个框架我们必须了解一下。

1.1 JUnit和mockito

我们在搜索java的测试框架中,经常会看到这2个框架。
JUnit 是一个功能强大的测试框架,旨在用 Java 编写和运行可重复的测试,使其成为单元测试工具包中的主要内容。它提供了一个用于编写和组织测试的简单 API,从而可以更轻松地在开发过程的早期识别和修复错误。
Mockito 是一种流行的 Java 模拟框架,允许开发人员创建模拟对象并定义其行为以用于测试目的。与专注于测试代码逻辑的 JUnit 不同,Mockito 用于模拟代码交互的依赖项或外部系统的行为。通过创建模拟对象,开发人员可以隔离被测试的代码,使他们能够只关注其行为,而不必担心依赖关系的复杂性。
主要区别:JUnit 是一个用于编写和执行测试的框架,而 Mockito 是一个用于创建模拟对象的框架。 JUnit 用于验证代码的正确性,而 Mockito 用于验证对象之间的交互并确保代码在其依赖项的上下文中正常工作。
spring-boot的web项目:JUnit也是会启动一个web项目进行单元测试,而Mockito则不会。因此Mockito更多用来做上下链路调用或者上下层依赖的单元测试,比如上下层依赖数据库,但是有时候希望只是测试某一部分代码逻辑,不想连接或连接不了数据库,这时候就可以使用Mockito模拟一个数据库访问返回数据。

1.2 代码实践

现在我们要讨论的是如何在项目中搭建脚手架引入测试用例。
spring-boot中已经有配置好的测试用例组件spring-boot-starter-test,该依赖自动集成junit、mockito等测试框架,非常方便。下面就以spring-boot-starter-test为例,在子模块manage-biz中引入测试用例

请参考manage-biz子模块

1)在pom文件中引入spring-boot-starter-test

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

2)在src目录下新建test/java目录
3)如果要做哪个接口做单元测试,则在test/java目录下建立一样的package
4)使用Junit测试:建立DemoControllerTest,引入@SpringBootTest和@RunWith(SpringRunner.class)
5)使用Mockito:建立DemoControllerWithMockTest,引入@RunWith(MockitoJUnitRunner.class)

2 拦截器

2.1 基本概念

在我们web后端中,拦截器是一个非常有用的东西。包括前面讲到的异常处理,都可以用来做拦截器处理。springboot的拦截器执行顺序如下图:
在这里插入图片描述

注意:如果某个拦截器的preHandle返回false,之后的所有拦截器的postHandle都不会执行,同时该拦截器的afterCompletion也不会执行

除了异常处理,我们还可以在访问入口中拦截获取用户信息存入ThreadLocal,一遍后续代码使用。

2.2 代码实践

下面就以一个获取用户信息为例子,做一个拦截器简单的示范。

参考manage-biz子模块

1)在manage-biz子模块中建立一个ThreadLocal存储用户信息,使用UserHolder作为存储和获取工具(注意ThreadLocal的使用,有时候后端会启用线程池,ThreadLocal会失效,具体可以参考《ThreadLocal引发的思考》)

package com.demo.manage.biz.constant;

import com.demo.manage.biz.entity.TUser;

public class UserHolder {

    private static final ThreadLocal<TUser> USER_INFO = new ThreadLocal<>();

    public static void setUserId(TUser tUser) {
        USER_INFO.set(tUser);
    }

    public static TUser getTUser() {
        return USER_INFO.get();
    }

    public static void removeTUser() {
        USER_INFO.remove();
    }
}

2)在manage-biz子模块中pom引入一些解析使用的依赖

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-oauth2-jose</artifactId>
</dependency>

3)在manage-biz子模块中新建拦截器LoginInterceptor(实现HandlerInterceptor接口)

package com.demo.manage.biz.interceptor;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONNull;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.demo.common.core.result.ResultCode;
import com.demo.common.exception.BizException;
import com.demo.manage.biz.constant.UserHolder;
import com.demo.manage.biz.entity.TUser;
import com.nimbusds.jose.JWSObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.ParseException;

@Component
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("=====================用户信息验证=======================");
        // 从请求头获取token
        String token = request.getHeader("Authorization");
        if(!StringUtils.hasText(token)){
            token = request.getHeader("token");
        }
        // 如果不存在token,则返回false
        if (!StringUtils.hasText(token)) {
            throw new BizException(ResultCode.USER_ERROR);
        }
        // 解析token
        try {
            token = StrUtil.replaceIgnoreCase(token, "Bearer ", Strings.EMPTY);
            log.info("user-->"+token);
            String payload = StrUtil.toString(JWSObject.parse(token).getPayload());
            JSONObject jsonObject = JSONUtil.parseObj(payload);
            JSONObject userDetails = (JSONObject)jsonObject.get("userDetails");
            TUser tUser =covert2TUser(userDetails);
            UserHolder.setUserId(tUser);
        } catch (ParseException e) {
            throw new RuntimeException("用户未登录");
        }
        return true;
    }


    public static TUser covert2TUser(JSONObject userDetails){
        JSONObject user = (JSONObject)userDetails.get("user");
        TUser tUser = new TUser();
        tUser.setId(((Integer)user.get("id")).longValue());
        tUser.setUsername((String) user.get("username"));
        tUser.setEmail(user.get("email")==null|| user.get("email") instanceof JSONNull ? null:(String) user.get("email"));
        return tUser;
    }

}

4)在DemoController里面的echo方法获取user打印,验证结果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2204126.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【gRPC】4—gRPC与Netty

gRPC与Netty ⭐⭐⭐⭐⭐⭐ Github主页&#x1f449;https://github.com/A-BigTree 笔记链接&#x1f449;https://github.com/A-BigTree/Code_Learning ⭐⭐⭐⭐⭐⭐ 如果可以&#xff0c;麻烦各位看官顺手点个star~&#x1f60a; &#x1f4d6;RPC专栏&#xff1a;https://…

TadTR(TIP 2022)视频动作检测方法详解

前言 论文&#xff1a;End-to-end Temporal Action Detection with Transformer 代码&#xff1a;TadTR 从论文题目可以看出 TadTR 是基于 Transformer 的端到端的方法&#xff0c;TAD 在视频动作分类任务上更进一步&#xff0c;不仅对动作分类&#xff0c;还要检测动作发生的…

力扣21~30题

21题&#xff08;简单&#xff09;&#xff1a; 分析&#xff1a; 按要求照做就好了&#xff0c;这种链表基本操作适合用c写&#xff0c;python用起来真的很奇怪 python代码&#xff1a; # Definition for singly-linked list. # class ListNode: # def __init__(self, v…

每日一题:单例模式

每日一题&#xff1a;单例模式 ❝ 单例模式是确保一个类只有一个实例&#xff0c;并提供一个全局访问点 1.饿汉式&#xff08;静态常量&#xff09; 特点&#xff1a;在类加载时就创建了实例。优点&#xff1a;简单易懂&#xff0c;线程安全。缺点&#xff1a;无论是否使用&…

uni-app如何搭建项目(一步一步教程)

来来来&#xff0c;看这里 uni-app新建项目教程uni-app项目结构 首先我们要有一个HBuilder这个软件&#xff0c;然后我们来搭建uni-app项目 uni-app新建项目教程 首先我们打开这个HBuilder软件&#xff0c;好我们就出现这个界面&#xff0c;我们点击新建项目   然后我们选择…

Github优质项目推荐 - 第六期

文章目录 Github优质项目推荐 - 第六期一、【WiFiAnalyzer】&#xff0c;3.4k stars - WiFi 网络分析工具二、【penpot】&#xff0c;33k stars - UI 设计与原型制作平台三、【Inpaint-Anything】&#xff0c;6.4k stars - 修复图像、视频和3D 场景中的任何内容四、【Malware-P…

小猿口算APP脚本(协议版)

小猿口算是一款专注于数学学习的教育应用,主要面向小学阶段的学生。它提供多种数学练习和测试,包括口算、速算、应用题等。通过智能化的题目生成和实时批改功能,帮助学生提高数学计算能力。此外,它还提供详细的学习报告和分析,帮助家长和教师了解学生的学习进度和薄弱环节…

批量处理vue2中文硬编码转i18n国际化(保姆级)

文章目录 背景技术选型使用软件与插件插件使用补充 背景 公司的项目需要适应国际化的需求&#xff0c;但是因为代码是一个成品的项目&#xff0c;也就导致&#xff0c;代码量巨大&#xff0c;连带着需要转国际化的硬编码中文也很多&#xff0c;如果一点点纯手工改动&#xff0…

RelationGraph实现工单进度图——js技能提升

直接上图&#xff1a; 从上图中可以看到整个工单的进度是从【开始】指向【PCB判责】【完善客诉】【PCBA列表】&#xff0c;同时【完善客诉】又可以同时指向【PCB判责】【PCBA列表】&#xff0c;后续各自指向自己的进度。 直接上代码&#xff1a; 1.安装 1.1 Npm 方式 npm …

“探索端智能,加速大模型应用” 火山引擎边缘智能x扣子技术沙龙圆满落幕!

9月21日&#xff0c;火山引擎边缘智能扣子技术沙龙在上海圆满落地&#xff0c;沙龙以“探索端智能&#xff0c;加速大模型应用”为主题&#xff0c;边缘智能、扣子、地瓜机器人以及上海交通大学等多位重磅嘉宾出席&#xff0c;从多维视角探讨 AI、 AIoT、端侧大模型等技术与发展…

嵌入式数据结构中线性表的具体实现

大家好,今天主要给大家分享一下,如何使用数据结构中的线性表以及具体的实现。 第一:线性表的定义和表示方法 线性表的定义 – 线性表就是零个或多个相同数据元素的有限序列。 • 线性表的表示方法 – 线性表记为: L=(a0,∙∙∙∙∙∙∙∙ai-1aiai+1 ∙∙∙∙∙∙an-1) •…

HTTP的工作原理

HTTP&#xff08;Hypertext Transfer Protocol&#xff09;是一种用于在计算机网络上传输超文本数据的应用层协议。它是构成万维网的基础之一&#xff0c;被广泛用于万维网上的数据通信。&#xff08;超文本(Hypertext)是用超链接的方法&#xff0c;将各种不同空间的文字信息组…

数据交换的金钟罩:合理利用安全数据交换系统,确保信息安全

政府单位为了保护网络不受外部威胁和内部误操作的影响&#xff0c;通常会进行网络隔离&#xff0c;隔离成内网和外网。安全数据交换系统是专门设计用于在不同的网络环境&#xff08;如内部不同网络&#xff0c;内部网络和外部网络&#xff09;之间安全传输数据的解决方案。 使用…

Redis 其他类型 渐进式遍历

我们之前已经学过了Redis最常用的五个类型了&#xff0c;然而Redis还有一些在特定场景下比较好用的类型 Redis最关键的五个数据类型&#xff1a; 上面的类型是非常常用&#xff0c;很重要的类型。 除此之外的其他类型不常用&#xff0c;只是在特定的场景能够发挥用处&#…

澳鹏干货 | 大语言模型的上下文窗口 (Context Windows)

大语言模型&#xff08;LLMs&#xff09;极大地提升了人工智能在理解和生成文本方面的能力。其中一个影响其效用的重要方面是“上下文窗口”&#xff08;Context Windows&#xff09;—— 这个概念直接影响着模型接收和生成语言的有效性。 本期澳鹏干货将深入探讨上下文窗口对…

微软确认Word离奇Bug 命名不当会导致文件被删

微软近日确认Word应用中存在一个Bug&#xff0c;该漏洞可能导致用户在特定情况下错误地删除文件。该问题主要出现在文件命名过程中&#xff0c;如果用户在保存Word文件时采用特定的命名方式&#xff0c;文件可能会被移动到回收站。 根据微软支持中心的消息&#xff0c;如果用户…

MVS海康工业相机达不到标称最大帧率

文章目录 一、相机参数设置1、取消相机帧率限制2、修改相机图像格式3、调整相机曝光时间4、检查相机数据包大小&#xff08;网口相机特有参数&#xff09;5、 恢复相机默认参数6、 相机 ADC 输出位深调整 二、系统环境设置1、 网口相机设置2、 USB 相机设置 一、相机参数设置 …

java对接GPT 快速入门

统一对接GPT服务的Java说明 当前&#xff0c;OpenAI等GPT服务厂商主要提供HTTP接口&#xff0c;这使得大部分Java开发者在接入GPT时缺乏标准化的方法。 为解决这一问题&#xff0c;Spring团队推出了Spring AI &#xff0c;它提供了统一且标准化的接口来对接不同的AI服务提供商…

毕设分享 大数据用户画像分析系统(源码分享)

文章目录 0 前言2 用户画像分析概述2.1 用户画像构建的相关技术2.2 标签体系2.3 标签优先级 3 实站 - 百货商场用户画像描述与价值分析3.1 数据格式3.2 数据预处理3.3 会员年龄构成3.4 订单占比 消费画像3.5 季度偏好画像3.6 会员用户画像与特征3.6.1 构建会员用户业务特征标签…

Linux查看下nginx及使用的配置文件

1、查到nginx进程 ps -aef | grep nginx2、通过进行pid查到nginx路径 pwdx <pid>3、根据路径得到配置文件 path***/nginx -t如下&#xff1a;