Using Play 2.0.1 I defined the following route:
GET /demo/list controllers.Demos.listDemos(page: Int ?= 0, orderBy: Int ?= 1, nameFilter: String ?= "", versionFilter: Long ?= -1, tagFilter: List[String] ?= Nil)
But I get this error on compile:
No QueryString binder found for type List[String]. Try to implement an implicit QueryStringBindable for this type.
I found the code from Play 2.1-RC (not officially released yet) which would solve the issue:
/**
* QueryString binder for List
*/
implicit def bindableList[T: QueryStringBindable] = new QueryStringBindable[List[T]] {
def bind(key: String, params: Map[String, Seq[String]]) = Some(Right(bindList[T](key, params)))
def unbind(key: String, values: List[T]) = unbindList(key, values)
}
/**
* QueryString binder for java.util.List
*/
implicit def bindableJavaList[T: QueryStringBindable] = new QueryStringBindable[java.util.List[T]] {
def bind(key: String, params: Map[String, Seq[String]]) = Some(Right(bindList[T](key, params).asJava))
def unbind(key: String, values: java.util.List[T]) = unbindList(key, values.asScala)
}
private def bindList[T: QueryStringBindable](key: String, params: Map[String, Seq[String]]): List[T] = {
for {
values <- params.get(key).toList
rawValue <- values
bound <- implicitly[QueryStringBindable[T]].bind(key, Map(key -> Seq(rawValue)))
value <- bound.right.toOption
} yield value
}
private def unbindList[T: QueryStringBindable](key: String, values: Iterable[T]): String = {
(for (value <- values) yield {
implicitly[QueryStringBindable[T]].unbind(key, value)
}).mkString("&")
}
But after a couple of hours trying, Play still doesn't find the code. I've tried using a custom object and implicit conversions to that object,but it still doesn't work.
How can I force Play to do the implicit conversion?
Update
I want to avoid 2.1-SNAPSHOT if possible as I'm concerned about its stability, but I will use it if there is no other way. I tried the solution from 4e6 but it did not work:
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: UNRESOLVED DEPENDENCIES ::
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: org.slf4j#slf4j-api;1.6.1: configuration not found in org.slf4j#slf4j-api;1.6.1: 'compile'. It was required from org.hibernate#hibernate-validator;4.2.0.Final compile
[warn] :: commons-codec#commons-codec;1.4: configuration not found in commons-codec#commons-codec;1.4: 'compile'. It was required from org.apache.httpcomponents#httpclient;4.1.2 compile
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
My sbt plugin contains this:
// Comment to get more information during initialization
logLevel := Level.Warn
// The Typesafe repository
resolvers ++= Seq(
Resolver.url("Typesafe Ivy Snapshots", url("http://repo.typesafe.com/typesafe/ivy-snapshots/"))(Resolver.ivyStylePatterns),
"Typesafe Releases" at "http://repo.typesafe.com/typesafe/releases/",
"Typesafe Snapshots" at "http://repo.typesafe.com/typesafe/snapshots/",
"DefaultMavenRepository" at "http://repo1.maven.org/maven2/",
"JavaNet1Repository" at "http://download.java.net/maven/1/")
// Use the Play sbt plugin for Play projects
addSbtPlugin("play" % "sbt-plugin" % "2.1-SNAPSHOT")
You can move your project to play
2.1-SNAPSHOT
instead (see "Create a new application without having Play installed" section of documentation). All you need is to changesbt-plugin
version and add extra resolvers. Here is my version ofplugins.sbt
Update
I don't know why you have problem with
slf4j
dependency. It is successfully downloaded from typesafe releases for me. You can try to explicitly add this repository to your application config (I meanBuild.scala
, notplugins.sbt
).I solved it at last. The code used is:
Under models, file QueryBinders.scala:
On Build.scala:
This will have to be removed when updating to 2.1, but it works and it avoids all the issues I had trying to update the project to 2.1 Snapshot.