在本教程中,我们使用 Jersey 和嵌入式 Jetty 创建一个简单的 Java REST 应用程序。我们还展示了如何将应用程序打包到可执行的 uber JAR 中。
Jersey 是一个开源框架,用于在 Java 中开发 RESTful Web 服务。它是 Java API for RESTful Web Services (JAX-RS) 规范的参考实现。
Jetty 是一个 Java HTTP (Web) 服务器和 Java Servlet 容器。它可以很容易地嵌入到设备、工具、框架、应用服务器和集群中。
RESTful 应用程序
RESTFul 应用程序创建一个遵循 REST 架构风格的系统 (API),用于设计网络应用程序。RESTful 应用程序使用 HTTP 请求对资源执行 CRUD(创建/读取/更新/删除)操作。
代码示例
以下是使用 Jersey 和嵌入式 Jetty 服务器创建的一个非常简单的 Java RESTful 应用程序。
$ tree
.
├── pom.xml
└── src
├── main
│ ├── java
│ │ └── com
│ │ └── zetcode
│ │ ├── app
│ │ │ └── Main.java
│ │ └── res
│ │ └── MyMessage.java
│ └── resources
└── test
└── java
这是我们的项目结构。
该项目由两个 Java 源文件和 Maven POM 文件组成。
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.zetcode</groupId>
<artifactId>JerseyJettyEx</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>JerseyJettyEx</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-jetty-http</artifactId>
<version>2.25</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-util</artifactId>
<version>9.4.0.v20161208</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<version>2.25</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<version>2.25</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>9.4.0.v20161208</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>9.4.0.v20161208</version>
</dependency>
</dependencies>
<build>
<finalName>JerseyJettyEx</finalName>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.5.0</version>
<executions>
<execution>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>com.zetcode.app.Main</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
在pom.xml
文件中,我们有必要的 Jersey 和 Jetty 依赖项。我们还使用exec-maven-plugin
,它用于执行 Java 程序。
package com.zetcode.res;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
@Path("msg")
public class MyMessage {
@GET
@Produces(MediaType.TEXT_PLAIN)
public String getMessage() {
return "My message\n";
}
}
我们定义一个资源。它响应 HTTP GET 请求并返回纯文本。
@Path("msg")
public class MyMessage {
@Path
注释标识资源响应的 URL 路径 。
package com.zetcode.app;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.glassfish.jersey.servlet.ServletContainer;
public class Main {
public static void main(String[] args) {
Server server = new Server(8080);
ServletContextHandler ctx =
new ServletContextHandler(ServletContextHandler.NO_SESSIONS);
ctx.setContextPath("/");
server.setHandler(ctx);
ServletHolder serHol = ctx.addServlet(ServletContainer.class, "/rest/*");
serHol.setInitOrder(1);
serHol.setInitParameter("jersey.config.server.provider.packages",
"com.zetcode.res");
try {
server.start();
server.join();
} catch (Exception ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
} finally {
server.destroy();
}
}
}
在Main.java
中,我们设置并启动 Jetty。
Server server = new Server(8080);
Jetty 服务器开始监听 8080 端口。
ServletContextHandler ctx =
new ServletContextHandler(ServletContextHandler.NO_SESSIONS);
下一步是创建一个ServletContextHandler
对象。
ctx.setContextPath("/");
使用该setContextPath()
方法,我们设置应用程序映射到的路径。
ServletHolder serHol = ctx.addServlet(ServletContainer.class, "/rest/*");
我们将 Jersey 添加ServletContainer
到 Jetty servlet holder。这基本上将泽西岛与 Jetty 连接起来。
serHol.setInitParameter("jersey.config.server.provider.packages",
"com.zetcode.res");
在这里,我们告诉 Jersey 去哪里寻找资源。
构建和运行应用程序
在以下步骤中,我们构建并运行应用程序。
$ mvn package
mvn package
我们使用命令 构建应用程序。
$ mvn exec:java
应用程序使用mvn exec:java
命令启动。
$ curl localhost:8080/rest/msg
My message
我们使用curl
工具向我们的资源发出 HTTP GET 请求。
Uber JAR
Uber JAR是一个 JAR,它在一个 JAR 文件中包含了我们的包及其所有依赖项。这样的 JAR 也称为胖 JAR。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<configuration>
<createDependencyReducedPom>true</createDependencyReducedPom>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>com.zetcode.app.Main</Main-Class>
</manifestEntries>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
有了它,maven-shade-plugin
我们可以创建一个包含所有依赖项的可执行 JAR。
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>com.zetcode.app.Main</Main-Class>
</manifestEntries>
</transformer>
为了使 JAR 可执行,它必须在清单中有一个主类。这是通过ManifestResourceTransformer
.
$ mvn clean package
我们清理并构建应用程序。
$ java -jar target/JerseyJettyEx-1.0-SNAPSHOT.jar
我们使用这个命令来启动应用程序。
在本教程中,我们使用 Jersey 和嵌入式 Jetty 创建了一个简单的 Java REST 应用程序。