> For the complete documentation index, see [llms.txt](https://jack80342.gitbook.io/spring-boot/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://jack80342.gitbook.io/spring-boot/v.-spring-boot-actuator/50.-endpoints/50.8-implementing-custom-endpoints/50.8.2-custom-web-endpoints.md).

# 50.8.2 自定义网络端点

在`@Endpoint`、`@WebEndpoint`或者`@WebEndpointExtension`上的操作会自动使用Jersey、Spring MVC或者Spring WebFlux通过HTTP暴露。

**网络端点请求谓语**

请求谓语会在网络暴露的端点上，为每一个操作自动产生。

**路径**

谓语的路径由端点的ID以及网络暴露的基础路径所决定。默认的基础路径是`/actuator`。比如，ID为`sessions`的端点会使用`/actuator/sessions`，作为它在谓语里的路径。

路径可以通过使用`@Selector`标注一个或者更多的操作方法参数，进一步自定义。这样的一个参数会添加进路径谓语，作为一个路径变量。当端点操作被调用时，变量值会传入操作方法。

**HTTP方法**

谓语的HTTP方法由操作类型所决定。如下所示：

| 操作                 | HTTP方法   |
| ------------------ | -------- |
| `@ReadOperation`   | `GET`    |
| `@WriteOperation`  | `POST`   |
| `@DeleteOperation` | `DELETE` |

**Consumes**

对于使用请求体的`@WriteOperation`（HTTP `POST`），谓语的consumes子句是`application/vnd.spring-boot.actuator.v2+json, application/json`。对于其它所有的操作，consumes子句是空的。

**Produces**

谓语的produces子句由`@DeleteOperation`、`@ReadOperation`和`@WriteOperation`注解的`produces`属性所决定。这个属性是可选的。如果它没被使用，produces子句会被自动决定。

如果操作方法返回`void`或者`Void`，produces子句是空的。如果操作方法返回`org.springframework.core.io.Resource`，produces子句`application/octet-stream`。对于其它所有的操作，produces子句是`application/vnd.spring-boot.actuator.v2+json, application/json`。

**网络端点响应状态**

端点操作的默认响应状态取决于操作类型（读取、写入或者删除）。

`@ReadOperation`返回一个值，响应状态将会是200（OK）。如果没有返回一个值，响应状态将会是404（没有找到）。

如果`@WriteOperation`或者`@DeleteOperation`返回一个值，响应状态将会是200（OK）。如果没有返回一个值，响应状态将会是204（没有内容）。

如果一个操作被调用了，但是没有需要的参数，或者参数无法转换成需要的类型，操作方法将不会被调用，响应状态将会是400（错误请求）。

**网络端点范围请求**

HTTP范围请求可以用于请求HTTP资源的一部分。当使用Spring MVC或者Spring Web Flux时，返回`org.springframework.core.io.Resource`的操作自动支持范围请求。

**注** 使用Jersey时，范围请求不被支持。

**网络端点安全**

在网络端点或是网络特定端点扩展上的操作会收到`urrent java.security.Principal`或者`org.springframework.boot.actuate.endpoint.SecurityContext`，作为一个方法参数。前者典型地和`@Nullable`结合使用，来为认证用户和未认证用户提供不同的行为。后者使用它的`isUserInRole(String)`方法，典型地用于执行权限检查。
