2

我正在使用 Jersey Test 来测试 Rest service DELETE 方法:

@DELETE
@Path("/myPath")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public MyResponse myMethod(MyRequest myRequest) {

我试过下面的例子和其他方法:

Entity<MyRequest> requestEntity = Entity.entity(new MyRequest(arg1, arg2), MediaType.APPLICATION_JSON);

target(MY_URI).request(MediaType.APPLICATION_JSON).method("DELETE", requestEntity)

target(MY_URI).request(MediaType.APPLICATION_JSON).build("DELETE", requestEntity).invoke();

但它不起作用。

如何在 Jersey 测试中进行 Http 删除?

4

1 回答 1

3

根据 HTTP 规范

如果 DELETE 请求包含实体主体,则忽略主体

虽然很多服务器仍然支持实体主体,但我猜是因为这个 Jersey 认为主体违反了 HTTP 合规性。Jersey 验证是否符合客户要求。要绕过此验证,您可以设置客户端属性

ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION

如果为 true,将禁止对 HTTP 规范合规性的严格验证。

默认情况下,Jersey 客户端运行时执行某些 HTTP 合规性检查(例如哪些 HTTP 方法可以促进非空请求实体等),以便在用户尝试建立不符合 HTTP 规范的通信时快速失败并出现异常。需要覆盖这些合规性检查并避免由于某种原因由 Jersey 客户端运行时引发的异常的用户可以将此属性设置为 true。因此,合规性问题将仅在日志中报告,不会引发异常。

请注意,该属性会抑制 Jersey 层异常。不合规行为可能会导致在底层 I/O 连接器层中引发不同的异常集。

可以在客户端运行时配置中或直接在单个请求上配置此属性。如果发生冲突,特定于请求的属性值优先于运行时配置中配置的值。

默认值为假。

要配置它JerseyTest,你可以做

@Override
public void configureClient(ClientConfig config) {
   config.property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true);
}

假设您通过调用 的target(..)方法发出请求JerseyTest,则上述配置将适用于所有请求。如果你只是想去掉对某些请求的验证,你也可以在上面设置属性WebTarget而不做上面的配置。

target(...).property(...).request()...

编辑

我可能会提到的另一件事是,Grizzly 是不支持实体的服务器之一,除非已配置。我不太确定如何在 JerseyTest 中配置它。因此,如果您使用的是 Grizzly 测试提供程序,它甚至可能无法在服务器端运行。

如果是这种情况,您尝试使用内存测试提供程序,或使用码头提供程序

编辑灰熊配置

编辑由Emanuele Lombardi提供

您可以使用以下代码段配置 Grizzly 测试提供程序:

@Override
protected TestContainerFactory getTestContainerFactory() throws TestContainerException {
    return new TestContainerFactory() {

        private final GrizzlyTestContainerFactory grizzlyTestContainerFactory = new GrizzlyTestContainerFactory();

        @Override
        public TestContainer create(URI baseUri, DeploymentContext deploymentContext) {
            TestContainer testContainer = grizzlyTestContainerFactory.create(baseUri, deploymentContext);
            try {
                HttpServer server = (HttpServer) FieldUtils.readDeclaredField(testContainer, "server", true);
                server.getServerConfiguration().setAllowPayloadForUndefinedHttpMethods(true);
            } catch (IllegalAccessException e) {
                fail(e.getMessage());
            }
            return testContainer;
        }
    };
}

下面的方法应该在 GrizzlyServer 启动之前被调用。

server.getServerConfiguration().setAllowPayloadForUndefinedHttpMethods(true)‌​;

使用反射检索服务器实例(在本例中通过org.apache.commons.lang3.reflect.FieldUtils#readDeclaredField)。
此代码一直有效,直到server字段名称未更改为GrizzlyTestContainerFactory#GrizzlyTestContainer,但对我来说似乎是一种合理的方法,至少在单元测试中是这样。

于 2016-03-30T14:05:02.730 回答