2015-01-05 5 views
1

Я очень новичок в области spray.io и scala в этом отношении, поэтому заранее извиняюсь, если я не получил терминологию прямо здесь, в отношении unmarshalling.Ошибка отмены маршрутизации по факту с http POST with spray.client

Я пытаюсь получить ответ HTTP POST с использованием конвейера, ожидается, что он потерпит неудачу, потому что мне нужен заголовок авторизации, но пока не будем игнорировать это.

Если я использую расширение хром Почтальон для POST к URL, я получаю этот ответ, простой и простой JSON:

{"status":"error","message":"You must identify yourself to access this resource.","url":"https://scrive.com/login"} 

Так что я начал с создания моего собственного класса случай для этого ответа, и реализовать мой собственный JsonProtocol, чтобы отменить ответ.

case class CreateFromTemplateResult(status: String, message: String, url: String) 

object ScriveJsonProtocol extends DefaultJsonProtocol { 
    implicit val createFromTemplateResponseFormat = jsonFormat3(CreateFromTemplateResult) 
} 

Итак, теперь я настроен, чтобы запустить мой конвейер и получить ответ.

val pipeline = sendReceive ~> unmarshal[CreateFromTemplateResult] 

val response = pipeline { 
    Post("https://api-testbed.scrive.com/api/v1/createfromtemplate/1") 
} 

response onComplete { 
    case Success(CreateFromTemplateResult(status, message, url)) => 
     requestContext.complete("success") 

    case Failure(error) => 
     requestContext.complete(error.getMessage) 
    } 

Запрос завершается, и дело OnFailure работает, но error.getMessage больше не JSON, как и в предыдущем примере Почтальон.

Status: 403 Forbidden 
Body: {"status":"error","message":"You must identify yourself to access this resource.","url":"https://scrive.com/login"} 

Поэтому мой вопрос становится, как я распаковать ошибка возвращается, и это тело в моем CreateFromTemplateResult случае? Или просто в json пойдет так же хорошо. Я не знаю, будет ли работать мой вопрос onSuccess, я хочу, чтобы у них было одинаковое поведение. Я хочу, чтобы они были в моем определенном формате CreateFromTemplateResult.

case class CreateFromTemplateResult(status: String, message: String, url: String) 

Большое спасибо за ваше время, и снова прошу прощения за мою плохую терминологию.

ответ

3

Ошибка в этом случае равна UnsuccessfulResponseException (вы можете видеть по коду unmarshall). Таким образом, вы можете сопоставить этот случай именно:

case Failure(e) => e match { 
    case ure: UnsuccessfulResponseException => 
    val response = ure.response 
    if(response.status = StatusCodes.Forbidden) 
     complete(response.as[CreateFromTemplateResult]) 
    else ... 
    case _ => ... 
} 

В качестве альтернативы вы можете предпочесть не использовать unmarshal вообще (или написать свой собственный unmarshal), и просто иметь дело с HttpResponse что sendReceive возвращается непосредственно.

+0

Спасибо, я попробую! Как я могу написать свой собственный unmarshaller и разобраться с HttpResponse напрямую? Звучит интересно. –

+0

Если вы посмотрите на реализацию 'unmarshal', это довольно простая функция, я думаю, просто скопируйте ее и измените способ проверки состояния. – lmm