为什么我的聊天服务器的Servlet的doPost方法不叫? [英] Why is my chat server servlet's doPost method not called?

查看:210
本文介绍了为什么我的聊天服务器的Servlet的doPost方法不叫?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我设计在Java中的聊天服务器。通信是基于HTTP,而不是基于SOCKET。在客户端我有一个小程序。在服务器端我有一个servlet。

I am designing a chat server in java. The communication is Http based and not socket based. In the client side I have an applet. In the server side I have a servlet.

小程序:我创建了一个新的线程来监听传入消息(GET方法)。主线程用于发送消息(POST消息)。

Applet: I create a new thread to listen for incoming messages(GET method). The main thread is used to send messages(POST messages).

局部code是:

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();
    }

}

这下一个code是从servlet的一面。它采用了观测接口识别并发送消息给客户。

This next code is from the servlet side. it uses the Observable interface to identify and send messages to 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;
}
}

正如你可以看到我已包括的System.out.println(一些信息);在一些地方。这只是用于调试目的。
在Java控制台,我得到以下的输出:

As you can see I have included System.out.println("Some message"); in some places. this was just for debugging purposes. In the Java console, I get the following output:

创建新的线程结果
  内部新的线程。结果
  里面也先。结果
  内部getNewMessage。结果
  想要听的servlet。

Creating new thread
Inside new thread.
inside first while.
Inside getNewMessage.
Trying to listen to servlet.

在servlet的一面,我得到在tomcat日志输出如下:

On the servlet side, I get the following output in the tomcat logs:

里面的doGet。结果
  里面getNextMessage。结果
  AddedObserver。

Inside Doget.
inside getNextMessage.
AddedObserver.

在我输入小程序的消息,并发送,我得到了Java控制台输出如下:

After I type a message in the applet, and send it, I get the following output in the Java console:

要发送信息:你DER ??结果
  信息发送!

Trying to send msg :you deR??
Message sent!

但在servlet的一面,我没有在日志得到任何东西。
我用O'Reily的Java Servlet编程参考(Observer接口来自那里)。但我没有得到两个客户端之间的聊天通讯。由于可以从日志可以理解,的doPost 方法不叫。 什么这样做的原因是什么?

But on the servlet side, I dont get anything in the logs. I used the O'Reily Java Servlet Programming as reference (The observer interface comes from there). But I am not getting any chat communication between two clients. As can be understood from the logs, the doPOST method is not called. What is the reason for this?

推荐答案

我在小程序端发送消息后接收消息(状态消息)解决了这一问题。在servlet的一面,在的doPost 的方法,我发出的状态消息(1),看完后消息。

I fixed the problem by receiving message (a status message) after sending the message in the applet side. In the servlet side, in the doPost method, I sent the status message ("1"), after reading the message.

我不知道究竟怎么这个固定的问题,但我想这因为我有 setDoInput(真); ,它正在等待一些消息阅读。

I don't know how exactly this fixed the problem, but I guess that since I had setDoInput(true);, it was waiting for some message to read.

总之,好消息是,我至少得到了上面的调试过程中所需的结果。

Anyway, the good news is that I have at least got the desired result of the above debugging process.

此外,有必要使用的ObjectInputStream 而不是 DataInputStream以 getNewMessage 方法(因为消息是由ObjectOutputStream的发送)。现在聊天服务器工程进展顺利。

Also, it was necessary to use ObjectInputStream instead of DataInputStream in the getNewMessage method (since the message was sent by ObjectOutputStream). Now the chat server works smoothly.

这篇关于为什么我的聊天服务器的Servlet的doPost方法不叫?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆