我是靠谱客的博主 香蕉柠檬,这篇文章主要介绍【底部有源码】SpringBoot 自定义参数类型转换一、缘起二、解决方式三、升级github  源码地址:https://github.com/liushangzaibeijing/TypeConvert.git,现在分享给大家,希望可以做个参考。

一、缘起

由于工作中的项目需要与第三方进行联调,在对方调用我方的接口中请求接受 Content-Type 为 application/x-www-form-urlencoded,但是针对该请求方式的 springBoot 中无法封装复杂类型的参数 例如一个 VO 对象中含有

  • 1、Date 类型或者

  • 2、List 对象

本博文针对其中的两个问题进行解决。

二、解决方式

1、构造 VO 对象

Order 对象

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/**  * author  xieqx  * date   2018/9/7  * 订单信息  */ public class Order {       /**      * 订单id      */     private Long orderId;       /**      * 订单编号      */     private String orderNo;       /**      * 预定时间 默认情况下的日期类型也无法进行封装 需要添加自定义的预定时间      */     private Date bookingTime;       /**      * 订单详情列表,controller封装的order对象中如果没有自定义的类型转换,默认情况下无法正确的封装      */     private List<OrderDetail> orderDetailList;     ...省略seter getter方法

OrderDetail 对象

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**  * @author  xieqx  * date   2018/9/7  * 订单详情   * 使用了lombok框架 简化了bean的创建  */ @AllArgsConstructor @Getter @Setter public class OrderDetail {       private Long productId;       private String productName;       /**      * 日期类型      */     private Date  buyTime; }

2.2 String 类型转换为 List 集合类型

与 2.1 转换 Date 类型相似 这里使用了 jackson 框架进行转换

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**  * author  xieqx  * date   2018/9/4  * 将String 转换为list集合  */ public class StringToListConverter  implements Converter<String, List<OrderDetail>> {       @Override     public List<OrderDetail> convert(String json) {         List<OrderDetail> priceDetails = JsonUtil.str2List(json,OrderDetail.class);         return  priceDetails;     }   }

2.3 转换类完成后,还需要将其交由 Spring 的容器进行处理,这里提供了两种方式

1、继承 WebMvcConfigurationSupport 类并将该对象创建进行添加

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@Configuration public class ApplicationConfig extends WebMvcConfigurationSupport {     /**      * 添加静态资源文件      * @param registry      */     @Override     public void addResourceHandlers(ResourceHandlerRegistry registry) {         registry.addResourceHandler("/static/img").addResourceLocations("/img/");         registry.addResourceHandler("/static/css").addResourceLocations("/css/");         registry.addResourceHandler("/static/js").addResourceLocations("/js/");         registry.addResourceHandler("/static/swf").addResourceLocations("/swf/");         registry.addResourceHandler("/static/media").addResourceLocations("/media/");     }       /**      * 添加自定义的Converters和Formatters.      */     @Override     protected void addFormatters(FormatterRegistry registry) {         //添加字符串转换list的自定义转换器         registry.addConverter(new StringToListConverter());         //添加字符串转换Date的自定义转换器         registry.addConverter(new StringToDateConverter());     }   }

使用该方式会破坏 SpringBoot 默认加载静态文件的默认配置,需要重新进行添加. 切记

2、第二种方式

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Configuration public class SpringDataConvert {       @Autowired     private RequestMappingHandlerAdapter requestMappingHandlerAdapter;       /**      * 增加字符串转换为List集合      */     @PostConstruct     public void addConversionConfig() {         ConfigurableWebBindingInitializer initializer = (ConfigurableWebBindingInitializer) requestMappingHandlerAdapter.getWebBindingInitializer();         if (initializer.getConversionService() != null) {             GenericConversionService genericConversionService = (GenericConversionService)initializer.getConversionService();             //添加字符串转换为list集合的转换机器             genericConversionService.addConverter(new StringToListConverter());             //添加字符串转换为日期类型的字符串             genericConversionService.addConverter(new StringToDateConverter());           }     } }

**   2.4 编写 controller 进行测试**

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Controller @RequestMapping("/api") public class DateConvertController {     private static final Logger logger = LoggerFactory.getLogger(DateConvertController.class);     /**      *       * @param order 订单信息      * @return  请求方式为application/x-www-form-urlencoded      */     @ResponseBody     @RequestMapping(value = "test",method = RequestMethod.POST, consumes = "application/x-www-form-urlencoded",produces = "application/json")     public Object checkInventoryForm(Order order){         if(order==null){             throw new RuntimeException("the hotelOrder is null");         }         return order;     } }

3、启动测试

**         3.1**、不添加日期类型转换器的 post 请求

提示 String 无法转换为 Date 类型

3.2  不添加 List 类型转换

提示 String 无法转换为 List

3.3、自定义的类型转换器都注册上

三、升级

** 3.1、 **如果我的 Order 在添加一个 Date 类型 checkOutTime 格式为 yyyy-MM-dd HH:mm:ss(区别于 bookingTime yyyy-MM-dd)

如果使用上面的日期类型转换,需要则无法处理怎可以使用 @DateFormat 注解来针对每一个日期类型的进行定制化的配置

并取消自定义的日期类型的转换器

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/**  * author  xieqx  * date   2018/9/7  * 订单信息  */ public class Order {       /**      * 订单id      */     private Long orderId;       /**      * 订单编号      */     private String orderNo;       /**      * 预定时间 默认情况下的日期类型也无法进行封装 需要添加自定义的预定时间      */     @DateTimeFormat(pattern = "yyyy-MM-dd")     //@JsonFormat( timezone = "GMT+8",pattern = "yyyy-MM-dd")     private Date bookingTime;       /**      * 离店时间      */     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")     private Date checkOutTime;       /**      * 订单详情列表,controller封装的order对象中如果没有自定义的类型转换,默认情况下无法正确的封装      */     private List<OrderDetail> orderDetailList;

postman 的请求结果

**3.2、**对于若干个相同集合的处理

添加一个用户列表 List需要重新构造一个类似于 StringToListConverter   去转换 User list 集合挺麻烦的,我们可以对于 StringToListConverter构造成范型,如下代码

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**  * @author  xieqx  * date   2018/9/4  * 将String 转换为list集合 范型的处理  */ public class StringToListConverter<T>  implements Converter<String, List<T>> {       @Override     public List<T> convert(String json) {         Type type  =  (Class < T > ) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];         Class clazz = type.getClass();         List<T> list = JsonUtil.str2List(json,clazz);         return  list;     }   }

需要解析 Bean 的集合形式只需继承即可

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
//解析OrderDetail 集合对象 public class StringToOrderDetailListConverter extends StringToListConverter<OrderDetail> {   }     //解析User 集合对象 public class StringToUserListConverter extends StringToListConverter<User> {   }

在 spring 中进行注册

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@Configuration public class SpringDataConvert {       @Autowired     private RequestMappingHandlerAdapter requestMappingHandlerAdapter;       /**      * 增加字符串转换为List集合      */     @PostConstruct     public void addConversionConfig() {         ConfigurableWebBindingInitializer initializer = (ConfigurableWebBindingInitializer) requestMappingHandlerAdapter.getWebBindingInitializer();         if (initializer.getConversionService() != null) {             GenericConversionService genericConversionService = (GenericConversionService)initializer.getConversionService();        //添加转换OrderDetail 集合             genericConversionService.addConverter(new StringToOrderDetailListConverter());    //添加转换User 集合    genericConversionService.addConverter(new StringToUserListConverter());                  //添加字符串转换为日期类型的字符串    //genericConversionService.addConverter(new StringToDateConverter());           }     } }

github  源码地址:https://github.com/liushangzaibeijing/TypeConvert.git


作者:liushangzaibeijing

来源链接:

https://blog.csdn.net/liushangzaibeijing/article/details/82493910

最后

以上就是香蕉柠檬最近收集整理的关于【底部有源码】SpringBoot 自定义参数类型转换一、缘起二、解决方式三、升级github  源码地址:https://github.com/liushangzaibeijing/TypeConvert.git的全部内容,更多相关【底部有源码】SpringBoot内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(43)

评论列表共有 0 条评论

立即
投稿
返回
顶部