在Scala中是否有一种简单的方法可以检查某个URL的资源是否以404响应?

时间:2013-12-19 06:00:00

标签: scala url

我是Scala的新手,我有一些网址。我需要检查URL引用的那些资源是否有效?如何使用Scala实现这一目标?

3 个答案:

答案 0 :(得分:2)

由于URL只是对Web资源的虚拟引用 - 它始终有效。 ;)

此外,您可以从资源中读取一行作为文本:

try {
  val text = Source.fromUrl(new java.net.URL(someString)).getLine
} catch {
  case java.io.IOException => // do something ...
}

或者从资源中读取所有行:

try {
  val source = Source.fromUrl(new java.net.URL(someString))
  for (line <- source) {
    println(line)
    // do anything you like with each line of text
  }
} catch {
  case java.io.IOException => // do something ...
}

或者您可以使用java类连接到资源并读取它的长度等等......:

try {
  val connection = (new java.net.URL(someString)).openConnection
  connection.connect;
  val l = connection.getContentLength
  // use the connection anyway you like
} catch {
  case java.io.IOException => // do something ...
}

答案 1 :(得分:2)

您需要使用http访问库来尝试访问该URL。使用play2的WS

import play.api.libs.ws.WS
val futureResponse:Future[Response] = WS.url("http://www.example.com/404.html").get()

然后你可以使用monadic操作来读取响应并做出反应

futureResponse.map {response => response.status==404} //will return a Future[Boolean]

或者您可以阻止,直到您确实收到回复:

import scala.concurrent._
import scala.concurrent.duration._

val response =Await.result(futureResponse, 5 seconds)
if(response.status==404) {
  ???
}else{
  ???
}

scala还有其他HTTP客户端,例如Dispatch

答案 2 :(得分:1)

我不认为使用Scala的标准库有一种简单的方法。但是还有其他几个库可以帮助您解决问题。

我会给你一个解释,说明如何使用Spray执行此操作。此解决方案的优势在于它是非阻塞的,但是对于Scala的新手,Future的使用对您来说可能是新的。

首先,您需要为项目添加一些依赖项。最简单的方法是使用SBT。将以下行添加到build.sbt

resolvers += "spray repo" at "http://repo.spray.io"

// Dependencies
libraryDependencies += "com.typesafe.akka" %% "akka-actor" % "2.2.3"

libraryDependencies += "io.spray" % "spray-client" % "1.2.0"

现在,程序的源代码看起来非常简单,也是非阻塞的:

import akka.actor.ActorSystem
import spray.http._
import spray.client.pipelining._
import scala.concurrent.Future
import scala.util.{ Success, Failure }

object HTTPTest extends App {
  implicit val system = ActorSystem("http-test")
  import system.dispatcher // execution context for futures

  // take an http request and return a future of http response
  val pipeline: HttpRequest => Future[HttpResponse] = sendReceive


  // this method will give you *only* the status code for a URL as a Future
  def getStatusFor(url: String): Future[Int] =
    pipeline(Get(url)).map { x => x.status.intValue }

  // use it this way
  getStatusFor("http://server.org/help").onComplete {
    case Success(statusCode) => println(statusCode)
    case Failure(err) => // do something with the exception
  }
}

这有帮助吗?