一般普通转化使用:
@Configuration public class WebMvcConfig extends WebMvcConfigurerAdapter { /** * 统一输出风格 */ @Override public void extendMessageConverters(List<HttpMessageConverter<?>> converters) { for (int i = 0; i < converters.size(); i++) { if (converters.get(i) instanceof MappingJackson2HttpMessageConverter) { ObjectMapper objectMapper = new ObjectMapper(); // 统一返回数据的输出风格 objectMapper.setPropertyNamingStrategy(new PropertyNamingStrategy.SnakeCaseStrategy()); //普通转换: firstName --> first_name //如果字段值为null 不返回 //objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS); objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+8")); MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); converter.setObjectMapper(objectMapper); converters.set(i, converter); break; } } } }解决带数字的问题
WebMvcConfig
import com.csc.config.webMvcConfig.PropertyNamingStrategyConfig; 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 org.springframework.context.annotation.Configuration; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import java.util.List; import java.util.TimeZone; @Configuration public class WebMvcConfig extends WebMvcConfigurerAdapter { /** * 统一输出风格 */ @Override public void extendMessageConverters(List<HttpMessageConverter<?>> converters) { for (int i = 0; i < converters.size(); i++) { if (converters.get(i) instanceof MappingJackson2HttpMessageConverter) { ObjectMapper objectMapper = new ObjectMapper(); // 统一返回数据的输出风格 //objectMapper.setPropertyNamingStrategy(new PropertyNamingStrategy.SnakeCaseStrategy()); //普通转换: firstName --> first_name //缺陷: 如: returnThisYear20 只能转换成:return_this_year20 可是我们想要的结果是:return_this_year_20 //使用自己重写的方法 objectMapper.setPropertyNamingStrategy(new PropertyNamingStrategyConfig.NumCaseStrategy()); //如果字段值为null 不返回 //objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS); objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+8")); MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); converter.setObjectMapper(objectMapper); converters.set(i, converter); break; } } } }PropertyNamingStrategyConfig
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; import com.fasterxml.jackson.databind.introspect.AnnotatedParameter; import java.io.Serializable; import java.util.regex.Pattern; public class PropertyNamingStrategyConfig implements Serializable { public static final PropertyNamingStrategy SNAKE_CASE = new PropertyNamingStrategy.SnakeCaseStrategy(); public static final PropertyNamingStrategy UPPER_CAMEL_CASE = new PropertyNamingStrategy.UpperCamelCaseStrategy(); public static final PropertyNamingStrategy LOWER_CAMEL_CASE = new PropertyNamingStrategy(); public static final PropertyNamingStrategy LOWER_CASE = new PropertyNamingStrategy.LowerCaseStrategy(); public static final PropertyNamingStrategy KEBAB_CASE = new PropertyNamingStrategy.KebabCaseStrategy(); //依照 PropertyNamingStrategy.SnakeCaseStrategy() 新增数字方法 public static final PropertyNamingStrategy NUM_CASE = new PropertyNamingStrategyConfig.NumCaseStrategy(); /** @deprecated */ @Deprecated public static final PropertyNamingStrategy CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES; /** @deprecated */ @Deprecated public static final PropertyNamingStrategy PASCAL_CASE_TO_CAMEL_CASE; public PropertyNamingStrategyConfig() { } public String nameForField(MapperConfig<?> config, AnnotatedField field, String defaultName) { return defaultName; } public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) { return defaultName; } public String nameForSetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) { return defaultName; } public String nameForConstructorParameter(MapperConfig<?> config, AnnotatedParameter ctorParam, String defaultName) { return defaultName; } static { CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES = SNAKE_CASE; PASCAL_CASE_TO_CAMEL_CASE = UPPER_CAMEL_CASE; } /** @deprecated */ @Deprecated public static class PascalCaseStrategy extends PropertyNamingStrategy.UpperCamelCaseStrategy { public PascalCaseStrategy() { } } /** @deprecated */ @Deprecated public static class LowerCaseWithUnderscoresStrategy extends PropertyNamingStrategy.SnakeCaseStrategy { public LowerCaseWithUnderscoresStrategy() { } } public static class KebabCaseStrategy extends PropertyNamingStrategy.PropertyNamingStrategyBase { public KebabCaseStrategy() { } public String translate(String input) { if (input == null) { return input; } else { int length = input.length(); if (length == 0) { return input; } else { 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) { if (upperCount > 1) { result.insert(result.length() - 1, '-'); } upperCount = 0; } else { if (upperCount == 0 && i > 0) { result.append('-'); } ++upperCount; } result.append(lc); } return result.toString(); } } } } public static class LowerCaseStrategy extends PropertyNamingStrategy.PropertyNamingStrategyBase { public LowerCaseStrategy() { } public String translate(String input) { return input.toLowerCase(); } } public static class UpperCamelCaseStrategy extends PropertyNamingStrategy.PropertyNamingStrategyBase { public UpperCamelCaseStrategy() { } public String translate(String input) { if (input != null && input.length() != 0) { char c = input.charAt(0); char uc = Character.toUpperCase(c); if (c == uc) { return input; } else { StringBuilder sb = new StringBuilder(input); sb.setCharAt(0, uc); return sb.toString(); } } else { return input; } } } public static class SnakeCaseStrategy extends PropertyNamingStrategy.PropertyNamingStrategyBase { public SnakeCaseStrategy() { } public String translate(String input) { if (input == null) { return input; } else { int 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 != '_') { 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; } } } public abstract static class PropertyNamingStrategyBase extends PropertyNamingStrategy { public PropertyNamingStrategyBase() { } public String nameForField(MapperConfig<?> config, AnnotatedField field, String defaultName) { return this.translate(defaultName); } public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) { return this.translate(defaultName); } public String nameForSetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) { return this.translate(defaultName); } public String nameForConstructorParameter(MapperConfig<?> config, AnnotatedParameter ctorParam, String defaultName) { return this.translate(defaultName); } public abstract String translate(String var1); } public static class NumCaseStrategy extends PropertyNamingStrategy.SnakeCaseStrategy { public NumCaseStrategy() { } public String translate(String input) { if (input == null) { return input; } else { int 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 != '_') { if (Character.isUpperCase(c)) { if (!wasPrevTranslated && resultLength > 0 && result.charAt(resultLength - 1) != '_') { result.append('_'); ++resultLength; } c = Character.toLowerCase(c); wasPrevTranslated = true; } else if(!wasPrevTranslated && resultLength > 0 && result.charAt(resultLength - 1) != '_' && Pattern.compile("^-?\\d+(\\.\\d+)?$").matcher(String.valueOf(c)).matches() && !Pattern.compile("^-?\\d+(\\.\\d+)?$").matcher(String.valueOf(input.charAt(i-1))).matches() ){ //新增数字判断 // Pattern.compile("^-?\\d+(\\.\\d+)?$").matcher(String.valueOf(c)).matches() && !Pattern.compile("^-?\\d+(\\.\\d+)?$").matcher(String.valueOf(input.charAt(i-1))).matches() // 表示 用正则表达式判断 当前位是数字 且 前一位不是数字 result.append('_'); ++resultLength; } else { wasPrevTranslated = false; } result.append(c); ++resultLength; } } return resultLength > 0 ? result.toString() : input; } } } }这样对于一般的转化都没问题 如:firstName转成first_name, firstName20转化成first_name_20, first20Name转化成first_20_name
这当中还有转换缺陷在于: 1.两个相连接的大写字母不能很好转换: 对个别的类似于: firstNameTTest只能转换成first_name_ttest,而我们想要的结果是first_name_t_test,这种情况下我暂时使用的方法是在实体类字段上面加@JsonProperty(“first_name_t_test”)注解来转化 2.一个大写字母后跟一个数字不能很好地转换: 对于个别的如:firstNameT20只能转换成first_name_t20,而我们想要的结果是first_name_t_20,这种情况下我暂时使用的方法是在实体类字段上加上@JsonProperty(“first_name_t_20”)注解来转化
最后:希望大家有好的解决这两个缺陷的方法,一起来沟通交流学习