Bild-Datei von Servlet an Browser senden

Status
Nicht offen für weitere Antworten.
Hallo Leute,
ich hab mal wieder ne blöde Frage...

Ich will dass mein Servlet auf Anfrage eines Browsers eine Bild-Datei sendet. Also wenn der Browser z.B. http://localhost:8080/MeinServlet/Bild.jpg aufruft, dass diese dann angezeigt wird.

Ich habe es zunächst mit folgendem Code versucht:
Code:
protected void doGet(HttpServletRequest req,HttpServletResponse res)throws ServletException, IOException
{  
    res.setContentType("image/jpeg");
    File f = new File("Bild.JPG");
    FileReader fr = new FileReader(f); 	
    OutputStreamWriter o = new OutputStreamWriter(res.getOutputStream());
    int groesse = 200;
    char[] puffer = new char[groesse];
    int n;
    n=fr.read(puffer);
    while(!(n<puffer.length))
    {
        o.write(puffer,0,groesse);
        n=fr.read(puffer);
    }
    o.write(puffer,0,n);
    o.flush();
    res.getOutputStream().close();
}

Beim Browser kommt auch sowas wie ein Bild an. Also ein Bild, welches von der Höhe und der Breite tatsächlich mit "Bild.JPG" übereinstimmt, nur sieht der Inhalt ganz anders aus, man kann nicht mal teilweise erkennen dass es sich um das selbe Bild wie "Bild.JPG" handeln soll.


Ich habe im Internet folgenden funktionierenden Code gefunden:

Code:
protected void doGet(HttpServletRequest req,HttpServletResponse res)throws ServletException, IOException
{  
    res.setContentType("image/jpeg");
    File f = new File("Bild.JPG");
    FileInputStream is = new FileInputStream(f);    
    ServletOutputStream os = res.getOutputStream();
    int c;
    while((c=is.read()) != -1)
    {
        os.write(c);
    }	  
    is.close();
    os.close();
    return;
}



Wieso funktioniert denn mein eigener Code (der obere) nicht?

mfg
 
mhn seltsam kann jetzt auf den ersten blick keinenen fehler finden... char[] müsste reichen. versuch mal testweuse ein int[] oder byte[]
 
Hab ich eben versucht, ich bin mei meinem Ansatz von umgestiegen von

Code:
.
...
FileReader fr = new FileReader(f);
char[] puffer = new char[groesse]
...

auf

Code:
...
FileInputStream fr = new FileInputStream(f);
byte[] puffer = new byte[groesse]
...

Es hat sich nichts geändert.
Für ein int[] gibts leider keine passende read()-Methode.




Noch was seltsames was ich dabei herausgefunden habe: Meine Datei ist 1961 Bytes groß (sagt Windows). Bei meinen Methoden mit char[] bzw. byte[] werden insgesamt 1964 Bytes gelsesen. Ist zwar auch schon merkwürdig, aber bei der zweiten Methode, bei der einzelne ints gelesen werden, finden insgesamt 3795 Aufrufe dieser read()-Methode statt...

Man könnte doch annehmen dass weniger Aufrufe stattfinden würden, wenn man einen größeren Datentyp einliest...



Sorry für die dummen Fragen, aber ich beschäftige mich gern mit dem low-level Bereich (auch wenns Java ist 😉 ).
Vielleicht kennt ja jemand ein Buch wo so low-level Zeugs übner Java drin steht (aber bitte nur low-level Zeugs - Programmieren kann ich schon 😉 )
 
Also ich habe mir mal das "Problemchen" angeschaut mit dem Ergebnis, dass irgendwo auf dem Weg des Kopierens das Charset / Encoding ne Macke bekommen muss. Wenn du dir den HEX-Code anschaust, dann stellt man fest, dass er teilweise die ANSII-Zeichen auf ASCII runterbricht (und dadurch natürlich totaler Murks in der Datei steht).
Hatte gerade auch das Problem beim programmatischen Kopieren einer Bilddatei. Endlich mal rausgefunden, woran es liegen könnte.
 
Das ist leider der Punkt, an dem ich dann auch die "richtige" Lösung verwendet habe:
Der FileReader sagt mir bei getEncoding() Cp1252
Nutze ich dieses im OutputStreamWriter, sehen die Daten zwar "anders" aus, aber zusammenfasst: Müll 😀
Nun hat mich aber die Neugier gepackt und ich will wissen, was da falsch läuft :bahnhof:

[Edit] "richtige" Lösung => Direkt von FileInputStream auf FileOutputStream
 
Zuletzt bearbeitet:
Aha, ok. Die Sache mit so nem Encoding Zeugs und UniCode hab ich schon befürchtet.

Code:
  protected void doGet(HttpServletRequest req,HttpServletResponse res)throws ServletException, IOException
  { 
     	res.setContentType("image/jpeg");
    	File f = new File("Yippie.JPG");
    	FileInputStream fi = new FileInputStream(f); 	
    	OutputStream out = res.getOutputStream();
    	
    	int groesse = 200;
     	byte[] puffer = new byte[groesse];
     	int n;
     	n=fi.read(puffer);
    	while(!(n<puffer.length))
    	{
    		out.write(puffer,0,groesse);
    		out.flush();
    		n=fi.read(puffer);
    	}
		
        out.write(puffer,0,n);
	out.flush();
    	res.getOutputStream().close();
 }


So geht's jedenfalls! Danke Leute.

Ich muss mich schämen dass ich darauf nicht selber gekommen bin! Ich war fest davon überzeugt, diese Variante mehrmals versucht zu haben... und in der API hab ich auch gelsesen. Wahrscheinlich hab ich da den Wald vor lauter Bäumen nicht mehr gesehen:

FileReader, InputStreamReader, BufferedReader, OutputStream, OutputStreamWriter, BufferedWriter, BufferedInputStream, BufferedOutputStream.

Hier mit char[], dort mit byte[]...

Da wirst ja noch verrückt!


Danke nochmals!
 
Zuletzt bearbeitet:
Hallo,

Sorry, wenn ich diesen alten Thread nochmal öffne, aber das hat genau mit meinem Problem zu tun. Ich benutze auch das o.g. Servlet, um Bilder in einem NEUEN Fenster darzustellen. Kann mir jemand verrraten, wie ich HTML Header Information vom Servlet an Client senden lassen kann. Ich will den Titel des Neuen Fensters individuell festlegen. Momentan wird als Titel immer die komplette http-Adresszeile zum Servlet angezeigt.

Vielen Dank für Eure Hilfe

Uwe
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben