PS:本篇文章主要记录的是本人在开发过程中所遇到的一些问题及解决方法,不喜勿喷,感谢大家支持。
一、下划线驼峰的互转,应用于RequestBody与restTemplate远程调用
1.前后端RequestBody与实体映射的下划线/驼峰互转,采用SpringBoot自带的jackson
@Configuration
public class AdditionalConfig {
@Bean
public Jackson2ObjectMapperBuilderCustomizer customJackson() {
Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer = (jackson2ObjectMapperBuilder) -> {
//若属性为null,则不将该属性返回给前端
jackson2ObjectMapperBuilder.serializationInclusion(JsonInclude.Include.NON_NULL);
//若遇到未知属性是否引起报错
jackson2ObjectMapperBuilder.failOnUnknownProperties(false);
//前端参数格式:
//SNAKE_CASE 下划线格式
//UPPER_CAMEL_CASE 每个单词首字母大写
//LOWER_CAMEL_CASE 第一个单词首字母小写,后续首字母大写
//LOWER_CASE 全部单词小写
//KEBAB_CASE 横线分割
jackson2ObjectMapperBuilder.propertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
};
return jackson2ObjectMapperBuilderCustomizer;
}
}
2.RestTemplate下划线驼峰互转:调用 RestTemplate(List<HttpMessageConverter<?>> messageConverters) 构造方法
1)方式一:使用已有的MappingJackson2HttpMessageConverter实例,传入ObjectMapper
Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder = new Jackson2ObjectMapperBuilder();
jackson2ObjectMapperBuilder.serializationInclusion(JsonInclude.Include.NON_NULL);
jackson2ObjectMapperBuilder.propertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
jackson2ObjectMapperBuilder.failOnUnknownProperties(false);
ObjectMapper mapper = jackson2ObjectMapperBuilder.build();
List<HttpMessageConverter<?>> messageConverters = new ArrayList<>();
messageConverters.add(new MappingJackson2HttpMessageConverter(mapper));
RestTemplate restTemplate = new RestTemplate(messageConverters);
2)方式二:重写自己的MessageConverter
public class MyMessageConverter<T> extends AbstractHttpMessageConverter<T> {
public MyMessageConverter(){
super(new MediaType("application", "json", Charset.forName("UTF-8")));
}
/**
* 是否应用于所有类型
* @param aClass
* @return
*/
@Override
protected boolean supports(Class<?> aClass) {
return true;
}
/**
* 转java对象
* @param aClass
* @param httpInputMessage
* @return
* @throws IOException
* @throws HttpMessageNotReadableException
*/
@Override
protected T readInternal(Class<? extends T> aClass, HttpInputMessage httpInputMessage)
throws IOException, HttpMessageNotReadableException {
Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder = new Jackson2ObjectMapperBuilder();
jackson2ObjectMapperBuilder.serializationInclusion(JsonInclude.Include.NON_NULL);
jackson2ObjectMapperBuilder.propertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
jackson2ObjectMapperBuilder.failOnUnknownProperties(false);
ObjectMapper mapper = jackson2ObjectMapperBuilder.build();
String str = new String(ByteStreams.toByteArray(httpInputMessage.getBody()));
T object = mapper.readValue(str,aClass);
return object;
}
/**
* 输出java对象
* @param t
* @param httpOutputMessage
* @throws IOException
* @throws HttpMessageNotWritableException
*/
@Override
protected void writeInternal(T t, HttpOutputMessage httpOutputMessage)
throws IOException, HttpMessageNotWritableException {
httpOutputMessage.getBody().write(t.toString().getBytes());
}
}
二、坑点杂记:
1.@Component 和 @Configuration管理的@bean
@Configuration
public class MyBeanConfig {
@Bean
public Country country(){
return new Country();
}
@Bean
public UserInfo userInfo(){
return new UserInfo(country());
}
}
通过new方式,@Configuration中管理的实例类似于单例,每次调用都是同一个地址。
通过new方式,@Component多次注入会得到不同的实例地址。
@Component
public class MyBeanConfig {
@Autowired
private Country country;
@Bean
public Country country(){
return new Country();
}
@Bean
public UserInfo userInfo(){
return new UserInfo(country);
}
}
使用@AutoWired得到的是同一个实例
2.@Bean注解默认使用注解下的方法名作为bean的id,可以通过@Bean(name=“”)进行显式命名