如何使用HTTP DELETE使用JerseyClientBuilder传递表单数据

时间:2016-08-08 20:02:13

标签: java rest jersey

我目前正在针对基于DropWizard的REST API应用程序编写单元测试。我正在测试的端点之一是添加和删除对象属性的2种方法。 POST调用创建一个属性,DELETE调用可以删除它。我能够提交一个POST请求,其中包含标识该属性的表单数据。我在提交带有标识属性的表单数据的DELETE请求时遇到了问题。要提交POST,我使用:

Client client = new JerseyClientBuilder(RULE.getEnvironment())
                                        .build(String.format("test client %d", _id));
_id++;

return client.target("http://localhost:5000/Object/12345/Property")
                     .request(MediaType.APPLICATION_JSON_TYPE)
                     .post(Entity.entity(form,MediaType.APPLICATION_FORM_URLENCODED_TYPE), Response.class);

这可以按预期工作。但是,JerseyInvocation.Builder对象的DELETE相关方法似乎缺少一种方法来传递定义表单参数的Entity对象。如果我尝试使用较低级别的.method()函数:

Client client = new JerseyClientBuilder(RULE.getEnvironment()).build(String.format("test client %d", _id));
_id++;

return client.target("http://localhost:5000/Object/12345/Property")
                     .request(MediaType.APPLICATION_JSON_TYPE)
                     .method("DELETE", 
                             Entity.entity(form,MediaType.APPLICATION_FORM_URLENCODED_TYPE), 
                             Response.class);

我收到这个完全没有用的例外:

java.lang.IllegalStateException: Entity must be null for http method DELETE.

我对HTTP规范的理解(以及stackoverflow的共识:Is an entity body allowed for an HTTP DELETE request?)表明具有DELETE的消息体完全在标准范围内,尽管某些实现任意决定阻止它。泽西岛似乎是有限的实施之一。这个问题的理想最小努力解决方案是什么? (假设DropWizard应用程序是不可变的,“只是重写REST API以不使用DELETE或使用不同的REST URI模式”的答案都没有帮助)我需要针对现有实现进行测试,而不是编写新的实现。

1 个答案:

答案 0 :(得分:3)

从Jersey 2.18版本开始,JerseyInvocation类使用HashMap验证HTTP方法及其实体,如下所示:

map.put("DELETE", EntityPresence.MUST_BE_NULL);

这就是您收到错误的原因“http方法DELETE的实体必须为null”。

注意:您必须告诉jersey停止其余的执行。请提供Jersey客户端配置属性ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION并添加以下给定代码以禁止验证,以便继续向Entity发送DELETE请求。 / p>

ClientConfig clientConfig = new ClientConfig();
clientConfig.property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true);
Client client = ClientBuilder.newClient(clientConfig);