X

Pavel Bucek's Weblog

  • February 4, 2011

Jersey Client - Making requests with HttpURLConnection hack

HttpURLConnection provided in JDK has serious limitation - you can't do requests with arbitrary chosen method - actually it limit methods to some subsed defined in javadoc, which is NOT extendable in any way.. which might cause some problems. For example you can't do PATCH request because it wasn't in HTTP spec in the time of writing that class. And if you would want to use it for making WebDav client, you are totally lost, it just can't be done.

 Well, until now ;)

One Jersey user - Markus Karg came with a workaround. Method name can be "injected" to one field in HttpURLConnection via injection and it will be used to create request. We don't want to have this enabled by default, so if you want to use it, you need to set property URLConnectionClientHandler.PROPERTY_HTTP_URL_CONNECTION_SET_METHOD_WORKAROUND to true.

        DefaultClientConfig config = new DefaultClientConfig();
        config.getProperties().put(URLConnectionClientHandler.PROPERTY_HTTP_URL_CONNECTION_SET_METHOD_WORKAROUND, true);
        Client c = Client.create(config);
        WebResource r = c.resource(getUri().path("test/entity").build());
        ClientResponse cr = r.method("GOTOSLEEP", ClientResponse.class);

will produce:

Feb 4, 2011 11:25:44 AM com.sun.jersey.api.client.filter.LoggingFilter log
INFO: 1 \* Client out-bound request
1 > GOTOSLEEP http://localhost:9997/test/test

and you can cleary see that method "GOTOSLEEP" was used and HttpURLConnection don't complain about anything. This workaround has some limitation - you can't put an entity to the request. And additionally, it \*probably\* wont work on some containers and maybe in future versions of JDK (containers sometimes have their own implementation of HttpURLConnection).

This functionality is available in current Jersey trunk (1.6-SNAPSHOT) and in promoted build 1.6-ea02 (which will be released later today).

Join the discussion

Comments ( 1 )
  • guest Saturday, July 28, 2012

    But wouldn't an non-HTTP method trip up because when the introspection looks for the GOTOSLEEP method/field on HttpURLConnection, it will not find it ... how would that be compensated for?

    private static final void setRequestMethodUsingWorkaroundForJREBug(final HttpURLConnection httpURLConnection, final String method) {

    try {

    httpURLConnection.setRequestMethod(method); // Check whether we are running on a buggy JRE

    } catch (final ProtocolException pe) {

    try {

    final Class<?> httpURLConnectionClass = httpURLConnection.getClass();

    final Field methodField = httpURLConnectionClass.getSuperclass().getDeclaredField("method");

    methodField.setAccessible(true);

    methodField.set(httpURLConnection, method);

    } catch (final Exception e) {

    throw new RuntimeException(e);

    }

    }

    }


Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.