在jetty嵌入式服务器启动后,我需要运行自己的逻辑。由于类加载器问题,我不会从主类开始。理想的解决方案似乎是从servlet初始化运行我的服务器逻辑。但是在jetty服务器启动后,不会调用init函数和构造函数。在第一个HTTP请求期间,正在创建servlet的一个实例。有没有可能让jetty立即初始化我的servlet,或者我真的需要用我的自定义类加载器加载所有类,然后启动jetty服务器?
这是主要类:
public class ServerLauncher {
public static void main(String[] args) {
JettyServerLauncher.launchHttp("target/server.war", "0.0.0.0", 8080);
// Starting my own logic here is causing classloader issues, because WebSocket classes are loaded by other classloader than my classes, that is the reason why I moved it into the servlet
}
}
这是我的jetty嵌入式服务器启动器:
import org.eclipse.jetty.annotations.AnnotationConfiguration;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.plus.webapp.EnvConfiguration;
import org.eclipse.jetty.plus.webapp.PlusConfiguration;
import org.eclipse.jetty.server.*;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.webapp.*;
import java.io.File;
public class JettyServerLauncher {
private static boolean isHttps;
private static File keyStoreFile;
private static String warPath;
private static String host;
private static int httpPort;
private static int httpsPort;
private static String keyStorePath;
private static String keyStorePass;
private static boolean needClientAuth;
public static void launchHttp(String warPath, String host, int httpPort) {
JettyServerLauncher.isHttps = false;
JettyServerLauncher.warPath = warPath;
JettyServerLauncher.host = host;
JettyServerLauncher.httpPort = httpPort;
launch();
}
public static void launchHttps(String warPath, String host, String keyStorePath, String keyStorePass, int httpPort, int httpsPort, boolean needClientAuth) {
JettyServerLauncher.isHttps = true;
JettyServerLauncher.warPath = warPath;
JettyServerLauncher.host = host;
JettyServerLauncher.httpPort = httpPort;
JettyServerLauncher.httpsPort = httpsPort;
JettyServerLauncher.keyStorePath = keyStorePath;
JettyServerLauncher.keyStorePass = keyStorePass;
JettyServerLauncher.needClientAuth = needClientAuth;
launch();
}
private static void launch() {
Server server = null;
try {
System.out.println("Initializing jetty server...");
if (isHttps) loadKeyStores(keyStorePath);
// Create jetty server
server = new Server(httpPort);
// Setup connectors
Connector httpConnector = createHttpConnector(server, host, httpPort, httpsPort);
if (isHttps) {
Connector httpsConnector = createHttpsConnector(server, host, httpsPort, keyStoreFile, keyStorePass, needClientAuth);
server.setConnectors(new Connector[]{httpConnector, httpsConnector});
} else {
server.setConnectors(new Connector[]{httpConnector});
}
// Add handlers for requests to collection of handlers
HandlerCollection handlers = new ContextHandlerCollection();
//handlers.addHandler(new SecuredRedirectHandler());
handlers.addHandler(createWebApp(warPath));
server.setHandler(handlers);
server.dump();
System.out.println("Starting jetty websocket and web server...");
server.start();
server.join();
} catch (Throwable t) {
t.printStackTrace();
System.err.println("Server initialization failed!");
System.out.println("Stopping the server...");
try {
server.stop();
} catch (Exception ignored) {}
}
}
private static WebAppContext createWebApp(String warPath) {
WebAppContext webApp = new WebAppContext();
webApp.setContextPath("/");
webApp.setWar(new File(warPath).getAbsolutePath());
webApp.setThrowUnavailableOnStartupException(true);
// Enable support for JSR-356 javax.websocket
webApp.setAttribute("org.eclipse.jetty.websocket.jsr356", Boolean.TRUE);
// Jetty will scan project for configuration files... This is very important for loading websocket endpoints by annotation automatically
webApp.setConfigurations(new Configuration[] {
new AnnotationConfiguration(),
new WebInfConfiguration(),
new WebXmlConfiguration(),
new MetaInfConfiguration(),
new FragmentConfiguration(),
new EnvConfiguration(),
new PlusConfiguration(),
new JettyWebXmlConfiguration()
});
return webApp;
}
private static Connector createHttpConnector(Server server, String host, int httpPort, int httpsPort) {
HttpConfiguration httpConf = new HttpConfiguration();
httpConf.setSendServerVersion(false);
if (isHttps) httpConf.setSecurePort(httpsPort);
ServerConnector connector = new ServerConnector(server, new HttpConnectionFactory(httpConf));
connector.setPort(httpPort);
connector.setHost(host);
return connector;
}
private static Connector createHttpsConnector(Server server, String host, int httpsPort, File keyStoreFile, String keyStorePass, boolean needClientAuth) {
SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
sslContextFactory.setKeyStorePath(keyStoreFile.getAbsolutePath());
sslContextFactory.setKeyStorePassword(keyStorePass);
sslContextFactory.setNeedClientAuth(needClientAuth);
// Setup HTTPS Configuration
HttpConfiguration httpsConf = new HttpConfiguration();
httpsConf.setSendServerVersion(false);
httpsConf.setSecureScheme("https");
httpsConf.setSecurePort(httpsPort);
httpsConf.setOutputBufferSize(32768);
httpsConf.setRequestHeaderSize(8192);
httpsConf.setResponseHeaderSize(8192);
httpsConf.addCustomizer(new SecureRequestCustomizer()); // adds ssl info to request object
// Establish the HTTPS ServerConnector
ServerConnector httpsConnector = new ServerConnector(server, new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString()), new HttpConnectionFactory(httpsConf));
httpsConnector.setPort(httpsPort);
httpsConnector.setHost(host);
return httpsConnector;
}
private static void loadKeyStores(String keyStorePath) {
keyStoreFile = new File(keyStorePath);
if (!keyStoreFile.exists()) {
throw new RuntimeException("Key store file does not exist on path '"+keyStoreFile.getAbsolutePath()+"'");
}
}
}
这是我的servlet:
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(displayName = "MyServlet", urlPatterns = { "/*" })
public class MyServlet extends HttpServlet {
@Override
public void init() {
// start new Thread with my server logic here (avoid classloader issues)
// but at least one HTTP request is needed to start it from this place
}
@Override
public void destroy() {}
@Override
public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException {
// handle http requests
}
}
我在谷歌上找到了这个,但我不知道如何在我的案例中使用它。https://www.eclipse.org/lists/jetty-users/msg02109.html
谢谢你的帮助。
如果您只是希望servlet在启动时初始化,那么使用注释...
@WebServlet(
displayName = "MyServlet",
urlPatterns = { "/*" },
loadOnStartup = 1
)
或者,您可以注册一个javax.servlet.ServletContextListener,它执行您需要的Context初始(ServletContextEvtionsce)
行为。
提示:如果您为嵌入式使用定义了一个自定义的ServletContextListener
,您可以从您正在使用的WAR外部将其添加到WebAppContext
中。
例子:
webApp.getServletHandler()
.addListener(new ListenerHolder(MyContextListener.class));
此外,这段代码是错误的,它显示了从旧代码片段复制/粘贴(这种技术来自circa Jetty 9.0.0到9.2.16)
webApp.setConfigurations(new Configuration[] {
new AnnotationConfiguration(),
new WebInfConfiguration(),
new WebXmlConfiguration(),
new MetaInfConfiguration(),
new FragmentConfiguration(),
new EnvConfiguration(),
new PlusConfiguration(),
new JettyWebXmlConfiguration()
});
在码头9.4。x您永远不会直接配置webApp。setConfigurations()
像这样,使用配置。改为在服务器上定义的类列表
。。。
起始时间:9.4.44。v20210927-嵌入式/LikeJettyXml。JAVA
Configuration.ClassList classlist = Configuration.ClassList
.setServerDefault(server);
classlist.addAfter(
"org.eclipse.jetty.webapp.FragmentConfiguration",
"org.eclipse.jetty.plus.webapp.EnvConfiguration",
"org.eclipse.jetty.plus.webapp.PlusConfiguration");
classlist.addBefore(
"org.eclipse.jetty.webapp.JettyWebXmlConfiguration",
"org.eclipse.jetty.annotations.AnnotationConfiguration");
从Jetty 10.0.0开始,您永远不会指定配置类或它们的顺序,因为支持JAR的存在就足够了,在Jetty 10内部,顺序得到了正确的解析。
但是,如果需要添加配置(由于JavaServiceLoader
不起作用的非标准部署问题),那么您仍然可以在服务器对象上配置其他配置(但不必担心这些配置的正确顺序)
从10.0.7开始-嵌入式/demos/LikeJettyXml。JAVA
Configurations.setServerDefault(server).add(
new EnvConfiguration(),
new PlusConfiguration(),
new AnnotationConfiguration()
);
来源:embedded/LikeJettyXml。JAVA
问题内容: 我正在编写一些示例代码,其中启动了嵌入式Jetty服务器。服务器必须仅加载一个servlet,将所有请求发送到servlet并在localhost:80上侦听 到目前为止,我的代码: 我可以用更少的代码/行做同样的事情吗?(使用Jetty 6.1.0)。 问题答案: 删除了不必要的空格,并内联移动了ServletHolder创建。删除了5行。
我有一个Spring Boot应用程序演示,遵循以下指南https://spring.io/guides/gs/rest-service/ PS:因为启动类不在我的bean的同一个包中,所以我显式地将@componentscan添加到我的启动类中。
运行Spring Boot应用程序时,嵌入式tomcat服务器无法启动。我刚刚在pom.xml中添加了所需的依赖项,并创建了一个简单的java POJO类。应用程序属性已经按照oracle数据库所需的jdbc配置以及Hibernate方言信息进行了设置。 执行mvn spring-boot:run时的控制台日志
我遇到这个问题已经有一段时间了,但没有找到解决方案。我正在rails中构建一个论坛应用程序。我刚刚完成将bootstrap和bootstrap gem添加到我的项目中。我去运行服务器,它以一个巨大的错误退出。在这里。
我有能力安装jetty,我只是下载了jetty7 zip并提取了服务器。 我需要在3台linux机器上设置这个。在一台机器中,服务器启动得很好,没有问题。 但是在另外两个中,当服务器启动时,它会显示以下错误。
问题内容: 我讨厌问这样一个模糊的问题,但是我很难找到一个简单的例子。这是我到目前为止的内容: 我可以找到的嵌入式Jetty示例始终显示如下内容,以启动运行的Server实例,但我不知道如何实例化WebSocketServlet。 如何创建可以处理WebSocket连接请求的嵌入式服务器? 问题答案: 更新:2013年12月2日 有关带有WebSocket的嵌入式码头的最新示例,请参见: http