Spring boot project, how to gracefully replace the blank value in the interface argument with null value?

itread01 2021-01-14 17:08:28
spring boot project gracefully replace


Problem occurs

When our company generated code , Query list unification is used setEntity() , The query is written as follows :

public List<BasReservoirArea> selectList(BasReservoirArea basReservoirArea) { QueryWrapper<BasReservoirArea> where = new QueryWrapper<>(); where.setEntity(basReservoirArea); return baseMapper.selectList(where);}

 

The query method is Get Method :

The front end is through url From the adduct , If one of the quotations is empty , Because of setEntity() It doesn't filter blanks , Execute sql When Will bring "" As an argument, as a query condition , There is a problem with the query :

So I want to change the blank to null To solve this problem .

Initial resolution

It's natural at first to think of setEntity Judge before , If BasReservoirArea In this example, if the value of a field is blank, it is set to null

//1. The object turns mapMap<Object, Object> map = MapUtil.beanToMap(test);//2. Remove null values MapUtil.removeNullValue(map);//3.map Turn back the object Test entity = JSON.parseObject(JSON.toJSONString(map), Test.class);

 

The tool classes used are as follows

/*** Convert object properties to map Combine */public static <T> Map<Object, Object> beanToMap(T bean) { Map<Object, Object> map = new HashMap<>(); if (bean != null) { BeanMap beanMap = BeanMap.create(bean); for (Object key : beanMap.keySet()) { map.put(key, beanMap.get(key)); } } return map;}/*** remove map Medium value Null value ** @param map* @return*/public static void removeNullValue(Map map) { Set set = map.keySet(); for (Iterator iterator = set.iterator(); iterator.hasNext(); ) { Object obj = (Object) iterator.next(); Object value = (Object) map.get(obj); remove(value, iterator); }}

 

The problem is solved .

Optimization

I feel that the above solutions are not professional enough , Not elegant enough , So find a better solution first , When the back end receives the index value , If the reception is blank , Set directly to null, So there's no need to switch again .

There are two things to consider in solving the problem , One is the front end through Get Ask for , With arguments on the path ; The other is Post Ask for , With Request Message .

Post Ask for a newspaper style

As I am familiar with Post The transformation of the style of Chinese newspaper , Know is MappingJackson2HttpMessageConverter Combine Jackson Realizing the transformation of newspaper style into an example , And also studied Jackson, So the solution is as follows

Establish a target for String.class Of Jackson The inverse sequence class of :

public class StringDescrializer extends JsonDeserializer<String> { @Override public String deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { String value = jsonParser.getValueAsString(); if (value == null || "".equals(value.trim())) { return null; } return value; }}

 

Build a MappingJackson2HttpMessageConverter  Bean:

@Bean@Primarypublic MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() { MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter(); // Set resolution JSON Tool class ObjectMapper objectMapper = new ObjectMapper(); objectMapper.getSerializerProvider().setNullValueSerializer( new JsonSerializer<Object>() { @Override public void serialize(Object value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { jsonGenerator.writeString(""); } } ); SimpleModule simpleModule = new SimpleModule(); simpleModule.addDeserializer(String.class, new StringDescrializer()); // Sign up for custom StringDescrializer //registerModules Functions can register multiple Module objectMapper.registerModule(simpleModule); // Ignore unknown properties Prevent parsing error objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); jsonConverter.setObjectMapper(objectMapper); List<MediaType> list = new ArrayList<>(); list.add(MediaType.APPLICATION_JSON_UTF8); jsonConverter.setSupportedMediaTypes(list); return jsonConverter;}

 

For Post In terms of newspaper style , The test was successful .

Get Path with arguments

The above solution does not apply to Get Method path with arguments , So we need to do something else .

Because I have used @InitBinder Notes , Know that you can inject custom PropertyEditor, stay Editor You can customize the format or return value , On , Customize a StringEditor To deal with the blank :、

public class StringEditor extends PropertyEditorSupport { //setAsText Complete the conversion of string to specific object type , @Override public void setAsText(String text) throws IllegalArgumentException { if (text == null || "".equals(text.trim())) { text = null; } setValue(text); } //getAsText Complete the conversion from specific object type to string . @Override public String getAsText() { if (getValue() != null) { return getValue().toString(); } return null; }}

 

Want to be global controller Share this Databinder:

@ControllerAdvicepublic class GlobalControllerAdiviceController { //WebDataBinder Is used to bind request arguments to the specified property editor , Can inherit WebBindingInitializer // To achieve an all controller Shared dataBiner @InitBinder public void dataBind(WebDataBinder binder) { /// Register the type converter operation for the specified type binder.registerCustomEditor(String.class, new StringEditor()); }}

 

For Get Path with arguments , And the test was successful

reflection

After solving the problem , I still don't think it's elegant enough , Feel like spring That should be taken into account , At last spring You can find StringTrimmerEditor(https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-beans) Can be realized 「Get」 Method to remove spaces from arguments :

It's just this editor Default is not registered , You need to register manually .

@ControllerAdvicepublic class GlobalControllerAdiviceController { //WebDataBinder Is used to bind request arguments to the specified property editor , Can inherit WebBindingInitializer // To achieve an all controller Shared dataBiner Java Code @InitBinder public void dataBind(WebDataBinder binder) { /// Register binder.registerCustomEditor(String.class, new StringTrimmerEditor(true)); }}

 

Be careful ,StringTrimmerEditor There is an argument in the constructor , If you pass in true, The blank is converted to null. This is what I wrote before StringEditor No need ,spring It's been written for us .

For 「Post」 In terms of newspaper style , In fact, all I need to change is 「Jackson ObjectMapper」, You don't need to customize the entire MappingJackson2HttpMessageConverter  , Just customize Jackson ObjectMapper. Baidu for a while , Sure enough, some students have a solution :

@Beanpublic Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() { return new Jackson2ObjectMapperBuilderCustomizer() { @Override public void customize(Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder) { jacksonObjectMapperBuilder .deserializerByType(String.class, new StdScalarDeserializer<String>(String.class) { @Override public String deserialize(JsonParser jsonParser, DeserializationContext ctx) throws IOException { // Here's the point : If blank, returns null String value = jsonParser.getValueAsString(); if (value == null || "".equals(value.trim())) { return null; } return value; } }); } };}

 

Put the above custom StringDescrializer and MappingJackson2HttpMessageConverter Get rid of , Just keep the top one .

Postscript

A lot of questions , In fact spring Have provided solutions , however spring The system is too big at the moment , So many API And functions are unknown . So it's a good habit to write down problems

Recommend good article

Strong ,10k+ Like it SpringBoot The backstage management system even gave a detailed tutorial !

Share a set based on SpringBoot and Vue Enterprise level open source projects in the background , The code is standard !

You can make money , Open source SpringBoot The mall system , It's super functional , Beautiful !

版权声明
本文为[itread01]所创,转载请带上原文链接,感谢
https://javamana.com/2021/01/20210114170415986K.html

  1. Rocketmq CPP client visual studio 2019 compilation
  2. Usage of data custom attribute in jquery
  3. Common decompression in Linux
  4. Upload large files in Java
  5. Sentry (v20.12.1) k8s cloud native architecture exploration, sentry for JavaScript manual capture event basic usage
  6. Sentry (v20.12.1) k8s cloud native architecture exploration, sentry for JavaScript manual capture event basic usage
  7. Docker + MySQL Cluster + read / write separation + MYCAT Management + vertical sub database + load balancing
  8. Docker + MySQL Cluster + read / write separation + MYCAT Management + vertical sub database + load balancing
  9. Java use interceptor infinite forwarding / redirection infinite loop / redirection times too many error (stack overflow error) solution
  10. Java use interceptor infinite forwarding / redirection infinite loop / redirection times too many error (stack overflow error) solution
  11. 010_ MySQL
  12. 010_ MySQL
  13. Fast integration of imsdk and Huawei offline push
  14. 消息队列之RabbitMQ
  15. Rabbitmq of message queue
  16. 初学java进制转换方面补充学习
  17. Learn java base conversion supplementary learning
  18. 了解一下RPC,为何诞生RPC,和HTTP有什么不同?
  19. 了解一下RPC,为何诞生RPC,和HTTP有什么不同?
  20. 初学java进制转换方面补充学习
  21. Learn about RPC, why RPC was born, and what's the difference between RPC and HTTP?
  22. Learn about RPC, why RPC was born, and what's the difference between RPC and HTTP?
  23. Learn java base conversion supplementary learning
  24. JDBC测试连接数据库
  25. JDBC test connection database
  26. 大厂面试官竟然这么爱问Kafka,一连八个Kafka问题把我问蒙了?
  27. The interviewers of big factories love to ask Kafka so much. I'm blinded by eight Kafka questions in a row?
  28. 安卓开发和java开发有什么区别!2021年BATJ30套大厂Android经典高频面试题,面试必问
  29. Spring Security OAuth2.0認證授權四:分散式系統認證授權
  30. What's the difference between Android development and java development! 2021 batj30 Android classic high frequency interview questions
  31. Spring security oauth2.0 authentication and authorization 4: distributed system authentication and authorization
  32. Java微服务 vs Go微服务,究竟谁更强!?
  33. 大厂面试官竟然这么爱问Kafka,一连八个Kafka问题把我问蒙了?
  34. Who is stronger, Java microservice vs go microservice!?
  35. Java微服务 vs Go微服务,究竟谁更强!?
  36. The interviewers of big factories love to ask Kafka so much. I'm blinded by eight Kafka questions in a row?
  37. Who is stronger, Java microservice vs go microservice!?
  38. springboot异常处理之404
  39. Spring boot exception handling 404
  40. Spring Boot Security 国际化 多语言 i18n 趟过巨坑
  41. springboot异常处理之404
  42. Spring boot security international multilingual I18N
  43. Spring boot exception handling 404
  44. Netty系列化之Google Protobuf编解码
  45. Netty之编解码
  46. Java编解码
  47. Netty解码器
  48. Netty与TCP粘包拆包
  49. Netty开发入门
  50. Java集合遍历时遇到的坑
  51. Spring IOC 源码解析(下)
  52. Spring IoC源码解析(上)
  53. Google protobuf codec of netty serialization
  54. Encoding and decoding of netty
  55. Java codec
  56. Netty decoder
  57. Netty and TCP packet sticking and unpacking
  58. Introduction to netty development
  59. Problems encountered in Java collection traversal
  60. Spring IOC source code analysis (2)