JAX-RS 是 jakarta.ws.rs 包中用于 HTTP 资源的 Jakarta 标准 API 和规范。
它定义注解、请求和响应类型、客户端 API、提供程序以及服务器发送事件支持。
Jersey 是符合该规范的 JAX-RS 实现。
JAX-RS 不同于 JAX-WS,后者关注 XML Web 服务。
定义资源 #
在编译期添加 Jakarta REST API,并在运行期添加 JAX-RS 实现。
资源类使用 @Path;方法使用 HTTP 方法注解,并可以增加相对路径:
@Path("/users")
@Produces(MediaType.APPLICATION_JSON)
public class UserResource {
@GET
@Path("/{id}")
public User get(@PathParam("id") long id) {
return service.find(id);
}
@POST
@Consumes(MediaType.APPLICATION_JSON)
public Response create(User input) {
User created = service.create(input);
return Response.created(
URI.create("/users/" + created.id())).entity(created).build();
}
}Application 子类可以使用 @ApplicationPath("/api") 注解。
外围容器或实现决定请求如何到达 JAX-RS 运行时。
绑定请求 #
为非请求体方法参数添加注解,标明其来源:
@PathParam、@QueryParam和@MatrixParam读取 URI 组件。@HeaderParam、@CookieParam和@FormParam读取标头、Cookie 和表单数据。@Context注入 JAX-RS 上下文对象。
@GET
public Response search(
@QueryParam("q") String query,
@QueryParam("limit") @DefaultValue("20") int limit) {
return Response.ok(service.search(query, limit)).build();
}未注解的资源方法参数通常是请求实体。其 Java 类型必须受到 MessageBodyReader 支持;
例如,从 JSON 绑定到对象需要已安装的 JSON 提供程序。声明 @Consumes 以使契约明确。
InputStream 可以接受原始实体,但单独的核心 JAX-RS 不会解析 multipart/form-data;
应使用受支持的多部分提供程序,例如 Jersey 的 multipart 模块。
使用 @BeanParam 将多个参数绑定组合到一个 bean:
public class PageRequest {
@QueryParam("offset") @DefaultValue("0") int offset;
@QueryParam("limit") @DefaultValue("20") int limit;
}将其作为 @BeanParam PageRequest page 使用。可以显式验证输入,
也可以使用运行时提供的 Jakarta Validation 集成。
生成响应和错误 #
方法可以直接返回实体,也可以返回 Response 来显式控制状态、标头和实体。
@Produces 参与内容协商。返回适当的状态和稳定的错误表示;不要向客户端暴露堆栈跟踪。
抛出 WebApplicationException(例如 NotFoundException 或 BadRequestException)会提供 HTTP 响应。
对于应用程序异常,编写 ExceptionMapper<T> 并使用 @Provider 标注:
@Provider
public class IllegalArgumentMapper
implements ExceptionMapper<IllegalArgumentException> {
public Response toResponse(IllegalArgumentException error) {
return Response.status(Response.Status.BAD_REQUEST)
.entity(Map.of("error", error.getMessage())).build();
}
}运行时会选择适用的映射器,其异常类型是所抛异常的最近超类型。 如果没有适用映射器,则根据容器集成生成服务器错误响应。
使用 Jersey 部署 #
Jersey 实现 JAX-RS 契约,但本身不接受 TCP 连接。在 servlet 容器中,
添加 org.glassfish.jersey.containers:jersey-container-servlet,
注册 org.glassfish.jersey.servlet.ServletContainer,并配置资源包扫描或 ResourceConfig。
对于嵌入式服务器,创建 ResourceConfig 并将其传递给受支持的 Jersey 容器。
尽可能让应用代码依赖 jakarta.ws.rs,并将 Jersey 特定配置隔离在部署边界。
评论
在 GitHub 上阅读或评论(发表评论需要登录)