How to load JSON file using Play with Scala

2020-06-30 05:48发布

I need to load a JSON file with a list of cities in one of my controllers, in order to pass it to a view afterwards.

I have placed the file here: app/assets/jsons/countriesToCities.json
(By the way: is this an appropriate location, or should I place it somewhere else?)

I have read the docs and I can see it is possible to create a JsValue from a string: https://www.playframework.com/documentation/2.4.x/ScalaJson#Using-string-parsing

I want to create a JsValue in a similar fashion. The difference is that I want to load the content from a file, not from a string... I haven't found any code snippet on how to do this, unfortunately.
Do I have to use something else to read the file into a string and only then use the parse method on that string?

Code snippets with examples on how to do this in the answers will be highly appreciated! :)

Thank you very much in advance!

4条回答
家丑人穷心不美
2楼-- · 2020-06-30 06:00

I usually need few small dictionaries to live in memory in order to build some plain LUTs (LookUp Tables). In order to achieve that I use the following piece of code (please it is worth noting I am using latest Play 2.6):

def loadJSONFromFilename(filename: String): Option[JsValue] =
  Option(Source.fromFile(filename).mkString)
    .map(Json.parse)

Using the previous function is just a matter of passing a filename path. Tailoring this to be used with Play you might need to place your file in a resource folder and to enable it you need to place this in your build.sbt file:

// include resources into the unversal zipped package using sbt dist
mappings in Universal ++= directory(baseDirectory.value / "resources")

Thus, you can use this resource folder this way in your Play class:

lazy val lutFilePath: Path = 
  Paths.get(env.rootPath.getAbsolutePath, "resources", "lut.json")
lazy val lutJson = loadJSONFromFilename(lutFilePath.toString)
查看更多
太酷不给撩
3楼-- · 2020-06-30 06:01

Here is how I managed to solve it:

val source: String = Source.fromFile("app/assets/jsons/countriesToCities.json").getLines.mkString
val json: JsValue = Json.parse(source)

Thanks for the help! :)

查看更多
我只想做你的唯一
4楼-- · 2020-06-30 06:07

Looks like the comment about the possible duplicate is how to read a file from your app/assets folder. My answer is about how to parse Json from a stream. Combine the two and you should be good to go.

Json.parse accepts a few different argument types, one of which is InputStream.

val stream = new FileInputStream(file)
val json = try {  Json.parse(stream) } finally { stream.close() }

P.S. When you can't find what you're looking for in the written docs, the API Docs are a good place to start.

查看更多
淡お忘
5楼-- · 2020-06-30 06:10

From Play 2.6, Environment has the getExistingFile, getFile, resource and resourceAsStream methods, E.g.:

class Something @Inject (environment: play.api.Environment) {
  // ...
  environment.resourceAsStream("data.json") map ( Json.parse(_) )

(Note, in this case data.json is inside the conf folder)

https://www.playframework.com/documentation/2.6.x/api/scala/index.html#play.api.Environment

查看更多
登录 后发表回答