Search code examples
restjerseyweb.xmlglassfish-3

How to enable/disable HTTP methods for RESTful Web service?


I'm writing a RESTful Web service. Technologies that I use:

  • Eclipse EE Kepler IDE
  • GlassFish 3 (based on Java 6)
  • Jersey
  • JDK v7

When I annotate a Java method with, for example, the @DELETE annotation I get the following HTTP error (invoked via URI):

HTTP Status 405 - Method Not Allowed

I would like to know how to enable/disable (so that to enable/disable the above HTTP error) those methods (PUT, HEAD, etc.) and at which level it can be done (Glassfish, Web.xml, etc). As well, can you invoke all of those resource methods (annotated with HTTP method type) from either Web browser's URI, within the <form>, or stand-alone client application (non-browser)?

For example, whether or not the following config line on deployment descriptor is present, it makes no difference:

<security-constraint>
 <web-resource-collection>
    <web-resource-name>RESTfulServiceDrill</web-resource-name>
    <url-pattern>/drill/rest/resource/*</url-pattern>
    <http-method>DELETE</http-method>  
 </web-resource-collection>

Of course, one's can disable a specific resource method by throwing an exception from it (and map it to an HTTP error) as the indication of it. That would indicate that the implementation is not available, for example.

So far, only @GET and @POST (on the <form>) resource methods work out, the other annotated methods, such as @POST (via URI), @PUT, @DELETE, @OPTIONS returns the above HTTP error. And this is where my question needs solutions. Why does the mentioned resource methods cause HTTP error when the former two don't?

An example of a resource method:

@DELETE
@Consumes(MediaType.TEXT_PLAIN)
@Produces(MediaType.TEXT_PLAIN)
@Path("/getDelete/{value}/{cat}")
public String getDelete(@PathParam("value") String value, @PathParam("cat") String cat){
    return value+" : "+cat;
}

Invoking URL:

<a href= "/RESTfulServiceDrill/rest/v6/exception/getDelete/Animal/cat">getDelete</a>

The deployment descriptor is empty, except for the above lines of XML code. So far, I made the app to work by using annotations, no Web.xml (only contains some default values, such as index.jsp files).

Any ideas out there?


Solution

  • To my understanding, You have your REST APIs exposed and you are trying to access it from HTML <form>.Now you are able to access the GET and POST methods(REST APIs) from HTML <form> but not PUT, DELETE and other HTTP methods.

    The reason why you get Method Not Allowed exception when you try to access DELETE or PUT or other HTTP methods is, HTML <form> does not support methods other than GET and POST.

    Even if you try

    <form method="delete"> or <form method="put"> 
    

    HTML will not understand these methods and consider this as simply <form> (i.e) default form method is GET. So even you have mentioned method as DELETE or PUT. It is a GET request.

    And when the call is made, the jersey container tries to find the requestpath(here"/getDelete/{value}/{cat}") with the specified method(here GET). Though this path exists,you have mentioned DELETE as acceptable method in your resource(@DELETE annotation says so). But Jersey is looking for GET now.Since it cant find @GET, it returns Method not allowed Exception.

    So, how to solve it?

    In HTML <form> you cant use HTTP methods other than GET and POST. It is better to have a wrapper in between the REST layer and HTML. So that you can make a POST call from your HTML, then the wrapper handles that call and which in-turns calls the DELETE of REST layer.

    And, why POST method is not working from browser is, By default Browser makes a GET call. Have a look at Postman to make REST calls with different Http methods.