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

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

问题描述

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

我在applet中键入一条消息并发送后,在Java控制台中得到以下输出:

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

尝试发送msg:you deR ??
消息已发送!

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

但是在servlet方面,我在日志中什么都没得到.我使用O'Reily Java Servlet编程作为参考(观察器接口来自那里).但是我没有在两个客户之间进行任何聊天交流.从日志中可以理解,没有调用 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?

推荐答案

在applet端发送消息后,我通过接收消息(状态消息)来解决此问题.在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天全站免登陆