范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

SpringBoot同一个接口同时支持form表单formdata的优雅写法

  网上很多代码都是千篇一律的 cvs,相信我只要你认真看完我写的这篇,你就可以完全掌握这个知识点,这篇文章不适合直接 cvs,一定要先理解。
  最近重写个项目遇到个比较棘手的问题,老项目是 PHP 接口,这个接口同时兼容 POST json 和 form 表单,更骚的是连 form-data 也兼容…因为写 PHP 请求的对接方代码不严谨。详见这里。
  而在 Java 中,一个接口只支持一种 content-type,json 就用 @RequestBody,form 表单就用 @RequestParam 或不写,form-data 就用 MultipartFile。兼容版本
  如果要把在一个接口中同时兼容三种,比较笨的办法就是获取 HttpServletRequest,然后自己再写方法解析。类似如下:private Map getParams(HttpServletRequest request) {      String contentType = request.getContentType();     if (contentType.contains("application/json")) {         // json 解析...         return null;     } else if (contentType.contains("application/x-www-form-urlencoded")) {         // form 表单解析 ...         return null;     } else if (contentType.contains("multipart")) {         // 文件流解析         return null;     } else {          throw new BizException("不支持的content-type");     }   } 复制代码
  但是这样写有弊端代码很丑,具体到解析代码又臭又长只能返回固定 map 或者自己重新组装参数类无法使用 @Valid 校验参数,像我这种几十个参数都要检验的简直是灾难优雅版本
  网上有 form 表单和 json 同时兼容的版本,但是没有兼容 form-data,我在这做一下补充。1. 自定义注解@Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface GamePHP { } 复制代码2. 自定义注解解析public class GamePHPMethodProcessor implements HandlerMethodArgumentResolver {      private GameFormMethodArgumentResolver formResolver;     private GameJsonMethodArgumentResolver jsonResolver;      public GamePHPMethodProcessor() {         List> messageConverters = new ArrayList<>();         PHPMessageConverter PHPMessageConverter = new PHPMessageConverter();         messageConverters.add(PHPMessageConverter);          jsonResolver = new GameJsonMethodArgumentResolver(messageConverters);         formResolver = new GameFormMethodArgumentResolver();     }      @Override     public boolean supportsParameter(MethodParameter parameter) {         GamePHP ann = parameter.getParameterAnnotation(GamePHP.class);         return (ann != null);     }      @Override     public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {         ServletRequest servletRequest = nativeWebRequest.getNativeRequest(ServletRequest.class);         String contentType = servletRequest.getContentType();         if (contentType == null) {             throw new IllegalArgumentException("不支持contentType");         }          if (contentType.contains("application/json")) {             return jsonResolver.resolveArgument(methodParameter, modelAndViewContainer, nativeWebRequest, webDataBinderFactory);         }          if (contentType.contains("application/x-www-form-urlencoded")) {             return formResolver.resolveArgument(methodParameter, modelAndViewContainer, nativeWebRequest, webDataBinderFactory);         }          if (contentType.contains("multipart")) {             return formResolver.resolveArgument(methodParameter, modelAndViewContainer, nativeWebRequest, webDataBinderFactory);         }          throw new IllegalArgumentException("不支持contentType");     } } 复制代码3. 添加到 spring configuration     @Bean     public MyMvcConfigurer mvcConfigurer() {         return new MyMvcConfigurer();     }      public static class MyMvcConfigurer implements WebMvcConfigurer {         public void addArgumentResolvers(List resolvers) {             resolvers.add(new GamePHPMethodProcessor());         }     } 复制代码4. form-data 的特殊处理
  引入 jar 包           commons-fileupload       commons-fileupload       1.3.1                 commons-io       commons-io       2.4      复制代码
  新增解析 bean@Bean(name = "multipartResolver") public MultipartResolver multipartResolver(){     CommonsMultipartResolver resolver = new CommonsMultipartResolver();     resolver.setDefaultEncoding("UTF-8");     resolver.setResolveLazily(true);//resolveLazily属性启用是为了推迟文件解析,以在在UploadAction中捕获文件大小异常     resolver.setMaxInMemorySize(40960);     resolver.setMaxUploadSize(50*1024*1024);//上传文件大小 50M 50*1024*1024     return resolver; } 复制代码
  特殊说明,GameJsonMethodArgumentResolver 和 GameFormMethodArgumentResolver 是我们自定义的 json 和 form 解析,如果你没有自定义的,使用 spring 默认的 ServletModelAttributeMethodProcessor 和 RequestResponseBodyMethodProcessor 也可以。
  只需将 @RequestParam 注解改为 @GamePHP,接口即可同时兼容三种 content-type。
  其流程为,spring 启动的时候,MyMvcConfigurer 调用 addArgumentResolvers 方法将 GamePHPMethodProcessor 注入,接到请求时,supportsParameter 方法判断是否使用此 resolver,如果为 true,则进入 resolveArgument 方法执行。
  至此我们可以得出一个结论,PHP 是世界上最垃圾的语言。写代码一时爽,维护火葬场。
  原文链接:https://juejin.cn/post/7054441239839506446

想买自主品牌家用SUV,预算13万左右,都有哪些选择?随着国产SUV产品种类的不断丰富,人们在购买新车时,往往会有越来越多的选择。这其中,1015万区间的SUV产品,是不少人考虑的重点。在这个价格区间内,自主品牌均推出了丰富的产品可供北大高材生被华为开除辞退你,与能力无关允许初生牛犊不怕虎的勇气,但绝不允许对于职场规则的亵渎!华为高材生万言书没有实践就请闭上嘴任正非正传一书里记录了这样一个故事华为一个新员工,北大毕业,刚到华为时,就公司的经营战略问48岁跟胡歌姐弟恋,身材秒杀半个娱乐圈假如有一天你胖成200多斤,你会怎么减下来?韩国国家级电视台SBS就发起一个类似的实验让教练带200多斤的超重者们减肥。满屏都是肥肉出乎意料的是,这个项目没有教练敢来挑战。因为学员有什么事是你去了新疆才知道?有什么事是你去了新疆才知道?最后。新疆是一个什么地方,很多第一印象只有羊肉串切糕戈壁沙漠,但这不是新疆的全部。55个民族聚居在此,乌鲁木齐是中亚最大的城市,新疆占了很多中国之最。新左撇子冷知识,不查不知道,原来世界上还有这么多左手好物8月13日,是国际左撇子日,在网络不发达的年代,我们对这个节日并没有什么概念,但是到了如今这个万物互联的时代,我们想要了解外面的世界,成本要比以前低很多。现在只要是网络能到达的地方疑似ModelQ实车伪装图曝光,助力中国市场取得更大战绩作为特斯拉CEO的马斯克,最近可谓是站在了风口浪尖。马斯克在上个月被联合国世界粮食计划署署长毕斯利点名呼吁捐款的风波尚未平息,11月2日,特斯拉CEO马斯克在社交平台(包括微博和推活久见?部分车型购买价回收,二手车价格上涨随着汽车产能的逐渐提升,及自主品牌的逐渐崛起,近年来在总体上,国内汽车的价格呈现下降走势。然而如果你最近关注汽车价格,特别是中高端品牌的汽车品牌,就会发现其售价不降反升。如果你以为像GL6这样适合家用的6座紧凑型MPV,为什么会不好卖当GL6刚刚上市的时候,笔者曾经对这款6座MPV颇为期待,因为传统的5座车对于二孩家庭来说有些力不从心,而传统的大MPV一来价格偏高,二来车身过大既不方便停车,油耗也偏高,因而对于作为曾经中级轿车主力车型的君越,现在值得买吗?作为一款历史悠久的汽车类型,轿车,特别是中级轿车,往往都是同样具有悠久历史的大型跨国车企的拳头产品。正如凯美瑞之于丰田,雅阁之于本田,迈腾帕萨特之于大众一样,均在其品牌中取得不错的退休金又涨了?养老金年年涨的利好政策,会一直持续下去吗?退休金又涨了!每当看到这样的新闻,总会引发退休人员之间的奔走相告。很多人都对这样的新闻见怪不怪乃至习以为常了。确实,从2005年到2021年,我国的养老金已经连续17年上涨。很多人来上海玩除了迪士尼,这些能涨知识的溜娃圣地,每个家长都应收藏作为中国最大经济最发达的城市,上海一直高居各节假日的Top旅游目的地前列。而就在即将到来的国庆假期,也必然会有很多家庭选择上海旅行。带孩子来上海,除了迪士尼外,还有一些博物馆类的景
年末机选苹果12对比FindX2Pro,只有它值得冲或许因为临近双12,智能手机市场又将掀起一轮新的购机热潮,所以最近后台有不少小伙伴在咨询iPhone12和OPPOFindX2Pro,究竟谁更值得买。那么今天我们就借这个机会,来给华为p50配置曝光,网友看到后表示攒钱入手作为国内手机市场的主要制造商,华为在许多手机中获得了很多销售。凭借这些手机,华为还占据了很大的市场份额。华为今年发布的华为P40系列和华为Mate40系列已经成为市场关注的焦点,华骁龙8656400万44W,vivo为冲销量狠放价为了满足高端手机用户的需求,vivo,OPPO,小米和华为都推出了5G旗舰手机,但是在这四家制造商推出的5G旗舰手机中,vivoNEX3S最具特色。在外观上,OPPO,小米和华为都OPPO智能电视R1初体验,这功能居然越用越爽?随着时间来到12月份,2020年不知不觉已经进入尾声,最近也是有不少朋友表示想趁着年尾入手一些好货,来迎接新一年的生活。而我作为一个数码产品爱好者也不例外,由于家里那台比较老旧的智赛博朋克2077来袭,想游戏体验更沉浸?这点一定要重视12月10日早上8点,大家期待已久的热门3A大作赛博朋克2077终于解禁,不少游戏爱好者也是在第一时间上手,并纷纷表示游戏情节很不错,更重要的是游戏画质相当可以。而说到游戏画质,我华为Mate40pro抢不到,三星S20却已经降到ampampquot退场价ampampquot不管它卖得好不好,三星S20系列毕竟是三星拥有的高端机器。所有方面的性能和配置均不可低估。只是初始价格太高。许多用户更喜欢选择华为和其他家用机型,但是华为最新的旗舰机Mate40p只为对标RedmiNote9,真我这款机型能打的过?最近,新的RedmiNote9系列终于发布了。它似乎已经成为新一代千元手机的首选。它的配置和成本效益确实值得一提,首批销量非常高,达到30万辆。这表明库存量仍然相对充足。看到这种情外贸企业,你真的了解海关数据吗?基于对今年跨境贸易的进出口数据,也就是对海关数据统计的结果分析,我国外贸出口总值不减反增!12月7日,据海关统计,今年前11月个月我国货物贸易出口总值19。4万亿元人民币,比去年同外贸企业,独立站背后的数据,还有这些妙用刚开始做跨境贸易的小伙伴们应该会问外贸企业如何打开海外市场?如何在海外市场上获取流量?如何展示企业产品?如何树立企业形象?这时候,建设独立站就成了外贸企业开拓海外市场的首选项。优质首销或创历史新高?不止设计和功能,Reno5系统体验也这么绝12月10日,OPPOReno5系列正式登场后,热度持续疯涨,毕竟能将轻薄RenoGlow2。0星钻工艺焕采人像视频65W超级闪充等功能和特性集于一身的,也就只有Reno5系列了。华为手机值得选的机型,这三款看一看,性能拍照都顶级华为Mate40Pro毕竟,华为Mate40Pro是华为最新的旗舰手机。它在性能拍照充电ID设计等方面都有很大的优势。此外,这款手机在线上线下的持续溢价,显示了它的受欢迎程度。核心