在 Play Framework 中通过 GET 请求发送日期参数的理想方式是什么?
What is the ideal way to send a date parameter over a GET request in Play Framework?
我是 Play Framework 的新手。我可以直接通过请求发送简单的数据类型,如字符串、整数等,并在后端 Java 方法中访问它们。
当我尝试在路由文件中执行此操作时,
GET /food/fetchMealInfo/:noOfDays/:dateSelected controllers.trackandplan.FoodController.fetchMealInfo(noOfDays : Integer, dateSelected : Date)
我收到一条错误消息
Compilation error
not found: type Date
将日期对象从前端 AngularJS 应用程序传输到 Play Framework 中的 Java 应用程序的正确、安全和干净的方法是什么。
请指导。
你有几个选择。稍微容易理解的方法是简单地将date/time作为Long
(unix时间戳)传输,并在控制器方法中将其转换为Date
。
GET /food/fetchMealInfo/:noOfDays/:dateSelected controllers.trackandplan.FoodController.fetchMealInfo(noOfDays: Integer, dateSelected: Long)
public static Result fetchMealInfo(Integer noOfDays, Long dateSelected) {
Date date = new Date(dateSelected.longValue());
...
}
更复杂的方法是使用 PathBindable
,这将允许您在路由文件本身中使用 Date
。但是,您仍然需要将 Date
作为 Long
传输(如果可能,PathBindable
将进行转换)。不幸的是,由于我们显然无法控制 Date
,我们必须在 Scala 中实现 PathBindable
,而不是 Java(Java 需要为 Date
,我们不能)。
app/libs/PathBinders.scala
package com.example.libs
import java.util.Date
import play.api.mvc.PathBindable
import scala.util.Either
object PathBinders {
implicit def bindableDate(implicit longBinder: PathBindable[Long]) = new PathBindable[Date] {
override def bind(key: String, value: String): Either[String, Date] = {
longBinder.bind(key, value).right.map(new Date(_))
}
override def unbind(key: String, date: Date): String = key + "=" + date.getTime().toString
}
}
为了让路由文件能够选择它,您需要将以下内容添加到您的 build.sbt
文件中:
PlayKeys.routesImport += "com.example.libs.PathBinders._"
PlayKeys.routesImport += "java.util.Date"
现在您可以在路由文件中使用 Date
(如 Long
),而无需为每个使用它的方法专门处理它。
GET /food/fetchMealInfo/:noOfDays/:dateSelected controllers.trackandplan.FoodController.fetchMealInfo(noOfDays: Integer, dateSelected: Date)
注意:如果您使用的是较旧的 Play 版本,这可能无法立即编译。我用 Play 2.3.8 和 sbt 0.13.5 测试了它。
也可以修改我在此处制作的 PathBindable
以使用基础 String
,并接受特定的日期格式。
package com.example.libs
import java.util.Date
import java.text.SimpleDateFormat
import play.api.mvc.PathBindable
import scala.util.{Either, Failure, Success, Try}
object PathBinders {
implicit def bindableDate(implicit stringBinder: PathBindable[String]) = new PathBindable[Date] {
val sdf = new SimpleDateFormat("yyyy-MM-dd")
override def bind(key: String, value: String): Either[String, Date] = {
for {
dateString <- stringBinder.bind(key, value).right
date <- Try(sdf.parse(dateString)).toOption.toRight("Invalid date format.").right
} yield date
}
override def unbind(key: String, date: Date): String = key + "=" + sdf.format(date)
}
}
将其作为 String
发送并在您的操作中将其解析为 Date
对象。
public static Result readDate(String date) {
DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
java.util.Date dateObj = null;
try {
dateObj = format.parse(date);
} catch (ParseException e) {
debug(date + " is invalid date");
}
return (dateObj == null)
? badRequest("Invalid date format")
: ok(dateObj.toString()
);
}
可以在 other question
中找到更多从字符串解析日期的示例
我是 Play Framework 的新手。我可以直接通过请求发送简单的数据类型,如字符串、整数等,并在后端 Java 方法中访问它们。
当我尝试在路由文件中执行此操作时,
GET /food/fetchMealInfo/:noOfDays/:dateSelected controllers.trackandplan.FoodController.fetchMealInfo(noOfDays : Integer, dateSelected : Date)
我收到一条错误消息
Compilation error
not found: type Date
将日期对象从前端 AngularJS 应用程序传输到 Play Framework 中的 Java 应用程序的正确、安全和干净的方法是什么。 请指导。
你有几个选择。稍微容易理解的方法是简单地将date/time作为Long
(unix时间戳)传输,并在控制器方法中将其转换为Date
。
GET /food/fetchMealInfo/:noOfDays/:dateSelected controllers.trackandplan.FoodController.fetchMealInfo(noOfDays: Integer, dateSelected: Long)
public static Result fetchMealInfo(Integer noOfDays, Long dateSelected) {
Date date = new Date(dateSelected.longValue());
...
}
更复杂的方法是使用 PathBindable
,这将允许您在路由文件本身中使用 Date
。但是,您仍然需要将 Date
作为 Long
传输(如果可能,PathBindable
将进行转换)。不幸的是,由于我们显然无法控制 Date
,我们必须在 Scala 中实现 PathBindable
,而不是 Java(Java 需要为 Date
,我们不能)。
app/libs/PathBinders.scala
package com.example.libs
import java.util.Date
import play.api.mvc.PathBindable
import scala.util.Either
object PathBinders {
implicit def bindableDate(implicit longBinder: PathBindable[Long]) = new PathBindable[Date] {
override def bind(key: String, value: String): Either[String, Date] = {
longBinder.bind(key, value).right.map(new Date(_))
}
override def unbind(key: String, date: Date): String = key + "=" + date.getTime().toString
}
}
为了让路由文件能够选择它,您需要将以下内容添加到您的 build.sbt
文件中:
PlayKeys.routesImport += "com.example.libs.PathBinders._"
PlayKeys.routesImport += "java.util.Date"
现在您可以在路由文件中使用 Date
(如 Long
),而无需为每个使用它的方法专门处理它。
GET /food/fetchMealInfo/:noOfDays/:dateSelected controllers.trackandplan.FoodController.fetchMealInfo(noOfDays: Integer, dateSelected: Date)
注意:如果您使用的是较旧的 Play 版本,这可能无法立即编译。我用 Play 2.3.8 和 sbt 0.13.5 测试了它。
也可以修改我在此处制作的 PathBindable
以使用基础 String
,并接受特定的日期格式。
package com.example.libs
import java.util.Date
import java.text.SimpleDateFormat
import play.api.mvc.PathBindable
import scala.util.{Either, Failure, Success, Try}
object PathBinders {
implicit def bindableDate(implicit stringBinder: PathBindable[String]) = new PathBindable[Date] {
val sdf = new SimpleDateFormat("yyyy-MM-dd")
override def bind(key: String, value: String): Either[String, Date] = {
for {
dateString <- stringBinder.bind(key, value).right
date <- Try(sdf.parse(dateString)).toOption.toRight("Invalid date format.").right
} yield date
}
override def unbind(key: String, date: Date): String = key + "=" + sdf.format(date)
}
}
将其作为 String
发送并在您的操作中将其解析为 Date
对象。
public static Result readDate(String date) {
DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
java.util.Date dateObj = null;
try {
dateObj = format.parse(date);
} catch (ParseException e) {
debug(date + " is invalid date");
}
return (dateObj == null)
? badRequest("Invalid date format")
: ok(dateObj.toString()
);
}
可以在 other question
中找到更多从字符串解析日期的示例