连接 Java 和 Python 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.URL和java.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();

        }

    }

}

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


代码 400,消息请求语法错误(“GET /add/{'x':100, 'y':1} HTTP/1.1”)


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


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


线程“main”中的异常 java.lang.RuntimeException:失败:HTTP 错误代码:-1 在 MyClass.main(MyClass.java:17)


我究竟做错了什么?


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


至尊宝的传说
浏览 85回答 2
2回答

鸿蒙传说

正如上面 @TallChuck 的评论所述,您需要替换或删除 URL 中的空格URL url = new URL("http://127.0.0.1:5000/add?x=100&y=12&text='Test'");我建议使用请求对象来检索 GET 调用中的参数。请求对象要访问 Flask 中的传入数据,您必须使用请求对象。请求对象保存来自请求的所有传入数据,其中包括 mimetype、referrer、IP 地址、原始数据、HTTP 方法和标头等。尽管请求对象保存的所有信息都可能有用,但我们只关注通常由端点调用者直接提供的数据。正如在发布大量参数和数据的评论中提到的,此任务的更合适的实现可能是使用 POST 方法。以下是后端 POST 相同实现的示例:from flask import Flask, jsonify, requestimport jsonapp = Flask(__name__)@app.route('/')def hello_world():&nbsp; &nbsp; return 'Hello World!'@app.route('/add/', methods = ['POST'])def add_numbers():&nbsp; &nbsp; if request.method == 'POST':&nbsp; &nbsp; &nbsp; &nbsp; decoded_data = request.data.decode('utf-8')&nbsp; &nbsp; &nbsp; &nbsp; params = json.loads(decoded_data)&nbsp; &nbsp; &nbsp; &nbsp; return jsonify({'sum': params['x'] + params['y']})if __name__ == '__main__':&nbsp; &nbsp; app.run(debug=True)这是使用 cURL 测试 POST 后端的简单方法:&nbsp;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 {&nbsp; &nbsp; public static void main(String args[]){&nbsp; &nbsp; &nbsp; &nbsp; HttpURLConnection conn = null;&nbsp; &nbsp; &nbsp; &nbsp; DataOutputStream os = null;&nbsp; &nbsp; &nbsp; &nbsp; try{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; URL url = new URL("http://127.0.0.1:5000/add/"); //important to add the trailing slash after add&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String[] inputData = {"{\"x\": 5, \"y\": 8, \"text\":\"random text\"}",&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "{\"x\":5, \"y\":14, \"text\":\"testing\"}"};&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for(String input: inputData){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; byte[] postData = input.getBytes(StandardCharsets.UTF_8);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; conn = (HttpURLConnection) url.openConnection();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; conn.setDoOutput(true);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; conn.setRequestMethod("POST");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; conn.setRequestProperty("Content-Type", "application/json");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; conn.setRequestProperty( "charset", "utf-8");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; conn.setRequestProperty("Content-Length", Integer.toString(input.length()));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; os = new DataOutputStream(conn.getOutputStream());&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; os.write(postData);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; os.flush();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (conn.getResponseCode() != 200) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new RuntimeException("Failed : HTTP error code : "&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + conn.getResponseCode());&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BufferedReader br = new BufferedReader(new InputStreamReader(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (conn.getInputStream())));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String output;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println("Output from Server .... \n");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; while ((output = br.readLine()) != null) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println(output);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; conn.disconnect();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; } catch (MalformedURLException e) {&nbsp; &nbsp; &nbsp; &nbsp; e.printStackTrace();&nbsp; &nbsp; }catch (IOException e){&nbsp; &nbsp; &nbsp; &nbsp; e.printStackTrace();&nbsp; &nbsp; }finally&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(conn != null)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; conn.disconnect();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}

函数式编程

你的 python 代码有一个严重的设计缺陷,这会产生一个非常危险的安全缺陷,并且(幸运的是,考虑到安全缺陷的存在)是你的代码无法工作的原因。在 URL 中的简单字符串旁边放置任何内容都是不好的做法,因为:URL 应该是地址,从语义上讲,将它们用作数据载体没有什么意义它通常需要杂乱的代码来生成和读取(在您的示例中,您被迫使用eval来解析请求,这是极其危险的)URL 的规则要求对字符进行编码(读起来很糟糕%20等等)如果您期望参数数量固定,则应该使用查询参数,否则最好使用请求正文。考虑到你的逻辑是什么,我认为使用查询参数在语义上会更好(所以你的请求看起来像/add?x=100&y=1)。一般来说,eval是你的敌人,而不是你的朋友,并且eval通过网络发送给你的东西是你的敌人。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java