flutter结合Spring boot开发app实战所遇问题及解决方法

背景

该项目为毕业的课程设计,针对校园信息的处理,开发一款具有针对性的APP,来完成校园内部的信息共享与传递。同时,也是作为初步入门flutter的小项目吧,当然了,这也是我本人第一次接触移动端开发。实不相瞒,很喜欢APP开发,于是,自己就开始琢磨flutter,为什么没有选择原生Android呢,主要还是因为,对于UI的布局渲染能力有限,会难许多吧(个人理解啦)

所运用到的主要技术与框架

  1. 后端则采用了java语言来编写,使用Spring boot来搭建项目,其他技术还有,aliSMS,JPush,Redis
  2. 移动端主要采用了谷歌的跨平台框架flutter,数据库有SQLLite

开发笔记(所遇BUG与解决方法,部分备忘信息)

  1. flutte与服务端返回参数的对应关系:
    通过flutter中的dio请求服务端接口获取参数时,flutter端中均采用 Map 类型来映射。当服务端某个参数返回为null时, 请求服务端返回的json数据时,在flutter中直接获取res属性则会出现属性不存在的异常,可通过Map的putIfAbsent(“res”, () => ‘’) 方法来解决。

    {
    	"statusCode":200,
    	"message":"请求成功"
    	"res":null
    }
    
  2. springboot整合Redis对redis.conf文件的配置
    (1) 在本地开发过程中,需要连接在阿里云轻量应用服务器中的Redis服务,则需要修改redis.conf文件,如下所示:

    #1.监听所有网络连接请求(0.0.0.0在网络地址中表示所有地址)
    bind:0.0.0.0    
    #2绑定局域网中的指定IP(即配置访问Redis的IP白名单)
    bind:192.168.42.25
    

    (2) 为了远程Redis服务的安全,避免网络中的恶意攻击,建议在redis.conf文件中设置访问Redis服务的密码,用于客户端的连接认证

    requirepass <密码>
    
     redis.conf文件中的bind代表绑定服务所在的本地的IP地址或者同一局域网中的IP,并不是连接Redis服务的IP地址
    
  3. 在flutter中如果使用 GestureDetector 来包裹 column 组件(比如,通过空白区域来触发某种行为,并作出某种响应),会出现点击空白区域无效的情况,可以采用 ListView 来处理。

  4. 如果需要手动关闭 flutter 的 showModalBottomSheet() 在点击菜单或者按钮完成后执行 Navigator.pop(context); 操作,因为在flutter中模态框默认也是一个页面,只是为半透明而已。

  5. 在使用 Column 中使用 ListView 和 GridView 作为子组件的时候会报没有指定高度的异常信息,可以通过设置 ListView 和 GridView 的shrinkWrap=true(或者使用height来设置高度,这样做的话,就没办法做到元素自适应了,还可以通过 flexible 组件的包装来解决。

  6. 在 flutter 中使用 choiceclip 组件时,可以通过判断选中的列表是否包含当前的元素来实现选中与未选中,从而作出不同的UI展示。 同时,也可以在该组件的 onSelected 函数中,作出点击标签之后的数据刷新处理以及UI变化

  7. flutter 中使用wrap组件可以实现流动布局,当一行不足以所有放下子组件时,会自动换行进行适配处理。解决了在使用 row 组件,会出现子组件过多时,出现便捷溢出的问题。(应用场景:展示文章,商品的标签等)

  8. 在flutter中使用定位时可以有多种选择,通过点击按钮来获取位置信息的话,使用geolocater插件来实现较为简单与方便,并且提供了经纬度转为地理编码的API。当然你也可以选择高德、百度、谷歌等地图服务提供商的开发API,在 flutter 中几乎都可以找到对应的插件。

  9. 在MySQL中,sum聚合函数的结果与null数据发生运算时,结果为null。

  10. 在处理mybatis的集合映射关系时,即collection标签的使用,示例如下:

    <reslutMap>
        
    	<id column="列名" property="属性名"/>
    	
    	<result column="列名" property="属性名"/>
    	<collection property="属性名" oftype="List集合中泛型的全类名">
    		
    		<id column="列名" property="属性名"/>
    		
    	    <result column="列名" property="属性名"/>
    	collection>
    reslutMap>
    
  11. 在mybatis使用更新语句,完成属性的动态更新时,可使用set标签将动态更新的判断语句放在标签体中,也可以使用trim标签指定suffix-override属性为英文逗号即可。他们的目的都是相同的为了去掉动态语句中多余的逗号。

  12. 在使用mybatis中的if语句时,偶尔出现以下异常信息:
    Malformed OGNL expression: facultyName != null and != ‘’
    ,由于mybatis的if 标签是采用OGNL语法来解析表达式的,而这里的属性名 facultyName 中含有的lt和OGNL表达式中的小于符号同名,导致出现错误。最后,找到问题是由于空格的问题造成的,经过排查,确实是空格造成的问题。(粗心大意害死人呀***)

  13. 在使用MySQL中的Count函数时,若不分组,最终将展示第一条记录,其他记录都会消失。

  14. 在 flutter 中 ListView 组件的children属性中不能存在为null的元素。

  15. 服务器返回的数据信息对 flutter 端来说都为Map类型,并且Map中的value均为*dynamic类型,后端若返回的是 List 数据,并且每个元素均为model时,可采用集合的map(function())API来指定泛型包装。向下面这样做即可:

    User user = (res as List).map<User>((m) => User.fromJson(m));
    
  16. 在 flutter 有状态的数据组件中执行setState(function())之前,建议优先判断下mounted属性值是否为true。判断当前组件是否已挂载在组件树中。

  17. flutter状态组件数据的动态数据初始化建议放在didChangeDependencies() 周期函数中来操作。

  18. 在 AndroidManifest.xml 的 application结点中 加入android:usesCleartextTraffic="true"参数,可解决 flutter 在使用webView_flutter时网页无法打开的问题。

  19. showModalBottomSheet弹出层携带有输入框组件时,并且点击弹出层中组件页面跳转并回传结果时,在push前需要先pop, 否则会影响第二个页面的输入框组件的使用。(场景:在评论区输入评论信息,点击@按钮进入@页面并回传数据

  20. 在 flutter 中可以State with WidgetsBindingObserver来监听state的布局变化,并在didChangeMetrics() 中做出一些监听的动作。(场景:比如点击键盘中的收起按钮,然后关闭弹出的评论框输入区域

  21. 在 flutter 中实现评论功能时,针对评论输入框的弹出的问题,因为做了监听,所以窗口变换的时候,也就是点击遮罩会pop两次,第一次关闭弹窗,第二次会pop出详情页面,因为控制弹出框显示的状态量没有做出改变,才导致pop两次。通过za在showModalBottomSheetthen() 来解决这个问题。

  22. 记录一次严重的失误,这次失误导致我一天时间都在找错误。问了很多人,都没有得到解决,最后还是找到了问题的原因,在使用Dio的过程中,为了等你陆之后的每次请求都可以携带JWT Token串,手动调用自己封装的dio工具,导致了后续在使用Content-Type来指定提交的数据类型时,出现了每次请求的时候都没办法改变这个值,均为null的情况。只因为我在已封装的dio中手动设置鉴权的请求,然后就出现了Content-Type无效的问题。(建议在需要鉴权信息的请求中,通过 options 参数来设置单次请求的请求头信息,也可以使用 provider 来共享这个数据,单独封装携带某种特有的请求头数据的请求 API)

  23. spring boot中做图片上传时,被提示上传文件大小过大的异常并且上传失败等问题,只需要在 spring boot 的application.properties或者application.yaml重新设置文件上传大小的参数即可得到解决。

     # 单文件的大小 
     spring.servlet.multipart.max-file-size=100MB
     # 请求的文件大小
     spring.servlet.multipart.max-request-size=500MB 
    
  24. 12:23:27.348 [http-nio-8080-exec-4] WARN org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver - Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'multipart/form-data;boundary=--dio-boundary-4285197029;charset=UTF-8' not supported]
    产生上述异常的原因是:在使用多媒体上传信息时,在请求中使用了 @RequestBody 注解,都替换为 @RequestParam 注解即可。

  25. flutter 做多文件上传的时候,服务端无法获取文件时,是由于服务端的 Spring MVC 在对多文件上传 MultipartFile[] 数组映射时,参数名需要为"files[]"

  26. Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
    产生上述异常的原因,有几个原因,(1)数据源的 URL 地址正确;(2)MySQL的JDBC的驱动包不正确。通过排查,均不是以上问题所造成的。最后发现是是因为在打包的过程中,对静态资源的打包处理配置有误,导致mybatis的xml文件没有一起打包导致的。像下面这样配置则会导致上述异常问题。

    		
    			
    				src/main/java/resources
    				
    					
    					**/*.*
    				
    			
    		
    

    解决办法:取消上述pom配置即可解决,默认是会将maven中的resource目录下的所有文件打包的

  27. 在CentOS中使用 netstat -lnp | grep 8000查看指定端口的应用程序。(扩展:查看java 程序使用 jps命令

  28. flutter 项目打为APK包
    (1)生成 APK签名,Windows 命令行执行:
    keytool -genkey -v -keystore E:/graduationDesign/back/flutter-apk-settting/Users/USER_NAME/key.jks -storetype JKS -keyalg RSA -keysize 2048 -validity 10000 -alias key

    (2)然后执行APK打包命令:flutter build apk

  29. 执行 flutter run有时间出现卡在Installing build\app\outputs\apk\app.apk的问题,导致真机安装完成并无法打开应用,同时无法找到已安装的flutter程序。使用以下两步即可解决:
    (1)卸载已安装的 flutter 程序。

    adb uninstall com.example.application.name
    

    注: 当安装 flutter 程序时,出现了 签名不一致 的问题,造成无法安装的时候,将手机调节到调试模式,然后执以上命令即可完成卸载,便可以继续安装。(首先保证电脑拥有adb服务
    (2)真机调试下安装 flutter 程序

    adb install C:\PathToYourProject\build\app\outputs\apk\app.apk
    

    小结

    以上问题在实战过程中,所遇见的个别问题,做了一下记录。希望能够为开发过程中遇见同类问题的你,提供一点借鉴与帮助。当然问题远不止此,还有一些问题由于匆忙和时间的问题,在开发中忽视了,没有得到记录与总结,愿以后的自己多记录多成长。

    因工作原因,也不怎么经常在线,最后在这里附上源码地址:
    Server地址:https://github.com/H-Mongo/flutterAppServer
    APP地址:https://github.com/H-Mongo/flutterAppServer
    欢迎大家一起来共建该项目并指证不足

你可能感兴趣的:(开发笔记,spring,flutter,android,redis,mysql)