网站备案取消 后果,wordpress订阅地址,html音乐网站源码,wordpress 数据库发布SpringBoot或OpenFeign中 Jackson 配置参数名蛇形、小驼峰、大驼峰、自定义命名
前言
在调用外部接口时#xff0c;对方给出的接口文档中#xff0c;入参参数名一会大写加下划线#xff0c;一会又是驼峰命名。 示例如下#xff1a;
{MOF_DIV_CODE: xx…SpringBoot或OpenFeign中 Jackson 配置参数名蛇形、小驼峰、大驼峰、自定义命名
前言
在调用外部接口时对方给出的接口文档中入参参数名一会大写加下划线一会又是驼峰命名。 示例如下
{MOF_DIV_CODE: xxxxx,.....yyyList: [VOU_DET_ID: xxxxx,......]
}至于为什么非要这样写不去深究它。背后默默 diss 一下。 当我利用OpenFeign调用接口时传入参数定义的DTO对象都是大写的如下
public class XxxReqDTO {private String MOF_DIV_CODE;....private String XXX_XXX_XXX....private ListYyyReqDTO yyyList;
}
/**
* 这里没有使用Data注解
* 用IDEA生成的setter()、getter()方法
* 如果Data 生成的出现问题可以改成自己生成。
**/也配置了MyBatis-Plus不自动转驼峰命名
mybatis-plus:configuration:map-underscore-to-camel-case: false但是控制台打印入参时却变成了小写、下划线、大写示例如下
{mOF_DIV_CODE : xxxxx......yyyList:[vOU_DET_ID: xxxxx,]
}因为之前遇到过类似的问题想到时SpringBoot Jackson序列化、反序列化及配置问题。 以下记录我的解决方法与过程。
解决办法
数据库字段重命名
这里以PostgreSQL为例本次开发使用指定数据库其他数据库自测下。本方法为偷懒做法多的时间用于摸鱼
select
pk_detail VOU_ID
from table;在查询时直接重命名字段记住一定要加引号不然数据库里查询结果列名字段也会是小写。 不加引号效果如下 这样使得让查询的结果与定义入参对象都是大写下划线的参数名。
配置Jackson
特地去看了下 PropertyNamingStrategy 的源码没找到我想要的命名方式。 源码如下
package com.fasterxml.jackson.databind;import com.fasterxml.jackson.databind.cfg.MapperConfig;
import com.fasterxml.jackson.databind.introspect.AnnotatedField;
import com.fasterxml.jackson.databind.introspect.AnnotatedMethod;
import com.fasterxml.jackson.databind.introspect.AnnotatedParameter;/*** Class that defines how names of JSON properties (external names)* are derived from names of POJO methods and fields (internal names),* in cases where no explicit annotations exist for naming.* Methods are passed information about POJO member for which name is needed,* as well as default name that would be used if no custom strategy was used.*p* Default (empty) implementation returns suggested (implicit or default) name unmodified*p* Note that the strategy is guaranteed to be called once per logical property* (which may be represented by multiple members; such as pair of a getter and* a setter), but may be called for each: implementations should not count on* exact number of times, and should work for any member that represent a* property.* Also note that calls are made during construction of serializers and deserializers* which are typically cached, and not for every time serializer or deserializer* is called.*p* In absence of a registered custom strategy, the default Java property naming strategy* is used, which leaves field names as is, and removes set/get/is prefix* from methods (as well as lower-cases initial sequence of capitalized* characters).*p* NOTE! Since 2.12 sub-classes defined here (as well as static singleton instances thereof)* are deprecated due to* a hrefhttps://github.com/FasterXML/jackson-databind/issues/2715databind#2715/a.* Please use constants and classes in {link PropertyNamingStrategies} instead.* */
SuppressWarnings(serial)
public class PropertyNamingStrategy // NOTE: was abstract until 2.7implements java.io.Serializable
{private static final long serialVersionUID 2L;/*** deprecated Since 2.12 deprecated. Use {link PropertyNamingStrategies#LOWER_CAMEL_CASE} instead.* See* a hrefhttps://github.com/FasterXML/jackson-databind/issues/2715databind#2715/a* for reasons for deprecation.*/Deprecated // since 2.12public static final PropertyNamingStrategy LOWER_CAMEL_CASE new PropertyNamingStrategy();/*** deprecated Since 2.12 deprecated. Use {link PropertyNamingStrategies#UPPER_CAMEL_CASE} instead.* See* a hrefhttps://github.com/FasterXML/jackson-databind/issues/2715databind#2715/a* for reasons for deprecation.*/Deprecated // since 2.12public static final PropertyNamingStrategy UPPER_CAMEL_CASE new UpperCamelCaseStrategy();/*** deprecated Since 2.12 deprecated. Use {link PropertyNamingStrategies#SNAKE_CASE} instead.* See* a hrefhttps://github.com/FasterXML/jackson-databind/issues/2715databind#2715/a* for reasons for deprecation.*/Deprecated // since 2.12public static final PropertyNamingStrategy SNAKE_CASE new SnakeCaseStrategy();/*** deprecated Since 2.12 deprecated. Use {link PropertyNamingStrategies#LOWER_CASE} instead.* See* a hrefhttps://github.com/FasterXML/jackson-databind/issues/2715databind#2715/a* for reasons for deprecation.*/Deprecated // since 2.12public static final PropertyNamingStrategy LOWER_CASE new LowerCaseStrategy();/*** deprecated Since 2.12 deprecated. Use {link PropertyNamingStrategies#KEBAB_CASE} instead.* See* a hrefhttps://github.com/FasterXML/jackson-databind/issues/2715databind#2715/a* for reasons for deprecation.*/Deprecated // since 2.12public static final PropertyNamingStrategy KEBAB_CASE new KebabCaseStrategy();/*** deprecated Since 2.12 deprecated. Use {link PropertyNamingStrategies#LOWER_DOT_CASE} instead.* See* a hrefhttps://github.com/FasterXML/jackson-databind/issues/2715databind#2715/a* for reasons for deprecation.*/Deprecated // since 2.12public static final PropertyNamingStrategy LOWER_DOT_CASE new LowerDotCaseStrategy();/*/**********************************************************/* API/***********************************************************//*** Method called to find external name (name used in JSON) for given logical* POJO property,* as defined by given field.* * param config Configuration in used: either codeSerializationConfig/code* or codeDeserializationConfig/code, depending on whether method is called* during serialization or deserialization* param field Field used to access property* param defaultName Default name that would be used for property in absence of custom strategy* * return Logical name to use for property that the field represents*/public String nameForField(MapperConfig? config, AnnotatedField field,String defaultName){return defaultName;}/*** Method called to find external name (name used in JSON) for given logical* POJO property,* as defined by given getter method; typically called when building a serializer.* (but not always -- when using getter-as-setter, may be called during* deserialization)* * param config Configuration in used: either codeSerializationConfig/code* or codeDeserializationConfig/code, depending on whether method is called* during serialization or deserialization* param method Method used to access property.* param defaultName Default name that would be used for property in absence of custom strategy* * return Logical name to use for property that the method represents*/public String nameForGetterMethod(MapperConfig? config, AnnotatedMethod method,String defaultName){return defaultName;}/*** Method called to find external name (name used in JSON) for given logical* POJO property,* as defined by given setter method; typically called when building a deserializer* (but not necessarily only then).* * param config Configuration in used: either codeSerializationConfig/code* or codeDeserializationConfig/code, depending on whether method is called* during serialization or deserialization* param method Method used to access property.* param defaultName Default name that would be used for property in absence of custom strategy* * return Logical name to use for property that the method represents*/public String nameForSetterMethod(MapperConfig? config, AnnotatedMethod method,String defaultName){return defaultName;}/*** Method called to find external name (name used in JSON) for given logical* POJO property,* as defined by given constructor parameter; typically called when building a deserializer* (but not necessarily only then).* * param config Configuration in used: either codeSerializationConfig/code* or codeDeserializationConfig/code, depending on whether method is called* during serialization or deserialization* param ctorParam Constructor parameter used to pass property.* param defaultName Default name that would be used for property in absence of custom strategy*/public String nameForConstructorParameter(MapperConfig? config, AnnotatedParameter ctorParam,String defaultName){return defaultName;}/*/**********************************************************/* Public base class for simple implementations/***********************************************************//*** deprecated Since 2.12 deprecated. See* a hrefhttps://github.com/FasterXML/jackson-databind/issues/2715databind#2715/a* for reasons for deprecation.*/Deprecatedpublic static abstract class PropertyNamingStrategyBase extends PropertyNamingStrategy{Overridepublic String nameForField(MapperConfig? config, AnnotatedField field, String defaultName){return translate(defaultName);}Overridepublic String nameForGetterMethod(MapperConfig? config, AnnotatedMethod method, String defaultName){return translate(defaultName);}Overridepublic String nameForSetterMethod(MapperConfig? config, AnnotatedMethod method, String defaultName){return translate(defaultName);}Overridepublic String nameForConstructorParameter(MapperConfig? config, AnnotatedParameter ctorParam,String defaultName){return translate(defaultName);}public abstract String translate(String propertyName);/*** Helper method to share implementation between snake and dotted case.*/protected static String translateLowerCaseWithSeparator(final String input, final char separator){if (input null) {return input; // garbage in, garbage out}final int length input.length();if (length 0) {return input;}final StringBuilder result new StringBuilder(length (length 1));int upperCount 0;for (int i 0; i length; i) {char ch input.charAt(i);char lc Character.toLowerCase(ch);if (lc ch) { // lower-case letter means we can get new word// but need to check for multi-letter upper-case (acronym), where assumption// is that the last upper-case char is start of a new wordif (upperCount 1) {// so insert hyphen before the last character nowresult.insert(result.length() - 1, separator);}upperCount 0;} else {// Otherwise starts new word, unless beginning of stringif ((upperCount 0) (i 0)) {result.append(separator);}upperCount;}result.append(lc);}return result.toString();}}/*/**********************************************************/* Standard implementations /***********************************************************//*** deprecated Since 2.12 use {link PropertyNamingStrategies.SnakeCaseStrategy} instead* (see* a hrefhttps://github.com/FasterXML/jackson-databind/issues/2715databind#2715/a* for reason for deprecation)*/Deprecated // since 2.12public static class SnakeCaseStrategy extends PropertyNamingStrategyBase{Overridepublic String translate(String input){if (input null) return input; // garbage in, garbage outint length input.length();StringBuilder result new StringBuilder(length * 2);int resultLength 0;boolean wasPrevTranslated false;for (int i 0; i length; i){char c input.charAt(i);if (i 0 || c ! _) // skip first starting underscore{if (Character.isUpperCase(c)){if (!wasPrevTranslated resultLength 0 result.charAt(resultLength - 1) ! _){result.append(_);resultLength;}c Character.toLowerCase(c);wasPrevTranslated true;}else{wasPrevTranslated false;}result.append(c);resultLength;}}return resultLength 0 ? result.toString() : input;}}/*** deprecated Since 2.12 use {link PropertyNamingStrategies.UpperCamelCaseStrategy} instead* (see* a hrefhttps://github.com/FasterXML/jackson-databind/issues/2715databind#2715/a* for reason for deprecation)*/Deprecated // since 2.12public static class UpperCamelCaseStrategy extends PropertyNamingStrategyBase{/*** Converts camelCase to PascalCase* * For example, userName would be converted to* UserName.** param input formatted as camelCase string* return input converted to PascalCase format*/Overridepublic String translate(String input) {if (input null || input.isEmpty()){return input; // garbage in, garbage out}// Replace first lower-case letter with upper-case equivalentchar c input.charAt(0);char uc Character.toUpperCase(c);if (c uc) {return input;}StringBuilder sb new StringBuilder(input);sb.setCharAt(0, uc);return sb.toString();}}/*** deprecated Since 2.12 use {link PropertyNamingStrategies.LowerCaseStrategy} instead* (see* a hrefhttps://github.com/FasterXML/jackson-databind/issues/2715databind#2715/a* for reason for deprecation)*/Deprecated // since 2.12public static class LowerCaseStrategy extends PropertyNamingStrategyBase{Overridepublic String translate(String input) {return input.toLowerCase();}}/*** deprecated Since 2.12 use {link PropertyNamingStrategies.KebabCaseStrategy} instead* (see* a hrefhttps://github.com/FasterXML/jackson-databind/issues/2715databind#2715/a* for reason for deprecation)*/Deprecated // since 2.12public static class KebabCaseStrategy extends PropertyNamingStrategyBase{Overridepublic String translate(String input) {return translateLowerCaseWithSeparator(input, -);}}/*** deprecated Since 2.12 use {link PropertyNamingStrategies.LowerDotCaseStrategy} instead* (see* a hrefhttps://github.com/FasterXML/jackson-databind/issues/2715databind#2715/a* for reason for deprecation)*/Deprecated // since 2.12public static class LowerDotCaseStrategy extends PropertyNamingStrategyBase {Overridepublic String translate(String input){return translateLowerCaseWithSeparator(input, .);}}/*/**********************************************************/* Deprecated variants, aliases/***********************************************************//*** deprecated Since 2.7 use {link PropertyNamingStrategies#SNAKE_CASE} instead.*/Deprecated // since 2.7public static final PropertyNamingStrategy CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES SNAKE_CASE;/*** deprecated Since 2.7 use {link PropertyNamingStrategies#UPPER_CAMEL_CASE} instead;*/Deprecated // since 2.7public static final PropertyNamingStrategy PASCAL_CASE_TO_CAMEL_CASE UPPER_CAMEL_CASE;/*** deprecated In 2.7 use {link PropertyNamingStrategies.SnakeCaseStrategy} instead*/Deprecated // since 2.7public static class LowerCaseWithUnderscoresStrategy extends SnakeCaseStrategy {}/*** deprecated In 2.7 use {link PropertyNamingStrategies.UpperCamelCaseStrategy} instead*/Deprecated // since 2.7public static class PascalCaseStrategy extends UpperCamelCaseStrategy { }
}
命名方式说明
LOWER_CAMEL_CASE小驼峰命名法例如userName、userName
UPPER_CAMEL_CASE大驼峰命名法 例如:ServiceDiscovery、LruCacheFactory
SNAKE_CASE蛇形命名法就是常用的小写字母加下划线命名法例如 user_name
LOWER_CASE 小写命名法字母均小写单词之间通常用下划线_连接例如first_name
KEBAB_CASE 采用小写字母和短横线-连接单词形似烤肉串例如user-profile
LOWER_DOT_CASE (所有字母均为小写并用点.连接字符的命名方式) 例如lower.case
// SNAKE_CASE 和 LOWER_CASE 似乎一样不知道理解没自行百度一下。 以上都不是我想要那就自定义。
自定义命名方式
UpperSnakeCaseStrategy.java import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.cfg.MapperConfig;
import com.fasterxml.jackson.databind.introspect.AnnotatedField;
import com.fasterxml.jackson.databind.introspect.AnnotatedMethod;/*** 配置字段名全大写和下划线分隔SCREAMING_SNAKE_CASE 大写蛇形命名法*/
public class UpperSnakeCaseStrategy extends PropertyNamingStrategy {Overridepublic String nameForField(MapperConfig? config, AnnotatedField field, String defaultName) {return toUpperSnakeCase(defaultName);}Overridepublic String nameForGetterMethod(MapperConfig? config, AnnotatedMethod method, String defaultName) {return toUpperSnakeCase(defaultName);}Overridepublic String nameForSetterMethod(MapperConfig? config, AnnotatedMethod method, String defaultName) {return toUpperSnakeCase(defaultName);}private String toUpperSnakeCase(String input) {if (input null) return null;return input.replaceAll(([a-z0-9])([A-Z]), $1_$2).toUpperCase();}
}全局配置Jackson import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;Configuration
public class JacksonConfig {Beanpublic ObjectMapper objectMapper() {ObjectMapper mapper new ObjectMapper();// 配置大写蛇形命名法mapper.setPropertyNamingStrategy(new UpperSnakeCaseStrategy());return mapper;}
}单个类配置
JsonNaming(UpperSnakeCaseStrategy.class)
public class Xxx{}针对这一个小驼峰命名特殊处理 JsonProperty(yyylList)private ListYyyReqDTO yyyList;对需要保留驼峰命名的字段单独使用JsonProperty注解 针对蛇形命名、小驼峰、大驼峰等正常的命名字段单独使用JsonProperty注解去实现。 例如
JsonProperty(yyy_list)
JsonProperty(yyyList)
JsonProperty(YyyList)蛇形首字母大写
自测自测应该也是能行的。 Jackson 提供了UPPER_CAMEL_CASE策略但需要结合SNAKE_CASE进行额外配置
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;Configuration
public class JacksonConfig {Beanpublic ObjectMapper objectMapper() {ObjectMapper mapper new ObjectMapper();// 配置大写蛇形命名法mapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE.withUpperCaseFirstLetter(true) // 首字母大写return mapper;// 注意这种方式生成的是 My_Field_Name如果需要全大写还需自定义}
}