mehandih / grails-jaxrs

Automatically exported from code.google.com/p/grails-jaxrs
0 stars 0 forks source link

[CRITCAL] Cannot have resource with a String id #42

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?

class MediaBundle {

    String id
    String name
    Date dateCreated
    Date lastUpdated

    List history
    static hasMany = [history:History]

    static constraints = {
        id(unique:true, blank:false)
        name(blank:false)
    }

    static mapping = {
        id generator:'assigned', column: 'id', type: 'string'
        history sort:'dateCreated', order:'desc'
    }    
}

curl -H 'Accept: application/xml' -H 'Content-Type: application/xml' 
-X PUT \
-d "<mediaBundle 
id=\"e739550e-5815-45c1-a130-3bdc58e34800\"><name>a-dev-mediabundle</name></medi
aBundle>" \
api/mediaBundle/e739550e-5815-45c1-a130-3bdc58e34800 

What is the expected output? What do you see instead?

200 ok...

But DomainObjectReaderSupport try to convert the id, wich is a uuid, to a long 
with static Long idFromMap(Map map) in ConverterUtils

so it throws 

2011-08-04 10:11:54,492 [http-8080-1] ERROR container.ContainerResponse  - The 
RuntimeException could not be mapped to a response, re-throwing to the HTTP 
container
java.lang.NumberFormatException: For input string: 
"e739550e-5815-45c1-a130-3bdc58e34800"

...
at org.grails.jaxrs.support.ConverterUtils.idFromMap(ConverterUtils.groovy:136)
...
at 
org.grails.jaxrs.support.DomainObjectReaderSupport.readFromXml(DomainObjectReade
rSupport.groovy:115)
...

What version of the product are you using? On what operating system?

both 0.4 and 0.5 m1 are affected

Please provide any additional information below.

Original issue reported on code.google.com by stest...@gmail.com on 4 Aug 2011 at 2:37

GoogleCodeExporter commented 8 years ago
fix:
Make a custom DomainObjectReader and override readFromXml(...) and change the 
line 27 with result.id = this.idFromMap(map) 

And add those methods at the end 
    private idFromMap(Map map) {
        if (!map.id) {
            return null
        }
        if (map.id instanceof Number) {
            return map.id.toLong()
        } else if(isNumeric(map.id)) {
            return Long.parseLong(map.id)
        }
        return map.id
    }

    def isNumeric = {
        def formatter = java.text.NumberFormat.instance
        def pos = [0] as java.text.ParsePosition
        formatter.parse(it, pos)

        // if parse position index has moved to end of string
        // them the whole string was numeric
        pos.index == it.size()
    }

Original comment by stest...@gmail.com on 4 Aug 2011 at 2:50

GoogleCodeExporter commented 8 years ago
Huge thanks for the fix. Good work!

I just pushed it to master 
(https://github.com/krasserm/grails-jaxrs/commit/933daa67a19416781d703f96818c132
85665009a). Please let me know if it works for you now. Will add tests tomorrow.

Original comment by krass...@googlemail.com on 4 Aug 2011 at 6:07

GoogleCodeExporter commented 8 years ago
Tests added.

Original comment by krass...@googlemail.com on 5 Aug 2011 at 4:19