2007年 1月 31日 水曜日
We just released a new version of
Pet Store 2.0.
Although the UI looks pretty much same, the codes were refactored
and we fixed a lot of bugs. Also this version of Pet Store includes
a new news.jsp which can be found when you click the left side
of the RSS bar.
and the news.jsp looks like:--
In the previous version of Pet Store 2.0, when you click this link it pops up another window to show the content of RSS feed, but now it guides you to the news.jsp which is one of the jsp page included in the package. There were a few problems in popping up the window, such as not working well with IE.
We also changed the logic to cache the RSS feed information in the server. Now it's caches data in an application scope so that all requests within the Pet Store context can share the same RSS feed information and both RSS bar and news.jsp use the same cached data.
The code in news.jsp(and the associated JavaScript) is very simple. Since the data is already constructed by ROME library on the server, it just consumes and rearrange the contents within the page.
Handling the strings in the RSS feed is a little tricky.
Because usually those strings in the feed contain characters which
are not usable in JSON, such as double quote, we need to 'escape' them
somehow. We use URL encoding for this purpose. We encode all strings
on the server side and decode them on the client's JavaScript.
However, as there's a slight difference between Java URL encoding
and JavaScript's URLencode() and URLdecode(), we needed to write
our own URLdecode() function for matching Java URL encoding mechanism.
Please
check this version of Pet Store 2.0
and let us know what you
think on the
forum.
2006年 12月 18日 月曜日
2006年 10月 02日 月曜日
FeedFetcherCache syndFeed = new HashMapFeedInfoCache();
FeedFetcher feedFetcher = new HttpURLFeedFetcher(feedInfoCache);
/* attach listener here if you need to change the behavior of
* response from the server
*/
SyndFeed syndFeed = feedFetcher.retrieveFeed(new URL(urlString));
then to process the feed:-
syndFeed.getTitle() // get the title of Feed title
List <SyndEntry> entries = syndFeed.getEntries();
for (SyndEntry entry : entries) {
entry.getTitle(); // get the title of each entry in the feed
}
The current RSS component generates the JSON from the feed and
sends back to the client, then the client side javascript processes
it and displays in a ticker. All of those back-end process is done
in the managed bean's method which is called by the javascript
via shale-remoting. There are some new features in this version
of Pet Store 2.0, such as tagging. So please check that out!
Posted by yuta
( 10月 02日 2006年, 03:00:58 午後 PDT )
Permalink
投稿されたコメント [0]
2006年 8月 18日 金曜日 Despite that there are some issues in captcha, such as in accessibility, it is widely used in many web applications to separate the human and computer activities. (For the detailed explanation about captcha, take a look at the wikipedia entry.) There are many implementations available for various languages to incorporate this mechanism into your web application. It's also very easy to do so with Java EE 5 and AWT and in fact, the latest release of Petstore 2.0 from Java BluePrints group has this functionality in fileupload component. It looks like this.
This mechanism consists of the following resources.
Captcha generator servlet
This servlet creates the captcha image with a
random string and put that information of the string into
HttpSession object for later reference.
Creating the image
dynamically is very simple. Although the code in Petstore 2.0 has a
little more twist like drawing lines as a noise and scatter
characters within the box, it essentially does:-
BufferedImage bufferImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics g = bufferImg.getGraphics();
g.setColor(background-color);
g.fillRect(0, 0, width, height);
g.setFont(new Font("Arial", Font.BOLD | Font.ITALIC, 30));
g.setColor(Color.GRAY);
g.drawString(message, startPosition, endPosition);
Also, after creating this image, it applies the filter to convert the
color to the blue-ish one. This is for a developer who wants to add
another kind of filter such as for a distortion.
The class which
generates the image and is used by the servlet can be seen
here
in java.net.
Captcha validation filter
This is a very simple filter which compares the
user input(with session id) and the stored string in the HttpSession
object. When matched, it just pass the request to the original
requested resource, otherwise it generates a error message in JSON
and sends back to the client.
So what's next? Perhaps I should create a JavaServer Faces component for captcha. Creating the component itself is relatively easy. They are just <h:outputText>, <h:graphicImage>, and <h:outputText> with attributes to specify the size, color, etc. The problem is a transaction for a validation. Yes, we can do a dynamic validation on only the client side with AJAX, however the logic to validate has to be associated with the process of the actual form submission. Even if we did the client side dynamic validation, the "proof" of validation still must be stored somewhere on the server side, otherwise people can mimic the form submission. That means a developer needs to implement a logic to do something in his or her web application even with JSF component. Well, I guess I need to think about this a little more...
Posted by yuta ( 8月 18日 2006年, 11:35:58 午前 PDT ) Permalink 投稿されたコメント [1]
2006年 5月 11日 木曜日 |
|
つい数分前に新しい
PetStore 2.0 Early Access 1.0をリリースしました。 前のバージョンは EJBのショーケースとしてEコマース的なアプリケーションでしたが、今回は Web Tierのみ(もちろんDBとの連携は Persistence APIですが)の アプリケーションになっています。PetStore 2.0 はAJAXを多用し、Google Maps などとの Mash up も行っています。その他にも、オートコンプリート、 プログレスバー、RSSリーダー、PayPalとの接続など盛りだくさんの 機能が含まれています。また、NetBeans 5.5 のプロジェクトとしても 使えます。ちょっと変更が必要なのですが、 Geertjanが Using the Pet Store 2.0 in NetBeans 5.5を書いてくれました。 このリリースで私たちが採用したプログラミングモデルには実験的なものも 含まれています。多くの方に使っていただいて、いろいろなフィードバックを 得られたらと思っています。 |
2006年 5月 02日 火曜日
日本語版アクエリアムが立ち上がりました。
もちろん、水族館の話ではなく、glassfish、JavaEE5、AJAXなど
今話題になっている情報へのポータルブログです。基本的には
英語版の情報を日本語で伝えるのですが、日本独自のブログや
情報も載せていきたいと思っています。
2006年 4月 14日 金曜日
2006年 4月 01日 土曜日
private static XhtmlHelper helper = new XhtmlHelper();
public void encodeEnd(FacesContext context, UIComponent component)
throws IOException {
ResponseWriter writer = context.getResponseWriter();
//shale remoting resource retrieval
helper.linkJavascript(context, component, writer,
Mechanism.CLASS_RESOURCE, "/META-INF/r-dir/yuta.js");
<managed-bean>
<managed-bean-name>c_request_handler</managed-bean-name>
<managed-bean-class>クラスバス</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>name</property-name>
<value>#{param.name}</value>
</managed-property>
</managed-bean>
private static XhtmlHelper helper=new XhtmlHelper();
public void encodeBegin(FacesContext context, UIComponent component)
throws IOException {
ResponseWriter writer = context.getResponseWriter();
// コールバック用のストリングを作ります
// "c_request_handler というのは、上のfaces-config中で指定した managed bean
// の名前です。
String callBackString = helper.mapResourceId(context,
Mechanism.DYNAMIC_RESOURCE,
"/c_request_handler/handleRequestMethod");
// この後、callBackString をjavascript で例えばボタンの onClick で別の
// function() を呼んでその中で XmlHttpRequest で送るための URL として
// 指定したりします
setName()、
getName() は必要です。そしてレンダラー中で書いたメソッド
handleRequestMethod()でgetName()とすれば
http://ほにゃらら/ほげほげ/handleRequestMethod?name=yoshida
なんていうリクエストがきたら Shale が自動的に値を返してくれます。
private static ResponseFactory factory = new ResponseFactory();
.........
public void handleRequestMethod() {
FacesContext context = FacesContext.getCurrentInstance();
..........
ResponseWriter writer = factory.getResponseWriter(context, "text/html");
writer.startElement(.................);
..........
}
2006年 3月 30日 木曜日
public void afterPhase(PhaseEvent event) {
String rootId = event.getFacesContext.getViewRoot().getViewId();
if (rootId.endsWith("特定のJavaScriptファイルとかを指すID")) {
handleResourceRequest(event, "/META-INF/コンポーネント名/ファイル名",
"text/javascript");
}
........
}
public void handleResourceRequest(PhaseEvent event, String resource, String contentType) {
1). getClass().getResourceAsStream(resource);で実際のリソース取ってきて、
2). event.getFacesContext().getExternalContext().getResponse();で
HttpServletResponse 取って、
3). リソース読み込んで response に setContentType()して、
OutputStream に書き出す
}
ただ、別のリソース
を追加したりしたときの管理がけっこう面倒だったり、複数の人が別々のコンポーネント
を作ってる時、当然 PhaseListener はそのコンポーネントの数だけ存在する場合が多く、
faces-config.xml に登録されたリスナはすべて起動されて結局同じ JavaScript を
複数回ロードしてしまうような結果をレンダーしてしまうとかいうけっこう厄介な問題が
あります。Today's Page Hits: 207