绑定Android Retrofit Multipart Data to Play框架



我一直在尝试将我的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)))
}

最新更新