Не удается получить InputStream для чтения в блок - PullRequest
0 голосов
/ 29 мая 2010

Я бы хотел, чтобы входной поток читался как блок вместо чтения конца потока (-1). Есть ли способ настроить поток для этого? Вот мой код сервлета:

    PrintWriter out = response.getWriter();
    BufferedReader in = request.getReader();
    try {
        String line;
        int loop = 0;
        while (loop < 20) {
            line = in.readLine();
            lgr.log(Level.INFO, line);
            out.println("<" + loop + "html>");

            Thread.sleep(1000);
            loop++;
            //
        }
    } catch (InterruptedException ex) {
        lgr.log(Level.SEVERE, null, ex);
    } finally {
        out.close();
    }

Вот мой код Мидлета:

    private HttpConnection conn;
    InputStream is;
    OutputStream os;
    private boolean exit = false;

    public void run() {

        String url = "http://localhost:8080/WebApplication2/NewServlet";
        try {
            conn =
                    (HttpConnection) Connector.open(url);
            is = conn.openInputStream();
            os = conn.openOutputStream();
            StringBuffer sb = new StringBuffer();
            int c;

            while (!exit) {
                os.write("<html>\n".getBytes());
                while ((c = is.read()) != -1) {
                    sb.append((char) c);
                }
                System.out.println(sb.toString());
                sb.delete(0, sb.length() - 1);


                try {
                    Thread.sleep(1000);
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
            }

            os.close();
            is.close();
            conn.close();

        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

Я пробовал InputStream.read, но он тоже не блокируется, он также возвращает -1. Я пытаюсь сохранить потоки ввода / вывода с обеих сторон. Я хочу, чтобы сервлет дождался ввода, обработал его и отправил ответ.
В приведенном выше коде он должен сделать это 20 раз.

спасибо за любую помощь

Ответы [ 3 ]

0 голосов
/ 29 мая 2010

Вы ищете асинхронный ввод-вывод. Это встроено в Servlet 3.0 (пример приложения в комплекте). Если вы все еще используете Servlet 2.5 или старше, ознакомьтесь с техникой Comet , вот документ Tomcat-target .

0 голосов
/ 03 июля 2010

Сервлет работает как простой механизм ответа на запрос. В Сервлете вы читаете данные из Reader, а затем отправляете ответ обратно в Writer.

В простых старых сервлетах до 3.0 или Comet или Continuations у вас нет возможности делать что-либо еще. Единственное, что вы можете сделать, это создать сеанс и заставить клиента отправить еще один запрос для получения дополнительной информации (вы можете использовать что-то в запросе, чтобы сделать то же самое, что и сеанс).

Похоже, вы ищете способ сохранить соединение открытым. Для этого у вас есть несколько решений, которые могут работать или не работать в зависимости от конфигурации вашего брандмауэра.

1) Обновление до движка Servlet, который поддерживает спецификацию Servlet 3.x
2) Используйте Tomcat Comet.
3) Используйте Jetty Continuations.
4) Используйте веб-сокеты.
5) Используйте KEEP_ALIVE и попросите клиента опросить открытое соединение

Как примечание: вы никогда не должны ставить Sleep в код своего сервера, это немедленный признак того, что вы делаете что-то не так.

0 голосов
/ 29 мая 2010

Согласно JavaDoc:

http://java.sun.com/j2se/1.4.2/docs/api/java/io/InputStream.html#read()

Этот метод блокируется до тех пор, пока не будут доступны входные данные, не обнаружен конец файла или не сгенерировано исключение.

Так что, пока вы загружаете буфер на одном конце, он будет использовать его на другом.

...