为什么我的聊天服务器 servlet 的 doPost 方法没有被调用? [英] Why is my chat server servlet's doPost method not called?

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

问题描述

我正在用 Java 设计一个聊天服务器.通信是基于 Http 的,而不是基于套接字的.在客户端,我有一个小程序.在服务器端,我有一个 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.

Applet:我创建了一个新线程来监听传入的消息(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).

部分代码是:

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

}

接下来的代码来自 servlet 端.它使用 Observable 接口来识别和发送消息给客户端.

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("Some message");在某些地方.这只是为了调试目的.在 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 里面.
添加了观察者.

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:

正在尝试发送消息:你是吗??
消息已发送!

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

但是在 servlet 方面,我没有在日志中得到任何信息.我使用 O'Reily Java Servlet Programming 作为参考(观察者接口来自那里).但是我没有在两个客户之间进行任何聊天交流.从日志中可以看出,没有调用 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(true);,它正在等待一些消息读取.

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.

此外,在getNewMessage 方法中需要使用ObjectInputStream 而不是DataInputStream(因为消息是由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天全站免登陆