72

JAX-RS 为 HTTP 动词(例如GET( @GET) 和POST( @POST))提供注释,但没有@PATCH注释。如何为PATCHHTTP 动词添加注释?

类似于以下内容:

@PATCH
public Response someCode() {
    // Code to handle the request
}
4

6 回答 6

74

我在这里得到了答案。

只需定义一个自定义 Patch 注释,这意味着您必须使用以下代码编写一个PATCH.java文件:

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@HttpMethod("PATCH")
public @interface PATCH {
}

导入包含 PATCH.java的包,然后您可以像使用其他 HTTP 方法注释一样使用它:

@PATCH
@Path("/data/{keyspace}")
@Produces({ "application/json" })
public void patchRow(@PathParam("keyspace") String keyspace, String body) 
throws Exception

我使用这个@PATCH 将一些 JSON 发送到我的 REST 服务。

于 2013-07-27T11:37:17.013 回答
25

使用 JAX-RS 2.1?

JAX-RS 2.1添加@PATCH到支持的 HTTP 方法列表中。

使用招摇?

在使用Swagger记录 REST API 时,您可以使用包中定义的现有@PATCH注解io.swagger.jaxrs

使用泽西岛和 Dropwizard?

Dropwizard在包中定义了一个@PATCH注解。io.dropwizard.jersey

自己写

如果上述方法对您不起作用,您可以编写自己的@PATCH注释:

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@HttpMethod("PATCH")
public @interface PATCH { }

注解用于将 HTTP 方法的名称与@HttpMethod注解相关联,从而创建 JAX-RS 规范所称的资源方法指示符

您自己的@PATCH注释应该可以在 Swagger 中正常工作。

于 2016-04-08T13:20:54.440 回答
5

在 Jersey 中这可以正常工作,但是当使用 Jersey Client 测试你的资源类时,你会得到异常:

java.net.ProtocolException: Invalid HTTP method: PATCH

有一个解决方法,通过设置客户端属性

HttpUrlConnectorProvider.SET_METHOD_WORKAROUND 

但是等一下,你最终会遇到以下异常:

javax.ws.rs.ProcessingException: java.net.ProtocolException: HTTP method PATCH doesn't support output

因此,除了使用 Jersey 2.10 版更改为 Apache HTTP 客户端库之外别无他法,它易于配置以使用 Apache HTTP 客户端,您只需在扩展的测试类中覆盖客户端配置方法JerseyTest

@Override
protected void configureClient(ClientConfig config) {
  config.register(CustomJacksonJsonProvider.class);
  ConnectorProvider connectorProvider = new ApacheConnectorProvider();
  config.connectorProvider(connectorProvider);
}

您还需要添加另一个 Maven 依赖项,jersey-apache-connector并且jersey-test-framework-provider-external,请参阅Jersey 文档

于 2014-07-29T06:54:20.523 回答
1

JAX-RS API 2.0.1 没有 PATCH。但是,查看 JAX-RS API 2.2-SNAPSHOT 代码,现在包含 PATCH。代码是:

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@HttpMethod(HttpMethod.PATCH)
@Documented
public @interface PATCH {
}

这是链接

在 2.2 发布之前,您可以使用相同的代码进行补救。对于 HttpMethod.PATCH,只需将其替换为“PATCH”即可。

于 2017-08-23T05:46:14.827 回答
0

这是我用 jax-rs 2.2 实现的 PATCH

人物类

public class Person {


    private Integer id;
    @NotEmpty
    @Size(min = 2)
    private String name;
    @NotEmpty
    @Size(min = 2)
    private String surname;

    // getters and setters
}

人员 REST API

/**
 * see https://tools.ietf.org/html/rfc6902 for further explanations
 */
@PATCH
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Path("/{id}")
public void modify(@PathParam("id") int id,
                   JsonArray input) {
    personDB.update(id, input);
}

个人数据库

public void update(int id, final JsonArray input) {

    final Person person = people.stream()
            .filter(i -> i.getId() == id)
            .findAny()
            .orElseThrow(NotFoundException::new);

    final JsonObject source; // json object person representation

    try (JsonReader jsonReader = Json.createReader(new StringReader(Json.createValue(JsonbBuilder.create().toJson(person)).getString()))) {
        source = jsonReader.readObject();
    }

    final JsonObject output; // apply update to source object
    try {
        output = Json.createPatch(input).apply(source);
    } catch (JsonException e) {
        throw new BadRequestException(e.getMessage());
    }

    try (final Jsonb jsonb = JsonbBuilder.create()) { // apply updates to final object
        final Person target = jsonb.fromJson(output.toString(), Person.class);
        person.setName(target.getName());
        person.setSurname(target.getSurname());
    } catch (Exception e) {
        throw new InternalServerErrorException(e);
    }
}

测试 API:

PATCH /person/{id}
[
    {
        "op": "add",
        "path": "/name",
        "value": "John"
    }
]

在这里您可以找到带有完整示例的项目

另请参阅RFC以获取更多说明

于 2021-10-22T09:19:33.750 回答
0

如果您使用的是 CXF 3.1.2 或更高版本(来源),则可以使用org.apache.cxf.jaxrs.ext.PATCH.

于 2017-12-19T10:37:38.023 回答