在Grails中发布嵌套资源的问题

tyl*_*ern 6 java rest grails groovy grails-orm

我在理解Grails Restful控制器如何工作方面遇到了问题.我正在尝试向嵌套资源发布帖子请求(见下文).我不确定我是否理解我需要更改以使其工作,因为看起来GET请求与其父资源项建立Bid的关联,但是当我尝试POST时,我被警告该项不能为空.

任何帮助表示赞赏!

Item.groovy

class Item {
    static hasMany = [bids:Bid]
}
Run Code Online (Sandbox Code Playgroud)

Bid.groovy

class Bid {
    Integer ownerId
    Double amount

    static belongsTo = [item:Item]

    static constraints = {
        ownerId nullable: false
        amount nullable: false
    }
}
Run Code Online (Sandbox Code Playgroud)

BidController.groovy

class BidController extends RestfulController<Bid> {
    static responseFormats = ['json', 'xml']
    BidController() {
        super(Bid)
    }
    @Override
    def getObjectToBind() {
        request.parameterMap.put('itemId', params.itemId)
        return request
    }
}
Run Code Online (Sandbox Code Playgroud)

ItemController.groovy

class ItemController extends RestfulController<Item> {
    static responseFormats = ['json', 'xml']
    ItemController() {
        super(Item)
    }
}
Run Code Online (Sandbox Code Playgroud)

UrlMappings.groovy

class UrlMappings {

    static mappings = {
        "/items"(resources:"item") {
            "/bids"(resources: "bid")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

URL映射

Controller: item
 |   GET    | /items                                                    | Action: index            
 |   GET    | /items/create                                             | Action: create           
 |   POST   | /items                                                    | Action: save             
 |   GET    | /items/${id}                                              | Action: show             
 |   GET    | /items/${id}/edit                                         | Action: edit             
 |   PUT    | /items/${id}                                              | Action: update           
 |  PATCH   | /items/${id}                                              | Action: patch            
 |  DELETE  | /items/${id}                                              | Action: delete    
Controller: bid
 |   GET    | /items/${itemId}/bids                                     | Action: index            
 |   GET    | /items/${itemId}/bids/create                              | Action: create           
 |   POST   | /items/${itemId}/bids                                     | Action: save             
 |   GET    | /items/${itemId}/bids/${id}                               | Action: show             
 |   GET    | /items/${itemId}/bids/${id}/edit                          | Action: edit             
 |   PUT    | /items/${itemId}/bids/${id}                               | Action: update           
 |  PATCH   | /items/${itemId}/bids/${id}                               | Action: patch            
 |  DELETE  | /items/${itemId}/bids/${id}                               | Action: delete                    
Run Code Online (Sandbox Code Playgroud)

发布请求

POST /AuctionService/items/1/bids HTTP/1.1
Content-Type: application/json
Host: localhost:8080
Connection: close
Content-Length: 34

{
    "ownerId": 1,
    "amount": 3.00
}
Run Code Online (Sandbox Code Playgroud)

响应

HTTP/1.1 422 Unprocessable Entity
Server: Apache-Coyote/1.1
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Fri, 25 Jul 2014 17:44:03 GMT
Connection: close

{"errors":[{"object":"auctionservice.Bid","field":"item","rejected-value":null,"message":"Property [item] of class [class auctionservice.Bid] cannot be null"}]}
Run Code Online (Sandbox Code Playgroud)

Mar*_*vid 0

RestfulController的实现有一个getObjectToBind() 返回请求对象的方法。我建议重写此方法并返回包含itemId此方法的注释中所述的密钥的映射。

另一种选择是在 http json 正文中发送 itemId。这有点多余,因为信息已经在 url 中表示了。但作为一种解决方法,这也可能是一个很好的解决方案。