我正在使用 Jersey Test 来测试 Rest 服务 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删除?
最佳答案
根据HTTP规范
If a DELETE request includes an entity body, the body is ignored
虽然很多服务器仍然支持实体主体,但我想是因为这个 Jersey 认为主体违反了 HTTP 合规性。 Jersey 验证是否符合客户要求。要绕过此验证,您可以设置客户端属性
ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION
If true, the strict validation of HTTP specification compliance will be suppressed.
By default, Jersey client runtime performs certain HTTP compliance checks (such as which HTTP methods can facilitate non-empty request entities etc.) in order to fail fast with an exception when user tries to establish a communication non-compliant with HTTP specification. Users who need to override these compliance checks and avoid the exceptions being thrown by Jersey client runtime for some reason, can set this property to true. As a result, the compliance issues will be merely reported in a log and no exceptions will be thrown.
Note that the property suppresses the Jersey layer exceptions. Chances are that the non-compliant behavior will cause different set of exceptions being raised in the underlying I/O connector layer.
This property can be configured in a client runtime configuration or directly on an individual request. In case of conflict, request-specific property value takes precedence over value configured in the runtime configuration.
The default value is false.
在 JerseyTest
中配置它,你可以这样做
@Override
public void configureClient(ClientConfig config) {
config.property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true);
}
假设您通过调用 target(..)
提出请求JerseyTest
的方法,以上配置将适用于所有请求。如果您只想删除某些请求的验证,您还可以在 WebTarget
上设置该属性。并且不进行上述配置。
target(...).property(...).request()...
编辑
我可能提到的另一件事是 Grizzly 是不支持该实体的服务器之一, unless configured 。我不太确定如何在 JerseyTest 中配置它。因此,如果您使用 Grizzly 测试提供程序,它甚至可能无法在服务器端工作。
如果是这种情况,你尝试使用内存测试提供程序,或者使用jetty提供程序
编辑 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
,但对我来说似乎是一个合理的方法,至少在单元测试中是这样。
关于testing - Jersey 测试 - 带有 JSON 请求的 Http Delete 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36310863/