Introduction
Jetty has a slogan, "Don't deploy your application in Jetty, deploy Jetty in your application." What this means is that as an alternative to bundling your application as a standard WAR to be deployed in Jetty, Jetty is designed to be a software component that can be instantiated and used in a Java program just like any POJO. Put another way, running Jetty in embedded mode means putting an HTTP module into your application, rather than putting your application into an HTTP server.
This tutorial takes you step-by-step from the simplest Jetty server instantiation to running multiple web applications with standards-based deployment descriptors. The source for most of these examples is part of the standard Jetty project.
Before doing this tutorial, it is worth while to do the Hello World tutorial. This tutorial is also available as a Embedding Jetty Webinar recording.
Details
To embed a Jetty server, the following steps are typical:
- Create the server
- Add/Configure Connectors
- Add/Configure Handlers
- Add/Configure Servlets/Webapps to Handlers
- Start the server
- Wait (join the server to prevent main exiting)
Creating a Server
The following code from SimplestServer.java instantiates and runs the simplest possible Jetty server:
public class SimplestServer { public static void main(String[] args) throws Exception { Server server = new Server(8080); server.start(); server.join(); } }
This runs an HTTP server on port 8080. It is not a very useful server as it has no handlers and thus returns a 404 error for every request.
Writing Handlers
To produce a response to a request, Jetty requires a Handler to be set on the server. A handler may:
- Examine/modify the HTTP request.
- Generate the complete HTTP response.
- Call another Handler (see HandlerWrapper).
- Select one or many Handlers to call (see HandlerCollection).
Hello World Handler
The following code based on HelloHandler.java shows a simple hello world handler:
public class HelloHandler extends AbstractHandler { public void handle(String target,Request baseRequest,HttpServletRequest request,HttpServletResponse response) throws IOException, ServletException { response.setContentType("text/html;charset=utf-8"); response.setStatus(HttpServletResponse.SC_OK); baseRequest.setHandled(true); response.getWriter().println("<h1>Hello World</h1>"); } }
The parameters passed to the handle method are:
- target–the target of the request, which is either a URI or a name from a named dispatcher.
- baseRequest–the Jetty mutable request object, which is always unwrapped.
- request–the immutable request object, which might have been wrapped.
- response–the response, which might have been wrapped.
The handler sets the response status, content-type and marks the request as handled before it generates the body of the response using a writer.
The following code from OneHandler.java shows how a Jetty server can use this handler:
public static void main(String[] args) throws Exception { Server server = new Server(8080); server.setHandler(new HelloHandler()); server.start(); server.join(); }
You now know everything you need to know to write an HTTP server based on Jetty. However, complex request handling is typically built from multiple Handlers. We will look in later sections at how you can combine handlers like aspects. You can see some of the handlers available in Jetty in the org.eclipse.jetty.server.handlerpackage.
Configuring Connectors
To configure the HTTP connectors that the server uses, you can set one or more connectors on the server. You can configure each connector with details such as interface, port, buffer sizes, timeouts, etc.
The following code is based on ManyConnectors.java and shows how to set and configure connectors for the Hello World example:
public class ManyConnectors { public static void main(String[] args) throws Exception { Server server = new Server(); SelectChannelConnector connector0 = new SelectChannelConnector(); connector0.setPort(8080); connector0.setMaxIdleTime(30000); connector0.setRequestHeaderSize(8192); SelectChannelConnector connector1 = new SelectChannelConnector(); connector1.setHost("127.0.0.1"); connector1.setPort(8888); connector1.setThreadPool(new QueuedThreadPool(20)); connector1.setName("admin"); SslSelectChannelConnector ssl_connector = new SslSelectChannelConnector(); String jetty_home = System.getProperty("jetty.home","../jetty-distribution/target/distribution"); System.setProperty("jetty.home",jetty_home); ssl_connector.setPort(8443); SslContextFactory cf = ssl_connector.getSslContextFactory(); cf.setKeyStore(jetty_home + "/etc/keystore"); cf.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"); cf.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g"); server.setConnectors(new Connector[]{ connector0, connector1, ssl_connector }); server.setHandler(new HelloHandler()); server.start(); server.join(); } }
Understanding Handler Collections, Wrappers and Scopes
Complex request handling is typically built from multiple Handlers that can be combined in various ways:
- A Handler Collection holds a collection of other handlers and calls each handler in order. This is useful for combining statistics and logging handlers with the handler that generates the response.
- A Handler List is a Handler Collection that calls each handler in turn until either an exception is thrown, the response is committed or the request.isHandled() returns true. It can be used to combine handlers that conditionally handle a request.
- A Handler Wrapper is a handler base class that can be used to daisy chain handlers together in the style of aspect-oriented programming. For example, a standard web application is implemented by a chain of a context, session, security and servlet handlers.
- A Context Handler Collection uses the longest prefix of the request URI (the contextPath) to select a specific ContextHandler to handle the request.
See also How to Write a Jetty Handler.
Configuring a File Server
The following code from FileServer.java uses a HandlerList to combine the ResourceHandler with the DefaultHandler:
public class FileServer { public static void main(String[] args) throws Exception { Server server = new Server(); SelectChannelConnector connector = new SelectChannelConnector(); connector.setPort(8080); server.addConnector(connector); ResourceHandler resource_handler = new ResourceHandler(); resource_handler.setDirectoriesListed(true); resource_handler.setWelcomeFiles(new String[]{ "index.html" }); resource_handler.setResourceBase("."); HandlerList handlers = new HandlerList(); handlers.setHandlers(new Handler[] { resource_handler, new DefaultHandler() }); server.setHandler(handlers); server.start(); server.join(); } }
The resource handler is passed the request first and looks for a matching file in the local directory to serve. If it does not find a file, the request passes to the default handler which generates a 404 (or favicon.ico).
Configuring a File Server with XML
Now is a good time to remind you that the Jetty XML configuration format can render simple Java code into XML configuration. So the File Server example above can be written with a little reordering in Jetty XML as follows:
<?xml version="1.0"?> <!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd"> <Configure id="FileServer" class="org.eclipse.jetty.server.Server"> <Call name="addConnector"> <Arg> <New class="org.eclipse.jetty.server.nio.SelectChannelConnector"> <Set name="port">8080</Set> </New> </Arg> </Call> <Set name="handler"> <New class="org.eclipse.jetty.server.handler.HandlerList"> <Set name="handlers"> <Array type="org.eclipse.jetty.server.Handler"> <Item> <New class="org.eclipse.jetty.server.handler.ResourceHandler"> <Set name="directoriesListed">true</Set> <Set name="welcomeFiles"> <Array type="String"><Item>index.html</Item></Array> </Set> <Set name="resourceBase">.</Set> </New> </Item> <Item> <New class="org.eclipse.jetty.server.handler.DefaultHandler"> </New> </Item> </Array> </Set> </New> </Set> </Configure>
You can run this XML file from the FileServerXml.java class:
public class FileServerXml { public static void main(String[] args) throws Exception { Resource fileserver_xml = Resource.newSystemResource("fileserver.xml"); XmlConfiguration configuration = new XmlConfiguration(fileserver_xml.getInputStream()); Server server = (Server)configuration.configure(); server.start(); server.join(); } }
Using Spring to Configure a File Server
You can also use the Spring framework to assemble Jetty servers. The file server example above can be written in Spring configuration as:
<beans> <bean id="Server" 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="8080"/> </bean> </list> </property> <property name="handler"> <bean id="handlers" class="org.eclipse.jetty.server.handler.HandlerList"> <property name="handlers"> <list> <bean class="org.eclipse.jetty.server.handler.ResourceHandler"> <property name="directoriesListed" value="true"/> <property name="welcomeFiles"> <list> <value>index.html</value> </list> </property> <property name="resourceBase" value="."/> </bean> <bean class="org.eclipse.jetty.server.handler.DefaultHandler"/> </list> </property> </bean> </property> </bean> </beans>
See also How to Configure Jetty with Spring.
Setting Contexts
A ContextHandler is a HandlerWrapper that responds only to requests that have a URI prefix that matches the configured context path.
Requests that match the context path have their path methods updated accordingly, and the following optional context features applied as appropriate:
* A Thread Context classloader. * A set of attributes * A set of init parameters * A resource base (aka document root) * A set of virtual host names
Requests that don't match are not handled.
The following code is based on OneContext.java and sets context path and classloader for the hello handler:
public class OneContext { public static void main(String[] args) throws Exception { Server server = new Server(8080); ContextHandler context = new ContextHandler(); context.setContextPath("/hello"); context.setResourceBase("."); context.setClassLoader(Thread.currentThread().getContextClassLoader()); server.setHandler(context); context.setHandler(new HelloHandler()); server.start(); server.join(); } }
Creating Servlets
Servlets are the standard way to provide application logic that handles HTTP requests. Servlets are like constrained Handlers with standard ways to map specific URIs to specific servlets. The following code is based on HelloServlet.java:
public class HelloServlet extends HttpServlet { private String greeting="Hello World"; public HelloServlet(){} public HelloServlet(String greeting) { this.greeting=greeting; } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); response.setStatus(HttpServletResponse.SC_OK); response.getWriter().println("<h1>"+greeting+"</h1>"); response.getWriter().println("session=" + request.getSession(true).getId()); } }
Setting a ServletContext
A ServletContextHandler is a specialization of ContextHandler with support for standard servlets. The following code from OneServletContext shows three instances of the helloworld servlet registered with a ServletContextHandler:
public class OneServletContext { public static void main(String[] args) throws Exception { Server server = new Server(8080); ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); context.setContextPath("/"); server.setHandler(context); context.addServlet(new ServletHolder(new HelloServlet()),"/*"); context.addServlet(new ServletHolder(new HelloServlet("Buongiorno Mondo")),"/it/*"); context.addServlet(new ServletHolder(new HelloServlet("Bonjour le Monde")),"/fr/*"); server.start(); server.join(); } }
Setting a Web Application Context
A Web Applications context is a variation of ServletContextHandler that uses the standard layout and web.xml to configure the servlets, filters and other features:
public class OneWebApp { public static void main(String[] args) throws Exception { String jetty_home = System.getProperty("jetty.home",".."); Server server = new Server(8080); WebAppContext webapp = new WebAppContext(); webapp.setContextPath("/"); webapp.setWar(jetty_home+"/webapps/test.war"); server.setHandler(webapp); server.start(); server.join(); } }
If during development, you have not assembled your application into a WAR file, you can run it from its source components with something like:
public class OneWebAppUnassembled { public static void main(String[] args) throws Exception { Server server = new Server(8080); WebAppContext context = new WebAppContext(); context.setDescriptor(context+"/WEB-INF/web.xml");
context.setResourceBase("../test-jetty-webapp/src/main/webapp"); context.setContextPath("/"); context.setParentLoaderPriority(true); server.setHandler(context); server.start(); server.join(); } }
Configuring a Context Handler Collection
A Context Handler Collection uses the longest prefix of the request URI (the contextPath) to select a specific context. The following example combines the previous two examples in a single Jetty server:
public class ManyContexts { public static void main(String[] args) throws Exception { Server server = new Server(8080); ServletContextHandler context0 = new ServletContextHandler(ServletContextHandler.SESSIONS); context0.setContextPath("/ctx0"); context0.addServlet(new ServletHolder(new HelloServlet()),"/*"); context0.addServlet(new ServletHolder(new HelloServlet("Buongiorno Mondo")),"/it/*"); context0.addServlet(new ServletHolder(new HelloServlet("Bonjour le Monde")),"/fr/*"); WebAppContext webapp = new WebAppContext(); webapp.setContextPath("/ctx1"); webapp.setWar(jetty_home+"/webapps/test.war"); ContextHandlerCollection contexts = new ContextHandlerCollection(); contexts.setHandlers(new Handler[] { context0, webapp }); server.setHandler(contexts); server.start(); server.join(); } }
Embedding JSP
Embedding JSP support can be a bit confusing if you look at the Jars under the lib/jsp directory in the jetty distribution. This is because we have to ship from Eclipse with the JSP bundles that are marked up as OSGi bundles, which you cannot directly download from Maven Central. There are dependencies available in Maven Central that work because they were the actual source for the OSGi bundles themselves. The OSGi bundles are simply these Maven Central artifacts decomposed into a few extra bundles.
An example of what you can use follows:
[INFO] org.eclipse.jetty:jetty-jsp-2.1:jar:7.2.2-SNAPSHOT [INFO] +- org.eclipse.jetty:jetty-util:jar:7.2.2-SNAPSHOT:provided [INFO] +- org.mortbay.jetty:jsp-2.1-glassfish:jar:2.1.v20100127:provided [INFO] | +- org.eclipse.jdt.core.compiler:ecj:jar:3.5.1:provided [INFO] | +- org.mortbay.jetty:jsp-api-2.1-glassfish:jar:2.1.v20100127:provided [INFO] | \- ant:ant:jar:1.6.5:provided [INFO] \- javax.servlet:servlet-api:jar:2.5:provided
You should be able to depend on one of the embedding aggregates that we provide to get these dependencies without too much trouble.
http://repo2.maven.org/maven2/org/eclipse/jetty/aggregate
출처 - http://wiki.eclipse.org/Jetty/Tutorial/Embedding_Jetty
고민의 시작은 사용법 괴상한 Tomcat 을 버리자는 것 하나. web.xml 없애고 spring.xml 도 없애서 자바 코드로 모든 설정을 하자는 것 하나. 웹 컨테이너 위에서 war 를 돌리는 것이 아니라 Servlet 컨테이너를 임베딩해서 평범한 자바 어플리케이션 실행시키듯이 main 메서드로 실행하자는 것 하나였습니다.
줄거리는 이러합니다. Jetty 서버를 임베딩해서 JettyServer POJO 를 만듭니다. 기존에 web.xml 에서 하던 Servlet Config 를 Java 코드로 대신합니다. servlet-spring.xml 설정들도 Spring Java Annotation 으로 대신합니다. 기존에 익숙하던 Servlet 모델 개념은 그대로 사용합니다.
기존에 Spring MVC 를 사용하시던 분들은 ContextLoaderListener, DispatcherServlet 에 익숙하실 겁니다. 아래 Jetty 설정 메서드들은 web.xml 에서 하던 것과 완전히 같은 기능을 합니다. 스터틱 파일 서비스를 위해서 Jetty 에 딸려오는 DefaultServlet 을 추가해줬습니다. JspServlet 도 추가했습니다.
package com.drypot.sleek.draft;
import org.apache.jasper.servlet.JspServlet;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.servlet.DispatcherServlet;
public class JettySetter {
public JettySetter() {
}
public void configure(Server server) {
setConnector(server);
setHandler(server);
}
public void setConnector(Server server) {
SelectChannelConnector connector = new SelectChannelConnector();
connector.setPort(8080);
server.addConnector(connector);
}
public void setHandler(Server server) {
ServletContextHandler handler = new ServletContextHandler(ServletContextHandler.SESSIONS) {
@Override
protected boolean isProtectedTarget(String target) {
while (target.startsWith("//"))
target = URIUtil.compactPath(target);
return StringUtil.startsWithIgnoreCase(target, "/web-inf") || StringUtil.startsWithIgnoreCase(target, "/meta-inf");
}
};
handler.setContextPath("/");
handler.setMaxFormContentSize(512 * 1024 * 1024);
handler.setResourceBase("/Users/drypot/Documents/java/sleek/drypot-sleek-web/src/main/webapp");
addContextLoaderListener(handler);
addDispatcherServlet(handler);
addJspServlet(handler);
addDefaultServlet(handler);
server.setHandler(handler);
}
public void addContextLoaderListener(ServletContextHandler handler) {
handler.addEventListener(new ContextLoaderListener());
handler.setInitParameter("contextClass", "org.springframework.web.context.support.AnnotationConfigWebApplicationContext");
handler.setInitParameter("contextConfigLocation", "com.drypot.sleek.draft");
}
public void addDispatcherServlet(ServletContextHandler handler) {
ServletHolder holder = new ServletHolder(new DispatcherServlet());
holder.setInitParameter("contextConfigLocation", "");
holder.setInitOrder(3);
handler.addServlet(holder, "/");
}
public void addJspServlet(ServletContextHandler handler) {
ServletHolder holder = new ServletHolder(new JspServlet());
holder.setInitParameter("modificationTestInterval", "5");
holder.setInitParameter("logVerbosityLevel", "DEBUG");
holder.setInitParameter("sendErrorToClient", "true");
holder.setInitParameter("compilerSourceVM", "1.5");
holder.setInitParameter("compilerTargetVM", "1.5");
holder.setInitParameter("fork", "false");
holder.setInitParameter("trimSpaces", "true");
holder.setInitOrder(2);
handler.addServlet(holder, "*.jsp");
}
public void addDefaultServlet(ServletContextHandler handler) {
ServletHolder holder = new ServletHolder(new DefaultServlet());
//holder.setInitParameter("resourceBase", "");
holder.setInitParameter("dirAllowed", "true");
holder.setInitParameter("welcomeServlets", "false");
holder.setInitParameter("gzip", "false");
handler.addServlet(holder, "*.css");
handler.addServlet(holder, "*.js");
handler.addServlet(holder, "*.ico");
}
public static void main(String[] args) {
try {
Server server = new Server();
new JettySetter().configure(server);
server.start();
server.join();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
servlet-spring.xml 을 대신하는 스프링 설정 클래스입니다. Jetty 설정부에서 contextConfigLocation 으로 Spring Component 스캐닝 범위를 설정하므로 여기에서는 @ComponentScan 어노테이션을 뺏습니다. 평소처럼 Datasource 등을 여기에 줄줄이 매달면 됩니다.
package com.drypot.sleek.draft;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
@EnableTransactionManagement
@EnableWebMvc
public class SpringConfig extends WebMvcConfigurerAdapter {
@Autowired
ApplicationContext context;
@Bean
public String someCoolObj() {
return "The Cool One";
}
}
테스트에 사용했던 Spring MVC 컨트롤러입니다.
package com.drypot.sleek.draft;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class DemoController {
@RequestMapping(value = "/hello", method = RequestMethod.GET)
@ResponseBody
public String hello(@RequestParam String name) {
return "Hello " + name;
}
}
다른 글에서 자세히 언급했었는데 Java Code-base Configuration 은 Spring 3.1.0.M2 부터 가능합니다.
Spring : Code-based Configuration For Spring MVC
http://drypot.com/post/215
Spring 관련 디펜던시는
<repositories>
<repository>
<id>org.springframework.maven.milestone</id>
<name>Spring Maven Milestone Repository</name>
<url>http://maven.springframework.org/milestone</url>
</repository>
</repositories>
<properties>
<org.springframework.version>3.1.0.M2</org.springframework.version>
</properties>
...
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework.version}</version>
</dependency>
Jetty 관련 디펜던시는
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>8.0.0.v20110901</version>
</dependency>
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jsp-2.1-glassfish</artifactId>
<version>2.1.v20100127</version>
</dependency>
JSP 처리하는 jasper 가 참 문제였는데, 예전 처럼 tomcat 에 포함된 jasper 를 그냥 가져다 쓰지 못합니다. Jetty 주위에 있는 jasper 수정판이 여러 가지인데 현재로서는 위에 포함한 아티펙트가 제일 쓰기 편합니다.
Jetty 를 쓰지 않고 개발자들에게 익숙한 Tomcat 을 써도 Embedded 스타일 코드를 쉽게 만들 수는 있습니다. 그런데 Tomcat 구조가 참으로 이상하여 당장 해놔야 겠다는 생각은 들지 않고 있는데, 인터넷 검색하시거나 org.apache.catalina.startup.Tomcat 클래스 사용하시면 별로 어렵지 않게(약간의 짜증을 수반? =,=) Tomcat 도 임베딩하실 수 있습니다.
출처 - http://drypot.tumblr.com/post/11171558936/jetty-spring-jsp-noxml
출처 - http://javacan.tistory.com/entry/Jetty-Embedding-In-Maven-Project
jetty embedding
jetty를 embed해서 사용하는 방법에 대해서 쉽게 따라해 볼 수 있는 페이지이다.
링크 : http://wiki.eclipse.org/Jetty/Tutorial/Jetty_HelloWorld
따라해보기위해서는 물론 java가 설치되어있어야한다.
jetty 라이브러리를 다운로드하는 방법이다. 여기서는 jetty의 모든 class가 들어있는 jar를 다운로드한다.
mkdir Demo cd Demo JETTY_VERSION=7.0.2.v20100331 wget -U none http://repo1.maven.org/maven2/org/eclipse/jetty/aggregate/jetty-all/$JETTY_VERSION/jetty-all-$JETTY_VERSION.jar wget -U none http://repo1.maven.org/maven2/javax/servlet/servlet-api/2.5/servlet-api-2.5.jar
라이브러리를 다운로드 한 directory에 아래와 같은 java코드를 작성한다.
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.ServletException; import java.io.IOException; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.handler.AbstractHandler; public class HelloWorld extends AbstractHandler { public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { response.setContentType("text/html;charset=utf-8"); response.setStatus(HttpServletResponse.SC_OK); baseRequest.setHandled(true); response.getWriter().println("<h1>Hello World</h1>"); } public static void main(String[] args) throws Exception { Server server = new Server(8080); server.setHandler(new HelloWorld()); server.start(); server.join(); } }
아래와 같이 클래스패스에 다운로드 받은 jar를 알려주고 컴파일 한다.
javac -cp servlet-api-2.5.jar:jetty-all-$JETTY_VERSION.jar HelloWorld.java
컴파일된 HelloWorld를 실행하면 서버가 뜬다.
java -cp .:servlet-api-2.5.jar:jetty-all-$JETTY_VERSION.jar HelloWorld
난 20108포트로 띄웠다.
브라우저로 접근한 모습
출처 - http://the-earth.tistory.com/149
September 21, 2010
How to embed Jetty Server
« Track window and widget events with AT-SPI | Main | AutoFS - Auto-Mount of Hard Drives »The Jetty J2EE webcontainer represents a highly modularized server application. Because of that you are able to start the web server directly in Java code. For example that allows developers to deploy Servlets, JSP pages and WAR files within JUnit tests or use the webcontainer directly for other issues. The following example shows basically how to start and configure Jetty.
package org.developers.blog.jetty.embedded; import org.mortbay.jetty.Connector; import org.mortbay.jetty.Server; import org.mortbay.jetty.nio.SelectChannelConnector; import org.mortbay.jetty.webapp.WebAppContext; public class JettyExample { public static void main(String[] args) throws Exception { Server server = new Server(); Connector connector = new SelectChannelConnector(); connector.setPort(8080); connector.setHost("127.0.0.1"); server.addConnector(connector); WebAppContext wac = new WebAppContext(); wac.setContextPath("/"); //expanded war or path of war file wac.setWar("./src/main/resources/web"); server.addHandler(wac); server.setStopAtShutdown(true); //another way is to use an external jetty configuration file //XmlConfiguration configuration = //new XmlConfiguration(new File("/path/jetty-config.xml").toURL()); //configuration.configure(server); server.start(); }
출처 - http://developers-blog.org/blog/default/2010/09/21/How-to-embedd-Jetty-Server
Jetty는 Jetty Embeding에서 포스팅한 것 처럼 프로그램에 임베딩이 가능한 Web Server/라이브러리이다.
요즘 Spring에 맛을 들인 후 여기저기 뒤적뒤적 하고 있는데... Spring과 Jetty를 통합하는 예제를 우연찮게 발견했다.
Christopher J. Stehno라는 분의 포스팅을 보면 매우 쉽고 간결하게 통합할 수 있는 예제가 있다. Spring의 위력을 절감하게 되는 부분이다.
- Spring 설정
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="server.Server" class="org.mortbay.jetty.Server" destroy-method="stop">
<property name="threadPool">
<bean class="org.mortbay.thread.QueuedThreadPool">
<property name="maxThreads" value="100" />
</bean>
</property>
<property name="connectors">
<list>
<bean class="org.mortbay.jetty.nio.SelectChannelConnector">
<property name="port" value="8080" />
<property name="maxIdleTime" value="30000" />
</bean>
</list>
</property>
<property name="handler">
<bean class="org.mortbay.jetty.handler.HandlerCollection">
<property name="handlers">
<list>
<ref local="server.ContextHandlerCollection" />
<bean class="org.mortbay.jetty.handler.DefaultHandler" />
<bean class="org.mortbay.jetty.handler.RequestLogHandler">
<property name="requestLog">
<bean class="org.mortbay.jetty.NCSARequestLog">
<constructor-arg value="cfg/logs/jetty-yyyy_mm_dd.log" />
<property name="extended" value="false"/>
</bean>
</property>
</bean>
</list>
</property>
</bean>
</property>
<property name="userRealms">
<list>
<bean class="org.mortbay.jetty.security.HashUserRealm">
<property name="name" value="Test Realm" />
<property name="config" value="cfg/etc/realm.properties" />
</bean>
</list>
</property>
<property name="stopAtShutdown" value="true" />
<property name="sendServerVersion" value="true"/>
</bean>
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="server.Server" />
<property name="targetMethod" value="addLifeCycle" />
<property name="arguments">
<list><ref local="server.ContextDeployer" /></list>
</property>
</bean>
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="server.Server" />
<property name="targetMethod" value="addLifeCycle" />
<property name="arguments">
<list><ref local="server.WebAppDeployer" /></list>
</property>
</bean>
<bean id="server.ContextHandlerCollection" class="org.mortbay.jetty.handler.ContextHandlerCollection" />
<bean id="server.ContextDeployer" class="org.mortbay.jetty.deployer.ContextDeployer">
<property name="contexts" ref="server.ContextHandlerCollection" />
<property name="configurationDir">
<bean class="org.mortbay.resource.FileResource">
<constructor-arg value="file://./cfg/contexts" />
</bean>
</property>
<property name="scanInterval" value="1" />
</bean>
<bean id="server.WebAppDeployer" class="org.mortbay.jetty.deployer.WebAppDeployer">
<property name="contexts" ref="server.ContextHandlerCollection" />
<property name="webAppDir" value="cfg/webapps" />
<property name="parentLoaderPriority" value="false" />
<property name="extract" value="true" />
<property name="allowDuplicates" value="false" />
<property name="defaultsDescriptor" value="cfg/etc/webdefault.xml" />
</bean>
</beans>
- Main Class
public static void main(String[] args) throws Exception {
ApplicationContext context = new FileSystemXmlApplicationContext("cfg/server-context.xml");
Server server = (Server)context.getBean("server.Server");
server.start();
server.join();
}
}
여기서 설정 몇가지만 변경해 주면... 웹서버가 만들어진다.
기존에 만들었던 Embed된 소스에 즉시 적용해 봐야겠다.
출처 - http://pigmon.tistory.com/157
'Web > WAS' 카테고리의 다른 글
jetty - No JSP support. Check that JSP jarsare in lib/jsp and that the JSP option has been specified to start.jar (0) | 2012.11.22 |
---|---|
jetty - maven 연동 (0) | 2012.11.21 |
jetty - 이클립스에서 사용 (0) | 2012.11.20 |
jetty 설치 및 실행 (0) | 2012.11.10 |
웹 애플리케이션 서버(Web Application Server; WAS) (0) | 2012.11.09 |