FileUpload ohne Servlets

Ich hab ein Programm geschrieben, was eigentlich genau das erledigt... du brauchst nur ein PHP Skript, welches dir die Datei am Server entgegen nimmt.

Java:
URL url = new URL("http://localhost:80/upload.php");
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
String boundary = "---------------------------" + createBoundary(srcFile.toString());
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
conn.setDoOutput(true);
conn.setUseCaches(false);

Image img = new ImageIcon(ImageIO.read(srcFile)).getImage();
BufferedImage outImg = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_RGB);

Graphics g = outImg.getGraphics();
g.drawImage(img, 0, 0, null);
g.dispose();

ByteArrayOutputStream byteStream = new ByteArrayOutputStream(512);

String content = "--" + boundary + "\r\n"
				 + "Content-Disposition: form-data; name=\"upload_file\"; filename=\"" + srcFile.toString() + "\"\r\n"
				 + "Content-Type: image/pjpeg\r\n"
				 + "\r\n";

byte[] bytes = content.getBytes();

byteStream.write(bytes, 0, bytes.length);
ImageIO.write(outImg, "jpg", byteStream);

content = "\r\n--" + boundary + "\r\n"
		+ "Content-Disposition: form-data; name=\"feld\"\r\n"
		+ "\r\n"
		+ "Inhalt\r\n"
		+ "--" + boundary + "--\r\n";

bytes = content.getBytes();
byteStream.write(bytes, 0, bytes.length);

byteStream.writeTo(conn.getOutputStream());

if(conn.getResponseCode() != HttpURLConnection.HTTP_OK) {

	// HTTP Anfrage erforlgreich abgesetzt
}

In PHP würdest du bei phpinfo() die Variablen $_FILES["upload_file"] und $_POST["feld"] sehen. Hier noch die Methode, mit welcher ich mein boundary generiere:

Java:
// benötigt java.security.*; Package

	public String createBoundary(String s)
		throws NoSuchAlgorithmException {

		MessageDigest md = MessageDigest.getInstance("MD5");
		md.update(s.getBytes());
		byte[] digest = md.digest();
		String boundary = "";

		for(int i = 0; i < digest.length; i++) {

			boundary += Integer.toHexString(digest[i] & 0xFF);
		}

		return boundary;
	}

lg Billie

[edit]Hab den Code für das Vekleinern des Bildes entfernt, bei mir war die Vorgabe Bild hat eine max. Höhe/Breite von 400px und wird automatisch verkleinert und dann erst zum Server geschieckt. Wenn du das Ganze als Applet realisierst, gibt es theoretisch keine Probleme wegen der Verbindung (ein Applet darf sich zum Server, von welchem es angefordert wurde, verbinden) aber was ich mich selbst gefragt habe, ist das Zugreifen auf die Bilddateien ... also der Benutzer wählt eine Datei aus, welche von seinem Rechner stammt und diese würd übertragen. Ich glaube, da geht es ohne Signierung des Applets nicht.[/edit]
 
Zuletzt bearbeitet:
Hallo

da ich zur Zeit auch mit dem Upload von Bildern zu kämpfen habe, bin ich auf dieses Board gestoßen... Ich hab deinen Code gleich ausprobieren wollen, das Problem ist nur, dass die Variablen $_FILES["upload_file"] und $_POST["feld"] dort irgendwie nicht auftauchen. Und die Datei wird folglich auch nicht erstellt....


Woran kann das eigentlich liegen? Bei anderen Beispielen, die ich getestet habe, ist es leider genauso.
Langsam bin ich nämlich richtig frustriert, dass die Lösung anscheinend so nah ist, und ich sie trotzdem nicht finden kann
 
Also wenn du in phpinfo() keine $_POST Variablen angezeigt bekommst und du auch keinen Fehler vom Server bekommst (einen anderen Error Code als HTTP_OK bzw. 200) solltest du deine Anfrage lokal testen.

Ich habe hierzu den Echo Server von http://www.javabuch.de/ verwendet. Hierzu kompilierst und startest du einfach folgende Java-Anwendung:

Java:
/* EchoServer.java */

import java.net.*;
import java.io.*;

public class EchoServer
{
  public static void main(String[] args)
  {
    int cnt = 0;
    try {
      System.out.println("Warte auf Verbindungen auf Port 7...");
      ServerSocket echod = new ServerSocket(7);
      while (true) {
        Socket socket = echod.accept();
        (new EchoClientThread(++cnt, socket)).start();
      }
    } catch (IOException e) {
      System.err.println(e.toString());
      System.exit(1);
    }
  }
}

class EchoClientThread
extends Thread
{
  private int    name;
  private Socket socket;

  public EchoClientThread(int name, Socket socket)
  {
    this.name   = name;
    this.socket = socket;
  }

  public void run()
  {
    String msg = "EchoServer: Verbindung " + name;
    System.out.println(msg + " hergestellt");
    try {
      InputStream in = socket.getInputStream();
      OutputStream out = socket.getOutputStream();
      out.write((msg + "\r\n").getBytes());
      int c;
      while ((c = in.read()) != -1) {
        out.write((char)c);
        if((char) c == '\n') System.out.print("\\n\r\n");
        else if((char) c == '\r') System.out.print("\\r");
        else System.out.print((char)c);
      }
      System.out.println("Verbindung " + name + " wird beendet");
      socket.close();
    } catch (IOException e) {
      System.err.println(e.toString());
    }
  }
}

Dann änderst du noch deine URL-Adresse zu der die Verbindung herstellst auf deinen lokalen Host und dem Port 7, also

http://localhost:7/upload.php

... die PHP-Datei ist eigentlich irrelevant, da du von diesem Server keine Antwort bekommen wirst du siehst nur die Anfrage und kannst diese dann auf Korrektheit überprüfen.

Wie gesagt, so habe ich mein Problem entdeckt.

mfg Billie
 
Zuletzt bearbeitet von einem Moderator:
Hallo Billie,

ich habe Deinen Code ausprobiert um eine Datei auf einen Server zu laden.
Auf jeden Fall vielen Dank, dass Du Deine Idee zur Verfügung stellst.

In der Zeile 37: byteStream.writeTo(conn.getOutputStream());
Tritt bei mir jedoch eine Exception auf:
java.net.ProtocolException: Already connected!

Hattest Du das Problem auch?

Gruß
kirie
 
Hellas,

Nein hatte leider nie diesen Fehler. Ich verstehe sie eigentlich auch nicht ganz, da es ja nur recht ist, dass eine Verbindung besteht. Aber evtl. probiert er sich erneut zu verbinden.

Ich werde es mir am Nachmittag nochmal ansehen. Trotzdem könntest du evtl. deinen gesamten Code posten.
 
Hey,

Werd mal dieses "alte" thema mit einer neuen frage entstauben^^..

Folgendes Problem: Ich will einen String von Java aus mittels CGI-Script auf einem server speichern lassen - als textdatei.

Code:
URL bildcgiURL=null;   

bildcgiURL = new URL("http",getCodeBase().getHost(),"/cgi-bin/bildupload.cgi");

HttpURLConnection conn = (HttpURLConnection)bildcgiURL.openConnection();

conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setDoInput(true);

String bildcgi="";

BufferedReader bildbr=null;
DataOutputStream bilddos=null;    
            

System.out.println(bildcgiURL);
try 
{
	bilddos = new DataOutputStream(conn.getOutputStream());
	bilddos.writeBytes(data);
	System.out.println("Login geht");
	
	bildbr = new BufferedReader(new InputStreamReader(conn.getInputStream()));
	bildcgi = bildbr.readLine();

	bilddos.close(); 
	bildbr.close();
}
catch(MalformedURLException e) 
{
	e.printStackTrace();
}
catch(IOException ex) 
{ 
	ex.printStackTrace();
}

Mit dem Code hab ich s versucht, nur die datei bleibt leer -> Ich vermute, er übergibt die Daten nicht richtig.
Das CGI-Script funktioniert sonst wunderbar, also mittels..

Code:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Unbenanntes Dokument</title>
</head>

<body>
<form action="/cgi-bin/bildupload.cgi" method="post" name="data">
Eingabe: <input type="text" name="data"> <input type=submit>
</form>
</body>
</html>

kann ich die datei+inhalt erstellen(zum testen des cgi-Scriptes). Was müsst man an dem Java-quelltext ändern, damit er die daten korrekt übergibt?

thx
 
Zuletzt bearbeitet:
Zurück