我有一个应用程序嵌入Jetty作为Web服务器来托管RESTful API。我一直在Ubuntu上用Eclipse开发它,当从IDE启动时,一切都很好。但是,当我打包应用程序并将其部署在服务器Jetty上时,不再响应请求。
服务器确实在我指定的端口上打开了一个套接字,并为spring-mvc启用INFO日志记录显示我的Controller及其方法被正确映射。请求成功打开一个连接,但之后没有数据被发回,实际上请求永远不会进入我的控制器代码。当我关闭应用程序时,我发现所有已建立的连接都被杀死了。
我已经检查过Eclipse项目的类路径上的所有库在部署时都在类路径上。我应该检查什么才能找出它在Eclipse中工作的原因并在其他地方被破坏?
Jetty是版本9,Java版本1.7,Spring 3.2.2。
编辑我发出请求时从Jetty调试日志记录:
2013-05-06 09:40:30,214 DEBUG qtp1215430550-35-acceptor-0-ServerConnector@263676bd{HTTP/1.1}{0.0.0.0:8090} [SelectorManager.java submit]-: <Queued change org.eclipse.jetty.io.SelectorManager$ManagedSelector$Accept@1493f589>
2013-05-06 09:40:30,215 DEBUG qtp1215430550-29-selector-2 [SelectorManager.java runChange]-: <Running change org.eclipse.jetty.io.SelectorManager$ManagedSelector$Accept@1493f589>
2013-05-06 09:40:30,217 DEBUG qtp1215430550-29-selector-2 [AbstractEndPoint.java onOpen]-: <onOpen SelectChannelEndPoint@38261f82{/127.0.0.1:39895<r-l>/127.0.0.1:8090,o=true,is=false,os=false,fi=FillInterest@4edeac9a{false,null},wf=WriteFlusher@7d15dae9{IDLE},it=30000}{null}{io=0,kio=0,kro=0}>
2013-05-06 09:40:30,220 DEBUG qtp1215430550-29-selector-2 [IdleTimeout.java checkIdleTimeout]-: <SelectChannelEndPoint@38261f82{/127.0.0.1:39895<r-l>/127.0.0.1:8090,o=true,is=false,os=false,fi=FillInterest@4edeac9a{false,null},wf=WriteFlusher@7d15dae9{IDLE},it=30000}{null}{io=0,kio=0,kro=0} idle timeout check, elapsed: 3 ms, remaining: 29997 ms>
2013-05-06 09:40:30,221 DEBUG qtp1215430550-29-selector-2 [HttpConnection.java <init>]-: <New HTTP Connection HttpConnection@5465f4d9{IDLE},g=HttpGenerator{s=START},p=HttpParser{s=START,0 of 0}>
2013-05-06 09:40:30,224 DEBUG qtp1215430550-29-selector-2 [AbstractConnection.java onOpen]-: <onOpen HttpConnection@5465f4d9{IDLE},g=HttpGenerator{s=START},p=HttpParser{s=START,0 of 0}>
2013-05-06 09:40:30,227 DEBUG qtp1215430550-29-selector-2 [AbstractConnection.java fillInterested]-: <fillInterested HttpConnection@5465f4d9{IDLE},g=HttpGenerator{s=START},p=HttpParser{s=START,0 of 0}>
2013-05-06 09:40:30,229 DEBUG qtp1215430550-29-selector-2 [SelectChannelEndPoint.java updateLocalInterests]-: <Local interests updated 0 -> 1 for SelectChannelEndPoint@38261f82{/127.0.0.1:39895<r-l>/127.0.0.1:8090,o=true,is=false,os=false,fi=FillInterest@4edeac9a{true,AC.ExReadCB@5465f4d9},wf=WriteFlusher@7d15dae9{IDLE},it=30000}{HttpConnection@5465f4d9{INTERESTED},g=HttpGenerator{s=START},p=HttpParser{s=START,0 of 0}}{io=1,kio=0,kro=0}>
2013-05-06 09:40:30,232 DEBUG qtp1215430550-29-selector-2 [SelectorManager.java createEndPoint]-: <Created SelectChannelEndPoint@38261f82{/127.0.0.1:39895<r-l>/127.0.0.1:8090,o=true,is=false,os=false,fi=FillInterest@4edeac9a{true,AC.ExReadCB@5465f4d9},wf=WriteFlusher@7d15dae9{IDLE},it=30000}{HttpConnection@5465f4d9{INTERESTED},g=HttpGenerator{s=START},p=HttpParser{s=START,0 of 0}}{io=1,kio=0,kro=0}>
2013-05-06 09:40:30,233 DEBUG qtp1215430550-29-selector-2 [SelectorManager.java runChange]-: <Running change org.eclipse.jetty.io.SelectChannelEndPoint$1@e56eabe>
2013-05-06 09:40:30,233 DEBUG qtp1215430550-29-selector-2 [SelectChannelEndPoint.java setKeyInterests]-: <Key interests updated 0 -> 1>
2013-05-06 09:40:30,234 DEBUG qtp1215430550-29-selector-2 [SelectorManager.java select]-: <Selector loop waiting on select>
2013-05-06 09:40:30,234 DEBUG qtp1215430550-29-selector-2 [SelectorManager.java select]-: <Selector loop woken up from select, 1/1 selected>
2013-05-06 09:40:30,234 DEBUG qtp1215430550-29-selector-2 [SelectChannelEndPoint.java setKeyInterests]-: <Key interests updated 1 -> 0>
2013-05-06 09:40:30,238 DEBUG qtp1215430550-29-selector-2 [SelectChannelEndPoint.java updateLocalInterests]-: <Local interests updated 1 -> 0 for SelectChannelEndPoint@38261f82{/127.0.0.1:39895<r-l>/127.0.0.1:8090,o=true,is=false,os=false,fi=FillInterest@4edeac9a{true,AC.ExReadCB@5465f4d9},wf=WriteFlusher@7d15dae9{IDLE},it=30000}{HttpConnection@5465f4d9{INTERESTED},g=HttpGenerator{s=START},p=HttpParser{s=START,0 of 0}}{io=0,kio=0,kro=1}>
2013-05-06 09:40:30,238 DEBUG qtp1215430550-29-selector-2 [SelectorManager.java runChange]-: <Running change org.eclipse.jetty.io.SelectChannelEndPoint$1@e56eabe>
2013-05-06 09:40:30,239 DEBUG qtp1215430550-29-selector-2 [QueuedThreadPool.java dispatch]-: <qtp1215430550{STARTED,2<=10<=10,i=0,q=4} dispatched AC.ExReadCB@5465f4d9>
2013-05-06 09:40:30,240 DEBUG qtp1215430550-29-selector-2 [SelectorManager.java select]-: <Selector loop waiting on select>
2013-05-06 09:40:35,88 DEBUG Scheduler-702565976 [IdleTimeout.java checkIdleTimeout]-: <SelectChannelEndPoint@238b5d33{/127.0.0.1:39894<r-l>/127.0.0.1:8090,o=true,is=false,os=false,fi=FillInterest@1293d180{false,null},wf=WriteFlusher@269f3407{IDLE},it=30000}{HttpConnection@1e10cb60{INTERESTED},g=HttpGenerator{s=START},p=HttpParser{s=START,0 of 0}}{io=0,kio=0,kro=1} idle timeout check, elapsed: 29996 ms, remaining: 4 ms>
2013-05-06 09:40:35,96 DEBUG Scheduler-702565976 [IdleTimeout.java checkIdleTimeout]-: <SelectChannelEndPoint@238b5d33{/127.0.0.1:39894<r-l>/127.0.0.1:8090,o=true,is=false,os=false,fi=FillInterest@1293d180{false,null},wf=WriteFlusher@269f3407{IDLE},it=30000}{HttpConnection@1e10cb60{INTERESTED},g=HttpGenerator{s=START},p=HttpParser{s=START,0 of 0}}{io=0,kio=0,kro=1} idle timeout check, elapsed: 30005 ms, remaining: -5 ms>
2013-05-06 09:40:35,99 DEBUG Scheduler-702565976 [IdleTimeout.java checkIdleTimeout]-: <SelectChannelEndPoint@238b5d33{/127.0.0.1:39894<r-l>/127.0.0.1:8090,o=true,is=false,os=false,fi=FillInterest@1293d180{false,null},wf=WriteFlusher@269f3407{IDLE},it=30000}{HttpConnection@1e10cb60{INTERESTED},g=HttpGenerator{s=START},p=HttpParser{s=START,0 of 0}}{io=0,kio=0,kro=1} idle timeout expired>
编辑2 我的Jetty服务器全部配置在spring beans中:
<bean id="JettyServer" class="org.eclipse.jetty.server.Server" init-method="start" destroy-method="stop">
<property name="connectors">
<list>
<bean id="Connector" class="org.eclipse.jetty.server.nio.SelectChannelConnector">
<property name="port" value="8090"/>
</bean>
</list>
</property>
<property name="handler">
<bean id="handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
<property name="handlers">
<list>
<bean id="servletContextHandler" class="org.eclipse.jetty.servlet.ServletContextHandler">
<property name="contextPath" value="/"/>
<property name="servletHandler">
<bean class="org.eclipse.jetty.servlet.ServletHandler">
<property name="servlets">
<list>
<bean class="org.eclipse.jetty.servlet.ServletHolder">
<property name="name" value="DefaultServlet"/>
<property name="servlet">
<bean class="com.company.project.api.DispatcherServletWrapper"/>
</property>
</bean>
</list>
</property>
<property name="servletMappings">
<list>
<bean class="org.eclipse.jetty.servlet.ServletMapping">
<property name="pathSpecs">
<list><value>/</value></list>
</property>
<property name="servletName" value="DefaultServlet"/>
</bean>
</list>
</property>
</bean>
</property>
</bean>
<bean class="org.eclipse.jetty.server.handler.RequestLogHandler">
<property name="requestLog">
<bean class="org.eclipse.jetty.server.NCSARequestLog">
<constructor-arg value="/opt/company/logs/jetty-yyyy_mm_dd.log"/>
<property name="extended" value="false" />
</bean>
</property>
</bean>
</list>
</property>
</bean>
</property>
</bean>
我需要调度程序servlet知道定义此Jetty服务器的ApplicationContext,所以为了引用,我的DispatcherServletWrapper类看起来像这样:
package com.company.project.api;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.GenericWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
public class DispatcherServletWrapper extends DispatcherServlet implements ApplicationContextAware {
private static final long serialVersionUID = -2281511575328213502L;
private ApplicationContext appContext;
@Override
public void setApplicationContext(ApplicationContext arg0)
throws BeansException {
this.appContext = arg0;
}
protected WebApplicationContext createWebApplicationContext(WebApplicationContext arg0) {
GenericWebApplicationContext wac = new GenericWebApplicationContext();
wac.setParent(appContext);
wac.refresh();
return wac;
}
}
答案 0 :(得分:1)
啊,连接器已经改变了Jetty 9。
从Jetty 9开始,连接器使用ConnectionFactory链构建,提供连接类型检测和回退。
这样做是为了支持替代Web连接类型的现代现实(例如TLS扩展,NPN,SPDY,WebSocket甚至准备HTTP/2.0
)。
以下是一些嵌入式示例:
在Jetty 9中配置标准HTTP连接器
package org.eclipse.jetty.embedded;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
public class OneConnector
{
public static void main(String[] args) throws Exception
{
// The Server
Server server = new Server();
// HTTP connector
ServerConnector http = new ServerConnector(server);
http.setHost("localhost");
http.setPort(8080);
http.setIdleTimeout(30000);
// Set the connector
server.addConnector(http);
// Set a handler
server.setHandler(new HelloHandler());
// Start the server
server.start();
server.join();
}
}
在Jetty 9中为SSL + NPN + SPDY / 3 + SPDY / 2 + HTTPS配置连接器链
package org.eclipse.jetty.embedded;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.SecureRequestCustomizer;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.SslConnectionFactory;
import org.eclipse.jetty.spdy.server.NPNServerConnectionFactory;
import org.eclipse.jetty.spdy.server.SPDYServerConnectionFactory;
import org.eclipse.jetty.spdy.server.http.HTTPSPDYServerConnectionFactory;
import org.eclipse.jetty.spdy.server.http.ReferrerPushStrategy;
import org.eclipse.jetty.util.ssl.SslContextFactory;
public class SpdyConnector
{
public static void main(String[] args) throws Exception
{
String jetty_home = System.getProperty("jetty.home","../../jetty-distribution/target/distribution");
System.setProperty("jetty.home", jetty_home);
// The Server
Server server = new Server();
// HTTP Configuration
HttpConfiguration http_config = new HttpConfiguration();
http_config.setSecureScheme("https");
http_config.setSecurePort(8443);
// HTTP connector
ServerConnector http = new ServerConnector(server,new HttpConnectionFactory(http_config));
http.setPort(8080);
server.addConnector(http);
// SSL Context Factory for HTTPS and SPDY
SslContextFactory sslContextFactory = new SslContextFactory();
sslContextFactory.setKeyStorePath(jetty_home + "/etc/keystore");
sslContextFactory.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4");
sslContextFactory.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g");
// HTTPS Configuration
HttpConfiguration https_config = new HttpConfiguration(http_config);
https_config.addCustomizer(new SecureRequestCustomizer());
// SPDY versions
HTTPSPDYServerConnectionFactory spdy2 =
new HTTPSPDYServerConnectionFactory(2,https_config);
HTTPSPDYServerConnectionFactory spdy3 =
new HTTPSPDYServerConnectionFactory(3,https_config,new ReferrerPushStrategy());
// NPN Factory
SPDYServerConnectionFactory.checkNPNAvailable();
NPNServerConnectionFactory npn =
new NPNServerConnectionFactory(spdy3.getProtocol(),spdy2.getProtocol(),http.getDefaultProtocol());
npn.setDefaultProtocol(http.getDefaultProtocol());
// SSL Factory
SslConnectionFactory ssl = new SslConnectionFactory(sslContextFactory,npn.getProtocol());
// SPDY Connector
ServerConnector spdyConnector =
new ServerConnector(server,ssl,npn,spdy3,spdy2,new HttpConnectionFactory(https_config));
spdyConnector.setPort(8443);
server.addConnector(spdyConnector);
// Set a handler
server.setHandler(new HelloHandler());
// Start the server
server.start();
server.join();
}
}