java - 连接 Java 和 Python Flask

标签 java python rest flask

我有一个简单的 Flask API:

from flask import Flask, jsonify

app = Flask(__name__)


@app.route('/')
def hello_world():
    return 'Hello World!'

@app.route('/add/<params>', methods = ['GET'])
def add_numbers(params):
    #params is expected to be a dictionary: {'x': 1, 'y':2}
    params = eval(params)
    return jsonify({'sum': params['x'] + params['y']})

if __name__ == '__main__':
    app.run(debug=True)

现在,我想从 Java 调用此方法并提取结果。我尝试过使用 java.net.URLjava.net.HttpURLConnection;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;


public class MyClass {
    public static void main(String[] args) {
        try {
            URL url = new URL("http://127.0.0.1:5000/add/{'x':100, 'y':1}");
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setRequestProperty("Accept", "application/json");

            if (conn.getResponseCode() != 200) {
                throw new RuntimeException("Failed : HTTP error code : "
                        + conn.getResponseCode());
            }

            BufferedReader br = new BufferedReader(new InputStreamReader(
                    (conn.getInputStream())));

            String output;
            System.out.println("Output from Server .... \n");
            while ((output = br.readLine()) != null) {
                System.out.println(output);
            }

            conn.disconnect();

        } catch (MalformedURLException e) {
            e.printStackTrace();
        }catch (IOException e){
e.printStackTrace();
        }
    }
}

但是这不起作用。在 Flask 服务器中,我收到一条错误消息:

code 400, message Bad request syntax ("GET /add/{'x':100, 'y':1} HTTP/1.1")

"GET /add/{'x':100, 'y':1} HTTP/1.1" HTTPStatus.BAD_REQUEST -

在 Java 代码中,我收到错误:

Exception in thread "main" java.lang.RuntimeException: Failed : HTTP error code : -1 at MyClass.main(MyClass.java:17)

我做错了什么?

我的最终目标是将字典对象传递给我的Python函数并将函数的响应返回给java。该词典可以包含超过一千个单词的文本值。我怎样才能实现这个目标?

编辑

根据评论和答案,我更新了 Flask 代码以避免使用 eval 并获得更好的设计:

@app.route('/add/', methods = ['GET'])
def add_numbers():
    params = {'x': int(request.args['x']), 'y': int(request.args['y']), 'text': request.args['text']}
    print(params['text'])
    return jsonify({'sum': params['x'] + params['y']})

现在我的网址是:“http://127.0.0.1:5000/add?x=100&y=12&text='Test'”

这样更好吗?

最佳答案

根据上面 @TallChuck 的评论,您需要替换或删除 URL 中的空格

URL url = new URL("http://127.0.0.1:5000/add?x=100&y=12&text='Test'");

我建议使用请求对象来检索 GET 调用中的参数。

The Request Object

To access the incoming data in Flask, you have to use the request object. The request object holds all incoming data from the request, which includes the mimetype, referrer, IP address, raw data, HTTP method, and headers, among other things. Although all the information the request object holds can be useful we'll only focus on the data that is normally directly supplied by the caller of our endpoint.

正如评论中提到的发布大量参数和数据,此任务更合适的实现可能是使用 POST 方法。

下面是关于后端 POST 的相同实现的示例:

from flask import Flask, jsonify, request
import json

app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello World!'

@app.route('/add/', methods = ['POST'])
def add_numbers():
    if request.method == 'POST':
        decoded_data = request.data.decode('utf-8')
        params = json.loads(decoded_data)
        return jsonify({'sum': params['x'] + params['y']})

if __name__ == '__main__':
    app.run(debug=True)

这是使用 cURL 测试 POST 后端的简单方法:

 curl -d '{"x":5, "y":10}' -H "Content-Type: application/json" -X POST http://localhost:5000/add

使用Java发布请求:

import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;

public class PostClass {
    public static void main(String args[]){
        HttpURLConnection conn = null;
        DataOutputStream os = null;
        try{
            URL url = new URL("http://127.0.0.1:5000/add/"); //important to add the trailing slash after add
            String[] inputData = {"{\"x\": 5, \"y\": 8, \"text\":\"random text\"}",
                    "{\"x\":5, \"y\":14, \"text\":\"testing\"}"};
            for(String input: inputData){
                byte[] postData = input.getBytes(StandardCharsets.UTF_8);
                conn = (HttpURLConnection) url.openConnection();
                conn.setDoOutput(true);
                conn.setRequestMethod("POST");
                conn.setRequestProperty("Content-Type", "application/json");
                conn.setRequestProperty( "charset", "utf-8");
                conn.setRequestProperty("Content-Length", Integer.toString(input.length()));
                os = new DataOutputStream(conn.getOutputStream());
                os.write(postData);
                os.flush();

                if (conn.getResponseCode() != 200) {
                    throw new RuntimeException("Failed : HTTP error code : "
                            + conn.getResponseCode());
                }

                BufferedReader br = new BufferedReader(new InputStreamReader(
                        (conn.getInputStream())));

                String output;
                System.out.println("Output from Server .... \n");
                while ((output = br.readLine()) != null) {
                    System.out.println(output);
                }
                conn.disconnect();
            }
    } catch (MalformedURLException e) {
        e.printStackTrace();
    }catch (IOException e){
        e.printStackTrace();
    }finally
        {
            if(conn != null)
            {
                conn.disconnect();
            }
        }
    }
}

关于java - 连接 Java 和 Python Flask,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57994238/

相关文章:

python - 使用 PRAW 在标题返回中获取 & 而不是 &

java - Windows 上的 Marshaller 在文件末尾添加新行

java - 如何让Hibernate创建数据库SQL脚本进行初始化和更新

Python cartopy map ,国外的剪辑区域(多边形)

python - 列出所有可为空的 Django 模型字段

java - 使用 Spring 和 Hibernate 的 REST Web 服务

spring - <mvc :annotation/> and AnnotationMethodHandlerAdapter bean 之间的区别

rest - 在 Wildfly 10.0 中,Java REST 线程永远处于 RUNNABLE 状态

java.lang.UnsupportedOperationException : Blobs are not cacheable

java - 使用 JExcel API,如何在不添加隐藏撇号的情况下输入未知数据类型的单元格值?