Jetty is an open source servlet container that provides a running environment for java-based Web content, such as JSPs and servlet. Jetty is written in the Java language, and its APIs are published in the form of a set of jar packages. Developers can instantiate an jetty container as an object and quickly provide network and web connectivity for some standalone-run (stand-alone) Java applications.
This article includes the following:
1. What is the meaning of an embedded servlet container?
2. Build an embedded container: Use the Jetty API
3. Separate configuration from code: XML-driven configuration files
4. Executable Jar Package
5. Conclusion
6. Resources
If you let a person name an open source servlet container, they might answer Apache Tomcat. But, Tomcat is not alone, we still have jetty. Jetty as an optional servlet container is just an extra feature, and it's really famous because it's designed as a servlet container that can be embedded in other Java code. This means that the development team provides jetty as a set of jar files, so you can instantiate the Servlet container as an object in your own code and manipulate the container object.
Jetty is not a new face in the servlet container; it has emerged since 1998. Jetty's release follows the Apache 2.0 Open source protocol, where you can use jetty without paying royalties for free software and business software.
In this article, I'll give you some insight into why you need an embedded servlet container, explain the basics of the jetty API, and show how to use an XML configuration file to minimize jetty code.
The sample code for this article was tested under Jetty5.1.10 and the Sun JDK 1.5.0_03.
Copyright notice: Any Web site authorized by the matrix, please be sure to retain the following author information and links
Author: Ethan Mccallum;shenpipi
Original: http://www.onjava.com/pub/a/onjava/2006/06/14/what-is-jetty.html
Matrix:http://www.matrix.org.cn/resource/article/44/44588_jetty.html
Keywords: Jetty
What is the meaning of embedded servlet containers?
Before you adopt jetty, the sensible thing to do is to ask yourself first why you need to embed a servlet container in your application. What caught my eye was the ability of jetty to provide servlet functionality for an existing application. This capability is useful for many organizations, including Java EE application Server manufacturers, software testers, and custom software manufacturers. Most Java developers can be divided into these three scenarios.
First, consider the edge of building your own Java EE application server. According to the specification, a complete application server must provide SERVLET,EJB, as well as some other features. You should adopt components that already exist and have been tested and use jetty instead of starting from scratch. Apache Geronimo, JBoss, and objectweb Jonas these teams do the same when building their own Java EE application servers.
Software testers benefit from the need to build their own servlet containers when existing containers do not meet their needs. For example, a colleague once wanted to find a way to drive a unit test that he wrote for the Web service code. For his situation--several developers plus several automated unit tests running in cruise control--I showed him how dynamic in his unit test group (suites test) (on the Fly) uses jetty to instantiate a servlet container. No extra scripts, no remaining files, only code.
For those who develop Java EE applications as products, why just provide a war file. This will give you a headache for the specification of the container and increase the cost of your technical support. Instead, you can provide the customer with an application that has startup, stop, and management capabilities. Even hardware manufacturers can benefit from it: Jetty requires only 350k of memory for ordinary HTTP services (without a servlet), which makes it possible to use them in smart devices. You can provide web-based control panels and have all the functionality of Java Web applications without worrying about the pressures of independent containers.
Finally, I'm betting that the most interesting application of the embedded servlet container will happen to people who never write a traditional web-based application. A combination of Java EE and HTTP can be used as a background for a C/s structure program. Consider an event-driven service, such as the (hypothetical) Message-driven Bank (mentioned in another article on Onjava), which starts from the main () method and waits for incoming requests, just like the daemon programs in UNIX. There must be some people who want to expose this program to a user-based style, such as a GUI desktop application, which is only a matter of time.
To create your own underlying components, protocol and socket communication codes are the most annoying, and can distract people from business logic, not to mention things that might be debugged in the future. Using an embedded jetty container to expose business logic through the HTTP protocol is a good choice, and it does not have to make too many changes to existing programs. Choose to use the Swing,swt,xui GUI and wrap the request into an HTTP POST operation, REST, and even soap to complete the loop. These generic protocols may be slightly less likely to be a bit less common than custom-specific protocols, but in a short time you will benefit from these existing, validated protocols and save a lot of effort.
building an embedded container: Using the jetty API
Hopefully the above ideas will stimulate your appetite and let you try the embedded servlet container. The sample program Step1driver demonstrates a simple service based on jetty. It creates an instance of a servlet container, maps a servlet class to a URI, and uses some URLs to invoke the servlet. For the simplicity of the code, I sacrificed some of the quality of the code.
The service object is the jetty container, and an instance of such an object produces a container.
Server service = new server ();
As a result, the service object is like a guesthouse without a door: No one can enter and use it, so there is no use. The next line of code sets the container to listen on localhost, Port 7501.
Service.addlistener ("localhost:7501");
To listen on all interface, do not use the hostname ("AddListener (": 7501 ")"). As the name implies, you can call AddListener () multiple times to listen on multiple interface.
Note that a reference to the server object is maintained in the sample code, which is needed in the future to stop the container.
Mapping a Web application to a service is intuitive:
Service.addwebapplication (
"/somecontextpath",
"/path/to/some.war"
) ;
This call processes the Web.xml Deployment Descriptor (descriptor) in a Web application to map the filter servlet and servlet, just as other containers do. The first parameter is the context path, and all of the servlet and JSP for the Web application are mapped to the URI relative to the path. The second parameter is the Web application itself. Can be a packaged war file or a Web application in directory format. Calling Addwebapplication () again can be used to add other Web applications.
Note that jetty does not need a complete compliant war file to deploy the servlet. If you write a custom application protocol that carries the HTTP protocol, you can load a single servlet and deliver it over the network. It is not necessary to use the war file just to make a non-Web application have access through the HTTP protocol.
To map this one-off servlet, create a context by invoking GetContext () dynamically on the service object. This sample code establishes a context called/embed.
Servlethttpcontext CTX = (servlethttpcontext)
Service.getcontext ("/embed");
If the context does not exist, calling GetContext () will create a new context
Next, call Addservlet () to map a servlet class to a URI
Ctx.addservlet (
"Simple",//servlet name
"/trythis/*",//URI mapping pattern
"Sample. Simpleservlet "//class name
) ;
The first parameter is a descriptive name for the servlet. The second parameter is the path to map, equivalent to the <url-pattern> in the Web.xml servlet map. This mapping path is relative to the context path, and this is/embed. "/*" means that the servlet receives a URI such as/embed/trythis, and it also receives all URIs that begin with this, such as/embed/trythis/123. This mapping is useful when using a single servlet as a gateway to a large system. Struts and Axis are examples of such mapping methods used in practical applications.
Sometimes you might want to make your context the root context, or "/", which is more like a normal HTTP service. Jetty supports this feature through Service.setrootwebapp ().
Service.setrootwebapp (
"/path/to/another.war"
) ;
The only one parameter is the path to a Web application.
The container is not active at this time. And it does not attempt to bind the socket to be tapped, the startup container needs to invoke:
Service.start ();
This method returns immediately, because Jetty will run the service in a separate thread. So, when the container is running, main () can do anything else.
The rest of the code uses a set of URLs to invoke this embedded container. These calls ensure that the container is already running and that the servlet works the way it expects.
Closing a container is as intuitive as starting it
Service.stop ();
Note The catch statement in the outermost try/catch block.
{
service.start ();
//... URL calls to mapped servlet ...
service.stop ();
}catch (Throwable t) {
system.exit (1);
}
The
displayed call System.exit () ensures that the container is closed when an exception occurs. Otherwise, the container runs continuously so the entire application does not exit. The
must remember that jetty Web applications are not limited to access using code. If I remove service.stop () from the code just now, the container will run and I can invoke the servlet in the browser, for example, the
http://localhost:7501/embed/TryThis/ Someextrainfo
You don't have to do exactly what I say. This sample code can be run as an Eclipse project. You can also write a shell script that runs on the unix/linux command line. In both cases, be sure that jetty is in your classpath.
Separate configuration from code: XML-driven configuration file
Although the jetty API is very intuitive and concise, a direct call to the Jetty API will have a lot of configuration information--port number, context Path,servlet class name--buried in the code. Jetty provides an xml-based configuration to replace the direct call API so that you can keep your code clean by putting the configuration information outside the code. The XML configuration file for the
Jetty is based on Java reflection. The classes in Java.lang.reflect represent methods and classes in Java so that you can instantiate an object and use the method's name and parameter type to invoke its method. In this case, the jetty XML configuration file parser translates the XML element and attributes into a reflection method call. The code in the
excerpt from the Step2driver sample class is an improved version of Step1driver. If you use a configuration file, you must have a certain amount of jetty code to load it.
URL serviceconfig =/* Load XML file/*;
can use an InputStream or URL
Xmlconfiguration serverfactory =
New Xmlconfiguration (ServiceConfig);
Server Service =
(Server) serverfactory.newinstance ();
Admittedly, this does not save much code than the Step1driver example, but even if you are adding a new servlet or Web application, the Step2driver code will not increase. The method of directly invoking service and context objects becomes worse with increasing configuration.
Listing 1 is an XML file loaded by Step2driver. The properties of the top <Configure> element indicate the class to instantiate. This is the jetty server object.
<!--1-->
<configure class= "Org.mortbay.jetty.Server" >
<!--2-->
<call name= "AddListener" >
<Arg>
<!--3-->
<new
class= "Org.mortbay.http.SocketListener" >
<!--4-->
<set name= "Host" >
<!--5-->
<systemproperty
Name= "Service.listen.host"
default= "localhost"
/>
</Set>
<set name= "Port" >
<systemproperty
Name= "Service.listen.port"
default= "7501"
/>
</Set>
</New>
</Arg>
</Call>
<call name= "GetContext" >
<Arg>/embed</Arg>
<!--
Call methods on the return value of
Server.getcontext ()
-->
<!--6-->
<call name= "Addservlet" >
<!--servlet name-->
<Arg> "Simple" </Arg>
<!--URL pattern-->
<Arg>/TryThis/*</Arg>
<!--servlet class-->
<arg>sample. Simpleservlet</arg>
</Call>
</Call>
</Configure>
The <Call> element represents the method to invoke on the server object. This is called AddListener (), such as the Mark (2), which itself has a child element called <arg>, which indicates the parameter of the method. Here I can only pass a string value as the listener's address, while AddListener () needs to accept a SocketListener object as an argument. So, I'm going to use <New> to instantiate a new SocketListener object at tag (3). The code at Mark 2 and 3 is equivalent to the following code:
Server.addlistener (
New SocketListener (...)
) ;
In order to configure SocketListener itself, you must use a <Call> to invoke its Sethost () method, and since this method follows the JavaBean naming convention, the example code uses the <Set> element (4) As a quick way. In the background, jetty assigns a value to the property specified by the Name property in set, and decides what method to call, here is Sethost ()
The Sethost () parameter is not shown here, but it uses <SystemProperty> to get the value of the parameter from the system properties, Service.listen.host and Service.listen.port from the system parameters. If the system properties are undefined, you can specify a default value using default. Here, 4 and 5 are equivalent to the following calls:
Socketlistener.sethost (
System.getproperty (
"Service.listen.host",
"LocalHost"
)
) ;
Finally, note that the <Call> element at Mark 6 is in <Call> that calls the GetContext method. The internal <Call> is acting on the returned object of the external <Call>, here, the Addservlet () method on the context returned by Getservlet () is invoked:
Server.getcontext (). Addservlet (...);
The wisdom of the Jetty team lies in further in-depth processing of this XML configuration file: We can note that all of the Jetty specific calls in Listing 1 are the values of the element and attribute, not the name, which means that the XML configuration file can be used on any class, not just in the Jetty class. Depending on how your application is written, you can configure it all using the jetty XML configuration file.
Executable Jar Package
If you use jetty XML to configure your application, you will need to use a lot of repetitive code to load your config file and run your application. But you can use jetty's executable Start.jar to load files for you, which will save you more code.
For example, you can use the following command line to load the jetty service in Step2driver.
Classpath= ... various Jetty JARs ...
Java "
-djetty.class.path=${classpath} "
-jar <jetty Install Path>/start.jar "
Standalone.xml
Note that this command simply loads the XML file to build the container and the listener, so it does not invoke the code in the sample code to test the URL.
Conclusion
An embedded jetty servlet container allows your web to use Java applications without being packaged into a formal Web application format. This provides a variety of possibilities to make jetty a versatile helper in your toolbox.
Of course, what I write here does not contain all the content of jetty. I suggest you visit Jetty's website to get more documentation and sample code.
Resources
---The sample code for this article.
The--the jetty Web site contains documents, examples, and links to downloads. It also contains a list page of items that use jetty. Also noteworthy is the Jettyplus subproject, which provides functionality (attributes) in Jndi, data sources, and other servlet specifications.
--sun ' s Java EE Web site, which contains links to the servlet specification
The--java Reflection in Action discusses the Java reflection and introspection APIs in detail.
For comparison, Onjava also publishes an article about Tomcat's embedded side.
--This article mentions the use of Swing, Xui, and SWT as a java-based GUI front-end (frontend) application
--message-driven Bank comes from another article, "Java without the application Server."
Ethan McCallum is committed to Unix/linux, C + +, and Java research.