I have embedded jetty server I want to create RESTful GET service which returns a pojo in XML/JSON format as response. can anyone give me one basic example how to write the handler for jetty? the example given only shows text type output.
问题:
回答1:
I suggest you use Jersey java REST framework (http://jersey.java.net/). The framework is easy to learn. You can use Object to Xml converter like JAXB to make your life easier.
回答2:
Hmm. I had the same problem. I solved it by having a utility jar file that reads a properties file to configure contexts for Jersey Servlets, handlers, static files, exploded webapps etc in such a way that the resulting application jar configures the contexts automagically and is run from the command line.
Basically I have a HandlerCollection and successively add the servlets to it.
ServletHolder servletHolder = new ServletHolder(ServletContainer.class);
servletHolder.setInitParameter(
"com.sun.jersey.config.property.packages",
clazz.getPackage().getName()
);
ServletContextHandler context = new ServletContextHandler(
server,
"/some_path",
ServletContextHandler.SESSIONS
);
context.setClassLoader(Thread.currentThread().getContextClassLoader());
context.addServlet(servletHolder, "/");
context.setHandler(handler);
handlers.addHandler(context);
Then I have an example Jersey servlet:
@Path("/user1")
public class JerseyResource1 {
public JerseyResource1() {
}
@GET
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public ExamplePojo getUser() {
log.debug("Inside ExampleJerseyResource1 getUser()");
ExamplePojo pojo = new ExamplePojo();
pojo.setNumber(100);
pojo.setWords("hello world 1");
return pojo;
}
}
The first calls gets a perf hit as Jersey configures stuff, but it works just peachy.
A junit test looks like this:
@BeforeClass
public static void setUpClass() throws Exception {
Thread startupThread = new Thread() {
@Override
public void run() {
try {
System.out.println("Starting Jetty...");
JettyMain.main(new String[] {});
// CHECKSTYLE_OFF: Because it does throw Exception!
} catch (Exception ex) {
// CHECKSTYLE_ON
System.err.println("Error Starting Jetty: " + ex);
}
}
};
startupThread.start();
System.out.println("Waiting a few seconds to ensure Jetty is started");
Thread.sleep(2000);
System.out.println("Ok. Starting tests");
}
@AfterClass
public static void tearDownClass() throws Exception {
ClientConfig config = new DefaultClientConfig();
Client client = Client.create(config);
WebResource service = client.resource(
UriBuilder.fromUri(
"http://localhost:8080/admin/stop?secret=YourSecret"
).build());
service.get(String.class);
System.out.println("Sent stop command");
}
@Test
public void testJersey1() {
System.out.println("Jersey1 returns correct 200 and body");
ClientResponse response = getService(
"http://localhost:8080/jersey1/user1/"
).get(ClientResponse.class);
assertEquals("Response is 200", 200, response.getStatus());
assertEquals(
"Valid body",
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
+ "<examplePojo><number>100</number><words>hello world 1</words></examplePojo>",
response.getEntity(String.class)
);
System.out.println("--> WORKED!");
}
CURL calls look like this:
# Show static public files folder:
curl -v http://localhost:8080/public/x.html
curl -v http://localhost:8080/public/x.txt
# Use baseline handlers:
curl -v http://localhost:8080/handler1/?url=hello
curl -v http://localhost:8080/handler2/?url=hello
# Use raw servlets with specific contexts:
curl -v http://localhost:8080/servlet1?url=hello
curl -v http://localhost:8080/servlet2?url=hello
# Call a Jersey servlet using default Accept header (xml):
curl -v http://localhost:8080/jersey1/user1/
curl -v http://localhost:8080/jersey2/user2/
# Request Jersey servlet but want JSON:
curl -v --header "Accept:application/json" http://localhost:8080/jersey1/user1/
# Use an exploded webapp:
curl -v http://localhost:8080/www/x.html
# Stop the server:
curl -v http://localhost:8080/admin/stop?secret=MySecret
Er... The following is not a plug. Seriously. It might be refused by the company...
I have a complete solution by which 1 jar file is added as a dependency and several tiny files (app.properties, classpath.sh, log4j.properties and run.sh) that completely configure a Jetty8 instance for numerous contexts, Handlers, Servlets, JerseyServlets, StaticFiles and ExplodedWebApps. The result is a self contained executable Jar that restarts, reloads, stops etc with almost zero effort. An added benefit is that it can act as a pseudo-classloader and avoids jar-hell. (A side effect is that mvn clean test works against it also)
If any one is interested, ping me and I can see if the company will allow me to OpenSource it and get it up on GitHub. Or perhaps even document it via my own site http://www.randomactsofsentience.com
回答3:
Just FYI on embedded Jetty in general... I have created a github project that I humbly submit may cover most of the embedded jetty issues that keep cropping up. See https://github.com/ZenGirl/EmbeddedJettyRepository for details.