Spring 对请求参数的优雅处方式(重写序列化方法)
Spring 对请求参数的优雅处方式(重写序列化方法)
- 描述
- 前端传参方式介绍
- 代码实现:
- 1、重写序列化方式代码
- 2、设置类自动加载到 Spring 中
描述
在我们日常项目开发过程中,往往会遇到前端请求参数中有空格的情况,前端提交后后端的字符串什么形式的都有(例: " xxx ", " xxxxx ", “”, “null” 等等),这样不对空格进行处理直接传参,不仅浪费空间,还会造成数据跟查询结果有出入的情况,引起很多不必要的麻烦。那么,怎么快速的去除前端传参中字符串类型参数的前后空格呢?
前端传参方式介绍
在开发过程中,后端接收前端的传参有两种方式:
- 使用 url 或者 form 表单进行传参,后端通过 @RequestParam 注解的方式,从 url 中获取参数。
- 使用 body 进行传参,后端通过 @RequestBody 注解进行参数的接收。
对于 url 或者 form 表单的方式,我们在参数绑定时注册下面的类即可对参数进行处理
@RestControllerAdvice
public class GlobalHandler {private static final Logger LOGGER = LoggerFactory.getLogger(GlobalHandler.class);/*** url和form表单中的参数trim* @param binder*/@InitBinderpublic void initBinder(WebDataBinder binder) {// 构造方法中 boolean 参数含义为如果是空白字符串, 是否转换为 null// 即如果为 true, 那么 "" 会被转换为 null, 否者为""binder.registerCustomEditor(String.class, new StringTrimmerEditor(true));}
}
对于使用 body 中的 JSON 或者 XML 的传参方式,在 Spring 中,默认是使用的 Jackson 对参数进行序列化处理,所以对 Jackson 加入如下的自定义转换器即可实现:
@Configuration
public class ApplicationConfig {/*** Request Body中JSON或XML对象参数trim** @return*/@Beanpublic Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {return jacksonObjectMapperBuilder -> {// 时区问题jacksonObjectMapperBuilder.timeZone(TimeZone.getDefault());jacksonObjectMapperBuilder.deserializerByType(String.class, new StdScalarDeserializer<String>(String.class) {@Overridepublic String deserialize(JsonParser jsonParser, DeserializationContext ctx)throws IOException {// 去除前后空格return StringUtils.trimWhitespace(jsonParser.getValueAsString());}});};}
}
代码实现:
1、重写序列化方式代码
对于上述的两种传参方式,我们优化一下,将两个合并成一个统一的类来进行实现;
package com.wblog.framework.config;import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.deser.std.StdScalarDeserializer;
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;import javax.servlet.Servlet;
import java.io.IOException;/*** 序列化处理前端请求数据的前后空格* @author wangxk* @date 2023-12-27*/
@Configuration
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class})
@AutoConfigureAfter(WebMvcAutoConfiguration.class)
public class WebMvcStringTrimAutoConfiguration {@ControllerAdvicepublic static class ControllerStringParamTrimConfig {/*** url和form表单中的参数trim*/@InitBinderpublic void initBinder(WebDataBinder binder) {// 构造方法中 boolean 参数含义为如果是空白字符串,是否转换为null// 即如果为true,那么 " " 会被转换为 null,否者为 ""StringTrimmerEditor stringTrimmerEditor = new StringTrimmerEditor(false);binder.registerCustomEditor(String.class, stringTrimmerEditor);}}/*** Request Body中JSON或XML对象参数trim*/@Beanpublic Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder.deserializerByType(String.class, new StdScalarDeserializer<String>(String.class) {@Overridepublic String deserialize(JsonParser jsonParser, DeserializationContext ctx)throws IOException {System.out.println("Jackson2ObjectMapperBuilderCustomizer jsonParser.getValueAsString() = " + jsonParser.getValueAsString());return StringUtils.trimWhitespace(jsonParser.getValueAsString());}});}
}
2、设置类自动加载到 Spring 中
由于 Spring 启动时,是默认加载同级别目录下所有的 Bean,如果我们重写的 WebMvcStringTrimAutoConfiguration 类是在外部目录时,我们就需要手动去指定一下需要加载的类,在 resurces 下创建 META-INF/spring.factories 文件,将我们的类加到里面去:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.wblog.framework.config.WebMvcStringTrimAutoConfiguration
参考链接:
- SpringBoot去除字符串类型参数的前后空格
- Springmvc请求参数的优雅处方式
相关文章:
Spring 对请求参数的优雅处方式(重写序列化方法)
Spring 对请求参数的优雅处方式(重写序列化方法) 描述前端传参方式介绍代码实现:1、重写序列化方式代码2、设置类自动加载到 Spring 中 描述 在我们日常项目开发过程中,往往会遇到前端请求参数中有空格的情况,前端提交…...
2024年中职“网络安全“—数字调查取证(attack817.pcapng)
目录 1.通过分析数据包找出恶意用户最初访问HTTP服务的包号,将该值作为Flag值提交, Flag格式为flag{xxx}; 2.继续查看数据包文件分析出恶意用户扫描了哪些端口,将全部的端口号按照一定顺序作为Flag值,提示:注意端口…...
如何使用VsCode编译C语言?
下载VsCode (1) 解压到D盘跟目录 (2) 运行[vscode.reg],注册右键菜单 (3) 进入[pack]文件夹,运行[install.bat]。安装基本插件。 下载mingw32 (1) 解压任意目录 (2) 我的电脑右键–高级系统设置–高级–环境变量–系统变量–Path(双击)–空白行(双击)–…...
SpringCloud 和 Linux 八股文第三期五问五答
SpringCloud 和 Linux 八股文第三期五问五答 作者:程序员小白条,个人博客 相信看了本文后,对你的面试是有一定帮助的! ⭐点赞⭐收藏⭐不迷路!⭐ 1)Linux常用命令 2)如何查看测试项目的日志 一…...
组件通信方式
组件通信方式有:vuex,ref,父子通信(父传子、子传父),兄弟通信(eventBus), 祖先后代通信(依赖注入) 父传子:父组件内:在子组件标签上设置自定义属…...
kbdnecnt.DLL文件缺失,软件或游戏无法启动运行,怎样快速修复?
不少人都在问“kbdnecnt.DLL文件”是什么?为什么电脑总是报错提示说“kbdnecnt.DLL文件缺失,软件无法启动”? 首先,先来了解“kbdnecnt.DLL文件”是什么? kbdnecnt.DLL是Windows操作系统中的一个动态链接库文件&#…...
Linux账户安全
一.Linux账户与组的基本概念 在Limux操作系统中,每一个文件和程序都归属于一个特定的 “用户”。每个用户都由一个唯一的身份来标识,这个标识称为用户ID (UserID, UID )。系统中的每一个用户也至少需要属于一个“用户分组”,即由系统管理员所…...
深度生成模型之GAN优化目标设计与改进 ->(个人学习记录笔记)
文章目录 深度生成模型之GAN优化目标设计与改进原始GAN优化目标的问题1. JS散度度量问题2. 梯度问题 优化目标的设计与改进1. 最小二乘损失GAN2. Energy-based GAN(EBGAN)3. Wasserstein GAN4. WGAN-GP5. Boundary Equilibrium GAN(BEGAN)6. Loss Sensitive GAN7. Relativeisti…...
程序员如何高效学习技术?
我们相信努力学习一定会有收获,但是方法不当,既让人身心疲惫,也没有切实的回报。 不少朋友每天都阅读技术文章,但是第二天就忘干净了。工作中领导和同事都认可你的沟通和技术能力,但是跳槽面试却屡屡碰壁。面试官问技术…...
一个无经验的大学毕业生,可以转行做软件测试吗?我的真实案例
在转行之前,我一直在思考,当代年轻人的真实生活情况究竟是什么样的。 朝九晚六,无休止的加班,每天往返于公司与家,没有一点点自己的生活,只能从心里面麻痹自己,以求得最后的慰籍。 这就是我之…...
三.Linux无名管道(PIPE)和有名管道(FIFO)的区别
目录 命名管道(Named Pipe): 无名管道(Anonymous Pipe): 总结: 无名管道(Anonymous Pipe)和命名管道(Named Pipe)都是进程间通信的机制&#x…...
英文字母替换加密(后移n位)
思路:首先写出后移(前移)1位的情况 , 然后逐渐累加至N位情况 #include <stdio.h> void test(char arr[] , int n ) { int i 0; int z 0; if( n < 0 ) { while( i ! n ) { …...
HAproxy群集
HAproxy群集 常见的集群调度器HAproxy 、nginx、LVS区别HAproxynginxlvs HAproxy介绍HAproxy特点HAproxy常见的负载均衡策略HAproxy会话保持HAproxy配置实例 常见的集群调度器 常见的web集群调度器分为软件和硬件 软件:LVS Haproxy nginx 硬件: F5 Ar…...
LeetCode2469. Convert the Temperature
文章目录 一、题目二、题解 一、题目 You are given a non-negative floating point number rounded to two decimal places celsius, that denotes the temperature in Celsius. You should convert Celsius into Kelvin and Fahrenheit and return it as an array ans [ke…...
【ROS2】MOMO的鱼香ROS2(五)ROS2入门篇——ROS2接口与自定义
ROS2接口与自定义 引言1 ROS2自带接口1.1 ROS2通用标准消息包1.2 ROS2传感器消息包1.3 ROS2几何相关消息包 2 ROS2接口介绍2.1 常用CLI命令2.2 原始数据类型与包装类型 3 自定义接口示例3.1 接口定义3.2 自定义接口RCLPY 引言 笔者跟着鱼香ROS的ROS2学习之旅 学习参考…...
python c语言 代码动态检查,python c语言语法分析
大家好,小编来为大家解答以下问题,python c语言 代码动态检查,python c语言语法分析,今天让我们一起来看看吧! Source code download: 本文相关源码 初学编程,应该学习哪一门编程语言,有不少人感…...
C++ DAY6 作业
1.用模板类写顺序表 #include <iostream>using namespace std;#define MAXSIZE 10 template <typename T> class Arr {T *data NULL;int len 0; public://构造函数Arr():data(new T){}Arr(T a,int len):data(new T(a)),len(len){}//析构函数~Arr(){delete data;}…...
华为服务器安装银河麒麟V10操作系统(IBMC安装)
iBMC是华为面向服务器全生命周期的服务器嵌入式管理系统。提供硬件状态监控、部署、节能、安全等系列管理工具,标准化接口构建服务器管理更加完善的生态系统。 服务器BMC IP:192.168.2.100 一、准备工作 1、确保本机和服务器BMC管理口在同一网络 2、银…...
macos下php 5.6 7.0 7.4 8.0 8.3 8.4全版本PHP开发环境安装方法
在macos中如果使用brew 官方默认的core tap 只可以安装官方最新的稳定版PHP, 如果想要安装 php 5.6 或者 php 8.4版本的PHP就需要使用第三方的tap , 这里分享一个比较全面的brew tap shivammathur/php 这个tap里面包含了从php5.6到最新版php8.4的所有可用最新版本PHP, 而且是同…...
Chatgpt为什么像打字机逐字输出?磨洋工,防止数据库被盗
在他后台的数据库里肯定是完整的结果,每次只给你一个单词一个单词的输送,一方面是为了耍酷,好像真的是一个人在那给你说话,另一方面也是防止第三方的抄袭者最快速度盗取采集偷走数据库。防止他们的服务器崩溃,可以多收几个月会员费。 都说搞…...
AI智能体技能超市:用SKILL.md标准打破AI能力壁垒
1. 项目概述:一个为AI智能体准备的“技能超市” 如果你和我一样,每天都在和各种AI编程助手打交道——Cursor、Claude Code、GitHub Copilot,那你肯定也遇到过这样的场景:想让AI帮你生成一张产品原型图,结果它告诉你“我…...
如何通过Python快速接入Taotoken并调用多模型API完成文本生成任务
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 如何通过Python快速接入Taotoken并调用多模型API完成文本生成任务 1. 准备工作:获取API Key与模型ID 在开始编写代码之…...
新手避坑指南:用Simulink搭建48V开关电源仿真,从整流到反激电路完整流程
新手避坑指南:用Simulink搭建48V开关电源仿真全流程实战 电力电子领域的仿真实验常常让初学者望而生畏——参数设置不当可能导致虚拟元器件"烧毁",波形失真却找不到原因。本文将手把手带你用Simulink搭建从交流整流到DC-DC变换的完整48V电源系…...
手把手教你用FPGA+CORDIC算法实现任意角度图像旋转(告别浮点运算)
FPGACORDIC算法实现高精度图像旋转的硬件优化实践 在数字图像处理领域,实时图像旋转是一项基础而关键的技术需求。传统基于浮点运算的旋转方案虽然直观,但在FPGA等硬件平台上往往面临资源占用高、时序难以满足的挑战。本文将深入探讨如何利用CORDIC&…...
华为MateBook D 2018 BIOS隐藏选项实战:手动解锁TPM2.0迎战Win11
1. 为什么需要手动解锁TPM2.0 去年Windows 11正式发布时,很多华为MateBook D 2018用户都遇到了一个尴尬问题:明明硬件配置完全达标,却因为BIOS里找不到TPM2.0开关而无法升级。我当时也卡在这个环节整整两天,直到发现原来TPM功能被…...
如何自定义 LangGraph 的 State Schema 以支持复杂业务数据流
标题选项 《LangGraph实战进阶:自定义State Schema搞定复杂业务数据流全指南》 《从零搞定LangGraph复杂工作流:State Schema自定义从原理到落地》 《告别简单Demo:自定义LangGraph State Schema支撑企业级复杂数据流》 《LangGraph核心原理解锁:State Schema自定义设计思路…...
FreeRTOS日志任务设计----LogTask 日志任务
🎬 渡水无言:个人主页渡水无言 ❄专栏传送门: 《linux专栏》《嵌入式linux驱动开发》《linux系统移植专栏》 ❄专栏传送门: 《freertos专栏》 《STM32 HAL库专栏》《linux裸机开发专栏》 ❄专栏传送门:《产品测评专栏》…...
2025年项目管理工具TOP10:Gitee引领技术驱动新浪潮
1.Gitee(码云):代码与管理的双核引擎 作为中国最大的代码托管平台,Gitee在2025年全面升级项目管理模块,成为技术团队的首选工具。其核心优势在于: 开发与协作无缝衔接:代码提交直接关联任务看板…...
开源协作平台Polar:一体化设计如何重塑开发者工作流
1. 项目概述:一个面向开发者的开源协作平台最近在和一些独立开发者朋友聊天时,大家普遍提到一个痛点:当你想启动一个开源项目,或者和几个朋友一起搞点小东西时,整个协作流程其实挺割裂的。代码托管在GitHub或GitLab&am…...
收藏!AI时代程序员转型指南:从纯编码到人机协同高手
本文揭示了AI对程序员行业的深刻变革:初级编码岗需求锐减,而AI协作、架构师等高端岗位需求激增。文章提出两个阶段提升竞争力:第一阶段掌握AI工具栈(编码助手、调试工具等)并遵循人机协同法则;第二阶段构建…...
