1

After upgrading grails 2.5.2 to 3.3.11, I am getting Method Not Allowed response while hitting POST request. The GET method works fine.

Controller:

package omapi

import grails.rest.RestfulController
import org.springframework.http.HttpStatus

import static org.springframework.http.HttpStatus.NOT_FOUND
import static org.springframework.http.HttpStatus.NO_CONTENT

class PhaseController extends RestfulController {

PhaseController(){
    super(Phase)
}

static responseFormats = ['json', 'xml']
static allowedMethods = [show:  'GET', index:'GET',productAcronym:'GET', phaseByName: 'GET',save:'POST',update:'PUT',delete:'DELETE', deleteGroup: 'DELETE', deletePhase: 'DELETE']

def phaseService

def index(){
    def phases = phaseService.getAllPhases()
    respond phases
}

def show(){
    def phase = phaseService.getPhaseById(params.id)
    respond phase
}

def phaseByName(){
    def phase = phaseService.getPhaseByName(params?.name)
    respond phase
}

def productAcronym() {
    def phase = phaseService.getPhaseByProductAcronym(params?.acronym)
    log.info("==== phase by product Acronym =====$params.acronym==");
    respond phase;
}
  }

URL Mapping:

package omapi

import grails.core.GrailsApplication
import java.nio.file.AccessDeniedException

class UrlMappings {

    static mappings = {

        "/applications/$id/processingGroup"(controller: "application",action: "processingGroup")
        "/accounts/$id/applications/"(controller: "accounts", action: "applications")
        "/accounts/$aId/application/$id/products/"(controller: "application", action: "products")
        "/ftpServer/connection"(controller: 'ftpServer', action: 'testConnection')
        "/application/$id/jobs/"(controller: "job",action: "jobByApplication")
        "/application/cycleDates"(controller: "cycleDates",action: "getCycleDatesByApplication")
        "/ProcessingBranch/branch/"(controller: "processingTicketBranch",action: "branch")

        "/application/$appCode/Offset"(controller: "ReportClientOffset",action: "offsetValue")
        "/$controller/$action?/$id?(.$format)?"{
            constraints {
                // apply constraints here
            }
        }
        "/$controller/$id"(parseRequest: true){
            action = [GET:"show",PUT:"update",POST:"404",DELETE:"delete"]
            constraints {
                id matches: /\d+/
            }
        }

        "/$controller"{
            action = [GET:"index",POST: "save",PUT:"update",DELETE:"delete"]
            constraints {
            }
        }

        "/"(view:"/index")
        "403"(controller: "error", action: "error403")
        "404"(controller: "error", action: "error404")
        "409"(controller: "error", action: "error409")
        "500"(controller: "error", action: "error500")
        "500"(controller: "error", action: "error403", exception: AccessDeniedException)
    }
}

Request: [POST] localhost:5555/OMApi/phase

Response:

{
    "timestamp": 1594295030496,
    "status": 405,
    "error": "Method Not Allowed",
    "message": "No message available",
    "path": "/OMApi/phase"
}

For grails 2.5.2, everything works fine. It looks like a Spring related issue. All the searches on this matter provided no results. Any idea? Is it due to some error in UrlMapping or other problems like CORS Interceptor not working?

1 Answers1

1

After upgrading grails 2.5.2 to 3.3.11, I am getting Method Not Allowed response while hitting POST request. The GET method works fine.

It looks like you have /OMApi/phase mapped to the index action in PhaseController which is configured with index: 'GET' in allowedMethods which means the index action is only accessible via a 'GET' request. Any other verb should result in a 405 for that action. If you want to allow both GET and POST for the index action (unclear why you want to do that) then change your allowedMethods to include index: ['GET', 'POST'] instead of index: 'GET'.

I hope that helps.

Jeff Scott Brown
  • 26,804
  • 2
  • 30
  • 47
  • 1
    Also, if you want to allow any verb (not just `GET` and `POST`) then you can simply remove the `index:` entry from `allowedMethods`. – Jeff Scott Brown Jul 10 '20 at 13:51
  • Thanks, @Jeff Scott Brown for the answer. The request `/OMAPI/phase` with the above-mentioned `allowedMethods` mapping was working fine for `GET ` as well as `POST` method in grails 2.5.2. The issue arose after upgrading of grails to 3.3.11. Are there any difference between defining `allowedMethods` in grails 2.5.2 and 3.3.11? could you please suggest any documentation? I cannot find any. – Uttam Sapkota Jul 15 '20 at 04:05
  • 1
    Without seeing a project which demonstrates the problem I can't say for sure why it worked or appeared to work differently in 2.5.2 but the behavior you are seeing in 3.3.11 is by design. Docs are at http://docs.grails.org/3.3.11/ref/Controllers/allowedMethods.html. When I originally wrote the allowedMethods stuff it was all done by a filter. Later I rewrote it to be configured at compile time. I don't remember if that was before or after 2.5. I tried to recreate the 2.5.2 behavior you cite and I can't, so I think there is some other factor. Sorry I can't be more help. – Jeff Scott Brown Jul 15 '20 at 12:40
  • Do you know any way to get `/OMApi/phase` work for both `GET` and `POST` method? If `/OMApi/phase POST` is requested then it will go to save method and if the `GET /OMApi/phase` is requested it will go to index method. I am extending RestfulController in my phase controller. The above scenario works fine if I create fresh grails 3.3.11 application but I get method not allowed for my grails application(upgraded from 2.5.2 to 3.3.11) – Uttam Sapkota Jul 16 '20 at 11:52