我一直在尝试将我的android多表单数据绑定到play框架表单绑定。但是现在它似乎在抱怨日期格式绑定失败了。任何帮助都将非常感激!
我目前从android应用程序发送过来的格式是"yyyy-MM-dd"
Things if have try:
- 试图设置我自己的日期格式在"application.conf"到 date.format = yyyy-MM-dd
-
试图手动设置java.util.Date格式。
val format = new java.text.SimpleDateFormat("yyyy-MM-dd") format.format(new java.util.Date())
这是Http数据映射我收到从Android改造。我打印了"request.body.dataParts"
Map(stock -> List(11), productname -> List(pleasework), price -> List(11.0), userid -> List(test), brand -> List(nike), condition -> List(New (with defects)), date -> List("2015-09-20"), category -> List(Shoe), ean -> List(e0ee9583-fb10-43c1-80f3-c1725251adfc), sold -> List(true))
错误信息Play Framework is complain:
Binding Failed
List(FormError(date,error.date,List()))
Play Framework Controller Code:
val format = new java.text.SimpleDateFormat("yyyy-MM-dd")
format.format(new java.util.Date())
val userForm = Form(
mapping(
"ean" -> text,
"date" -> of(dateFormat),
"sold" -> boolean,
"productname" -> text,
"userid" -> text,
"price" -> of(doubleFormat),
"stock" -> number,
"brand" -> text,
"category" -> text ,
"condition" -> text
)(Product.apply)(Product.unapply)
)
def multiuploaddata = Action(parse.multipartFormData) {
implicit request =>
userForm.bindFromRequest()(request).fold (
errFrm =>{
println("Binding Failed")
println(errFrm.errors)
},
userData => {
println("Success bind: " + userData.ean)
}
)
}
Ok("Receive MultiImage is okay!")
}
Android Retrofit接口代码:
@Multipart
@POST("/multiuploaddata")
void updateProductImageData(@Part("ean") String ean,
@Part("date") Date date,
@Part("sold") boolean sold,
@Part("productname") String productname,
@Part("userid") String userid,
@Part("price") double price,
@Part("stock") int stock,
@Part("brand") String brand,
@Part("category") String category,
@Part("condition") String condition
, @PartMap Map<String, TypedFile> Files, Callback<Photo> callback);
Android Fragment onClickListener:
mDoneButton = (Button) v.findViewById(R.id.done_button);
mDoneButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Calling the retrofit Interface to send Data and Images over to server
service.updateProductImageData(mProduct.getId().toString(),
mProduct.getDate(), mProduct.isSold(), mProduct.getProductName(),
mProduct.getUserId(), mProduct.getPrice(), mProduct.getStock(), mProduct.getBrand(), mProduct.getCategory()[0],
mProduct.getCondition()[0], files, new retrofit.Callback<Photo>() {
@Override
public void success(Photo photo, Response response) {
Log.d(TAG, "SUCCESS UPLOAD MULTI IMAGE!!! " + response);
}
@Override
public void failure(RetrofitError error) {
}
});
我最终遵循了Haito的建议,将日期转换为epoch长度的值,并将其发送给play框架。所以现在从play框架中检索Date值后,我需要将其转换回日期并进行自己的格式化。
val datetime = new Date(1442802362000L)
更新的Play框架代码:
val userForm1 = Form(
mapping(
"ean" -> text,
"date" -> longNumber, <--- change to long instead of date
"sold" -> boolean,
"productname" -> text,
"userid" -> text,
"price" -> of(doubleFormat),
"stock" -> number,
"brand" -> text,
"category" -> text ,
"condition" -> text
)(Product1.apply)(Product1.unapply)
)
Android Fragment code:
service.updateProductImageData2(mProduct.getId().toString(),
// Convert the date value into long
mProduct.getDate().getTime(), mProduct.isSold(), mProduct.getProductName(),
mProduct.getUserId(), mProduct.getPrice(), mProduct.getStock(), mProduct.getBrand(), mProduct.getCategory()[0],
mProduct.getCondition()[0], files, new retrofit.Callback<Photo>() {
@Override
public void success(Photo photo, Response response) {
Log.d(TAG, "SUCCESS UPLOAD MULTI IMAGE!!! " + response);
}
@Override
public void failure(RetrofitError error) {
}
});
我确实挖出了日期格式和解析函数,并试图修改它。但是我猜我对scala还是很陌生,无法让它工作。
我发现很奇怪的一件事是,对于def dateParse(data: String)函数。如果我传入值"2015-09-02",它将工作。但是如果值是从它的函数参数中获取的,它将工作。我在"data"参数上做了一个println,它是相同的"2015-09-02",但我就是不工作。
// This will work
def dateParse(data: String) = {formatter.parseDateTime("2015-09-02").toDate}
// This will not work
def dateParse(data: String) = {formatter.parseDateTime(data).toDate}
解析和dateFormat函数的代码:
private def parsing[T](parse: String => T, errMsg: String, errArgs: Seq[Any])(key: String, data: Map[String, String]): Either[Seq[FormError], T] = {
stringFormat.bind(key, data).right.flatMap { s =>
println("The Data is: " + data("date"))
scala.util.control.Exception.allCatch[T]
.either(parse(s))
.left.map(e => Seq(FormError(key, errMsg, errArgs)))
}
}
def dateFormat(pattern: String, timeZone: TimeZone = TimeZone.getDefault): Formatter[Date] = new Formatter[Date] {
val jodaTimeZone = org.joda.time.DateTimeZone.forTimeZone(timeZone)
val formatter = org.joda.time.format.DateTimeFormat.forPattern(pattern).withZone(jodaTimeZone)
def dateParse(data: String) = {formatter.parseDateTime(data).toDate}
override val format = Some(("format.date", Seq(pattern)))
def bind(key: String, data: Map[String, String]) = parsing(dateParse, "error.date", Nil)(key, data)
def unbind(key: String, value: Date) = Map(key -> formatter.print(new org.joda.time.DateTime(value).withZone(jodaTimeZone)))
}