springboot接口入参下划线转驼峰以及返回参数驼峰转下划线实现
1.背景
在实际开发中,通常来说java里面是使用驼峰的命名规则;
但是有时候在对接其他三方平台的接口时,要求使用下划线的命名规则,这时候就涉及到如何让自己的接口满足三方平台的下划线;
实现方式有
1.java里面也使用下下划线的方式接收和响应,但是不推荐这样,因为虽然满足了接口需求,但是不符合java里面的命名规范;
2.java里面使用驼峰,接收到参数后手动转换,这样做太麻烦.
3.java里面使用驼峰,写一个工具方法,通过注解的方式,统一转换,推荐,也是实际开发中常用的方式
那些地方需要转换
1.传入参数的时候(下换线转为驼峰)
2.响应结果的时候(驼峰转为下划线)
因为响应结果的时候(驼峰转为下划线)比较简单,先搞定这个
2.响应结果的时候(驼峰转为下划线)
方式一:在返回对象的类上加注解(推介)
@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
案例如下:

方法二:在字段上注解
@JsonProperty(value = "order_card")

3.传入参数的时候(下换线转为驼峰)
方式一:自己手动封装,不推荐,略;
方式二:接收为Map对接,通过Json转换(如果系统中只有少数个别接口需要转换,可以这样写);
步骤一:接收对象上的字段上加注解 @JsonProperty(value = "order_card")

步骤二:控制层出的写法如下

方式三:通过实现接口HandlerMethodArgumentResolver的方式,强烈推荐
步骤一:自定义注解 ParameterConvert

@Target(value = ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface ParameterConvert {
}
步骤二:自定义类AbstractCustomizeResolver

import org.springframework.core.Conventions;
import org.springframework.core.MethodParameter;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.Errors;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer; import java.lang.annotation.Annotation; /**
* @Copyright (C) XXXXXXXXXXX科技股份技有限公司
* @Author: lidongping
* @Date: 2021-05-13 19:24
* @Description:
*/
public abstract class AbstractCustomizeResolver implements HandlerMethodArgumentResolver {
/**
* 校验
*
* @param parameter
* @param mavContainer
* @param webRequest
* @param binderFactory
* @param arg
* @throws Exception
*/
protected void valid(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory, Object arg) throws Exception {
String name = Conventions.getVariableNameForParameter(parameter);
WebDataBinder binder = binderFactory.createBinder(webRequest, arg, name);
if (arg != null) {
validateIfApplicable(binder, parameter);
if (binder.getBindingResult().hasErrors() && isBindExceptionRequired(binder, parameter)) {
throw new MethodArgumentNotValidException(parameter, binder.getBindingResult());
}
}
mavContainer.addAttribute(BindingResult.MODEL_KEY_PREFIX + name, binder.getBindingResult());
} /**
* @param binder
* @param parameter
*/
protected void validateIfApplicable(WebDataBinder binder, MethodParameter parameter) {
Annotation[] annotations = parameter.getParameterAnnotations();
for (Annotation ann : annotations) {
Validated validatedAnn = AnnotationUtils.getAnnotation(ann, Validated.class);
if (validatedAnn != null || ann.annotationType().getSimpleName().startsWith("Valid")) {
Object hints = (validatedAnn != null ? validatedAnn.value() : AnnotationUtils.getValue(ann));
Object[] validationHints = (hints instanceof Object[] ? (Object[]) hints : new Object[]{hints});
binder.validate(validationHints);
break;
}
}
} protected boolean isBindExceptionRequired(WebDataBinder binder, MethodParameter parameter) {
int i = parameter.getParameterIndex();
Class<?>[] paramTypes = parameter.getMethod().getParameterTypes();
boolean hasBindingResult = (paramTypes.length > (i + 1) && Errors.class.isAssignableFrom(paramTypes[i + 1]));
return !hasBindingResult;
} }
步骤三:自定义类 UnderlineToCamelArgumentResolver

import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.PropertyAccessorFactory;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.ModelAndViewContainer; import java.util.Iterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern; public class UnderlineToCamelArgumentResolver extends AbstractCustomizeResolver {
/**
* 匹配_加任意一个字符
*/
private static final Pattern UNDER_LINE_PATTERN = Pattern.compile("_(\\w)"); @Override
public boolean supportsParameter(MethodParameter methodParameter) {
return methodParameter.hasParameterAnnotation(ParameterConvert.class);
} @Override
public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer,
NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
Object org = handleParameterNames(methodParameter, nativeWebRequest);
valid(methodParameter, modelAndViewContainer, nativeWebRequest, webDataBinderFactory, org);
return org;
} /**
* 处理参数
*
* @param parameter
* @param webRequest
* @return
*/
private Object handleParameterNames(MethodParameter parameter, NativeWebRequest webRequest) {
Object obj = BeanUtils.instantiate(parameter.getParameterType());
BeanWrapper wrapper = PropertyAccessorFactory.forBeanPropertyAccess(obj);
Iterator<String> paramNames = webRequest.getParameterNames();
while (paramNames.hasNext()) {
String paramName = paramNames.next();
Object o = webRequest.getParameter(paramName);
System.out.println(paramName + "=" + o);
wrapper.setPropertyValue(underLineToCamel(paramName), o);
}
return obj;
} /**
* 下换线转驼峰
*
* @param source
* @return
*/
private String underLineToCamel(String source) {
Matcher matcher = UNDER_LINE_PATTERN.matcher(source);
StringBuffer result = new StringBuffer();
while (matcher.find()) {
matcher.appendReplacement(result, matcher.group(1).toUpperCase());
}
matcher.appendTail(result);
return result.toString();
}
}
步骤四:整合到springboot中,在WebConfig中添加如下代码

@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(new UnderlineToCamelArgumentResolver());
}

步骤五:使用,很简单,在接收参数的对象前加注解

4.完美
springboot接口入参下划线转驼峰以及返回参数驼峰转下划线实现的更多相关文章
- springboot项目中接口入参的简单校验
.katex { display: block; text-align: center; white-space: nowrap; } .katex-display > .katex > ...
- Spring AOP 自定义注解获取http接口及WebService接口入参和出参
注解方法实现过程中可以采用如下获取方式:—以下为例 HttpServletRequest request = ((ServletRequestAttributes) RequestContextHo ...
- java接口入参模板化,适用于企业化服务远程调度模板化的场景,接口入参实现高度可配置化
需求:远程服务接口模板化配置提供接入服务 模板接口分为三个模块:功能路由.参数校验.模板入库 路由:这里的实现方式很简单,就是根据业务标识找到对应的处理方法 参数校验: 参数校验这步涉及模板和校验类两 ...
- (一)将mockjs集成到VUE中后,怎样根据接口入参返回mock结果
1)安装mockjs,这一步跳过 2)在项目中建立mock模块,笔者的目录结构如下 mock模块与接口模块一一对应,有一个接口,就有一个mock 3)编写登陆模块mock接口,代码如下: import ...
- robot:接口入参为图片时如何发送请求
https://www.cnblogs.com/changyou615/p/8776507.html 接口是上传图片,通过F12抓包获得如下信息 由于使用的是RequestsLibrary,所以先看一 ...
- RobotFramework:发现一个大坑,当post接口入参为json时,千万不能用sojson转化后的json串(ride解析会有异常,非sojson工具问题),直接用浏览器粘过来的就行
问题背景: 和以往一样愉快的进行着自动化测试,突然就不停的提示我,“程序异常”,查看log发现data中的json变为了数组?????? 那算了,我不先组装入参数据直接data=json入参吧,wha ...
- Postman—上个接口返回数据作为下个接口入参
//将数据解析成json格式 var data=JSON.parse(responseBody); //获取totalRentPrice值 var totalRentPrice=jsonData.da ...
- pytest.9.使用fixture参数化接口入参
From: http://www.testclass.net/pytest/test_api_using_params/ 背景 接上一节v2ex网站的查看论坛节点信息的api.具体如下: 节点信息 获 ...
- springBoot controller入参LocalDateTime
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss") @DateTimeForma ...
- 入参是小数的String,返回小数乘以100的String
String money = request.getParameter("orderAmt"); BigDecimal moneyDecimal = new BigDecimal( ...
随机推荐
- session 和 cookie 有什么区别?
a.存储位置不同:session 存储在服务器端:cookie 存储在浏览器端. b.安全性不同:cookie 安全性一般,在浏览器存储,可以被伪造和修改. c.容量和个数限制:cookie 有容量限 ...
- 说一下 JSP 的 4 种作用域?
page:代表与一个页面相关的对象和属性. request:代表与客户端发出的一个请求相关的对象和属性.一个请求可能跨越多个页面,涉及多个 Web 组件:需要在页面显示的临时数据可以置于此作用域. s ...
- 什么是JDBC的最佳实践?
a.数据库资源是非常昂贵的,用完了应该尽快关闭它.Connection, Statement, ResultSet等JDBC对象都有close方法,调用它就好了. b.养成在代码中显式关闭掉 ...
- ecnuoj 5039 摇钱树
5039. 摇钱树 题目链接:5039. 摇钱树 感觉在赛中的时候,完全没有考虑分数规划这种做法.同时也没有想到怎么拆这两个交和并的式子.有点难受-- 当出现分数使其尽量大或者小,并且如果修改其中直接 ...
- HBase 中的 JVM 与 GC
HBase中JVM基本配置 在JVM中,默认情况下会设置minimum heap size 为 1/64 可用物理内存,并为maximum heap size设置 1/4 的物理可用内存(不过在Jav ...
- 无业游民写的最后一个.net有关项目框架
理想很丰满,现实往往很残酷. 一种按照ddd的方式,根据业务来把自己需要的模块一个一个写出来,再按照模块把需要的接口一个一个的写出来,堆砌一些中间件,以及解耦的command,handler等等 ,一 ...
- Linux创建新用户时遇到的问题记录
创建新用户命令: useradd -d "/home/guest" -m -s "/bin/bash" guest 报错: useradd: cannot op ...
- 实测14us,Linux-RT实时性能及开发案例分享—基于全志T507-H国产平台
本文带来的是基于全志T507-H(硬件平台:创龙科技TLT507-EVM评估板),Linux-RT内核的硬件GPIO输入和输出实时性测试及应用开发案例的分享.本次演示的开发环境如下: Windows开 ...
- Win10 下安装使用easyocr图片识别工具
[前言] 最近在做图像识别相关的工作,找到了一个名为EasyOCR的pythoh 库. 使用过程中出现了一些问题,现做简单记录. [正文] 1. 安装EasyOCR 我用了最简单的方法:pip3 in ...
- Spring声明事务和分布式事务处理技术
Spring声明事务的两种方式 方式一.传统的编程式事务管理: 需要手动编写代码在业务层注入事务管理模板(一般不用) 方式二.基于 AOP 技术实现的声明式事务管理: Spring 声明式事务管理在底 ...