SpringBoot项目自定义统一响应体设计_附上完整测试代码

SpringBoot 中统一响应格式及统一异常处理,你应该这样做 在我们开发SpringBoot后端服务时,一般需要给前端统一响应格式,方便前端调试及配置错误提示等等。这篇文章讲讲实际工作中统一响应格式及统一异常处理是如何做的。 阅读详情

目录

1. 介绍

2. 示例

​3. 自定义响应类和响应码枚举类设计

3.1 响应类Result

3.2 响应码枚举类

4. 数据库以及Java代码

4.1 数据库示例

4.1.1 数据库列展示

4.1.2 数据库建表DDL

4.2 实体类PO

4.3 Controller

4.4 Service

4.5 ServiceImpl

4.6 Mapper

5. 调接口测试

5.1 保存订单

5.2 根据订单id查询一条订单数据

6. 更新预告--->全局异常处理

6.1 更新全局异常处理

​6.2 国际化

6.3 自动根据请求头注入用户会话信息

6.3.1 Controller

6.3.2 ServiceImpl

6.3.3 控制台


1. 介绍

自定义响应类是指在开发中,根据业务需求自定义的用于封装接口响应数据的类。通常情况下,一个自定义响应类包含了接口返回的相关信息,如状态码、消息、数据等。

自定义响应类的设计灵活多样,可以根据具体的业务需求进行定义。一般来说,一个自定义响应类应该包括以下属性或方法:

  1. 状态码(Code):表示接口调用的状态,如成功、失败、错误等。
  2. 消息(Message):对接口调用结果的描述信息,可以是成功或失败的提示信息。
  3. 数据(Data):接口返回的具体数据。

作用

通过自定义响应类,可以将接口响应数据按照统一的格式进行封装和返回,方便前端或其他调用方解析和处理。同时,自定义响应类也可以提供更多的灵活性,可以根据具体的业务场景进行定制,满足不同的需求。

2. 示例

我们这里以 根据订单id查询一条订单数据为例:

如下所示:返回了一个响应体:包括响应码, 具体消息, 以及具体的响应数据:


3. 自定义响应类和响应码枚举类设计

3.1 响应类Result

注意类设计泛型, 这样无论什么类型的返回数据(String、Boolean、Integer、List)都可以。

响应类Result通常是依赖于响应码枚举类ResultCodeEnum, 而非独立存在

package com.rehse.common;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;

/**
 * @author: Rehse
 * @description: Result
 * @date: 2025/8/14
 */
@Data
@Builder
@AllArgsConstructor
// <T> 为泛型, 可以代表任意数据类型
public class Result<T> {
    private String code;
    private String message;
    private T data;

    public Result(){
    }
    public Result(ResultCodeEnum codeEnum) {
        this.code = codeEnum.getCode();
        this.message = codeEnum.getMessage();
    }

    public Result(ResultCodeEnum codeEnum, T data) {
        this.code = codeEnum.getCode();
        this.message = codeEnum.getMessage();
        this.data = data;
    }

    public static <T> Result<T> success() {
        Result<T> response = new Result<>();
        response.setCode(ResultCodeEnum.SUCCESS.getCode());
        response.setMessage("成功");
        return response;
    }

    // 用得最多的就是这个
    public static <T> Result<T> success(T data) {
        Result<T> response = new Result<>();
        response.setCode(ResultCodeEnum.SUCCESS.getCode());
        response.setMessage("成功");
        response.setData(data);
        return response;
    }

    public static <T> Result<T> fail(String msg) {
        Result<T> response = new Result<>();
        response.setCode(ResultCodeEnum.FAIL.getCode());
        response.setMessage(msg);
        return response;
    }

    public static <T> Result<T> fail(String code, String message) {
        Result<T> response = new Result<>();
        response.setCode(code);
        response.setMessage(message);
        return response;
    }


}

看似那么多, 其实返回成功时候, 主要只是用 传参为数据的这个方法

 // 用得最多的就是这个
    public static <T> Result<T> success(T data) {
        Result<T> response = new Result<>();
        response.setCode(ResultCodeEnum.SUCCESS.getCode());
        response.setMessage("成功");
        response.setData(data);
        return response;
    }

3.2 响应码枚举类

package com.rehse.common;
import java.util.Objects;
import java.util.stream.Stream;
/**
 * @author: Rehse
 * @description: ResultCodeEnum
 * @date: 2025/8/13
 */
public enum ResultCodeEnum {
    SUCCESS("10000", "成功"),
    FAIL("100001", "失败"),
    BAD_REQUEST("400", "请求错误"),
    UNAUTHORIZED("401", "未授权"),
    METHOD_NOT_ALLOWED("405", "请求方法不允许");


    private String code;            // 状态码
    private String message;          // 消息

    ResultCodeEnum(String code, String message) {
        this.code = code;
        this.message = message;
    }

    public String getCode() {
        return this.code;
    }

    public String getMessage() {
        return this.message;
    }

    public static ResultCodeEnum valueof(String code) {
        return Stream.of(values())
                .filter(option -> Objects.equals(option.code, code))
                .findFirst()
                .orElseThrow(() -> new IllegalArgumentException("No matching enum value for [" + code + "]"));
    }

}

4. 数据库以及Java代码

4.1 数据库示例

4.1.1 数据库列展示

4.1.2 数据库建表DDL

-- ----------------------------
-- Table structure for t_order
-- ----------------------------
DROP TABLE IF EXISTS `t_order`;
CREATE TABLE `t_order`  (
  `id` int NOT NULL AUTO_INCREMENT,
  `order_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
  `user_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
  `merchant_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
  `status` int NULL DEFAULT NULL,
  `create_time` datetime NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
  `update_time` datetime NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

4.2 实体类PO

package com.rehse.po;

import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;

@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("t_order")
public class Order {

    /**
     * 主键
     */
    @TableId(value = "id")
    private Long id;

    /**
     * 订单id
     */
    private String orderId;

    /**
     * 用户id
     */
    private String userId;

    /**
     * 商家id
     */
    private String merchantId;

    /**
     * 订单状态
     */
    private Integer status;

    /**
     * 创建时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createTime;

    /**
     * 更新时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date updateTime;


}

4.3 Controller

package com.rehse.controller;

import com.rehse.common.Result;
import com.rehse.po.Order;
import com.rehse.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/rehse/order")
public class OrderController {

    @Autowired
    private OrderService orderService;

    @PostMapping("/saveOrder")
    public Result<Boolean> saveOrder(@RequestBody Order order){
        return Result.success(orderService.saveOrder(order));
    }

    @PostMapping("/selectByOrderId")
    public Result<Order> selectByOrderId(@RequestParam("orderId") String orderId){
        Order order = orderService.selectByOrderId(orderId);
        return Result.success(order);
    }
}

4.4 Service

package com.rehse.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.rehse.po.Order;

public interface OrderService extends IService<Order> {
    Order selectByOrderId(String orderId);

    Boolean saveOrder(Order order);
}

4.5 ServiceImpl

package com.rehse.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rehse.mapper.OrderMapper;
import com.rehse.po.Order;
import com.rehse.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.UUID;

@Slf4j
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
    @Autowired
    private OrderMapper orderMapper;


    @Override
    public Boolean saveOrder(Order order) {
        Order orderNew = new Order();
        BeanUtils.copyProperties(order, orderNew);
        orderNew.setOrderId(String.valueOf(UUID.randomUUID()).replace("-", ""));
        orderNew.setCreateTime(new Date());
        orderNew.setUpdateTime(new Date());
        orderNew.setStatus(0);
        return save(orderNew);
    }

    @Override
    public Order selectByOrderId(String orderId) {
        return orderMapper.selectByOrderId(orderId);
    }


}

4.6 Mapper

package com.rehse.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.rehse.po.Order;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;


@Mapper
public interface OrderMapper extends BaseMapper<Order> {

    @Select("select * from t_order where order_id = #{orderId}")
    Order selectByOrderId(@Param("orderId") String orderId);
}

5. 调接口测试

这里用了ApiPost, 比postman好用, 不需要登录:

5.1 保存订单

5.2 根据订单id查询一条订单数据

6. 更新预告--->全局异常处理

感谢宝宝们看完这篇博客, 感觉有帮助的话一键三连么么哒!

25届Java小登已入职, 入职后也要继续提升哇,猪咪将会不定期分享学习笔记!

重铸Java荣光, 我辈义不容辞!

本期博客只是个简单demo, 其中的响应消息为固定死的, 非常不通用。

后续还会进行进一步优化, 请关注跟进吧么么哒!

接下来将会按照顺序依次1.更新全局异常处理->2.国际化->3.自动根据请求头注入用户会话信息

强烈建议这几篇博客一起看, 因为我是一天写完的, 

为了保持优快云活跃度, 我打算一天一发, 下一篇将会于2025年8月18日00:01:00自动更新:

6.1 更新全局异常处理

比如当调用接口:根据订单id查询一条订单, 如果没有传入订单id,那么肯定会抛出异常的:

示例:


6.2 国际化

根据请求头传入的语言为中文还是英文, 返回不同的响应消息。

示例:

设置请求头中的语言为英文, 当传入订单id为空时, 返回异常为相应的英文。

6.3 自动根据请求头注入用户会话信息

在某个用户在平台上面进行操作的时候, 会存在很多用户会话信息:包括用户id, 用户姓名, 用户邮箱等。

后续将会更新通过一个注解@UserSession, 一步注入用户会话信息

示例:

6.3.1 Controller

在接口里面添加了注解@UserSession

  @PostMapping("/saveOrder")
    public Result<Boolean> saveOrder(@UserSession UserSessionInfo userSessionInfo, @RequestBody Order order){
        return Result.success(orderService.saveOrder(order));
    }

6.3.2 ServiceImpl

@Override
    public Boolean saveOrder(Order order) {
        UserSessionInfo userSessionInfo = SessionThreadLocalUtil.getCurrentUserInfo();
        System.out.println("当前的UserSessionInfo为 : " + userSessionInfo);
        Order orderNew = new Order();
        BeanUtils.copyProperties(order, orderNew);
        orderNew.setUserId(String.valueOf(userSessionInfo.getUserId()));
        orderNew.setOrderId(String.valueOf(UUID.randomUUID()).replace("-", ""));
        orderNew.setCreateTime(new Date());
        orderNew.setUpdateTime(new Date());
        orderNew.setStatus(0);
        return save(orderNew);
    }

6.3.3 控制台

SpringBoot快速入门:从项目创建到RESTful API实战详解 在Java企业级开发领域,Spring框架是构建复杂应用的核心基石,但其繁琐的配置流程常令开发者却步。SpringBoot通过“约定大于配置”的设计哲学,实现了自动化配置与快速启动,其核心原理在于自动配置机制和Starter依赖管理。这一技术革新极大地提升了开发效率,降低了项目搭建门槛,使得开发者能够专注于业务逻辑实现。在微服务架构和云原生应用开发场景中,SpringBoot因其内嵌服务器、简化部署等特性成为首选框架。本文聚焦于SpringBoot项目实战,详细解析了如何使用IntelliJ IDEA创建项 阅读详情

相关推荐

从零搭建SpringBoot项目:IDEA环境配置与Maven依赖管理实战

Java企业级开发中,项目构建与依赖管理是核心基础环节。Maven作为主流构建工具,通过POM文件定义项目结构和依赖关系,实现依赖的自动下载与版本管理。其技术价值在于标准化项目生命周期,提升团队协作效率。在SpringBoot应用开发场景下,Maven与SpringBoot Starter机制结合,能快速引入Web、数据访问等模块依赖。本文聚焦IDEA集成开发环境,详解如何配置Maven镜像仓库优化下载速度,并通过Spring Initializr或手动配置pom.xml两种方式创建项目,解决JDK版本匹配

leonard61306500的专栏 412

基于SpringBoot3+Java17基础架构研发框架规范编码实战

 课程目标:你将对研发框架的代码封装和开发规范制定的底层实现逻辑有所掌握,并形成自己的开发封装套路,告别CRUD课程简介:   1. 课程背景: 能帮你解决什么问题?企业中通常由架构师搭建好开发框架,里面包含了很多封装好的基础结构,日志规范以及响应的异常统一处理,还有相应的参数校验等。很多初中高级开发工程师没有机会接触这部分代码的逻辑,而这部分代码逻辑又是非线性的,单纯看代码逻辑是看不出来执行顺序的,需要大量调试总结。不像mvc代码结构,你知道从Controller层看到Service再到Dao层,而这样底层的基础性代码则像积木,不熟悉的前提下需要一块块的插入拔出,不断总结,而沿着本课程的顺序梳理与实战你将会豁然开朗。市面上的大多文章结构较散,并且处理不够全面,比如返回结构通常是 具体的正例与反例日志统一处理 统一异常处理及特殊的情况处理 参数优雅校验 1基础的校验 2. 自定义校验 3.分组校验最重要的是给大家捋顺了一个清晰的实现结构以上在我们后面章节Spring Boot HelloWorld的至少10个可扩展点里有更多的相关介绍,在核心章节里有更细致的讲解实现。理解框架升级底层逻辑: 全网首套基于Spring Boot 3.x+Java 17开发系列 SpringBoot3的升级背景和路线逻辑掌握代码重构及编码效率提升技巧学习基于最为前沿的Spring Boot 3.x 和 Java 17 开发代码依赖于Spring Boot 3.x Java 17环境开发穿插相应新版本的变化讲解可编写完成一个生产级开发规范框架的制定 包含不限于 统一响应结构统一异常处理基于ThreadLocal处理请求RequestId基于日志框架的MDC 统一记录日志统一状态码处理Filter中的异常及状态码处理,以及日志的完整性处理自定义优雅参数校验学习源码剖析方式方法等等 3. 课程规划1.  课程章节规划 2. 讲课方式代码实战为主+图文演示为辅例如说明后端校验的重要性 以一张图清晰明了的展示说明解答了为何前端有了前端校验还要后端校验的问题 3. 特别说明本课程所有代码使用版本会随着Spring Boot 3.x的开发进度而更新,直到Spring Boot 3.x的正式版本发布,可放心食用本课程的重点会侧重放在研发框架的基础规范编码上,并非专注于SpringBoot3.x和Java17的新特性上讲解。主要是两点原因,1课程的方向侧重点, 2. SpringBoot3.x 官方尚处于MileStone/Snapshot版并未Release,所以大家可关注本人编程燃风后续的产品课程。本课程代码同样适用于Spring Boot 1.x 2.x 只需微调API和相关库版本的即可(注意1.x已经归档不维护) 常见问题:问:是否讲解Java17和SpringBoot3新特性答:本课程的重点会侧重放在研发框架的基础规范编码上,并非专注于SpringBoot3.x和Java17的新特性上讲解。主要是两点原因,1课程的方向侧重点是框架基础规范编码实战 2. SpringBoot3.x 官方尚处于MileStone/Snapshot版并未Release,所以大家可关注本人编程燃风后续的讲解课程。问:代码仅限于SpringBoot3吗? SpringBoot2和SpringBoot1是否适用?答:本课程代码同样适用于Spring Boot 1.x 2.x 只需微调API和相关库版本的即可(注意1.x已经归档不维护)。另外本课程重点讲解代码封装和底层实现逻辑和具体API版本关联不大,只是基于最新的SpringBoot3和Java17实现而已,请放心使用。

十分钟快速上手 - SpringBoot项目搭建指南

摘要:本文介绍了快速搭建SpringBoot项目骨架的完整流程。首先分析了SpringBoot的优势,包括简化配置、自动依赖管理和内嵌容器等特性。然后详细说明了三种创建方式:通过Spring Initializr网站、IDE内置工具或手动配置。文章还解析了项目结构,演示了编写RESTful接口和基础配置的方法,并介绍了单元测试与打包运行步骤。最后提供了进阶学习方向建议和常用资源链接,帮助开发者快速上手SpringBoot开发。

2403_87233054的博客 717

Spring Boot 统一响应

统一响应封装

学习学习学习学习 2161

【SpringBoot 4.x 第144节】统一响应体设计的边界:Result 包装、异常响应与分页响应!

🏆 本文收录于 《滚雪球学 Spring Boot 4.x》 专栏。本专栏面向 有一定 Java 基础,但尚未系统学习 Spring Boot 的读者,采用“滚雪球式学习法”:先跑通、再理解、再重构、再上线,带你从第一个 Hello API 开始,逐步完成一个可部署、可监控、可扩展的后端项目。

**My Coding Family** 158

Cesium创建无人机视锥,同步视锥与鹰眼地图视角,实现视锥键盘控制。解决视锥初始化位置不准确问题等

本文描述了一个基于Cesium的3D视锥体可视化系统开发过程。系统实现了主视图与鹰眼视图的双屏联动,支持通过键盘控制视锥体的空间移动(WASD前后左右,Q/E旋转,C/Z升降),并实时同步更新两个视图。关键技术包括:1)基于主视图Scene创建Camera实现视锥体精确绘制;2)通过PerspectiveFrustum设置视锥参数;3)建立双视图的相机位置及视角同步机制。目前暂未实现视锥体far/near边界在鹰眼视图中的可视化,该系统可应用于无人机视角监控等三维场景交互需求。

coder_bin的博客 1588

SpringBoot中优雅地实现统一响应对象

近日心血来潮想做一个开源项目,目标是做一款可以适配多端、功能完备的模板工程,包含后台管理系统和前台系统,开发者基于此项目进行裁剪和扩展来完成自己的功能开发。本项目为前后端分离开发,后端基于Java21和开发,后端使用JWT等技术栈,前端提供了vueangularreactuniapp微信小程序等多种脚手架工程。在前后端分离的项目开发过程中,我们通常会对数据返回格式进行统一的处理,这样可以方便前端人员取数据。但如果定义好响应对象R。

zzcoder的博客 1262

HDMI调试避坑指南:从AVI InfoFrame到通用控制包,这些DataIsland Packet细节千万别忽略

本文深入解析HDMI调试中DataIsland数据包的关键细节,包括AVI InfoFrame、通用控制包和音频时钟再生包(ACR)的配置与故障排查。通过实际案例和寄存器配置示例,帮助工程师快速定位显示异常、色彩失真和音频中断等问题,提升HDMI接口调试效率。

weixin_30897233的博客 632

springboot(2):统一响应体

统一响应体包括code、msg和data三个标准的键值对。这里直接返回这样的数据应该不太标准,按道理这个json应该放在data里面。

weixin_41747787的博客 359

大疆无人机地理视频制作全流程:从SRT文件到GIS叠加(附实战避坑指南)

本文详细解析了大疆无人机地理视频制作全流程,从解析SRT文件中的位姿数据,到在GIS软件中构建地理视频工程并生成可分发的文件。文章重点介绍了地理视频的核心概念、数据处理实战技巧,并探讨了其在应急响应、工程巡检等场景的高级应用与精度边界,为GIS工程师和无人机爱好者提供了一份实用的避坑指南。

river的博客 462

使用moveit中的报错及解决

1.fatal error: moveit/move_group_interface/move_group.h: 没有那个文件或目录。// #include <moveit/move_group_interface/move_group.h> 改为。问题1 moveit/move_group_interface/move_group.h: 没有那个文件或目录。在运行c++程序时报错。

qq_60566155的博客 2285

SpringBoot 响应体与异常的统一处理实践

本文介绍了SpringBoot中实现统一响应和异常处理的优雅方案。通过定义通用的ApiResult包装类,结合ResponseBodyAdvice实现响应自动包装,利用@RestControllerAdvice集中处理异常,可有效解决传统开发中重复编码、格式不统一等问题。该方案使业务代码更简洁专注,响应结构标准化,异常处理集中化,大幅提升开发效率和可维护性。关键实现包括:1)统一API响应结构封装;2)全局响应处理器自动包装正常结果;3)全局异常拦截器统一处理错误。这种声明式处理机制为构建健壮RESTful

muyun2800的博客 1035

使用这个算法我可以实现英雄联盟里英雄的走位|Java 开发实战

A算法,A(A-Star)算法是一种静态路网中求解最短路径最有效的直接搜索方法,也是解决许多搜索问题的有效算法。算法中的距离估算值与实际值越接近,最终搜索速度越快。 基本概念 首先在大学我们遇到最多的算法Dijkstra、Floyd、广度搜索、深度搜索。关于这些算法我们以后再慢慢的研究,今天的重点在A算法上。A算法是一种启发式算法。与上述几种算法不同的是A*算法在考虑起始节点的同时还会考虑到目标节点的代价。 在A*算法中我们给每个节点都定义一些属性。最基本的就是下文提到的三基数-这里的三基数是我自己定义.

Java进阶营 312

RESTful+统一响应体+API自动文档的SprinBoot项目

随着互联网技术的发展和移动应用的广泛应用,要求前端开发必须与后端开发分离,实施工程化开发模式。网页有网页的处理方式,APP有APP的处理方式,但无论哪种前端,所需的数据基本相同,在实际开发中,常用Swagger-API接口文档自动生成工具,帮助项目自动生成和维护接口文档。接口中有时返回数据,有时又没有,还有的会出错,也就是返回结果不一致,客户端调用时非常不方便。统一的接口是RESTful风格的核心内容。,即通过URL表明要操作的资源,通过请求方法表明要执行的操作,通过返回的状态码表明这次请求的结果。

weixin_51293984的博客 3508

083、多帧降噪(MFR)与VST算法:低照度场景下的信噪比提升与鬼影抑制

本文深入探讨了多帧降噪(MFR)和VST算法在低照度场景中的应用与优化。作者从实际项目案例出发,指出单帧降噪的局限性,详细分析了MFR的核心原理与工程实现中的关键环节,包括帧对齐、帧选择、融合策略和鬼影抑制等技术要点。文章特别强调VST变换对噪声均匀化的重要性,并分享了实际开发中的调试经验与参数优化技巧,如"三明治"调试法和性能平衡策略。最后指出,优秀的MFR方案需要在信噪比提升、鬼影抑制和纹理保留之间找到场景化的平衡点,建议开发者通过真实场景测试验证算法效果。全文既有理论分析,又包含丰富的实战经验和技术细

zzfmlxs的博客 121

《爬虫和逆向教程》 - 专栏介绍和目录

本专栏为爬虫初学者和进阶开发者量身定制的爬虫和逆向学习园地。为你提供全面而深入的爬虫和逆向技术指导,从入门到精通,从基础理论到高级实战,助你在数据的海洋中畅游,挖掘出有价值的信息。通过本专栏的学习,你将具备独立开发和优化爬虫程序的能力,及逆向分析能力和项目开发能力,成为爬虫领域的佼佼者。

数据知道的博客 2万+

SpringBoot项目配置国际化

本文系统介绍了Spring Boot项目中国际化的实现方案。通过MessageSource+LocaleResolver组合,将文案抽离到i18n资源文件,实现运行时自动切换语言。包括:1)创建i18n目录及多语言properties文件;2)配置basename指定资源文件前缀;3)改造响应体和异常码使用MessageSource获取消息;4)自定义LocaleResolver实现请求头语言解析;5)通过MessageUtils工具类实现消息动态切换。文章还预告了后续将实现的用户会话信息自动注入功能。

bugMaker_0621的博客 1900

【人脸识别/轻量级模型】MobileFaceNet:适用于人脸识别的轻量级网络模型(文末附pytorch代码)

MobileFaceNet:用于人脸识别的轻量级网络模型

Roaddd的博客 6983

SpringBoot项目通过自定义注解根据请求头注入用户会话信息_企业级方案

本文介绍了一种通过自定义注解@UserSession实现用户会话信息自动注入的方法。通过实现HandlerMethodArgumentResolver接口创建参数解析器,从请求头获取用户ID、姓名等信息,并使用建造者模式构建UserSessionInfo对象。该方案将用户会话信息处理逻辑从业务代码中抽离,业务方法只需添加注解即可自动获取会话信息,并通过ThreadLocal实现线程安全共享。

bugMaker_0621的博客 1165

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

【图书管理系统】深入解析基于 SpringBoot 统一返回结果封装:实现结果封装的方法、引入拦截器和统一返回结果后的代码交互流程

@SneakyThrows、@ControllerAdvice、supports()、beforeBodyWrite()、writeValueAsString、StringHttpMessageConverter、MappingJackson2XmlHttpMessageConverter、

OuO-1 的博客 1699

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

SpringBoot项目企业级全局异常处理

本文介绍了SpringBoot项目中全局异常处理的实现方法,统一捕获并处理Controller层的异常。文章详细展示了业务异常类、通用错误码枚举的实现,以及全局异常处理器的代码示例。该方法能有效避免代码重复,统一异常响应格式。同时预告了后续将更新的国际化支持和用户会话信息自动注入功能,包括根据请求头语言返回不同响应消息,以及通过@UserSession注解自动注入用户信息的实现方案。

bugMaker_0621的博客 1448

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

springBoot统一响应类型3.1版本

通过实践而发现真理,又通过实践而证实真理和发展真理。从感性认识而能动地发展到理性认识,又从理性认识而能动地指导革命实践,改造主观世界和客观世界。实践、认识、再实践、再认识,这种形式,循环往复以至无穷,而实践和认识之每一循环的内容,都比较地进到了高一级的程度。简单回忆:基础统一响应1.0在1.0的基础上,进行优化加工在1.0,2.0的基础上进行迭代后的全局响应3.0完成全局统一响应(无论成功还是失败)

c_yanxin_ru的博客 721

Spring Cloud Gateway 获取响应体消息

文章目录一、场景介绍二、演示代码 一、场景介绍   在通常情况下,微服务的业务功能都需要通过网关来进行转发,记录业务响应日志通过网关来记录是最有利的方式。 二、演示代码 测试版本 组件名 版本号 Spring Boot 2.2.5.RELEASE Spring Cloud Hoxton.SR3 Spring Cloud Alibaba 2.2.1.RELEASE 测试代码 import com.google.common.base.Joiner; import com.g

Rambo's Blog 3384

SpringBoot项目中JUnit5的10个实战技巧

JUnit5的扩展模型非常灵活。我们可以通过实现BeforeEachCallback、AfterEachCallback等接口创建自定义扩展。我在项目中常用这个功能来初始化测试环境,比如创建临时文件或数据库连接。

IndigoNight21的博客 999

Springboot项目学习之各组件的用法和逻辑结构

RESTful(Representational State Transfer)风格的Web服务是一种设计Web服务的架构风格,它是基于HTTP协议和统一资源定位器(URL)的架构风格。RESTful Web服务遵循REST原则,使用HTTP方法(如GET、POST、PUT、DELETE等)来操作资源,使用URL来唯一标识资源,使用标准的MIME类型(如JSON、XML等)来表示资源的状态。

weixin_68929783的博客 1798

SpringBoot入门指南:从零开始构建第一个项目

SpringBoot 是当前 Java 开发中非常流行的框架之一,极大地简化了 Spring 应用程序的开发,提供了开箱即用的配置和最佳实践。本文将详细介绍如何从零开始创建一个简单的 SpringBoot 项目,并逐步讲解每一个操作步骤。

java李阳勇的博客 4727
上一篇: 算法:leetcode_146_LRU 缓存
下一篇: SpringBoot项目企业级全局异常处理
bugMaker_Rehse
博客等级 码龄1年 133粉丝 17原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值