【问题标题】:HTTP method GET is not supported by this URL with comet processor带有彗星处理器的此 URL 不支持 HTTP 方法 GET
【发布时间】:2018-10-17 07:32:56
【问题描述】:

这可能是重复的,但没有一个答案有帮助..

我有一个实现 CometProcessor 的 http servlet,我提到了 this 示例,并将 tomcat 连接器协议切换为非阻塞 io。但是每次我尝试运行该项目时,它都会给我

错误请帮忙

下面是我的 Servlet(加上辅助类)和 web.xml

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.servlet.ServletException;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.catalina.CometEvent;
import org.apache.catalina.CometProcessor;

import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.io.SyndFeedInput;

public class TomcatWeatherServlet extends HttpServlet implements CometProcessor {

    private static final long       serialVersionUID    = 1L;
    private Logger                  logger              = Logger.getLogger(TomcatWeatherServlet.class.getName());

    private MessageSender           messageSender       = null;
    private static final Integer    TIMEOUT             = 60 * 1000;

    @Override
    public void destroy() {
        messageSender.stop();
        messageSender = null;

    }

    @Override
    public void init() throws ServletException {
        messageSender = new MessageSender();
        Thread messageSenderThread = new Thread(messageSender,
                "MessageSender[" + getServletContext().getContextPath() + "]");
        messageSenderThread.setDaemon(true);
        messageSenderThread.start();

    }

    public void event(final CometEvent event) throws IOException, ServletException {
        HttpServletRequest request = event.getHttpServletRequest();
        HttpServletResponse response = event.getHttpServletResponse();
        if (event.getEventType() == CometEvent.EventType.BEGIN) {
            request.setAttribute("org.apache.tomcat.comet.timeout", TIMEOUT);
            logger.log(Level.INFO, "Begin for session: " + request.getSession(true).getId());
            messageSender.setConnection(response);
            Weatherman weatherman = new Weatherman(95118, 32408);
            weatherman.start();
        } else if (event.getEventType() == CometEvent.EventType.ERROR) {
            logger.log(Level.INFO, "Error for session: " + request.getSession(true).getId());
            event.close();
        } else if (event.getEventType() == CometEvent.EventType.END) {
            logger.log(Level.INFO, "End for session: " + request.getSession(true).getId());
            event.close();
        } else if (event.getEventType() == CometEvent.EventType.READ) {
            throw new UnsupportedOperationException("This servlet does not accept data");
        }

    }

    private class Weatherman {

        private final List<URL> zipCodes;
        private final String    YAHOO_WEATHER   = "http://weather.yahooapis.com/forecastrss?p=";

        public Weatherman(Integer... zips) {
            zipCodes = new ArrayList<URL>(zips.length);
            for (Integer zip : zips) {
                try {
                    zipCodes.add(new URL(YAHOO_WEATHER + zip));
                } catch (Exception e) {
                    logger.log(Level.INFO, "weather man failed");
                }
            }
        }

        public void start() {
            Runnable r = new Runnable() {

                public void run() {
                    int i = 0;
                    while (i >= 0) {
                        int j = i % zipCodes.size();
                        SyndFeedInput input = new SyndFeedInput();
                        try {
                            InputStreamReader isr = new InputStreamReader(zipCodes.get(i).openStream());
                            SyndFeed feed = input.build(isr);
                            SyndEntry entry = (SyndEntry) feed.getEntries().get(0);
                            messageSender.send(entryToHtml(entry));
                            Thread.sleep(3000L);
                        } catch (Exception e) {
                            logger.log(Level.INFO, "start failed");
                        }
                        i++;
                    }
                }
            };
            Thread t = new Thread(r);
            t.start();
        }

        private String entryToHtml(SyndEntry entry) {
            StringBuilder html = new StringBuilder("<h2>");
            html.append(entry.getTitle());
            html.append("</h2>");
            html.append(entry.getDescription().getValue());
            return html.toString();
        }
    }

    private class MessageSender implements Runnable {

        protected boolean                   running     = true;
        protected final ArrayList<String>   messages    = new ArrayList<String>();
        private ServletResponse             connection;

        private synchronized void setConnection(ServletResponse connection) {
            this.connection = connection;
            notify();
        }

        public void stop() {
            running = false;
        }

        /**
         * Add message for sending.
         */
        public void send(String message) {
            synchronized (messages) {
                messages.add(message);
                logger.log(Level.INFO, "Message added #messages=" + messages.size());
                messages.notify();
            }
        }

        public void run() {
            while (running) {
                if (messages.size() == 0) {
                    try {
                        synchronized (messages) {
                            messages.wait();
                        }
                    } catch (InterruptedException e) {
                        logger.log(Level.INFO, e.getMessage());
                    }
                }
                String[] pendingMessages = null;
                synchronized (messages) {
                    pendingMessages = messages.toArray(new String[0]);
                    messages.clear();
                }
                try {
                    if (connection == null) {
                        try {
                            synchronized (this) {
                                wait();
                            }
                        } catch (InterruptedException e) {
                            logger.log(Level.INFO, e.getMessage());
                        }
                    }
                    PrintWriter writer = connection.getWriter();
                    for (int j = 0; j < pendingMessages.length; j++) {
                        final String forecast = pendingMessages[j] + "<br>";
                        writer.println(forecast);
                        logger.log(Level.INFO, "Writing:" + forecast);
                    }
                    writer.flush();
                    writer.close();
                    connection = null;
                    logger.log(Level.INFO, "Closing connection");
                } catch (IOException e) {
                    logger.log(Level.INFO, "IOExeption sending message", e);
                }
            }
        }
    }
}



 <?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <servlet>
        <servlet-name>WeatherServlet</servlet-name>
        <servlet-class>servlet.TomcatWeatherServlet</servlet-class> 
    </servlet>
    <servlet-mapping>
        <servlet-name>WeatherServlet</servlet-name>
        <url-pattern>/Weather</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
        </welcome-file-list>
    </web-app>

【问题讨论】:

  • 显示您正在使用的 web.xml 或 servlet。
  • 我使用的是tomcat 9.0.0.M3

标签: java tomcat comet


【解决方案1】:

这里有几个问题。

首先,您还没有在 servlet 中实现 doGet 方法,这就是为什么在该资源上调用 GET 会返回 405 响应。当您使用常规 HTTP 调用 GET /Weather 时,您期望得到什么?

其次,Tomcat 在 8.5 中放弃了对 Comet 的支持,转而支持更标准的 WebSocket API。

因此,您根本无法将 Comet 与 Tomcat 9 一起使用。我很惊讶您甚至能够在 Tomcat 9 中初始化该 servlet。您必须获取一堆 JAR 文件从旧的 Tomcat 安装,以使其均匀加载。但除非您降级到 Tomcat 8.0,否则它永远不会真正起作用。

你最好切换到 WebSocket。

【讨论】:

  • 嗨..据我了解彗星编程上述代码是事件驱动的,即一旦初始化servlet,它就使用服务器端推送(所以不需要doGet()IMO)所以预期的行为一旦 servlet 初始化,它将开始向客户端推送数据,请参见 WeatherMan 类。第二,是的,我后来意识到,自 8.5 以来,对彗星的支持已被删除
  • Comet 确实是面向事件的,但您正在浏览器中发出普通的 HTTP 请求。您不能只在代码中键入implements CometProcessor 并更改远程客户端与您的servlet 交互的方式。您的客户也必须知道该怎么做。
猜你喜欢
  • 2013-11-14
  • 1970-01-01
  • 2016-05-25
  • 1970-01-01
  • 2015-09-05
  • 1970-01-01
相关资源
最近更新 更多