springboot项目配置参数请求及返回均为下划线方式

1,268次阅读
没有评论

1.请求参数为下划线
下划线方式参数请求,使用对象接收,则需要进行下划线转驼峰处理:
注意:请求接口不可使用@ModelAttribute接收对象,其原理和@RequestParam(“userId”)相同,请求参数根据后台所定义的接收参数名一致,不会进行驼峰转换处理。
1.自定义参数转换类,重写ServletRequestDataBinder中addBindValues方法,对参数进行处理

import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValue;
import org.springframework.web.bind.ServletRequestDataBinder;
import javax.servlet.ServletRequest;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**

  • 自定义CustomServletRequestDataBinder类,继承ServletRequestDataBinder,
  • 重写addBindValues方法,将入参通过underLineToCamel方法进行转换处理
    *
  • @author Tom
  • @date 2021-07-23
    */
    public class CustomServletRequestDataBinder extends ServletRequestDataBinder { private final Pattern underLinePattern = Pattern.compile(“_(\w)”); public CustomServletRequestDataBinder(final Object target) {
    super(target);
    } /**
    • 遍历请求参数对象 把请求参数的名转换成驼峰体,重写addBindValues绑定数值的方法
    • @param mpvs 请求参数列表
    • @param request 请求
      */
      @Override
      protected void addBindValues(MutablePropertyValues mpvs, ServletRequest request) {
      List pvs = mpvs.getPropertyValueList();
      List adds = new LinkedList<>();
      for (PropertyValue pv : pvs) {
      String name = pv.getName();
      String camel = this.underLineToCamel(name);
      if (!name.equals(camel)) {
      adds.add(new PropertyValue(camel, pv.getValue()));
      }
      }
      pvs.addAll(adds);
      }

    /**

    • 下划线转驼峰方法(如: 把app_id转换成appId)
    • @param value 要转换的下划线字符串
    • @return 驼峰体字符串
      */
      private String underLineToCamel(final String value) {
      final StringBuffer sb = new StringBuffer();
      Matcher m = this.underLinePattern.matcher(value);
      while (m.find()){
      m.appendReplacement(sb, m.group(1).toUpperCase());
      }
      m.appendTail(sb);
      return sb.toString();
      }

}

2.自定义属性处理器CustomServletModelAttributeMethodProcessor,继承ServletModelAttributeMethodProcessor重写bindRequestParameters方法,将bind方法替换为我们自定义的CustomServletRequestDataBinder

import org.springframework.util.Assert;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor;
import javax.servlet.ServletRequest;

/**

  • 自定义属性处理器: CustomServletModelAttributeMethodProcessor
  • 继承ServletModelAttributeMethodProcessor类,重写bindRequestParameters方法,
  • 将bind方法替换为我们自定义的CustomServletRequestDataBinder
    *
  • @author Tom
  • @date 2021-07-23
    */
    public class CustomServletModelAttributeMethodProcessor extends ServletModelAttributeMethodProcessor { public CustomServletModelAttributeMethodProcessor(final boolean annotationNotRequired) {
    super(annotationNotRequired);
    } @Override
    protected void bindRequestParameters(WebDataBinder binder, NativeWebRequest request) {
    ServletRequest servletRequest = request.getNativeRequest(ServletRequest.class);
    Assert.state(servletRequest != null, “No ServletRequest”);
    ServletRequestDataBinder servletBinder = (ServletRequestDataBinder) binder;
    /**
    * ServletModelAttributeMethodProcessor此处使用的servletBinder.bind(servletRequest)
    * 修改的目的是为了将ServletRequestDataBinder换成自定的CustomServletRequestDataBinder
    */
    new CustomServletRequestDataBinder(servletBinder.getTarget()).bind(servletRequest);
    }

}

3.实现WebMvcConfigurer类,重写addArgumentResolvers方法,引入CustomServletModelAttributeMethodProcessor

import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.xiaomi.config.request.CustomServletModelAttributeMethodProcessor;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.ArrayList;
import java.util.List;

/**

  • 添加自定义拦截器,消息转换器等
    *
  • @Author Tom
  • @Date 2021-07-22
  • @Description 实现WebMvcConfigurer接口
    */
    @Configuration
    public class WebConfig implements WebMvcConfigurer { /**
    • 配置入参转换器 – 重写HTTP请求参数转换规则(前端请求参数为下划线类型,自动转换为驼峰形式进行对象参数封装)
    • @param resolvers
      */
      @Override
      public void addArgumentResolvers(List resolvers) {
      resolvers.add(new CustomServletModelAttributeMethodProcessor(true));
      }
      }

      2.返回参数将驼峰转换为下划线
      使用Jackson方式处理:
      方式一:

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

/**

  • 解决前端和后台交互过程中时间格式问题,比如LocalDateTime中带”T的问题”
    *
  • @author Tom
  • @date 2021-07-22
    */
    @Configuration
    @ConditionalOnClass({ObjectMapper.class})
    @AutoConfigureBefore({JacksonAutoConfiguration.class})
    public class JacksonConfig { public JacksonConfig() {
    } @Bean
    public ObjectMapper getObjectMapper() {
    ObjectMapper objectMapper = new ObjectMapper();
    JavaTimeModule javaTimeModule = new JavaTimeModule();
    javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(“yyyy-MM-dd HH:mm:ss”)));
    javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(“yyyy-MM-dd”)));
    javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(“HH:mm:ss”)));
    javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(“yyyy-MM-dd HH:mm:ss”)));
    javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(“yyyy-MM-dd”)));
    javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(“HH:mm:ss”)));
    objectMapper.registerModule(javaTimeModule);
    SimpleModule simpleModule = new SimpleModule();
    simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
    simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
    simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
    simpleModule.addSerializer(BigDecimal.class, ToStringSerializer.instance);
    objectMapper.registerModule(simpleModule);
    objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
    objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);//对于fastjson缺省使用SnakeCase策略(统一对象参数下划线形式)
    objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    return objectMapper;
    }
    }

上面代码中,为我本地配置的JacksonConfig,其中将对象参数驼峰形式转换为下划线的代码仅一句:
PS:由于Jackson本身已经封装好,所以需要情况下直接配置即可

objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);//对于fastjson缺省使用SnakeCase策略(统一对象参数下划线形式)

方式二:
在配置文件中修改:

spring:
application:
name:
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
default-property-inclusion: non_null
property-naming-strategy: SNAKE_CASE #对于fastjson缺省使用SnakeCase策略(统一对象参数下划线形式)

property-naming-strategy: SNAKE_CASE
fastjson缺省使用四种策略:

属性名策略说明:

CamelCase策略,Java对象属性:personId,序列化后属性:persionId

PascalCase策略,Java对象属性:personId,序列化后属性:PersonId

SnakeCase策略,Java对象属性:personId,序列化后属性:person_id

KebabCase策略,Java对象属性:personId,序列化后属性:person-id

正文完
可以使用微信扫码关注公众号(ID:xzluomor)
post-qrcode
 0
评论(没有评论)

文心AIGC

2024 年 6 月
 12
3456789
10111213141516
17181920212223
24252627282930
文心AIGC
文心AIGC
人工智能ChatGPT,AIGC指利用人工智能技术来生成内容,其中包括文字、语音、代码、图像、视频、机器人动作等等。被认为是继PGC、UGC之后的新型内容创作方式。AIGC作为元宇宙的新方向,近几年迭代速度呈现指数级爆发,谷歌、Meta、百度等平台型巨头持续布局
文章搜索
热门文章
潞晨尤洋:日常办公没必要上私有模型,这三类企业才需要 | MEET2026

潞晨尤洋:日常办公没必要上私有模型,这三类企业才需要 | MEET2026

潞晨尤洋:日常办公没必要上私有模型,这三类企业才需要 | MEET2026 Jay 2025-12-22 09...
面向「空天具身智能」,北航团队提出星座规划新基准丨NeurIPS’25

面向「空天具身智能」,北航团队提出星座规划新基准丨NeurIPS’25

面向「空天具身智能」,北航团队提出星座规划新基准丨NeurIPS’25 鹭羽 2025-12-13 22:37...
5天连更5次,可灵AI年末“狂飙式”升级

5天连更5次,可灵AI年末“狂飙式”升级

5天连更5次,可灵AI年末“狂飙式”升级 思邈 2025-12-10 14:28:37 来源:量子位 让更大规...
钉钉又发新版本!把 AI 搬进每一次对话和会议

钉钉又发新版本!把 AI 搬进每一次对话和会议

钉钉又发新版本!把 AI 搬进每一次对话和会议 梦晨 2025-12-11 15:33:51 来源:量子位 A...
商汤Seko2.0重磅发布,合作短剧登顶抖音AI短剧榜No.1

商汤Seko2.0重磅发布,合作短剧登顶抖音AI短剧榜No.1

商汤Seko2.0重磅发布,合作短剧登顶抖音AI短剧榜No.1 十三 2025-12-15 14:13:14 ...
最新评论
ufabet ufabet มีเกมให้เลือกเล่นมากมาย: เกมเดิมพันหลากหลาย ครบทุกค่ายดัง
tornado crypto mixer tornado crypto mixer Discover the power of privacy with TornadoCash! Learn how this decentralized mixer ensures your transactions remain confidential.
ดูบอลสด ดูบอลสด Very well presented. Every quote was awesome and thanks for sharing the content. Keep sharing and keep motivating others.
ดูบอลสด ดูบอลสด Pretty! This has been a really wonderful post. Many thanks for providing these details.
ดูบอลสด ดูบอลสด Pretty! This has been a really wonderful post. Many thanks for providing these details.
ดูบอลสด ดูบอลสด Hi there to all, for the reason that I am genuinely keen of reading this website’s post to be updated on a regular basis. It carries pleasant stuff.
Obrazy Sztuka Nowoczesna Obrazy Sztuka Nowoczesna Thank you for this wonderful contribution to the topic. Your ability to explain complex ideas simply is admirable.
ufabet ufabet Hi there to all, for the reason that I am genuinely keen of reading this website’s post to be updated on a regular basis. It carries pleasant stuff.
ufabet ufabet You’re so awesome! I don’t believe I have read a single thing like that before. So great to find someone with some original thoughts on this topic. Really.. thank you for starting this up. This website is something that is needed on the internet, someone with a little originality!
ufabet ufabet Very well presented. Every quote was awesome and thanks for sharing the content. Keep sharing and keep motivating others.
热评文章
读懂2025中国AI走向!公司×产品×人物×方案,最值得关注的都在这里了

读懂2025中国AI走向!公司×产品×人物×方案,最值得关注的都在这里了

读懂2025中国AI走向!公司×产品×人物×方案,最值得关注的都在这里了 衡宇 2025-12-10 12:3...
5天连更5次,可灵AI年末“狂飙式”升级

5天连更5次,可灵AI年末“狂飙式”升级

5天连更5次,可灵AI年末“狂飙式”升级 思邈 2025-12-10 14:28:37 来源:量子位 让更大规...
戴尔 x OpenCSG,推出⾯向智能初创企业的⼀体化 IT 基础架构解决方案

戴尔 x OpenCSG,推出⾯向智能初创企业的⼀体化 IT 基础架构解决方案

戴尔 x OpenCSG,推出⾯向智能初创企业的⼀体化 IT 基础架构解决方案 十三 2025-12-10 1...
九章云极独揽量子位三项大奖:以“一度算力”重构AI基础设施云格局

九章云极独揽量子位三项大奖:以“一度算力”重构AI基础设施云格局

九章云极独揽量子位三项大奖:以“一度算力”重构AI基础设施云格局 量子位的朋友们 2025-12-10 18:...
乐奇Rokid这一年,一路狂飙不回头

乐奇Rokid这一年,一路狂飙不回头

乐奇Rokid这一年,一路狂飙不回头 梦瑶 2025-12-10 20:41:15 来源:量子位 梦瑶 发自 ...