Jersey test - Http Delete method with JSON request

2019-08-13 15:22发布

问题:

I am using Jersey Test to test Rest service DELETE method:

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

I have tried the example below and other methods:

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

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

and

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

But it does not work.

How to make Http Delete in Jersey test?

回答1:

According to the HTTP specification

If a DELETE request includes an entity body, the body is ignored

Though a lot servers still support the entity body, I guess because of this Jersey considers the body as breaking HTTP Compliance. Jersey validates compliance with client requests. To get around this validation, you can set the client property

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.

To configure it in JerseyTest, you can do

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

Assuming you are making your requests by calling the target(..) method of the JerseyTest, the above configuration will be for all request. If you just want to remove the validation for certain requests, you can also set the property on the WebTarget and not do the above configuration.

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

EDIT

Another thing I might mention is that Grizzly is one of the servers that doesn't support the entity, unless configured. I'm not quite sure though how to configure that in JerseyTest. So if you are using the Grizzly test provider, it may not even work on the server side.

If this is the case, you try to use the in-memory test provider, or use the jetty provider