簡體   English   中英

Java-使用HttpURLConnection發出POST請求並將圖像發送到服務器

[英]Java - Using HttpURLConnection to make POST request and send image to server

我正在一個團隊軟件項目中,該項目涉及為名為SeeFood的基於服務器的AI設計客戶端。 您可以發送圖片,然后它會告訴您圖片中是否有食物。 當前,我們已經在服務器上部署了一個python腳本,該腳本接受Http POST請求並使用給定的圖像調用AI。 您可以訪問34.236.92.140。

我現在面臨的挑戰是讓Java客戶端能夠將圖像發送到服務器,對其進行分析並獲得響應。 我一直在嘗試不同的方法,包括Apache HttpComponents庫,但是在運行代碼時,我不斷從服務器獲取以下響應代碼:

400 BAD REQUEST
Server: Apache/2.4.27 (Amazon) PHP/5.6.30 mod_wsgi/3.5 Python/2.7.12
Connection: close
Content-Length: 192
Date: Fri, 17 Nov 2017 16:11:28 GMT
Content-Type: text/html; charset=UTF-8

從對HTTP代碼400的研究來看,服務器不喜歡我格式化POST請求的方式。 有沒有人有使用HTTP服務器和通過POST發送圖像的經驗? 同樣,您可以在34.236.92.140嘗試服務器端應用程序。 我還將包括Java客戶端和Python服務器代碼。

Java客戶端(exportImages和readResultsToString方法下的相關代碼):

package javaapplication12;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.WritableByteChannel;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.*;
import static javafx.application.Application.launch;
import javafx.event.*;
import javafx.geometry.*;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.*;

public class UserInterface extends Application {
    private List<File> _images;
    /**
     * @param args the command line arguments
     */
public static void main (String[] args) {
    System.setProperty("java.net.preferIPv4Stack" , "true");
    launch (args);
}

@Override
public void start (Stage primaryStage) {
    final FileChooser fc=new FileChooser ();
    primaryStage.setTitle ("SeeFood AI User Interface");
    Button imageButton=new Button ("Import Images");
    Button exportButton=new Button ("Send Images to SeeFood");
    //When image button is pressed, a FileChooser should load up and add all selected images to a list
    imageButton.setOnAction ((ActionEvent event) -> {
        _images=fc.showOpenMultipleDialog (primaryStage);
        if (_images!=null) {
            int i=0;
            //loop to verify that all selected images are added
            for (File file:_images) {
                System.out.println ("image "+i);
                i++;
            }
        }
    });

    exportButton.setOnAction ((ActionEvent event) -> {
        try {
            exportImages();
        } catch (IOException ex) {
            Logger.getLogger(UserInterface.class.getName()).log(Level.SEVERE, null, ex);
        }
    });
    final GridPane inputGridPane=new GridPane ();

    GridPane.setConstraints (imageButton,0,0);
    GridPane.setConstraints (exportButton,0,1);
    inputGridPane.setHgap (6);
    inputGridPane.setVgap (6);
    inputGridPane.getChildren ().addAll (imageButton, exportButton);

    final Pane rootGroup=new VBox (12);
    rootGroup.getChildren ().addAll (inputGridPane);
    rootGroup.setPadding (new Insets (12,12,12,12));
    primaryStage.setScene (new Scene (rootGroup));
    primaryStage.show ();
}
/**
 * Sends one or more images to SeeFood via HTTP POST.
 * @throws MalformedURLException
 * @throws IOException 
 */
private void exportImages() throws MalformedURLException, IOException{       
    //InetAddress host=InetAddress.getByName(_ip);
//        System.out.println(InetAddress.getByName(_ip));
    URL url=new URL("http://34.236.92.140");
    HttpURLConnection con=(HttpURLConnection) url.openConnection();
    String output;

    con.setRequestMethod("POST");
    con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
    con.setRequestProperty("Content-Type", "multipart/form-data");

    FileChannel in;
    WritableByteChannel out;

    con.setDoOutput(true);  //this must be set to true in order to work
    con.setDoInput(true);

    for(File file:_images){
        in=new FileInputStream(file).getChannel();
        out=Channels.newChannel(con.getOutputStream());

        in.transferTo(0, file.length(), out);

        StringBuilder builder = new StringBuilder();
        builder.append(con.getResponseCode())
               .append(" ")
               .append(con.getResponseMessage())
               .append("\n");

        Map<String, List<String>> map = con.getHeaderFields();
        for (Map.Entry<String, List<String>> entry : map.entrySet()){
            if (entry.getKey() == null) 
                continue;
            builder.append( entry.getKey())
                   .append(": ");

            List<String> headerValues = entry.getValue();
            Iterator<String> it = headerValues.iterator();
            if (it.hasNext()) {
                builder.append(it.next());

                while (it.hasNext()) {
                    builder.append(", ")
                           .append(it.next());
                }
            }

            builder.append("\n");
        }

        System.out.println(builder);
         //Output the result from SeeFood
        //Later on, this result should be stored for each image
        output=readResultsToString(con);


        if(output!=null){
            System.out.println(output);
        } else {
            System.out.println("There was an error in the connection.");
        }
        in.close();
        out.close();
    }       
    con.disconnect();
}

/**
 * Helper method to exportImages(). Should get response from server
 * and append contents to string.
 * @param con - the active http connection
 * @return response from the server
 */
private String readResultsToString(HttpURLConnection con){
    String result = null;
    StringBuffer sb = new StringBuffer();
    InputStream is = null;

    try {          
        is=new BufferedInputStream(con.getInputStream());
        BufferedReader br=new BufferedReader(new InputStreamReader(is));
        String inputLine="";
        while((inputLine=br.readLine())!=null){
            sb.append(inputLine);
        }
        result=sb.toString();
    } catch (IOException ex) {
        Logger.getLogger(UserInterface.class.getName()).log(Level.SEVERE, null, ex);
    } finally {
        if(is!=null){
            try {
                is.close();
            } catch (IOException ex) {
                Logger.getLogger(UserInterface.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
    return result;
}
}

Python服務器:

from flask import Flask, send_from_directory, request
from werkzeug.utils import secure_filename
import argparse
import numpy as np
import tensorflow as tf
from PIL import Image
import sys

app = Flask(__name__)

'''
method for uploading files to the server 
via http POST request
'''
@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        f = request.files['file']
        f.save(secure_filename(f.filename))
        print f.filename
        score = ai_call(f.filename)
        #save file in location based on score
        return score

    return '''
<!doctype html>
<title>Upload new File</title>
<h1>Upload new File</h1>
<form method=post enctype=multipart/form-data>
  <p><input type=file name=file>
     <input type=submit value=Upload>
</form>
'''
'''
method for returning files from the server based on filename
'''
@app.route('/download/<file_name>')
def get_file(file_name):
    return app.send_static_file(file_name)

'''
index page
needs to be motifed to return default images
'''
@app.route('/')
def index():
    find_food
    return 'Hello World'

"""
A script to ask SeeFood if it sees food in the image at 
path specified by the command line argument.
"""
def ai_call(system_arg):
    #parser = argparse.ArgumentParser(description="Ask SeeFood if there is 
food in the image provided.")
#parser.add_argument('image_path', help="The full path to an image file stored on disk.")
#args = parser.parse_args()

# The script assumes the args are perfect, this will crash and burn otherwise.

###### Initialization code - we only need to run this once and keep in memory.
sess = tf.Session()
saver = tf.train.import_meta_graph('saved_model/model_epoch5.ckpt.meta')
saver.restore(sess, tf.train.latest_checkpoint('saved_model/'))
graph = tf.get_default_graph()
x_input = graph.get_tensor_by_name('Input_xn/Placeholder:0')
keep_prob = graph.get_tensor_by_name('Placeholder:0')
class_scores = graph.get_tensor_by_name("fc8/fc8:0")
######

# Work in RGBA space (A=alpha) since png's come in as RGBA, jpeg come in as RGB
# so convert everything to RGBA and then to RGB.
#image_path = args.image_path
image_path = system_arg
image = Image.open(image_path).convert('RGB')
image = image.resize((227, 227), Image.BILINEAR)
img_tensor = [np.asarray(image, dtype=np.float32)]
print 'looking for food in '+ image_path

#Run the image in the model.
scores = sess.run(class_scores, {x_input: img_tensor, keep_prob: 1.})
print scores
# if np.argmax = 0; then the first class_score was higher, e.g., the model sees food.
# if np.argmax = 1; then the second class_score was higher, e.g., the model does not see food.
if np.argmax(scores) == 1:
    print "No food here... :disappointed: "
else:
    print "Oh yes... I see food! :D"
return str(scores)

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

您可以提供的任何幫助都將受到贊賞。 先感謝您。

我有一個類似的問題。 我通過-

String url = "http://127.0.0.1:8080/";
// 2. create obj for the URL class
        URL obj = new URL(url);
        // 3. open connection on the url
        HttpURLConnection con = (HttpURLConnection) obj.openConnection();
        con.setRequestMethod("POST");
        con.setRequestProperty("Content-Type","image/jpeg");
        con.setDoInput(true);
        con.setDoOutput(true);
        OutputStream out = con.getOutputStream();
        DataOutputStream image = new DataOutputStream(out);

Path path = Paths.get("jpeg.jpg");
byte[] fileContents =  Files.readAllBytes(path);
image.write(fileContents, 0, fileContents.length);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM