2010-03-24 3 views
1

Je suis en train de concevoir un serveur de discussion en Java. La communication est basée sur Http et non basée sur la socket. Du coté client j'ai une applet. Du coté serveur j'ai une servlet.Pourquoi la méthode doPost de ma servlet de chat n'est-elle pas appelée?

Applet: Je crée un nouveau thread pour écouter les messages entrants (méthode GET). Le thread principal est utilisé pour envoyer des messages (messages POST).

Le code partiel est:

public void start() { 
    System.out.println("Creating new thread"); 
    Thread thread = new Thread(this); 
    thread.start(); 
} 

private String getNewMessage() { 
    System.out.println("Inside getNewMessage"); 
    String msg = null; 
    try { 
     while(msg == null) { 
      System.out.println("Trying to listen to servlet"); 
      URL servlet = new URL(getCodeBase(), "NewServlet?mode=msg"); 
      URLConnection con = servlet.openConnection(); 

      con.setUseCaches(false); 

      DataInputStream din = new DataInputStream(new BufferedInputStream(con.getInputStream())); 
      msg = din.readUTF(); 
      System.out.println("message read :" + msg); 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    return msg + "\n"; 
} 
public void run() { 
    System.out.println("Inside new thread"); 
    while(true) { 
     System.out.println("inside first while"); 
     String newMsg = getNewMessage(); 
     chatOutput.append(newMsg); 
     System.out.println("Appended!!"); 
    } 
} 
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) { 
    String message = chatInput.getText(); 
    chatInput.setText(""); 
    chatOutput.append(message + "\n"); 
    try { 
     System.out.println("Trying to send msg :" + message); 
     URL url = new URL(getCodeBase(), "NewServlet"); 
     URLConnection servletConnection = url.openConnection(); 

     servletConnection.setDoInput(true); 
     servletConnection.setDoOutput(true); 
     servletConnection.setUseCaches(false); 
     servletConnection.setRequestProperty("Content-Type", "application/octet-stream"); 

     ObjectOutputStream out = new ObjectOutputStream(servletConnection.getOutputStream()); 
     out.writeObject(message); 
     out.flush(); 
     out.close(); 

     System.out.println("Message sent!"); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

} 

Ce code suivant est du côté de la servlet. il utilise l'interface Observable pour identifier et envoyer des messages aux clients.

public class NewServlet extends HttpServlet { 
// getNextMessage() returns the next new message. // It blocks until there is one. 
public String getNextMessage() { 
// Create a message sink to wait for a new message from the 
// message source. 
    System.out.println("inside getNextMessage"); 
return new MessageSink().getNextMessage(source);} 

@Override 
protected void doGet(HttpServletRequest request, HttpServletResponse response) 
throws ServletException, IOException { 
    System.out.println("Inside Doget"); 
    response.setContentType("text/plain"); 
    PrintWriter out = response.getWriter(); 

    out.println(getNextMessage()); 
} 

// broadcastMessage() informs all currently listening clients that there 
// is a new message. Causes all calls to getNextMessage() to unblock. 
public void broadcastMessage(String message) { 
// Send the message to all the HTTP-connected clients by giving the 
// message to the message source 
source.sendMessage(message); } 
@Override 
protected void doPost(HttpServletRequest request, HttpServletResponse response) 
throws ServletException, IOException { 
    System.out.println("Inside DoPost"); 
    try { 
    ObjectInputStream din= new ObjectInputStream(request.getInputStream()); 
    String message = (String)din.readObject(); 

     System.out.println("received msg"); 
    if (message != null) broadcastMessage(message); 
     System.out.println("Called broadcast"); 
// Set the status code to indicate there will be no response 
    response.setStatus(response.SC_NO_CONTENT); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

/** 
* Returns a short description of the servlet. 
* @return a String containing servlet description 
*/ 
@Override 
public String getServletInfo() { 
    return "Short description"; 
} 

MessageSource source = new MessageSource();} 

class MessageSource extends Observable { 
public void sendMessage(String message) { 
    System.out.println("inside sendMsg"); 
setChanged(); 
notifyObservers(message); 
} 
} 

class MessageSink implements Observer { 
String message = null; // set by update() and read by getNextMessage() 
// Called by the message source when it gets a new message 
synchronized public void update(Observable o, Object arg) { 
// Get the new message 
message = (String)arg; 
// Wake up our waiting thread 
notify(); 
} 
// Gets the next message sent out from the message source 
synchronized public String getNextMessage(MessageSource source) { 
// Tell source we want to be told about new messages 
source.addObserver(this); 
    System.out.println("AddedObserver"); 
// Wait until our update() method receives a message 
while (message == null) { 
    try { wait(); } catch (Exception ignored) { } 
} 
// Tell source to stop telling us about new messages 
source.deleteObserver(this); 
// Now return the message we received 
// But first set the message instance variable to null 
// so update() and getNextMessage() can be called again. 
String messageCopy = message; 
message = null; 
    System.out.println("Returning msg"); 
return messageCopy; 
} 
} 

Comme vous pouvez le voir, j'ai inclus System.out.println ("Some message"); à certains endroits. c'était juste à des fins de débogage. Dans la console Java, je reçois la sortie suivante:

Création d'un nouveau fil
intérieur nouveau thread.
l'intérieur d'abord tout.
À l'intérieur de getNewMessage.
Essayer d'écouter la servlet.

Du côté de servlet, je reçois la sortie suivante dans les journaux de tomcat:

intérieur Doget.
inside getNextMessage.
AddedObserver.

Après avoir taper un message dans l'applet et l'envoyer, je reçois la sortie suivante dans la console Java:

Essayer d'envoyer msg: ?? vous dér
Message envoyé!

Mais du côté de servlet, je ne obtenir quoi que ce soit dans les journaux. J'ai utilisé la programmation de servlets Java O'Reily comme référence (l'interface de l'observateur vient de là). Mais je ne reçois aucune communication par clavardage entre deux clients. Comme on peut le comprendre à partir des journaux, la méthode doPOST n'est pas appelée. Quelle est la raison pour cela?

Répondre

1

J'ai corrigé le problème en recevant un message (un message d'état) après avoir envoyé le message du côté de l'applet. Dans le côté servlet, dans la méthode doPost, j'ai envoyé le message d'état ("1") après avoir lu le message.

Je ne sais pas exactement comment cela a résolu le problème, mais je suppose que puisque j'avais setDoInput(true);, il attendait la lecture de certains messages.

Quoi qu'il en soit, la bonne nouvelle est que j'ai au moins obtenu le résultat souhaité du processus de débogage ci-dessus.

En outre, il était nécessaire d'utiliser ObjectInputStream au lieu de DataInputStream dans la méthode getNewMessage (puisque le message a été envoyé par ObjectOutputStream). Maintenant, le serveur de discussion fonctionne correctement.

+0

Vous avez oublié d'ajouter les mauvaises nouvelles. Je peux envoyer des messages, mais je reçois un message "null" en retour (la partie de méthode GET qui écoute les autres utilisateurs en tapant des messages et les affiche, dans ce cas il affiche "null"). – mithun1538

+0

Correction de cela aussi. Remplacé la partie "DataInputStream ..." dans la fonction getNewMessage avec ObjectInputStream ... C'est parce que l'applet envoie le message entré par un ObjectOutputStream(). Maintenant, le serveur de discussion fonctionne correctement – mithun1538

Questions connexes