我目前正在针对基于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模式”的答案都没有帮助)我需要针对现有实现进行测试,而不是编写新的实现。
答案 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);