Web Services using Play!

Posted: August 15, 2010 in Play Framework

A reasonably undocumented feature of Play is the ease in which Web Services can be integrated into your application. This quick blog will show you how easy it is to create a Play Web Application to do a currency conversion calculation, using Live currency rates between some popular currencies.If you have not already done so, download the latest version of Play from http://www.playframework.org.

Open your command prompt at the directory where you have unzipped and type.

play new currency

Follow the on-screen prompts to set up your new application.
Next start the server by typing

play run currency

Now, open the file currency/app/views/Application/index.html.
In this page we want to have two drop down lists with common currencies to select, and a value field. Change the code so that it looks like the following.

#{extends 'main.html' /}
#{set title:'Home' /}

<h1>Play! Currency Converter</h1>
<form action="@{Application.convert()}" method="POST">
    Currency From:
	<select name="from">
		<option value="USD">USD - US Dollar</option>
		<option value="GBP">GBP - UK Pound Sterling</option>
		<option value="EUR">EUR - Euro</option>
	</select><br />
    Currency To:
	<select name="to">
		<option value="USD">USD - US Dollar</option>
		<option value="GBP">GBP - UK Pound Sterling</option>
		<option value="EUR">EUR - Euro</option>
	</select><br />
	Amount: <input type="text" name="amount" /> <br />

	<input type="submit" name="conv" value="Convert" />
</form>

This code is fairly straightforward HTML. The only Play feature in the code is the form action which points to a Play action (which we will create next), using the @{Application.convert()} code.

Next, we need to open the app/controllers/Application.java.
We need to add the convert action to send our form data to. The file should look like this.

package controllers;

import play.mvc.*;
import play.libs.*;
import org.w3c.dom.Document;

public class Application extends Controller {
	
    public static void convert(String from, String to, Float amount) {
		
        String wsReq = "<?xml version=\"1.0\" encoding=\"utf-8\"?><soap12:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap12=\"http://www.w3.org/2003/05/soap-envelope\">" +
					  "<soap12:Body><ConversionRate xmlns=\"http://www.webserviceX.NET/\">" +
                      "<FromCurrency>"+from+"</FromCurrency>" +
                      "<ToCurrency>"+to+"</ToCurrency>"+
					  "</ConversionRate></soap12:Body></soap12:Envelope>";
					  
		Document doc = WS.url("http://www.webservicex.net/CurrencyConvertor.asmx").setHeader("Content-Type", "application/soap+xml").body(wsReq).post().getXml();
		String rate = doc.getElementsByTagName("ConversionRateResult").item(0).getTextContent();
		
		Float total = amount * Float.parseFloat(rate);
		render(from, to, amount, rate, total);
	}

    public static void index() {
        render();
    }
}

The main piece of code we are concerned about is the convert method. This method is called when the form is submitted (courtesy of the @{Application.convert()} code in the index.html page).
The method takes 3 parameters, which Play automatically maps from the HTTP parameters sent by the form, so we have the values present immediately when the method is created.

The first thing we do in the method (Play calls these methods actions, so we will do the same from now on), is to create the XML for the soap request. The XML is a reasonably simple SOAP request containing the envelope and body, and the currency symbols we want to convert from and to.

Next, is the WebService part of Play. To use web services in Play, we need to use the play.libs.WS class. Let’s take a closer look at the Web Service call.

Document doc = WS.url("http://www.webservicex.net/CurrencyConvertor.asmx").setHeader("Content-Type", "application/soap+xml").body(wsReq).post().getXml();

The first part of the request specifies the URL that we want to connect to. Here I am using a free sample webservice for live currencies. The second part adds a header to the request. For the request to work, the request needs to specify that the content is soap-xml, which is why the header needs to be added. The third part sets the body of the request to the SOAP xml we created at the start of the action, and the final part sends the SOAP request using the post method.
The final part (getXml()) returns the response as a Document object, ready for parsing.

The rest of the convert action simply gets the result from the returned XML, and calculates the total amount converted from the amount to convert multiplied by the exchange rate returned from the web service. All of the values (including the ones submitted by the form) are then passed through to the HTML page, so that they can be rendered, by calling the render method.

Finally, we need to output the results of the conversion. So let’s create a new file called app/views/Application/convert.html, and add the following code.

#{extends 'main.html' /}
#{set title:'Converted' /}

<h1>Total ${to} ${total}</h1>
Converted ${amount} ${from} to ${to} at an exchange rate of ${rate}

We can now try out our application. Go to http://localhost:9000 and you will see a page like this.

If we choose USD and GBP and set an amount, then click convert, we should see the results similar to the following.

To achieve this result, our code called an external web service to look up the Live exchange rate between these two currencies, and then used the results in our controller to perform the necessary calculations to display the results on the screen.

How cool is that! A currency conversion application, using real LIVE currency rates, written in less than 50 lines of code.

About these ads
Comments
  1. Dirk says:

    Nice! I had no idea that the WS class existed. Up until now I was using the apache HTTPClient classes which are much more complex than WS.

    Thanks for the tip!

  2. engin says:

    Isn’t “Apache Axis” easier to use ?

  3. opensas says:

    great article! I guess a rest sample would be quite similar, using the url instead of the body to pass data…

  4. Bence says:

    As far as I know PLay can render xml too.

    Is there a way to set up a groovy-like play template for the xmlrequest? Like this:


    ${from}
    ${to}

    and then render the xml request out of it?

    It would be much more nice!

    • codemwnci says:

      Yes, play can render XML using groovy, but as part of the MVC pattern, so therefore as the View of an action request.

      As the webservice is being used server side, and a the result of the webservice being displayed in the browser using a standard HTML view, this is not that easy.

      It is not impossible, because you can access the groovy engine, but it is not a neat solution.

  5. Bence says:

    As far as I know Play can render xml too.

    Is there a way to set up a groovy-like Play template for the xmlrequest? Like this:


    <FromCurrency>${from}</FromCurrency>
    <ToCurrency>${to}</ToCurrency>

    and then render the xml request out of it?

    It would be much more nice!

    • Bence says:

      …and how exactly can render a template into a String?

      From a controller I can call render() / renderHtml()/ renderJson(), but I don’t know what is the target of the rendering.

      My netbeansified project does not provide the actual source code of play classes, just method skeletons like this:

      protected static void renderHtml(Object html) {
      //compiled code
      throw new RuntimeException(“Compiled Code”);
      }

      This way I cannot check the source code.

      • Bence says:

        So you mean:

        Template template = TemplateLoader.load(template(templateName));
        String content = template.render(args);

        …where the templateName is the name of the file, and args is a map is the contains all the bindings I want to use in this rendering.

  6. Bull says:

    Can you make a blog post with the other way around?

    That is creating the Web Service in Play! for others to consume, or should one use another framework for that?

    • codemwnci says:

      Play is exceptionally good at creating webservices for others to consume due to it’s RESTful nature. It is actually one of the chapters in my book.
      However, a simple explanation would be to create a controller action, that is set up in the routes file to be of format XML, and using the normal play View to output XML. The only difference is, rather than calling your Groovy template actionMethodName.html, you would call your file actionMethodName.xml.

  7. […] http://playframework.wordpress.com/2010/08/15/web-services-using-play/ Bookmark on Delicious Digg this post Recommend on Facebook share via Reddit Share with Stumblers Tweet about it Subscribe to the comments on this post 未分类 ← Why be such a monster? My Tju….. pro git → /* */ […]

  8. OK with play 1.2.1, but with play 1.2.3 I get reponse 400 : “Invalid header”.

  9. You constructed quite a few superb ideas inside your post, “Web Services using Play!
    Wayne’s Play Framework Blog”. I will possibly be heading back to your page soon enough. Thx ,Temeka

  10. This excellent blog post, “Web Services using Play!
    Wayne’s Play Framework Blog” illustrates that you actually understand precisely what you are writing about! I personally completely agree with your blog. Many thanks ,Ezekiel

  11. This particular posting, “Web Services using Play!
    Wayne’s Play Framework Blog” ended up being superb. I am producing out a backup to demonstrate to my close friends. Thanks,Sheila

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s