Grails 2.5 REST PUT не вызывается

#json #grails

#json #grails

Вопрос:

Grails 2.4 RESTful controller.

У меня есть основной вопрос. У меня есть контроллер RESTful с простым классом домена, и мой GET, POST работает нормально. Как мне отправить запрос PUT JSON? Я использую контроллеры, сгенерированные RESTful по умолчанию

 url -i -X POST -H "Content-Type: application/json" -d '{"roleId":1,"username":"testuser5"}' http://localhost:8090/testapp/User
HTTP/1.1 201 Created
Server: Apache-Coyote/1.1
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Thu, 03 Jul 2014 02:07:13 GMT

{"id":null,"userId":79,"username":"testuser5"}
  

Затем я попробовал PUT, используя тот же приведенный выше ответ JSON (удалил id: null и изменил имя пользователя):

 curl -i -X PUT -H "Content-Type: application/json" -d '{"userId":79,"username":"testuser6"}' http://localhost:8090/testapp/User
  

Запрос отправляется в index, и я получаю список пользователей. Что я делаю не так? Как мне вызвать метод «update»? Если я добавлю свой собственный метод и я сделаю PUT, будет вызван мой собственный метод.

Класс домена:

 class User {
    Integer userId
    String username

    static mapping = {
        table 'user'
        version false
        id name:'userId', column: 'user_id'
    }

    static constraints = {
        username blank:false, nullable:false
    }
}
  

Контроллер RESTful:

 class UserController extends RestfulController {
    static responseFormats = ['json', 'xml']
    static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"]

    def index(Integer max) {
        params.max = Math.min(max ?: 10, 100)
        respond User.list(params), model:[userInstanceCount: User.count()]
    }
    def show(User userInstance) {
        respond userInstance
    }
    def create() {
        respond new User(params)
    }

     @Transactional
    def update(User userInstance) {
        println "*** in update "
        if (userInstance == null) {
            notFound()
            return
        }

        if (userInstance.hasErrors()) {
            respond userInstance.errors, view:'edit'
            return
        }

        userInstance.save flush:true

        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.updated.message', args: [message(code: 'User.label', default: 'User'), userInstance.id])
                redirect userInstance
            }
            '*'{ respond userInstance, [status: OK] }
        }
    }

    protected void notFound() {
        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.not.found.message', args: [message(code: 'user.label', default: 'User'), params.id])
                redirect action: "index", method: "GET"
            }
            '*'{ render status: NOT_FOUND }
        }
    }
}
  

Ответ №1:

Вы пропускаете вызов user.validate() перед вызовом hasErrors() . Смотрите

https://github.com/grails/grails-core/blob/master/grails-plugin-rest/src/main/groovy/grails/rest/RestfulController.groovy#L99

Комментарии:

1. Я добавил prinln в самую первую строку в методе ‘update’, и я не вижу его, когда вызываю PUT с помощью curl. Как я должен вызвать update?? В начале контроллера у меня есть: static allowedMethods = [сохранить: «ОПУБЛИКОВАТЬ», обновить: «ПОМЕСТИТЬ», удалить: «УДАЛИТЬ»] Я также добавил проверку, как вы упомянули, но безуспешно.

2. В вашем URL, который вы передаете в запрос PUT, отсутствует идентификатор

3. Что делать, если у вас нет идентификатора, например, когда идентификатор генерируется сервером и возвращается методом PUT?