PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Java: XMLDe- und Encoder



MJA
09.12.2004, 15:24
Hi Leute.

Ich programmiere grade mit Java eine Websteuerung für ein Visual Basic Modul.
Die Verbindung wird über TPC hergestellt (Java-seitig ein normaler ClientSocket, VB-seitig ein WinSock), das Java-Programm ist der Client, das VB-Programm der Server. Das Herstellen der Verbindung funktioniert auch und ich kann auch Streams verschicken. Allerdings habe ich noch zwei Probleme: Einerseits werden die Antworten des VB-Moduls bei mir erst ausgegeben, wenn das VB-Programm beendet wurde (Ich vermute ein Problem mit dem Puffer von BufferedReader) und zweitens weiß ich nicht, wie ich eine Ereignisstreuerung für den ClientSocket schreibe, also das wenn eine Antwort vom Server kommt, das er dann eine bestimmte Methode ausführt. Hier ist meine Java-Code:



import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;

class Com
{
public static void communication(BufferedReader reader, BufferedReader in, StringBuffer buffer, PrintStream out)
throws IOException
{
String command = reader.readLine();
out.print(command);

String input = in.readLine();
if (input != null)
{
buffer.append(input);
System.out.println(input.toString());
}
}

public static void main(String args[])
{
try
{
Socket cs = new Socket(args.length == 0 ? "localhost" : args[0], 4003);
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
BufferedReader in = new BufferedReader(new InputStreamReader(cs.getInputStream()));
StringBuffer buffer = new StringBuffer();
PrintStream out = new PrintStream(cs.getOutputStream());

communication(reader, in, buffer, out);
}
catch(/*UnknownHostException is a*/ IOException e)
{
System.err.println("Es ist ein Fehler aufgetreten. Das Programm wird nun beendet.");
return;
}
}
}


Kann mir jemand bei einem der beiden oder besser beiden Probleme helfen? Danke.

MfG
Jan

Johannes
09.12.2004, 15:54
Moin!
Das Problem mit VB ist folgendes: Das Winshock-Modul sendet keinen Zeilenumbruch mit, auf das der Readline Befehl von deinem Java-Server wartet. Deshalb muss dein VB-Programm immer so senden:

Winsock1.SendData "data" & vbCrLf

Dann weiß Readline, wann alle Daten da sind, also das Ende des Datenstroms angekommen ist.

Damit der Server auf eingehende Daten reagiert, kannst du zum Beispiel einen Thread definieren, der mit einer While-Schleife immer mit readLine() auf neue Daten wartet und mit denen dann irgend etwas macht.

Gruß
Johannes

MJA
09.12.2004, 16:01
Danke!
Das mit dem Thread ist noch so ein kleines Problem, weil ich noch nicht so gut in Java bin. Falls du grade Langeweile hast kannst du mir das ja schreiben ;-)

MfG
Jan

Johannes
09.12.2004, 16:10
Also ich kann dir diese Seite hier empfehlen: http://www.galileocomputing.de/openbook/javainsel3/

Da findest du nahezu alles, was du für Java brauchst, Threads natürlich eingeschlossen, aber auch die Netzwerkgeschichten. Wenn du erst einmal keinen Thread machen willst, dann schreibe die Schleife einfach die die main-Funktion. Geht auch...

Gruß
Johannes

MJA
09.12.2004, 16:21
Da kann ich dich sogar noch verbessern: Es gibt mittlerweile eine neue Ausgabe der "Insel". Im Juli ist nämlich Java "Tiger" 5 (1.5) rausgekommen und dazu gibt es gleich noch eine neue Auflage der "Insel". Ich hab das Buch auch hier neben mir stehen. Die Webadresse ist: http://www.galileocomputing.de/openbook/javainsel4/
Siehste sogar von Noobs kann man lernen ;-)

MfG
Jan

Johannes
09.12.2004, 16:26
Jo, ich hatte nur den alten Link, aber hier auf der Platte verwende ich auch Version 4 :-)

Gruß
Johannes

MJA
10.12.2004, 12:44
Hi.

Ich habe das ganze jetzt mit einem Thread Programmiert, alles geht wunderbar, danke nochmal.
Jetzt kommt die nächste Geschichte. Das ganze soll als Applet auf eine Website eingebunden werden. Allerdings kenn ich mich mit Applets nicht so aus, vorallem ist die Frage ob ein Applet Sockets zulässt und ob Threads erlaubt sind. Weiß da jemand bescheid?
Hier wieder der Code, den ich in ein Applet umschreiben will:


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;

public class Com
{
public static Socket cs = null;
public static BufferedReader reader = null;
public static BufferedReader in = null;
public static PrintStream out = null;

public static void main(String args[])
{
try
{
cs = new Socket("localhost", 4003);
reader = new BufferedReader(new InputStreamReader(System.in));
in = new BufferedReader(new InputStreamReader(cs.getInputStream()));
out = new PrintStream(cs.getOutputStream());

Thread t1 = new Thread(new Output());
Thread t2 = new Thread(new Input());
t1.start();
t2.start();
}

catch(/*UnknownHostException is a*/ IOException e)
{
System.err.println("Es ist ein Fehler aufgetreten. Das Programm wird nun beendet.");
return;
}
}
}

class Input
extends Com
implements Runnable
{
public void run()
{
try
{
System.out.println(in.readLine());
run();
}

catch (IOException e)
{
System.err.println("Es ist ein Fehler aufgetreten. Das Programm wird nun beendet.");
return;
}
}
}

class Output
extends Com
implements Runnable
{
public void run()
{
try
{
out.print(reader.readLine());
run();
}

catch (IOException e)
{
System.err.println("Es ist ein Fehler aufgetreten. Das Programm wird nun beendet.");
return;
}
}
}


Achja, ist es möglich in einem Applet eine Konsole zu initialisieren anstatt einer graphischen Oberfläche? Weil AWT und Swing beherrsche ich noch nicht und deshalb soll das ertsmal über eine Konsole laufen, falls möglich.

MfG
Jan

Johannes
10.12.2004, 13:04
Moin,
ich glaube Applet und Konsole lassen sich nicht kombinieren, aber mit Applets kenne ich mich nicht aus.

Gruß
Johannes

MJA
10.12.2004, 13:10
Schade.
Aber das was ich da noch programmiert hab mit den Threads, sieht das soweit gut aus? Ich hab das eben im Buch nachgelesen und geschrieben. Kann ich an der Performance noch was verbessern? Z.B. gibt es eine möglichkeit die beiden Reader und den PrintStream nicht global zu definieren? (Den Socket hab ich jetzt auch lokal definiert, eben noch geändert)

MfG
Jan

Johannes
10.12.2004, 13:27
Also optimieren im Sinne von Verbesserung der Performance kannst du glaube ich nicht mehr, aber ein paar Sachen lassen sich verschönern.

Die Streams würde ich nicht global definieren sondern im Konstruktor deiner Runnable-Klassen erzeugen. So ungefähr, ich habe das jetzt nicht getestet:


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;

public class Com
{
public static Socket cs = null;

public static void main(String args[])
{
try
{
cs = new Socket("localhost", 4003);

Thread t1 = new Thread(new Output( cs ));
Thread t2 = new Thread(new Input( cs ));
t1.start();
t2.start();
}

catch(/*UnknownHostException is a*/ IOException e)
{
System.err.println("Es ist ein Fehler aufgetreten. Das Programm wird nun beendet.");
return;
}
}
}

class Input
extends Com
implements Runnable
{
BufferedReader in = null;
public Input( Socket cs ) {
in = new BufferedReader(new InputStreamReader(cs.getInputStream()));
}
public void run()
{
try
{
while( true ) {
System.out.println(in.readLine());
}
}

catch (IOException e)
{
System.err.println("Es ist ein Fehler aufgetreten. Das Programm wird nun beendet.");
return;
}
}
}

class Output
extends Com
implements Runnable
{
PrintStream out = null;
BufferedReader reader = null;
public Output( Socket cs ) {
reader = new BufferedReader(new InputStreamReader(System.in));
out = new PrintStream(cs.getOutputStream());
}
public void run()
{
try
{
while( true ) {
out.print(reader.readLine());
}
}

catch (IOException e)
{
System.err.println("Es ist ein Fehler aufgetreten. Das Programm wird nun beendet.");
return;
}
}
}


Gruß
Johannes

P.S. Das erneute Aufrufen von run() ist nicht gut, habs mal durch die while-schleife ersetzt. Sonst hast du Rekursion...

MJA
10.12.2004, 13:35
Ok, danke. Ich werd das dann übernehmen.
Allerdings gibt es bei


BufferedReader in = null;
public Input( Socket cs )
{
in = new BufferedReader(new InputStreamReader(cs.getInputStream()));
}


und bei


public Output( Socket cs )
{
reader = new BufferedReader(new InputStreamReader(System.in));
out = new PrintStream(cs.getOutputStream());
}

Jeweils eine UnhandledIOException, aber das kann ich auch selbst beseitigen.

MfG
Jan

MJA
10.12.2004, 14:53
So, jetzt hab ich den fertigen Code. Hier:



import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;

public class Com
{
public static void main(String args[])
{
try
{
Socket cs = new Socket("localhost", 4003);

Thread t1 = new Thread(new Output(cs));
Thread t2 = new Thread(new Input(cs));
t1.start();
t2.start();
}

catch (/*UnknownHostException is a*/ IOException e)
{
System.err.println("Es ist ein Fehler aufgetreten. Das Programm wird nun beendet.");
return;
}
}
}

class Output
extends Com
implements Runnable
{
BufferedReader reader = null;
PrintStream out = null;

public Output(Socket cs)
{
reader = new BufferedReader(new InputStreamReader(System.in));

try
{
out = new PrintStream(cs.getOutputStream());
}

catch (IOException e)
{
System.err.println("Es ist ein Fehler aufgetreten. Das Programm wird nun beendet.");
return;
}
}

public void run()
{
while(true)
try
{
out.print(reader.readLine());
}

catch (IOException e)
{
System.err.println("Es ist ein Fehler aufgetreten. Das Programm wird nun beendet.");
return;
}
}
}

class Input
extends Com
implements Runnable
{
BufferedReader in = null;

public Input(Socket cs)
{
try
{
in = new BufferedReader(new InputStreamReader(cs.getInputStream()));
}

catch (IOException e)
{
System.err.println("Es ist ein Fehler aufgetreten. Das Programm wird nun beendet.");
return;
}
}

public void run()
{
while(true)
try
{
System.out.println(in.readLine());
}

catch (IOException e)
{
System.err.println("Es ist ein Fehler aufgetreten. Das Programm wird nun beendet.");
return;
}
}
}


Dieses ewige Try & Catch! Kann man nicht irgendwas globales für IOExceptions definieren? Ich meine throws ist auch nicht das ware. Ein Globales Try & Catch wäre das was ich brauche, gibt es da eine Möglichkeit?

MfG
Jan

Johannes
10.12.2004, 15:01
Nein, ein globales Try and Catch gibt es nicht, das musst du schon so machen... :-)

Gruß
Johannes

MJA
11.12.2004, 17:59
Hi ich bins wieder mal.

Kann mir hier irgendjemand sagen, wie man aus dem oben angeführten Code ein Applet macht? Das wäre ganz nett.

MfG
Jan

Johannes
11.12.2004, 18:09
Deine Com-Klasse muss von Applet erben, also "extends Applet" musst du hinter den Klassennamen schreiben. Zuerst musst du jedoch mit
"import java.applet.Applet;" das ganze importieren.
Und die main()-Funktion muss durch "paint( Graphics g )" ersetzt werden.

Gruß
Johannes

MJA
11.12.2004, 18:15
Danke! Ich dachte eigendlich, weil du meinstest du kennst dich da nicht so aus, dass jemand anders antwortet, aber ich hab gegen deine Antwort auch nix ;-)
Ich müsste das ganze dann abe mit graphischer Oberfläche machen, stimmts? Na das wird ein Spaß ;-) wo ich das doch gar nicht kann! *g*

MfG
Jan

MJA
06.01.2005, 14:56
Hi, ich bins mal wieder!

Ich schreibe grade an einem XML-Encoder, allerdings klappt das ganze nicht so ganz. Der Encoder soll aus einem Java Programm eine XML-Datei schreiben. Das geht! Auf umgekehrtem Weg geht es auch schon aber mir ist es zu mühsam alle Programme in XML mit Hand zu schreiben. Also will ich es mit einem XML-Encoder einfach von Java nach XML "übersetzten" lassen. Hier meine Encoder-Code:


import java.beans.XMLEncoder;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

public class XMLencode
{
public static void main(String args[])
{
try
{
String output = "Programm.xml", input = "Programm.java";
Object o = new FileInputStream(input);

XMLEncoder e = new XMLEncoder(new FileOutputStream(output));
e.writeObject(o);
}
catch (FileNotFoundException e)
{
System.out.println(e.getMessage());
}
}
}


Es kommen folgende Fehlermedlungen:

java.lang.InstantiationException: java.io.FileInputStream
Continuing ...
java.lang.Exception: XMLEncoder: discarding statement XMLEncoder.writeObject(FileInputStream);
Continuing ...

Hier zum Verständniss die Codes für den Umgekehrten Weg (ein Java Programm als XML-Datei mit einem XML-Decoder ausführen):

Der Decoder:


import java.beans.XMLDecoder;
import java.io.FileInputStream;
import java.io.IOException;

class XMLdecode
{
public static void main(String args[])
{
String inputfile = "sample.xml";

try
{
XMLDecoder d = new XMLDecoder(new FileInputStream(inputfile));
Object o = d.readObject();
}
catch (IOException e)
{
System.out.println(e.getMessage());
}
}
}


Und die XML-Datei:


<?xml version="1.0" encoding="UTF-8"?>
<java version="1.4.1_03" class="java.beans.XMLDecoder">
<object class="javax.swing.JFrame">
<void property="size">
<object class="java.awt.Dimension">
<int>378</int>
<int>327</int>
</object>
</void>
<void property="contentPane">
<void method="add">
<object id="JButton0" class="javax.swing.JButton">
<string>Disable Text Field</string>
<void property="preferredSize">
<object class="java.awt.Dimension">
<int>336</int>
<int>34</int>
</object>
</void>
<void property="bounds">
<object class="java.awt.Rectangle">
<int>17</int>
<int>135</int>
<int>336</int>
<int>34</int>
</object>
</void>
<void method="addActionListener">
<object class="java.beans.EventHandler" method="create">
<class>java.awt.event.ActionListener</class>
<object id="JTextField0" class="javax.swing.JTextField">
<void property="preferredSize">
<object class="java.awt.Dimension">
<int>226</int>
<int>21</int>
</object>
</void>
<void property="bounds">
<object class="java.awt.Rectangle">
<int>63</int>
<int>201</int>
<int>226</int>
<int>21</int>
</object>
</void>
<void property="enabled">
<boolean>false</boolean>
</void>
<void property="document">
<void property="documentProperties">
<void id="Boolean0" method="get">
<string>filterNewlines</string>
</void>
</void>
</void>
</object>
<string>disable</string>
</object>
</void>
</object>
</void>
<void method="add">
<object idref="JTextField0"/>
</void>
<void method="add">
<object id="JButton1" class="javax.swing.JButton">
<string>Enable Text Field</string>
<void property="preferredSize">
<object class="java.awt.Dimension">
<int>339</int>
<int>36</int>
</object>
</void>
<void property="bounds">
<object class="java.awt.Rectangle">
<int>16</int>
<int>86</int>
<int>339</int>
<int>36</int>
</object>
</void>
<void method="addActionListener">
<object class="java.beans.EventHandler" method="create">
<class>java.awt.event.ActionListener</class>
<object idref="JTextField0"/>
<string>enable</string>
</object>
</void>
</object>
</void>
<void method="add">
<object id="JLabel0" class="javax.swing.JLabel">
<void property="preferredSize">
<object class="java.awt.Dimension">
<int>335</int>
<int>69</int>
</object>
</void>
<void property="bounds">
<object class="java.awt.Rectangle">
<int>21</int>
<int>15</int>
<int>335</int>
<int>69</int>
</object>
</void>
<void property="text">
<string>This is my First GUI Java Application!Nikos Fakos 2003.</string>
</void>
</object>
</void>
<void property="preferredSize">
<object class="java.awt.Dimension">
<int>370</int>
<int>300</int>
</object>
</void>
<void property="bounds">
<object class="java.awt.Rectangle">
<int>0</int>
<int>0</int>
<int>370</int>
<int>300</int>
</object>
</void>
<void property="layout">
<object id="SpringLayout0" class="javax.swing.SpringLayout">
<void method="addLayoutComponent">
<object idref="JLabel0"/>
<object class="java.beans.Expression">
<object idref="SpringLayout0"/>
<string>getConstraints</string>
<array class="java.lang.Object" length="1">
<void index="0">
<object idref="JLabel0"/>
</void>
</array>
<void property="value">
<void property="x">
<object class="javax.swing.Spring" method="constant">
<int>21</int>
</object>
</void>
<void property="y">
<object class="javax.swing.Spring" method="constant">
<int>15</int>
</object>
</void>
<void method="setConstraint">
<string>East</string>
<null/>
</void>
<void method="setConstraint">
<string>South</string>
<null/>
</void>
</void>
</object>
</void>
<void method="addLayoutComponent">
<object idref="JButton0"/>
<object class="java.beans.Expression">
<object idref="SpringLayout0"/>
<string>getConstraints</string>
<array class="java.lang.Object" length="1">
<void index="0">
<object idref="JButton0"/>
</void>
</array>
<void property="value">
<void property="x">
<object class="javax.swing.Spring" method="constant">
<int>17</int>
</object>
</void>
<void property="y">
<object class="javax.swing.Spring" method="constant">
<int>135</int>
</object>
</void>
<void method="setConstraint">
<string>East</string>
<null/>
</void>
<void method="setConstraint">
<string>South</string>
<null/>
</void>
</void>
</object>
</void>
<void method="addLayoutComponent">
<object idref="JTextField0"/>
<object class="java.beans.Expression">
<object idref="SpringLayout0"/>
<string>getConstraints</string>
<array class="java.lang.Object" length="1">
<void index="0">
<object idref="JTextField0"/>
</void>
</array>
<void property="value">
<void property="x">
<object class="javax.swing.Spring" method="constant">
<int>63</int>
</object>
</void>
<void property="y">
<object class="javax.swing.Spring" method="constant">
<int>201</int>
</object>
</void>
<void method="setConstraint">
<string>East</string>
<null/>
</void>
<void method="setConstraint">
<string>South</string>
<null/>
</void>
</void>
</object>
</void>
<void method="addLayoutComponent">
<object idref="JButton1"/>
<object class="java.beans.Expression">
<object idref="SpringLayout0"/>
<string>getConstraints</string>
<array class="java.lang.Object" length="1">
<void index="0">
<object idref="JButton1"/>
</void>
</array>
<void property="value">
<void property="x">
<object class="javax.swing.Spring" method="constant">
<int>16</int>
</object>
</void>
<void property="y">
<object class="javax.swing.Spring" method="constant">
<int>86</int>
</object>
</void>
<void method="setConstraint">
<string>East</string>
<null/>
</void>
<void method="setConstraint">
<string>South</string>
<null/>
</void>
</void>
</object>
</void>
</object>
</void>
</void>
<void property="glassPane">
<void property="bounds">
<object class="java.awt.Rectangle">
<int>0</int>
<int>0</int>
<int>370</int>
<int>300</int>
</object>
</void>
</void>
<void property="layeredPane">
<void property="bounds">
<object class="java.awt.Rectangle">
<int>0</int>
<int>0</int>
<int>370</int>
<int>300</int>
</object>
</void>
</void>
<void property="name">
<string>frame0</string>
</void>
<void property="visible">
<object idref="Boolean0"/>
</void>
</object>
</java>


Kann mir jemand helfen?
Das Hauptproblem liegt darin, denke ich zumindest, eine Java-Datei in ein Object umzuwandeln.
Danke.

MfG
MJA