Я отправляю json
на мой scala
код, но я получаю ошибку ``, когда json
анализируется.
{"practice-question":{"title":"dummy title","description":"<p>some D</p><p><strong>with bold</strong></p><ol><li><strong>no 1</strong></li></ol>","tags":["javascript"],"references":["dummy references"],"hints":["<p><u>some hint</u></p>"],"image":["data:image/png;base64,iVBORw0],"answer":[{"filename":"c.js","answer":"function c(){\n c;\n}"}],"success-test":"dummy success test","fail-test":"dummy fail test"}}))
Проверка json
начинается с
val questionOption = jsonBody.validateOpt[Question] //should give JsSuccess or JsError
Это должно вызвать следующее Reads
implicit val questionReads:Reads[Question] = (JsPath \ "practice-question").read[PracticeQuestion](PracticeQuestionReads)
.map((x:PracticeQuestion)=>Question.apply (x))
Reads
для PracticeQuestion
равно
implicit object PracticeQuestionReads extends Reads[PracticeQuestion] {
def reads(json:JsValue):JsResult[PracticeQuestion] = {
println(s"validating json ${json}")
val structurallyValidated = json.validateOpt[PracticeQuestion](practiceQuestionValidateStructureReads) //check that structurally the json maps to PracticeQuestion
println(s"structurally validated ${structurallyValidated}")
val structuralValidationResult = structurallyValidated match {
case JsSuccess(questionOpt,path)=>{
val result = questionOpt.map(question=>{
//TODOM - should check size of other lists (hints, references etc.)
if(question.image.length <0 || question.image.length > 3)
{
JsError("invalid no. of images")
}
else {
JsSuccess(question)
}
}).getOrElse(JsError("Error in validating Json"))
result
}
case JsError(errors) =>{
//TODOM - replace print with logger.
println("errors in json structure: "+errors)
JsError(errors)
}
}
structuralValidationResult match {
case JsSuccess(question,path)=>{
//TODOM - check that for other mandatory fields (esp in Lists)are not empty
if(question.answer.length == 0){
JsError("Missing Answer")
} else {
JsSuccess(question);
}
}
case JsError(errors) =>{
JsError(errors)
}
}
}
}
и Reads
, используемым в PracticeQuestionReads
is
implicit val practiceQuestionValidateStructureReads: Reads[PracticeQuestion] = {
println("in conversion");
val p = //p is of type FunctionBuilder[Reads]#CanBuild. This is an intermediary object used to create Reads[PracticeQuestion].
(JsPath \ "question-id").readNullable[UUID] and
(JsPath \ "description").read[String] and
(JsPath \ "hints").read[List[String]] and
(JsPath \ "image").read[List[String]] and //while image data is optional, this field is always present i.e. will get at least image:[]
(JsPath \ "success-test").read[String] and
(JsPath \ "fail-test").read[String] and
(JsPath \ "tags").read[Set[String]] and
(JsPath \ "title").read[String] and
(JsPath \ "answer").read[List[AnswerSection]] and
(JsPath \ "references").read[List[String]] and
(JsPath \ "question-creator").readNullable[QuestionCreator] and
(JsPath \ "creation-year").readNullable[Long] and //year/month are for internal consumption so not worried about receiving it from a client
(JsPath \ "creation-month").readNullable[Long] and
(JsPath \ "creation-hour").readNullable[Long] and
(JsPath \ "creation-minute").readNullable[Long]
//apply method of CanBuildX with a function to translate individual values to your model, this will return your complex Reads
val q = p.apply((PracticeQuestion.apply _))
q
}
Мне структура et c. смотри хорошо Что я делаю не так?