RESTEasy指南

2025/04/08

1. 简介

JAX-RS(Java API for RESTful Web Services)是一组Java API,提供对创建REST API的支持,并且该框架充分利用了注解来简化这些API的开发和部署。

在本教程中,我们将使用RESTEasy(JBoss提供的JAX-RS规范的可移植实现),以创建简单的RESTful Web服务。

2. 项目设置

我们将考虑两种可能的情况:

  • 独立安装:适用于每个应用服务器
  • JBoss AS设置:仅考虑在JBoss AS中部署

2.1 独立设置

让我们从使用独立设置的JBoss WildFly 10开始。

JBoss WildFly 10附带RESTEasy版本6.2.9.Final,但正如你所见,我们将使用新的6.2.9.Final版本配置pom.xml。

并且得益于resteasy-servlet-initializer,RESTEasy通过ServletContainerInitializer集成接口提供与独立Servlet 3.0容器的集成。

让我们看一下pom.xml:

<properties>
    <resteasy.version>6.2.9.Final</resteasy.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.jboss.resteasy</groupId>
        <artifactId>resteasy-servlet-initializer</artifactId>
        <version>${resteasy.version}</version>
    </dependency>
    <dependency>
        <groupId>org.jboss.resteasy</groupId>
        <artifactId>resteasy-client</artifactId>
        <version>${resteasy.version}</version>
    </dependency>
</dependencies>

jboss-deployment-structure.xml

在JBoss中,以WAR、JAR或EAR形式部署的所有内容都是模块,这些模块称为动态模块。

除此之外,$JBOSS_HOME/modules中还有一些静态模块。由于JBoss有RESTEasy静态模块-对于独立部署,jboss-deployment-structure.xml是必需的,以便排除其中一些模块。

这样,我们的WAR中包含的所有类和JAR文件都将被加载:

<jboss-deployment-structure>
    <deployment>
        <exclude-subsystems>
            <subsystem name="resteasy" />
        </exclude-subsystems>
        <exclusions>
            <module name="javaee.api" />
            <module name="jakarta.ws.rs.api"/>
            <module name="org.jboss.resteasy.resteasy-jaxrs" />
        </exclusions>
        <local-last value="true" />
    </deployment>
</jboss-deployment-structure>

2.2 JBoss设置

如果你要使用JBoss 6或更高版本运行RESTEasy,你可以选择采用应用程序服务器中已经捆绑的库,从而简化pom:

<dependencies>
    <dependency>
        <groupId>org.jboss.resteasy</groupId>
        <artifactId>resteasy-jaxrs</artifactId>
        <version>${resteasy.version}</version>
    </dependency>
</dependencies>

请注意,jboss-deployment-structure.xml不再需要。

3. 服务器端代码

3.1 Servlet版本3 web.xml

现在让我们快速浏览一下我们简单项目的web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
     http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">

    <display-name>RestEasy Example</display-name>

    <context-param>
        <param-name>resteasy.servlet.mapping.prefix</param-name>
        <param-value>/rest</param-value>
    </context-param>
</web-app>

仅当你想在API应用程序前面添加相对路径时才需要resteasy.servlet.mapping.prefix

此时,需要特别注意的是,我们没有在web.xml中声明任何Servlet,因为resteasy-servlet-initializer已作为依赖添加到pom.xml中。原因是-RESTEasy提供了实现jakarta.server.ServletContainerInitializer的org.jboss.resteasy.plugins.servlet.ResteasyServletInitializer类。

ServletContainerInitializer是一个初始化程序,它在任何Servlet上下文准备好之前执行-你可以使用此初始化程序为你的应用程序定义Servlet、过滤器或监听器。

3.2 Application类

jakarta.ws.rs.core.Application类是一个标准JAX-RS类,你可以实现它来提供有关部署的信息:

@ApplicationPath("/rest")
public class RestEasyServices extends Application {

    private Set<Object> singletons = new HashSet<Object>();

    public RestEasyServices() {
        singletons.add(new MovieCrudService());
    }

    @Override
    public Set<Object> getSingletons() {
        return singletons;
    }
}

如你所见,这只是一个列出所有JAX-RS根资源和提供程序的类,并使用@ApplicationPath注解进行标注。

如果返回类和单例的任何空集,则将扫描WAR以查找JAX-RS注解资源和提供程序类。

3.3 服务实现类

最后,让我们在这里看一个实际的API定义:

@Path("/movies")
public class MovieCrudService {

    private Map<String, Movie> inventory = new HashMap<String, Movie>();

    @GET
    @Path("/getinfo")
    @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
    public Movie movieByImdbId(@QueryParam("imdbId") String imdbId) {
        if (inventory.containsKey(imdbId)) {
            return inventory.get(imdbId);
        } else {
            return null;
        }
    }

    @POST
    @Path("/addmovie")
    @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
    public Response addMovie(Movie movie) {
        if (null != inventory.get(movie.getImdbId())) {
            return Response
                    .status(Response.Status.NOT_MODIFIED)
                    .entity("Movie is Already in the database.").build();
        }

        inventory.put(movie.getImdbId(), movie);
        return Response.status(Response.Status.CREATED).build();
    }
}

4. 总结

在此快速教程中,我们介绍了RESTEasy并用它构建了一个超级简单的API。

Show Disqus Comments

Post Directory

扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章