毕设(二)Spring Boot调用Python脚本运行

前言

整个调用过程只是一次简单尝试
使用的是Java的Runtime.getRuntime()方法
起因是因为毕设需要用到python的人脸识别,所以有了这么个想法

正确流程

  1. 写个python脚本
import numpy as np
 
a = np.arange(12).reshape(3,4)
print(a)

  1. 创建个springboot项目,写个Controller
package com.example.demo.controller;

import com.example.demo.service.FaceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;

@RestController
@RequestMapping("/face")
public class faceController {
    @Autowired
    private FaceService faceService;

    @RequestMapping("/face")
    public void face() throws IOException {
        faceService.faceRecognition();
    }
}

  1. 写个Service
package com.example.demo.service;

import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;

@Service
public class FaceService {

    public void faceRecognition() throws IOException{
        //前面一半是本地环境下的python的启动文件地址,后面一半是要执行的python脚本地址
        String[] arguments = new String[] {"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\Python36_64\\python.exe", "D:\\python\\Tensorflow\\Face_recognition\\Face_recognition\\demo1.py"};
        Process proc;
        try {
            proc = Runtime.getRuntime().exec(arguments);// 执行py文件
            //用输入输出流来截取结果
            BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
            String line = null;
            while ((line = in.readLine()) != null) {
                System.out.println(line);
            }
            in.close();
            //waitFor是用来显示脚本是否运行成功,1表示失败,0表示成功,还有其他的表示其他错误
            int re = proc.waitFor();
            System.out.println(re);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

这里需要解释一下
开头的arguments。逗号前半部分的地址我是在写python脚本的的vs里面找到的,如下
其他的软件应该也类似,总之就是找到运行python脚本的python环境,然后在python环境下找python.exe这个文件
毕设(二)Spring Boot调用Python脚本运行_第1张图片

  1. 运行测试,访问localhost:8080/face/face,若控制台显示如下即成功
    毕设(二)Spring Boot调用Python脚本运行_第2张图片
    如果运行失败,输出的是个1,那就换下面的代码找问题
package com.example.demo.service;

import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;

@Service
public class FaceService {

    public void faceRecognition() throws IOException{
        //前面一半是本地环境下的python的启动文件地址,后面一半是要执行的python脚本地址
        String[] arguments = new String[] {"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\Python36_64\\python.exe", "D:\\python\\Tensorflow\\Face_recognition\\Face_recognition\\demo1.py"};
        Process proc;
        try {
            proc = Runtime.getRuntime().exec(arguments);// 执行py文件
            //用输入输出流来截取结果
            FileInputStream errorStream = (FileInputStream)proc.getErrorStream();
            InputStreamReader isr = new InputStreamReader(errorStream,"gbk");//读取
            System.out.println(isr.getEncoding());
            BufferedReader in = new BufferedReader(isr);//缓冲
            String line = null;
            while ((line = in.readLine()) != null) {
                System.out.println(line);
            }
            in.close();
            //waitFor是用来显示脚本是否运行成功,1表示失败,0表示成功,还有其他的表示其他错误
            int re = proc.waitFor();
            System.out.println(re);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

看它输出的错误信息是什么,去找相应的问题

一些大坑

1、使用python指代默认地址

如下,前半部分直接用python指代默认的python.exe地址

proc = Runtime.getRuntime().exec("python D:\\demo1.py");// 执行py文件

很有可能出错,因为系统默认的很可能和你自己安装的python不在同一个地方
这里建议还是在IDE中找到运行python脚本的python环境,然后找python.exe这个文件

2、安装了anaconda

这个是最麻的,本来用上面这个方法地址填python给我报错了,然后按照网上教程安装了anaconda,然后地址改成安装的anaconda地址,如下

String[] arguments = new String[] {"E:\\anaconda3\\python.exe", "D:\\python\\Tensorflow\\Face_recognition\\Face_recognition\\demo1.py"};

然后就给我弹出一大堆库的版本错误的信息,比如numpy,安装anacond时它默认下载的是1.20.3版本,然后说这个和anaconda安装的python3.9版本冲突,无法执行python脚本
然后我就想着那我更新一下版本呗,它要哪个版本就下哪个版本
结果就发现这个东西pip也pip不了,conda也报错
起初是说默认的国外安装源不行,无法访问,要换国内的镜像源
然后我换了国内的,继续报错,说还是无法访问,这里有两种可能,要不是镜像源已经废弃了,要不是下面这个问题地址问题
然后我发现是地址问题,网上复制的镜像源地址都是https://巴拉巴拉,只要去掉那个s就行了,换成http://巴拉巴拉就能访问了
但是改了之后继续报错,虽然比之前好一点了,好像可以访问了,但是下载不下来
麻了,搞了几个小时都没搞好,一气之下,就不想用这个破办法了,于是脑壳一转,脑洞大开,哈哈!我就想到了反正只是调用python环境而已,为什么不用自己以前下的环境呢?之前的环境既然可以运行python脚本,干嘛要用新的环境呢?
哇,恍然大悟,赶快改成下面这样使用之前下的python环境,果然好了

String[] arguments = new String[] {"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\Python36_64\\python.exe", "D:\\python\\Tensorflow\\Face_recognition\\Face_recognition\\demo1.py"};

默默给自己点个赞,干得漂亮,兄弟!

你可能感兴趣的:(毕业设计,springboot,python)