お天気情報をJSONでくれるWebAPIがあるので、それを利用してお天気アプリを作成しよう。
WebAPI確認
1.まずはWebAPIから吐き出されるJSONを確認しよう。
今回はlivedoorから提供されているWeather Hacks
のAPIを使用する。まずは東京のお天気情報のリクエストURLを叩いてレスポンスを確認しよう。
http://weather.livedoor.com/forecast/webservice/json/v1?city=130010

まるっとコピーしてJSON整形サイトで確認してもよいが、吐き出す内容が多いのでChromeにプラグインとしてインストールしたJSON formatterで確認してみる。

要素を折りたたむことができるので全体像をつかむのに便利だ。
2.アプリの仕様を決める。
すべての要素を盛り込んでアプリを作ってもいいが、今回は送信されるデータのうち、title,description,forecastsを利用することとする。
アプリ作成
下準備
1.エクリプス、新規動的Webプロジェクトから[joytas13]アプリを作成する。
2.GsonでJsonパースを行いたいので以下のファイルをWEB-INF/libの中に貼り付ける。
model
1.Jsonデータとにらめっこしながらmodelを作成する。今回は以下のような3つのクラスを作成した。
●model.Image.java(forecastがもっている画像情報クラス)
03 | import java.io.Serializable; |
05 | public class Image implements Serializable{ |
17 | public int getWidth() { |
20 | public void setWidth( int width) { |
23 | public String getUrl() { |
26 | public void setUrl(String url) { |
29 | public String getTitle() { |
32 | public void setTitle(String title) { |
35 | public int getHeight() { |
38 | public void setHeight( int height) { |
●model.Forecast.java(1日分のお天気データクラス)
(Jsonにあるtemperatureは今回不使用)
03 | import java.io.Serializable; |
22 | public class Forecast implements Serializable{ |
23 | private String dateLabel; |
28 | public String getDateLabel() { |
31 | public void setDateLabel(String dateLabel) { |
32 | this .dateLabel = dateLabel; |
34 | public String getTelop() { |
37 | public void setTelop(String telop) { |
40 | public String getDate() { |
43 | public void setDate(String date) { |
46 | public Image getImage() { |
49 | public void setImage(Image image) { |
●model.Weather.java(本体となるクラス、3日分の天気などをhas-aで持つ)
(使いたい部分を抽出してクラスのフィールドとする)
03 | import java.io.Serializable; |
18 | public class Weather implements Serializable{ |
20 | private String description; |
21 | private Forecast[] forecasts; |
23 | public String getTitle() { |
26 | public void setTitle(String title) { |
29 | public String getDescription() { |
32 | public void setDescription(String description) { |
33 | this .description = description; |
35 | public Forecast[] getForecasts() { |
38 | public void setForecasts(Forecast[] forecasts) { |
39 | this .forecasts = forecasts; |
controller
1.リクエストを処理するコントローラーを以下のように作成する。
[処理の流れ]
WebAPIにHttpリクエストを投げて、その結果(Json)をInputStreamで取得。
取得したデータをGsonでパースしてWeatherオブジェクトを生成し、リクエストスコープに詰めている。
なお、Jsonに含まれる改行コードの部分をbrタグに変換するメソッドを別メソッドにしている。
(こうすることで改行コード部分をHtml上で改行させることができる)
●controller.Main.java(Servlet)
03 | import java.io.IOException; |
04 | import java.io.InputStream; |
05 | import java.io.InputStreamReader; |
06 | import java.net.HttpURLConnection; |
09 | import javax.servlet.RequestDispatcher; |
10 | import javax.servlet.ServletException; |
11 | import javax.servlet.annotation.WebServlet; |
12 | import javax.servlet.http.HttpServlet; |
13 | import javax.servlet.http.HttpServletRequest; |
14 | import javax.servlet.http.HttpServletResponse; |
16 | import com.google.gson.Gson; |
17 | import com.google.gson.JsonArray; |
18 | import com.google.gson.JsonObject; |
19 | import com.google.gson.stream.JsonReader; |
26 | * Servlet implementation class Main |
29 | public class Main extends HttpServlet { |
30 | private static final long serialVersionUID = 1L; |
32 | protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { |
34 | URL url= new URL( "http://weather.livedoor.com/forecast/webservice/json/v1?city=130010" ); |
36 | HttpURLConnection con=(HttpURLConnection)url.openConnection(); |
37 | con.setRequestMethod( "GET" ); |
39 | InputStream is=con.getInputStream(); |
41 | InputStreamReader isr= new InputStreamReader(is, "UTF-8" ); |
43 | JsonReader reader= new JsonReader(isr); |
45 | JsonObject root= new Gson().fromJson(reader,JsonObject. class ); |
47 | Weather w= new Weather(); |
49 | w.setTitle(root.get( "title" ).getAsString()); |
52 | w.setDescription(nl2br(root.get( "description" ).getAsJsonObject().get( "text" ).getAsString())); |
54 | JsonArray fArray=root.get( "forecasts" ).getAsJsonArray(); |
56 | Forecast[] forecasts= new Forecast[fArray.size()]; |
58 | for ( int i= 0 ;i<fArray.size();i++) { |
60 | JsonObject fObj=fArray.get(i).getAsJsonObject(); |
62 | Forecast f= new Forecast(); |
64 | f.setTelop(fObj.get( "telop" ).getAsString()); |
65 | f.setDateLabel(fObj.get( "dateLabel" ).getAsString()); |
66 | f.setDate(fObj.get( "date" ).getAsString()); |
68 | JsonObject iObj=fObj.get( "image" ).getAsJsonObject(); |
70 | Image image= new Image(); |
72 | image.setHeight(iObj.get( "height" ).getAsInt()); |
73 | image.setTitle(iObj.get( "title" ).getAsString()); |
74 | image.setUrl(iObj.get( "url" ).getAsString()); |
75 | image.setWidth(iObj.get( "width" ).getAsInt()); |
82 | w.setForecasts(forecasts); |
84 | request.setAttribute( "weather" , w); |
86 | RequestDispatcher rd=request.getRequestDispatcher( "/WEB-INF/view/main.jsp" ); |
87 | rd.forward(request,response); |
92 | public static String nl2br(String str) { |
93 | if (str == null || str.equals( "" )) { |
96 | str = str.replace( "\n" , "<br>" ); |
view
1.modelとcontrollerの連携により欲しいデータが作れたので後はviewで表示するだけだ。
いつものように/WEB-INF/の中にviewフォルダを作ってmain.jspを配置しよう。
●/WEB-INF/view/main.jsp
01 | <%@ page language= "java" contentType= "text/html; charset=UTF-8" |
02 | pageEncoding= "UTF-8" import = "model.*" %> |
04 | Weather w=(Weather)request.getAttribute( "weather" ); |
10 | <meta charset= "UTF-8" /> |
11 | <title><%=w.getTitle() %></title> |
14 | <h1><%=w.getTitle() %></h1> |
15 | <p><%=w.getDescription() %></p> |
17 | <% for (Forecast f:w.getForecasts()) {%> |
19 | <td><%=f.getDateLabel() %></td> |
20 | <td><%=f.getTelop() %></td> |
21 | <td><%=f.getDate() %></td> |
22 | <%Image image=f.getImage(); %> |
23 | <td><img src= "<%=image.getUrl()%>" width= "<%=image.getWidth() %>" height= "<%=image.getHeight() %>" alt= "<%=image.getTitle()%>" ></td> |
完成品
1.以下のように東京の3日分(時間帯によっては2日分)のお天気情報が表示されれば成功だ。

コメント