Jakarta RESTful Web Services介绍

Jakarta RESTful Web Services(jakarta.ws.rs)详解 一、简介 jakarta.ws.rs 是 Jakarta EE 规范的一部分,用于构建符合 REST 架构风格的 Web 服务。它是 JAX-RS(Java API for RESTful Web Services)的 …

Jakarta RESTful Web Services(jakarta.ws.rs)详解

一、简介

jakarta.ws.rs 是 Jakarta EE 规范的一部分,用于构建符合 REST 架构风格的 Web 服务。它是 JAX-RS(Java API for RESTful Web Services)的 Jakarta 命名空间版本,前身是 Java EE 的 javax.ws.rs

JAX-RS 提供了一套基于注解的简洁方式,来定义资源类、处理 HTTP 请求、生成响应,以及集成内容协商、过滤器、拦截器、异常处理等高级特性。它是 Jakarta EE 中开发 REST API 的标准方式,兼容实现包括 Jersey、RESTEasy、Apache CXF 等。

二、核心包结构

jakarta.ws.rs 包结构主要如下:

  • jakarta.ws.rs.core:核心类型,如 ResponseUriInfoMediaType 等。
  • jakarta.ws.rs.client:JAX-RS 客户端 API。
  • jakarta.ws.rs.container:服务器端容器相关 API,如过滤器、拦截器。
  • jakarta.ws.rs.ext:扩展 SPI,如自定义实体解析器。
  • jakarta.ws.rs:顶级注解接口定义,如 @Path@GET@POST 等。

三、基本注解与使用

JAX-RS 使用一系列注解将普通的 Java 类变成 Web 服务端点。常见注解如下:

1. 资源路径注解:@Path

@Path("/hello")
public class HelloResource {
    @GET
    public String sayHello() {
        return "Hello, World!";
    }
}
  • @Path 可用于类和方法,指定请求路径。
  • 支持路径参数,如 /users/{id}

2. HTTP 方法注解

  • @GET:处理 GET 请求。
  • @POST:处理 POST 请求。
  • @PUT:处理 PUT 请求。
  • @DELETE:处理 DELETE 请求。
  • @HEAD@OPTIONS@PATCH 也支持。
@POST
@Consumes(MediaType.APPLICATION_JSON)
public Response createUser(User user) {
    // 保存用户逻辑
    return Response.status(Response.Status.CREATED).build();
}

3. 请求参数绑定注解

  • @PathParam:绑定路径参数。
  • @QueryParam:绑定查询参数。
  • @HeaderParam:绑定请求头参数。
  • @FormParam:绑定表单字段。
  • @CookieParam:绑定 Cookie 值。
@GET
@Path("/{id}")
public Response getUser(@PathParam("id") int id) {
    User user = findUserById(id);
    return Response.ok(user).build();
}

4. 消费与生产内容类型

  • @Consumes:声明请求体支持的媒体类型。
  • @Produces:声明响应体产生的媒体类型。
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response createUser(User user) {
    save(user);
    return Response.ok(user).build();
}

四、Response 与 ResponseBuilder

JAX-RS 的 Response 类型用于自定义返回信息。

return Response.status(200)
               .entity("Success")
               .header("X-Custom-Header", "value")
               .build();

常见状态码:

  • 200 OK
  • 201 Created
  • 204 No Content
  • 400 Bad Request
  • 401 Unauthorized
  • 404 Not Found
  • 500 Internal Server Error

五、JAX-RS 客户端 API(jakarta.ws.rs.client

除了服务器端,JAX-RS 也提供了标准的 REST 客户端 API。

Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://localhost:8080/api/hello");
String response = target.request(MediaType.TEXT_PLAIN).get(String.class);

支持链式构造、请求构造器、实体封装等高级操作:

User user = new User("Tom", 25);
Response response = target
    .request()
    .post(Entity.entity(user, MediaType.APPLICATION_JSON));

六、内容协商

JAX-RS 支持基于 AcceptContent-Type 头部自动匹配请求与响应格式。

@GET
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public User getUser() {
    return new User("Tom", 25);
}

客户端发送请求时设置 Accept:

Accept: application/xml

服务端会自动返回 XML。

七、异常处理

可以通过定义 ExceptionMapper<T extends Throwable> 处理全局异常:

@Provider
public class NotFoundExceptionMapper implements ExceptionMapper<NotFoundException> {
    @Override
    public Response toResponse(NotFoundException ex) {
        return Response.status(Response.Status.NOT_FOUND)
                       .entity("Resource not found")
                       .build();
    }
}

八、拦截器与过滤器

过滤器主要用于修改请求或响应;拦截器则用于拦截实体的读写过程。

1. 过滤器

@Provider
public class LoggingFilter implements ContainerRequestFilter {
    public void filter(ContainerRequestContext requestContext) {
        System.out.println("Incoming request: " + requestContext.getUriInfo().getRequestUri());
    }
}

2. 拦截器

@Provider
public class LoggingReaderInterceptor implements ReaderInterceptor {
    public Object aroundReadFrom(ReaderInterceptorContext context) throws IOException {
        InputStream in = context.getInputStream();
        // 可读取输入流日志
        return context.proceed();
    }
}

九、实体提供者(MessageBodyReader/Writer)

自定义类型的序列化与反序列化:

@Provider
@Produces("application/custom")
public class MyWriter implements MessageBodyWriter<MyObject> {
    // 实现 writeTo() 方法
}

用于扩展非标准类型(如 YAML、ProtoBuf)的处理方式。

十、部署与运行

JAX-RS 可部署在 Jakarta EE 容器(如 Payara、WildFly),也可用独立容器运行,如使用 Jersey + Jetty:

ResourceConfig config = new ResourceConfig();
config.packages("com.example.resources");

HttpServer server = GrizzlyHttpServerFactory.createHttpServer(
    URI.create("http://localhost:8080/api/"), config);

十一、完整示例项目

@Path("/users")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class UserResource {

    private static final Map<Integer, User> userDb = new HashMap<>();

    @GET
    public List<User> listUsers() {
        return new ArrayList<>(userDb.values());
    }

    @GET
    @Path("/{id}")
    public Response getUser(@PathParam("id") int id) {
        User user = userDb.get(id);
        if (user == null) {
            return Response.status(Response.Status.NOT_FOUND).build();
        }
        return Response.ok(user).build();
    }

    @POST
    public Response createUser(User user) {
        int id = userDb.size() + 1;
        user.setId(id);
        userDb.put(id, user);
        return Response.status(Response.Status.CREATED).entity(user).build();
    }

    @PUT
    @Path("/{id}")
    public Response updateUser(@PathParam("id") int id, User updated) {
        if (!userDb.containsKey(id)) {
            return Response.status(Response.Status.NOT_FOUND).build();
        }
        updated.setId(id);
        userDb.put(id, updated);
        return Response.ok(updated).build();
    }

    @DELETE
    @Path("/{id}")
    public Response deleteUser(@PathParam("id") int id) {
        User removed = userDb.remove(id);
        if (removed == null) {
            return Response.status(Response.Status.NOT_FOUND).build();
        }
        return Response.noContent().build();
    }
}

对应的 User 类:

public class User {
    private int id;
    private String name;
    private int age;

    // getters and setters
}

十二、总结与建议

  • jakarta.ws.rs 提供构建 REST API 的全面能力,是 Jakarta EE 中极具实用性的 API。
  • 建议结合 Jersey、RESTEasy 等实现,搭配 CDI、JPA 等 Jakarta 技术构建完整的企业级应用。
  • REST API 文档可结合 OpenAPI(Swagger)自动生成。
  • JAX-RS 更适合无状态服务设计,适合现代微服务架构风格。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页