JavaのWeb Applicationとして、RSS/Atom Feedを作成するプログラムを作成してみましょう。J2EE web
applicationの開発に精通した方には、今回の内容はあまり有益ではないかも知れませんが、「RSS/Atom
FeedってどうWebから生成すればいいのだろう」と漠然と考えている方にはお勧めです。Javaのツールを使って簡単に実現することができます。今回
はJava.netのRome Projectが提供しているFeed Syndication APIとそのsample
codeをそのまま利用します。
RomeのFeed Syndication APIを利用することで、様々なFeed Formatに非常に簡単に対応することが可能です。もちろん、JavaのAPIですから既存のJ2EE web applicationにも直ぐに適用することができます。JDK だけで開発するのも可能ですが、今回は今後のことも考えて、最新のJava統合開発環境のNetBeans 4.1 日本語版と、J2EE 1.4の実行環境であるApplication Server 8.1 PEを利用します。
こんな簡単なことをするのに、なぜ統合開発環境とApp serverをと思われるかもしれませんが、ビルドや配備作業、デバッグ、プロファイリング、HTTPモニタ機能など、現実の開発に必要なツールが多数含 まれているためです。(今後好評ならこれを発展させて行きたいので・・・)
準備

アプリケーションの開発




アプリケーションの実行

最後に
このサンプルアプリケーションでは、初回ということで、Feedの情報をServletのコード内で作成していますが、情報をDBから取得したり、動的に生成したり、または、ユーザによってJ2EEの機能を活用した認証や、Feedのパーソナライズしたりすることにより、様々なことが可能になります。(LDAPと連携してここのIdentity情報をベースにしたPersonalized Feedなども実現できますね。)またJ2EE Application Server上で構築することは、このアプリの可用性向上や、負荷分散機能の実現が容易なことをも意味します。
この記事が好評なようであれば・・・、次の機会にこれらに挑戦してみたいと思います。(NetBeansのMobility Packを利用して、MIDPのRSS Readerと連携するってもも個人的には興味がありますが・・・)
Rome Projectのメンバーに感謝。
RomeのFeed Syndication APIを利用することで、様々なFeed Formatに非常に簡単に対応することが可能です。もちろん、JavaのAPIですから既存のJ2EE web applicationにも直ぐに適用することができます。JDK だけで開発するのも可能ですが、今回は今後のことも考えて、最新のJava統合開発環境のNetBeans 4.1 日本語版と、J2EE 1.4の実行環境であるApplication Server 8.1 PEを利用します。
こんな簡単なことをするのに、なぜ統合開発環境とApp serverをと思われるかもしれませんが、ビルドや配備作業、デバッグ、プロファイリング、HTTPモニタ機能など、現実の開発に必要なツールが多数含 まれているためです。(今後好評ならこれを発展させて行きたいので・・・)
準備
- Rome プロジェクトの サ イトからバイナリをダウンロード、解凍し、rome-0.6.jarを取り出します。Romeは、JDOMを利用しているため、JDOMのサイトからJDOM 1.0のバイナリをダウンロード、解凍し、jdom.jarを取り出します。
- 今回は無料で利用できるJava開発ツールと、J2EE Application Serverを利用するため、NetBeansとSun Java System Application Server 8.1 Platform Editionをインストールします。NetBeans, SJS Appliction Server 8.1 PEは、NetBeans.orgからダウンロードが可能です。NetBeans.orgのダウンロードページからNetBeans IDE 4.1 with J2EE Application Server 8.1 PE bundleを選んでください。バイナリをダウン ロード後、インストールしてください。インストールしたApplication Server 8.1 PEは、NetBeansを起動し、左側パネルの「実行時」タグをクリックし実行時ペインを開き、サーバを右クリックし、「サーバを追加」を選択してくだ さい。ウィザードが起動し、指示に従い情報を入力することで追加することが出来ます。
アプリケーションの開発
- NetBeansを起動し、新規プロジェクトを作成してください。ここではFeedApplication1としてWebアプリ ケーションのプロジェクトを作成します。
- プロジェクトタグのFeedApplication1を右クリックし、新規からJavaパッケージを選択し、このアプリケーションの package名を指 定します。ここでは、jp.co.sun.feedとしています。
- プロジェクトタグのライブラリを右クリックし、「JAR/フォルダを追加」を選び、rome-0.6.jarとjdom.jarをそれぞれ追 加してください。
- プロジェクトタグのFeedApplication1を右クリックし、新規からサーブレットを選択し、新しく SampleFeedServletを作成します。サーブレットのパッケージ名は、先ほど作成したjp.co.sun.feedが選択可能になっていま す。<コンテキスト>/<URLマッピング名>でSampleFeedServletが呼び出されるよう、URLマッピングを /feedとします。
- 作成したSampleFeedServletのコードを追加します。このコードはRome
プロジェクトのサンプルコードを修正して利用しています。(コードの詳細はまた別の機会にでも紹介することにします。)Feedが英語のままだとつまらな
いので、記述は日本語に変更しています。
/*
* SampleFeedServlet.java
* Most of codes are copyed from rome-sample-06 FeedServlet.java
* Please refer to rome-sample-06 which is available on
http://wiki.java.net/bin/view/Javawsxml/Rome
* Created on 2005/08/11, 16:51, Akihito Fujii
*/
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
software
* distributed under the License is distributed on an "AS IS"
BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied.
* See the License for the specific language governing permissions
and
* limitations under the License.
*
*/
package jp.co.sun.feed;
import java.io.*;
import java.net.*;
import javax.servlet.*;
import javax.servlet.http.*;
import com.sun.syndication.feed.synd.*;
import com.sun.syndication.io.FeedException;
import com.sun.syndication.io.SyndFeedOutput;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author akihito
* @version
*/
public class SampleFeedServlet extends HttpServlet {
private static final String DEFAULT_FEED_TYPE =
"default.feed.type";
private static final String FEED_TYPE = "type";
private static final String MIME_TYPE =
"application/xml; charset=UTF-8";
private static final String
COULD_NOT_GENERATE_FEED_ERROR = "Could not generate feed";
private static final String DATE_FORMAT =
"yyyy-MM-dd";
private String _defaultFeedType;
public void init() {
_defaultFeedType =
getServletConfig().getInitParameter(DEFAULT_FEED_TYPE);
_defaultFeedType =
(_defaultFeedType!=null) ? _defaultFeedType : "atom_0.3";
}
/** Processes requests for both HTTP
<code>GET</code> and <code>POST</code> methods.
* @param request servlet request
* @param response servlet response
*/
protected void processRequest(HttpServletRequest
request, HttpServletResponse response)
throws ServletException, IOException {
DateFormat dateParser = new
SimpleDateFormat(DATE_FORMAT);
SyndFeed feed = new
SyndFeedImpl();
feed.setTitle("Sample Feed
(created with Rome)");
feed.setLink("http://rome.dev.java.net");
feed.setDescription("このフィードはRome(Java syndication
utilities)を利用して生成されています。");
List entries = new
ArrayList();
SyndEntry entry;
SyndContent description;
entry = new SyndEntryImpl();
entry.setTitle("Rome v0.1");
entry.setLink("http://wiki.java.net/bin/view/Javawsxml/Rome01");
try {
entry.setPublishedDate(dateParser.parse("2004-06-08"));
}
catch (ParseException ex) {
//
IT CANNOT HAPPEN WITH THIS SAMPLE
}
description = new
SyndContentImpl();
description.setType("text/plain");
description.setValue("Romeの初期リリースです。");
entry.setDescription(description);
entries.add(entry);
entry = new SyndEntryImpl();
entry.setTitle("Rome v0.2");
entry.setLink("http://wiki.java.net/bin/view/Javawsxml/Rome02");
try {
entry.setPublishedDate(dateParser.parse("2004-06-16"));
}
catch (ParseException ex) {
//
IT CANNOT HAPPEN WITH THIS SAMPLE
}
description = new
SyndContentImpl();
description.setType("text/plain");
description.setValue("バグ修正、APIのマイナーチェンジ、数件の新機能の追加。"+
"<p>詳細は <a
href=\"http://wiki.java.net/bin/view/Javawsxml/RomeChangesLog#RomeV02\">Changes
Log for 0.2</a>を参照してください</p>");
entry.setDescription(description);
entries.add(entry);
entry = new SyndEntryImpl();
entry.setTitle("Rome v0.3");
entry.setLink("http://wiki.java.net/bin/view/Javawsxml/Rome03");
try {
entry.setPublishedDate(dateParser.parse("2004-07-27"));
}
catch (ParseException ex) {
//
IT CANNOT HAPPEN WITH THIS SAMPLE
}
description = new
SyndContentImpl();
description.setType("text/html");
description.setValue("<p>バグ修正、APIの変更、数件の新機能追加、ユニットテストの実施</p>
"+
"<p>詳細は<a
href=\"http://wiki.java.net/bin/view/Javawsxml/RomeChangesLog#RomeV03\">Changes
Log for 0.3</a>を参照してください。</p>");
entry.setDescription(description);
entries.add(entry);
entry = new SyndEntryImpl();
entry.setTitle("Rome v0.4");
entry.setLink("http://wiki.java.net/bin/view/Javawsxml/Rome04");
try {
entry.setPublishedDate(dateParser.parse("2004-09-24"));
}
catch (ParseException ex) {
//
IT CANNOT HAPPEN WITH THIS SAMPLE
}
description = new
SyndContentImpl();
description.setType("text/html");
description.setValue("<p>バグ修正、APIの変更、数件の新機能追加、ユニットテストの実施終了<
/p>"+
"<p>詳細は<a
href=\"http://wiki.java.net/bin/view/Javawsxml/RomeChangesLog#RomeV04\">Changes
Log for 0.4</a>を参照してください。</p>");
entry.setDescription(description);
entries.add(entry);
feed.setEntries(entries);
try {
String feedType = request.getParameter(FEED_TYPE);
System.out.println("FeedType:"+ feedType);
feedType = (feedType!=null) ? feedType : _defaultFeedType;
feed.setFeedType(feedType);
response.setContentType(MIME_TYPE);
SyndFeedOutput output = new SyndFeedOutput();
output.output(feed,response.getWriter());
}
catch (FeedException ex) {
String msg = COULD_NOT_GENERATE_FEED_ERROR;
log(msg,ex);
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,msg);
}
}
// <editor-fold defaultstate="collapsed"
desc="HttpServlet methods. Click on the + sign on the left to edit the
code.">
/** Handles the HTTP <code>GET</code>
method.
* @param request servlet request
* @param response servlet response
*/
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
processRequest(request,
response);
}
/** Handles the HTTP <code>POST</code>
method.
* @param request servlet request
* @param response servlet response
*/
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
processRequest(request,
response);
}
/** Returns a short description of the servlet.
*/
public String getServletInfo() {
return "Short description";
}
// </editor-fold>
}- 作成されているindex.jspを編集します。
(省略)
<body>
<h1>Feed JSP Page</h1>
<BR><A HREF="./feed">FeedServlet
パラメータなし</A><BR>
<BR><A
HREF="./feed?type=atom_0.3">FeedServlet Atom</A><BR>
<BR><A
HREF="./feed?type=rss_1.0">FeedServlet RSS 1.0</A><BR>
<BR><A
HREF="./feed?type=rss_2.0">FeedServlet RSS 2.0</A><BR>
<%--(以下省略)- Webアプリケーションの配備記述子に、デフォルトのFeedタイプをを指定するための初期パラメータを追加します。
アプリケーションの実行
- 実行ボタンを押し、アプリケーションをコンパイル、パッケージング、配備し、実行します。ブラウザが起動され、index.jspが表示され ます。それぞれのリンクをクリックすることにより、1つのサーブレットから異なるフォーマットのFeedが生成されます。以下はAtom, RSS 1.0, RSS 2.0の実行例です。
最後に
このサンプルアプリケーションでは、初回ということで、Feedの情報をServletのコード内で作成していますが、情報をDBから取得したり、動的に生成したり、または、ユーザによってJ2EEの機能を活用した認証や、Feedのパーソナライズしたりすることにより、様々なことが可能になります。(LDAPと連携してここのIdentity情報をベースにしたPersonalized Feedなども実現できますね。)またJ2EE Application Server上で構築することは、このアプリの可用性向上や、負荷分散機能の実現が容易なことをも意味します。
この記事が好評なようであれば・・・、次の機会にこれらに挑戦してみたいと思います。(NetBeansのMobility Packを利用して、MIDPのRSS Readerと連携するってもも個人的には興味がありますが・・・)
Rome Projectのメンバーに感謝。
cool
Posted by wow gold on 11月月 03日, 2008年 at 10:42 午前 JST #