使用Spring Boot搭建本地服务器
搭建的是一个本地服务器,在与客户端通信时需要连接同一个局域网,并且要将局域网的 IP 地址告诉客户端,利用 HTTP 请求,使用 HttpServletRequest 方法接收客户端传来的图片并将其命为制定的文件名 保存在制定的文件夹下,使用 HttpServletRequest方法将结果发送给客户端。

服务端调用外部可执行程序及和客户端的通信

通信过程:
1.服务器接收小程序拍照传来的图片,保存到本地
2.Java调用可执行程序(识别算法C++写的)对牡丹花图片进行识别
3.对识别结果打包由服务器发送给小程序显示

1. java调用另一台电脑生成的外部可执行程序(.exe)

c++做的识别算法:debug->release
java提供了两种方法:两种都会返回一个用于管理操作系统进程的Process对象。最终生成的Process子进程是独立于Jvm之外的进程,就算没有对象应用指向它,它也不会被GC关闭或者释放。
image.png
Runtime.getRuntime().exec(“cmd /c dir”)
项目采用Runtime类的getRuntime()方法获取到当前运行时对象的引用,通过exec方法接收命令并执行,它可以执行像cmd中的语法。
保存图片:
服务器接收到图片后将其命名并保存在与可执行程序相同的路径下,调用外部程序对其处理和识别,将识别结果在控制台上输出,获得花的类别。
(详细:设置缓存区xxxx)
我把执行算法的路径命令写在一个.bat文件(批处理文件,执行)里,放在了程序所在的文件下面,然后通过Runtime类的getRuntime().exec(cmd)调用。这样就成功执行外部程序,实现牡丹花的识别。

2. 获得外部可执行程序的输入输出结果(即:java输入输出重定向)

调用了exec方法会生成一个本地进程,返回一个Process子类的实例。这个进程没有自己的终端和控制台,它的识别结果通过Process.getInputStream()方法重定向到父进程。
然后在java父进程中就可以调用BufferReader类的InputStreamReader()去读取字符内容,也就是我识别的结果。

3. 和小程序的通信

TCP是底层通讯协议,定义的是数据传输和连接方式的规范
HTTP是应用层协议,定义的是传输数据的内容的规范
HTTP协议中的数据是利用TCP协议传输的,所以支持HTTP也就一定支持TCP

我们是一台电脑作为本地服务器,所以是开热点,手机也连着同个热点,形成一个局域网,小程序里获取电脑的ip。
小程序和服务器的连接是TCP连接,经过三次握手。数据传输时,小程序通过HTTP协议向服务端发送请求,然后服务器接收请求,调用外部程序得到识别结果,再返回给小程序。
定义了一个HashMap保存花名字和介绍,转成JSON格式输出。
image.png

遇到问题:小程序和服务端联调的时候,因为是扣的控制窗口的字符串。对字符串变量关键信息的定位。

在Controller层里接受请求后,使用ServletFileUpload处理上传的文件数据,解析请求,设置缓存,字节流存储图片到本地。

登录授权

微信小程序上授权弹窗和按钮,没授权的先授权;授过权的存储userid是有值的。
获取用户昵称和头像,然后调用wx.login()方法,获得code传到服务器。
后端将code、appId、appSecret(这两个是开发者设置中的)作为后端url的参数,调用微信后端接口,获得openid和session_key。
对openid和session_key做处理,根据openid去数据库查询,判断新老用户
返回用户openid

查缓存有没有注册,获取openid(用户的唯一标识,牵扯支付、登录授权等)
会话密钥 微信session_key的有效期是3天。。wx.checkSession查登录态,回调失败就是过期了,登录态过期就要重新调用wx.login获取新的 用户code,重新登录请求。

微信客户端用wx.getUserInfo()获取用户信息。