00.scala2014. 3. 28. 13:43
반응형

After writing a Java REST (RESTful) client using Apache HttpClient, I turned around and modified that code to be a Scala REST client, also using the Apache HttpClient library.

Here then, without much introduction, is the source code for a Scala REST client example, which demonstrates how to read information from the Yahoo Weather API, which is actually an RSS feed. As a result, this example also demonstrates how to search an XML document for the information you want, using the built-in Scala XML parsing capabilities.

package tests

import java.io._
import org.apache.http.HttpEntity
import org.apache.http.HttpResponse
import org.apache.http.client.ClientProtocolException
import org.apache.http.client.HttpClient
import org.apache.http.client.methods.HttpGet
import org.apache.http.impl.client.DefaultHttpClient
import scala.collection.mutable.StringBuilder
import scala.xml.XML

object ScalaApacheHttpRestClient {

  def main(args: Array[String]) {
  
    // (1) get the content from the yahoo weather api url
    val content = getRestContent("http://weather.yahooapis.com/forecastrss?p=80020&u=f")
    
    // (2) convert it to xml
    val xml = XML.loadString(content)
    assert(xml.isInstanceOf[scala.xml.Elem])  // needed?

    // (3) search the xml for the nodes i want
    val temp = (xml \\ "channel" \\ "item" \ "condition" \ "@temp") text
    val text = (xml \\ "channel" \\ "item" \ "condition" \ "@text") text

    // (4) print the results
    val currentWeather = format("The current temperature is %s degrees, and the sky is %s.", temp, text.toLowerCase())
    println(currentWeather)
  }
  
  /**
   * Returns the text content from a REST URL. Returns a blank String if there
   * is a problem.
   */
  def getRestContent(url:String): String = {
    val httpClient = new DefaultHttpClient()
    val httpResponse = httpClient.execute(new HttpGet(url))
    val entity = httpResponse.getEntity()
    var content = ""
    if (entity != null) {
      val inputStream = entity.getContent()
      content = io.Source.fromInputStream(inputStream).getLines.mkString
      inputStream.close
    }
    httpClient.getConnectionManager().shutdown()
    return content
  }

}

Description

As you can see from the main method, the code is pretty simple, only involving a few steps. The getRestContent function does a lot of the dirty work involved in getting the content from a REST URL. (That function can probably be written better, as I'm ignoring a number of exceptions that can happen.)

There is also some magic involved in processing the XML using the Scala XML library. It took me longer to figure out the syntax to search the XML for the nodes I wanted than it did to write the rest of this example, so I'll discuss that Scala XML syntax in another tutorial.

As I mentioned in my earlier Java RESTful client example, there are several other good ways of creating REST clients in Java and Scala, including using the Jersey project, or the Apache CXF project. Those libraries are specifically geared more towards web services and implementing the API of the Java JSRs that describe web services, while the Apache HttpClient library just simplifies the process of creating HTTP clients. Which one you use is up to you, and I hope/plan to write RESTful clients in Scala using each of those libraries.

In trying to keep this short, I'll leave the example and discussion at that. As usual, if you have any questions, comments, or improvements, just leave a note in the comments section below.

Posted by 1010