-
-
Save agemooij/7679130 to your computer and use it in GitHub Desktop.
/** | |
* The MIT License (MIT) | |
* | |
* Copyright (c) 2013-2015 Andrew Snare, Age Mooij | |
* | |
* Permission is hereby granted, free of charge, to any person obtaining a copy | |
* of this software and associated documentation files (the "Software"), to deal | |
* in the Software without restriction, including without limitation the rights | |
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
* copies of the Software, and to permit persons to whom the Software is | |
* furnished to do so, subject to the following conditions: | |
* | |
* The above copyright notice and this permission notice shall be included in all | |
* copies or substantial portions of the Software. | |
* | |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
* SOFTWARE. | |
*/ | |
package com.scalapenos.spray | |
import spray.json._ | |
/** | |
* A custom version of the Spray DefaultJsonProtocol with a modified field naming strategy | |
*/ | |
trait SnakifiedSprayJsonSupport extends DefaultJsonProtocol { | |
import reflect._ | |
/** | |
* This is the most important piece of code in this object! | |
* It overrides the default naming scheme used by spray-json and replaces it with a scheme that turns camelcased | |
* names into snakified names (i.e. using underscores as word separators). | |
*/ | |
override protected def extractFieldNames(classTag: ClassTag[_]) = { | |
import java.util.Locale | |
def snakify(name: String) = PASS2.replaceAllIn(PASS1.replaceAllIn(name, REPLACEMENT), REPLACEMENT).toLowerCase(Locale.US) | |
super.extractFieldNames(classTag).map { snakify(_) } | |
} | |
private val PASS1 = """([A-Z]+)([A-Z][a-z])""".r | |
private val PASS2 = """([a-z\d])([A-Z])""".r | |
private val REPLACEMENT = "$1_$2" | |
} | |
object SnakifiedSprayJsonSupport extends SnakifiedSprayJsonSupport |
Thank you, this was immensely helpful!
Awesome! Thanks!
So, a few minutes ago I wanted to do this once more and no longer had access to my original implementation. Amusingly Googling to see if there was a better way of doing this by now led me here…
Thanks for preserving this. :)
Now officially licensed with the MIT license
Thanks. Really helpful.
what a great code! thank you so much
great code! will use this
What about combined json field names(I mean fields with underscore and not underscore)? for example I have following json:
{ "requestId": "sdsdsdsdsd", "_links": { "self": { "href": "https://ecom2.nbu.uz/v1/Orders/f963d8c1-fe19-44e6-8441-e6e496b399b5" }, "redirectToCheckout": { "href": "https://ecom2.nbu.uz/Checkout/f963d8c1-fe19-44e6-8441-e6e496b399b5" } } }
Your solution not works here, because spray json will asks "request_id" field. Can you give any suggestions by that situation?
@sm-tester this code is ancient and nowadays I would not use it myself since spray-json has explicit support for defining the exact field names you want to map to.
Use something like this:
val input = """{ "requestId": "sdsdsdsdsd", "_links": { "self": { "href": "https://ecom2.nbu.uz/v1/Orders/f963d8c1-fe19-44e6-8441-e6e496b399b5" }, "redirectToCheckout": { "href": "https://ecom2.nbu.uz/Checkout/f963d8c1-fe19-44e6-8441-e6e496b399b5" } } }"""
case class Input(...)
implicit val format = jsonFormat(Input, "requestId", "_links")
e.g. you can map the original fields to whatever you call your fields in the case class by just specifying the names explicitly.
So please do not use this ancient code and instead use the standard spray-json features.
This code was adapted by me from an original idea and implementation by @asnare