Search code examples
javaweb-serviceshttp-patch

Supporting the "PATCH" verb - WSHttpHandler handleExchange gives WARNING: Cannot handle HTTP method: PATCH


I have created a class that uses javax.xml.ws.Endpoint to create a REST endpoint:

@WebServiceProvider
@ServiceMode(value = javax.xml.ws.Service.Mode.MESSAGE)
@BindingType(value = HTTPBinding.HTTP_BINDING)
public class SpecificRestAPI implements Provider<Source>
{
    // arg 0: url including port, e.g. "http://localhost:9902/specificrestapi"
    public static void main(String[] args)
    {
        String url = args[0];
        // Start
        Endpoint.publish(url, new SpecificRestAPI());       
    }

    @Resource
    private WebServiceContext wsContext;


    @Override
       public Source invoke(Source request)
       {
          if (wsContext == null)
             throw new RuntimeException("dependency injection failed on wsContext");
          MessageContext msgContext = wsContext.getMessageContext();
          switch (((String) msgContext.get(MessageContext.HTTP_REQUEST_METHOD)).toUpperCase().trim())
          {
             case "DELETE": 
                 return processDelete(msgContext);
             case "PATCH" :
                 return processPatch(msgContext);
'etc...

The issue is, when I run this application in Eclipse and use curl to PATCH a request through to it with the following command:

curl -i -X PATCH http://localhost:9902/specificrestapi?do=action

I get the following WARNING in the Eclipse console:

Jul 30, 2019 3:39:15 PM com.sun.xml.internal.ws.transport.http.server.WSHttpHandler handleExchange WARNING: Cannot handle HTTP method: PATCH

And the following response to my curl request:

curl: (52) Empty reply from server

Looking here, in the WSHTTPHandler class, I can see where the issue is:

    private void handleExchange(HttpExchange msg) throws IOException {
    WSHTTPConnection con = new ServerConnectionImpl(adapter,msg);
    try {
        if (fineTraceEnabled) {
            LOGGER.log(Level.FINE, "Received HTTP request:{0}", msg.getRequestURI());
        }
        String method = msg.getRequestMethod();
        ' THIS IS THE PROBLEM - IT DOESN'T KNOW ABOUT PATCH!
        if(method.equals(GET_METHOD) || method.equals(POST_METHOD) || method.equals(HEAD_METHOD)
        || method.equals(PUT_METHOD) || method.equals(DELETE_METHOD)) {
            adapter.handle(con);
        } else {
            if (LOGGER.isLoggable(Level.WARNING)) {
                LOGGER.warning(HttpserverMessages.UNEXPECTED_HTTP_METHOD(method));
            }
        }
    } finally {
        msg.close();
    }
}

So, what options do I have? a) Can I replace WSHTTPHandler with a custom class of my own; and if so how do I tell my Endpoint that I want to use it? or b) Is there a newer version of WSHttpHandler, a more modern alternative, or a different approach to creating a webservice that I could use that would allow this?


Solution

  • PATCH is not supported here - other handlers should be used instead.