Sending a PATCH request from JAX-RS client?

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Sending a PATCH request from JAX-RS client?

Simon Roberts
I have been bullied into using the PATCH approach for partial updates, and had no problem creating a server side annotation and implementation for this.

However, when I try to write client code for testing, it fails. It seems to be systemic, rather than an error on my part, as the error shows up as 

java.net.ProtocolException: Invalid HTTP method: PATCH
at java.net.HttpURLConnection.setRequestMethod(HttpURLConnection.java:440)

and a quick check of the documentation for HttpURLConnection does indeed indicate that it's unwilling to allow anything other than the specfic methods it lists, and that list doesn't include PATCH.

So is the JAX-RS client unable to do PATCH (or other custom methods)? Or is there some approach to getting this to work?

In case it's of any interest, my attempt to create this request is nutshelled in this:

Response r = ib1.build("PATCH", Entity.json(new CustomerTO("Phoenix", null))).invoke();

Any pointers will be gratefully accepted...

Cheers,
Simon


--
Simon Roberts
Certified Professional Photographer
http://dancingcloudphotography.com
(303) 249 3613
Reply | Threaded
Open this post in threaded view
|

Re: Sending a PATCH request from JAX-RS client?

Markus Karg-2-3

See https://blogs.oracle.com/PavelBucek/entry/jersey_client_making_requests_with but AFAIK the name of the property was changed meanwhile.

 

Regards

-Markus

 

 

From: [hidden email] [mailto:[hidden email]] On Behalf Of Simon Roberts
Sent: Dienstag, 7. April 2015 21:55
To: [hidden email]
Subject: [Jersey] Sending a PATCH request from JAX-RS client?

 

I have been bullied into using the PATCH approach for partial updates, and had no problem creating a server side annotation and implementation for this.

 

However, when I try to write client code for testing, it fails. It seems to be systemic, rather than an error on my part, as the error shows up as 

 

java.net.ProtocolException: Invalid HTTP method: PATCH

            at java.net.HttpURLConnection.setRequestMethod(HttpURLConnection.java:440)

 

and a quick check of the documentation for HttpURLConnection does indeed indicate that it's unwilling to allow anything other than the specfic methods it lists, and that list doesn't include PATCH.

 

So is the JAX-RS client unable to do PATCH (or other custom methods)? Or is there some approach to getting this to work?

 

In case it's of any interest, my attempt to create this request is nutshelled in this:

 

Response r = ib1.build("PATCH", Entity.json(new CustomerTO("Phoenix", null))).invoke();

 

Any pointers will be gratefully accepted...

 

Cheers,

Simon

 

 

--

Simon Roberts
Certified Professional Photographer
http://dancingcloudphotography.com
(303) 249 3613

Reply | Threaded
Open this post in threaded view
|

Re: Sending a PATCH request from JAX-RS client?

Simon Roberts
In reply to this post by Simon Roberts
Thanks Markus,

That pushed my search a little further, and eventually I found that Jersey has a (seemingly undocumented?) feature for this:

client.property(HttpUrlConnectorProvider.SET_METHOD_WORKAROUND, true);

Seems to solve this adequately. Weird that it doens't appear to show up in the docs. Perhaps PATCH isn't all that common?

Cheers,
Simon


Subject: [Jersey] Re: Sending a PATCH request from JAX-RS client?

See https://blogs.oracle.com/PavelBucek/entry/jersey_client_making_requests_with but AFAIK the name of the property was changed meanwhile.

 

Regards

-Markus


Reply | Threaded
Open this post in threaded view
|

Re: Sending a PATCH request from JAX-RS client?

Craig McClanahan-2
When I had a similar problem recently, I chose to have my server implement HttpMethodOverrideFilter (from Jersey) so that lame (non-PATCH-capable) clients could send an X-HTTP-Method-Override header and do a POST.  Clients that do understand how to PATCH can still do it.

Craig


On Thu, Apr 9, 2015 at 10:13 AM, Simon Roberts <[hidden email]> wrote:
Thanks Markus,

That pushed my search a little further, and eventually I found that Jersey has a (seemingly undocumented?) feature for this:

client.property(HttpUrlConnectorProvider.SET_METHOD_WORKAROUND, true);

Seems to solve this adequately. Weird that it doens't appear to show up in the docs. Perhaps PATCH isn't all that common?

Cheers,
Simon


Subject: [Jersey] Re: Sending a PATCH request from JAX-RS client?

See https://blogs.oracle.com/PavelBucek/entry/jersey_client_making_requests_with but AFAIK the name of the property was changed meanwhile.

 

Regards

-Markus



Reply | Threaded
Open this post in threaded view
|

Re: Sending a PATCH request from JAX-RS client?

Markus Karg-2-3

Craig,

 

Let me chime in again.

 

You can make this solution portable by simply writing your own HTTP Method Override Filter (Paraphrasing Arun Gupta’s recent advice: “if there is a standard solution, don’t use the proprietary alternative”). (NB this would be a perfect start for a library of portable JAX-RS extensions!).

 

An example how to do this is shown in this article of Adam Bien on the Oracle web site (http://www.oracle.com/technetwork/articles/java/jaxrs20-1929352.html):

 

@Provider

@PreMatching

public class HttpMethodOverrideEnabler implements ContainerRequestFilter {

    public void filter(ContainerRequestContext requestContext) throws IOException {

        String override = requestContext.getHeaders().getFirst("X-HTTP-Method-Override");

        if (override != null) {

            requestContext.setMethod(override);

        }

    }

}

 

Regards

-Markus

 

Von: Craig McClanahan [mailto:[hidden email]]
Gesendet: Donnerstag, 9. April 2015 21:50
An: [hidden email]
Betreff: [Jersey] Re: Sending a PATCH request from JAX-RS client?

 

When I had a similar problem recently, I chose to have my server implement HttpMethodOverrideFilter (from Jersey) so that lame (non-PATCH-capable) clients could send an X-HTTP-Method-Override header and do a POST.  Clients that do understand how to PATCH can still do it.

 

Craig

 

 

On Thu, Apr 9, 2015 at 10:13 AM, Simon Roberts <[hidden email]> wrote:

Thanks Markus,

 

That pushed my search a little further, and eventually I found that Jersey has a (seemingly undocumented?) feature for this:

 

client.property(HttpUrlConnectorProvider.SET_METHOD_WORKAROUND, true);

 

Seems to solve this adequately. Weird that it doens't appear to show up in the docs. Perhaps PATCH isn't all that common?

 

Cheers,

Simon

 

 

Subject: [Jersey] Re: Sending a PATCH request from JAX-RS client?

See https://blogs.oracle.com/PavelBucek/entry/jersey_client_making_requests_with but AFAIK the name of the property was changed meanwhile.

 

Regards

-Markus

 

 

Reply | Threaded
Open this post in threaded view
|

Re: Sending a PATCH request from JAX-RS client?

Markus Karg-2-3
In reply to this post by Simon Roberts

It has nothing to do with PATCH in particular, the problem is more related to the interpretation of the HTTP specification: It explicitly names some HTTP verbs, but it does not explicitly say that any HTTP implementation must be able to process any future additions like PATCH. BTW, I contributed the technology behind SET_METHOD_WORKAROUND to Jersey as a need to run WebDAV verbs actually, not particularly for the PATCH verb. Jersey internally uses HttpUrlConnection which explicitly forbids some verbs, and the Jersey team had not choice to either ignore my request or to simply add my patch as an optional feature. The feature in turn has to stay optional for backwards compatibility – because some existing applications may rely on HttpUrlConnection’s rejection of custom verbs.

 

I hope that the planned HTTP 2 Client in Java SE 9 will solve this so the trick hopefully won’t be needed anymore then. J

 

Regards

-Markus

 

Von: [hidden email] [mailto:[hidden email]] Im Auftrag von Simon Roberts
Gesendet: Donnerstag, 9. April 2015 19:13
An: [hidden email]
Betreff: [Jersey] Re: Sending a PATCH request from JAX-RS client?

 

Thanks Markus,

 

That pushed my search a little further, and eventually I found that Jersey has a (seemingly undocumented?) feature for this:

 

client.property(HttpUrlConnectorProvider.SET_METHOD_WORKAROUND, true);

 

Seems to solve this adequately. Weird that it doens't appear to show up in the docs. Perhaps PATCH isn't all that common?

 

Cheers,

Simon

 

 

Subject: [Jersey] Re: Sending a PATCH request from JAX-RS client?

See https://blogs.oracle.com/PavelBucek/entry/jersey_client_making_requests_with but AFAIK the name of the property was changed meanwhile.

 

Regards

-Markus

 

Reply | Threaded
Open this post in threaded view
|

Re: Sending a PATCH request from JAX-RS client?

Craig McClanahan-2
In reply to this post by Markus Karg-2-3
The org.glassfish.jersey.server.filter.HttpMethodOverrideFilter I mentioned is a bit more elaborate than that, but accomplishes the same basic thing on the server side.  But it's really more a problem on the client side than the server side, for two reasons:

* The verb restrictions in HttpURLConnection makes it not possible to use the default Jersey Client configuration without a hack, or using something like Apache's HttpClient instead.

* In JAX-RS's client API, there's no direct support for PATCH in things like Invocation, so you have to get down into the guts to know what you are doing.

Hopefully the next versions of Java and JAX-RS will recognize that PATCH is a standard (http://tools.ietf.org/html/rfc5789), and has been for just over five years now.

Craig


On Fri, Apr 10, 2015 at 1:48 AM, Markus Karg <[hidden email]> wrote:

Craig,

 

Let me chime in again.

 

You can make this solution portable by simply writing your own HTTP Method Override Filter (Paraphrasing Arun Gupta’s recent advice: “if there is a standard solution, don’t use the proprietary alternative”). (NB this would be a perfect start for a library of portable JAX-RS extensions!).

 

An example how to do this is shown in this article of Adam Bien on the Oracle web site (http://www.oracle.com/technetwork/articles/java/jaxrs20-1929352.html):

 

@Provider

@PreMatching

public class HttpMethodOverrideEnabler implements ContainerRequestFilter {

    public void filter(ContainerRequestContext requestContext) throws IOException {

        String override = requestContext.getHeaders().getFirst("X-HTTP-Method-Override");

        if (override != null) {

            requestContext.setMethod(override);

        }

    }

}

 

Regards

-Markus

 

Von: Craig McClanahan [mailto:[hidden email]]
Gesendet: Donnerstag, 9. April 2015 21:50
An: [hidden email]
Betreff: [Jersey] Re: Sending a PATCH request from JAX-RS client?

 

When I had a similar problem recently, I chose to have my server implement HttpMethodOverrideFilter (from Jersey) so that lame (non-PATCH-capable) clients could send an X-HTTP-Method-Override header and do a POST.  Clients that do understand how to PATCH can still do it.

 

Craig

 

 

On Thu, Apr 9, 2015 at 10:13 AM, Simon Roberts <[hidden email]> wrote:

Thanks Markus,

 

That pushed my search a little further, and eventually I found that Jersey has a (seemingly undocumented?) feature for this:

 

client.property(HttpUrlConnectorProvider.SET_METHOD_WORKAROUND, true);

 

Seems to solve this adequately. Weird that it doens't appear to show up in the docs. Perhaps PATCH isn't all that common?

 

Cheers,

Simon

 

 

Subject: [Jersey] Re: Sending a PATCH request from JAX-RS client?

See https://blogs.oracle.com/PavelBucek/entry/jersey_client_making_requests_with but AFAIK the name of the property was changed meanwhile.

 

Regards

-Markus