2013年4月23日火曜日

JBoss7にJSF1.2をデプロイする

JBoss7のGateInに、JSF1.2のポートレットをデプロイしてアクセスすると、
必ずUnsupportedOperationExceptionが発生して動かない。

で、調べてみた処web.xmlにコンテキストパラメータを設定しないといけないようだ。

[参考ページ]
Deploying Simple JSF 1.2 application in jboss 7
https://community.jboss.org/thread/170729
Design of AS7 multi-JSF feature
https://community.jboss.org/wiki/DesignOfAS7Multi-JSFFeature
JBoss AS7 tips
http://www.liferay.com/ja/community/wiki/-/wiki/Main/JBoss+AS7+tips
JSF 1.2 in AS 7
JBoss AS7 comes with JSF 2.0 implementation. Still, you can enable JSF 1.2 very simply, by adding the following snipped in web.xml:
<context-param>
      <param-name>org.jboss.jbossfaces.JSF_CONFIG_NAME</param-name>
      <param-value>Mojarra-1.2</param-value>
</context-param>

Lastly, application do not need jsf implementation jars or jstl jars, as they are already available by JBoss AS7.

20130527 追記
ただし、使用可能なのはデフォルトのMojarra 1.2, Mojarra 2.0, MyFaces 2.0。
MyFaces 1.2以下はデフォルトではNGみたい。
Chapter 3. Deploying Your JSF Applications
http://docs.jboss.org/jbossas/6/JSF_Guide/en-US/html/jsf.deployer.config.html
JBoss AS ships with three JSF Implementations, Mojarra 1.2, Mojarra 2.0, and MyFaces 2.0.

ちなみにMyFacesの場合は、こんな感じ。
Tomcatアプリケーションで動かす場合でも、この設定が必要。
(JBoss7固有の方便が、Tomcatでも強制されるってのは非常に迷惑だと思うのだが…)
<context-param>
      <param-name>org.jboss.jbossfaces.JSF_CONFIG_NAME</param-name>
      <param-value>MyFaces-1.2</param-value>
</context-param>


20130527 追記
上記はOpenShiftのEWS(Tomcat7)上でTobagoを動作させるのに使用した設定。
JBoss7.1上ではNGかもしれない。
素朴にスンゴク迷惑千万なWEBコンテナに思えるのだが…。

[web.xml]

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>FileServlet</servlet-name>
<servlet-class>com.test.FileServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>FileServlet</servlet-name>
<url-pattern>/FileServlet</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>30</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>faces/view.jsp</welcome-file>
</welcome-file-list>
<context-param>
<description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
<context-param>
<param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
<param-value>resources.application</param-value>
</context-param>
<listener>
<listener-class>com.sun.faces.config.ConfigureListener</listener-class>
</listener>
<context-param>
<param-name>org.jboss.jbossfaces.JSF_CONFIG_NAME</param-name>
<param-value>Mojarra-1.2</param-value>
</context-param>
</web-app>

2013年4月21日日曜日

JSFポートレット・ファイルアップロード

JSFのファイルアップロード方法を解説したページがあったのでここに載せておく。
JSF Portlet File Upload
https://jsfportletbridge.java.net/public/JSFPortletFileUpload.html

まだ試してないが、
たぶんサブミットのアクションリスナで実装するのだと思う。

JSFにはファイルアップロード機能が無いので、SpringをWEBフレームワークとして優先させてたけど、ファイルアップロードがOKならばハナシはチョット変わってくる。
(ただJSF的には亜流感がかなりあるように思うが…)

そもそも何故JSFは2.0になってもファイルアップロード機能がサポートされないのだろう?
と疑問に思う。
誰も必要としていないのだろうか?
それなら、このような解説ページができるワケが無いよね。
何故なのだろう?

JSF Portlet File Upload
JSFポートレット・ファイルアップロード
This uses Portlet Filter approach to provide File Upload functionality in JSF Portlet.
これはJSFポートレットの中にファイルアップロード機能を提供する為にポートレットフィルタを使用したアプローチである。
This provides a generic solution that works in all JSF Portlet Bridges and will work on portals that support JSR 286.
ここで提供するのは通常のソリューションであり、全JSFポートレットブリッジで機能し、JSR286をサポートするポータルで機能する。
Following are the steps to add fileupload functionality in your jsf portlet ( See the example jsf fileupload portlet that uses this functionality.)
下記に追記するのは、あなたのJSFポートレットの中にファイルアップロード機能を追加するステップである(JSFファイルアップロード・ポートレットの例でこの機能の使用を見て欲しい)。

1. Add the following JARs to the WEB-INF/lib of the jsf portlet webapp.The version numbers doesn't matter as long as you get the newest.
1.下記JARファイルをJSFポートレットwebappのWEB-INF/libに追加する。最新版を入手する限り、バージョン番号は重要ではない。
commons-fileupload-1.2.1-jar  (supports file upload capability for a portlet)
commons-fileupload-1.2.1-jar  (ポートレットのファイルアップロード機能をサポート)
commons-io-1.4-jar (required by commons-fileupload)
commons-io-1.4-jar (commons-fileuploadに必要)
portlet-fileupload-filter.jar (handles the portlet filter and the fileupload functionality and makes the org.apache.commons.fileupload.FileItem available as a request attribute, Source Code)
portlet-fileupload-filter.jar (ポートレットフィルタとファイルアップロード機能をハンドルし、org.apache.commons.fileupload.FileItemをリクエスト属性として有効にさせる, ソースコード)


2. Add the following portlet filter entry in the portlet.xml
2.portlet.xmlに下記ポートレットフィルタ・エントリを追加する。
<portlet-app ..... version='2.0'>
    <portlet>
        <portlet-name>name_of_the_portlet</portlet-name>
                ........
    </portlet>
    <filter>
        <filter-name>PortletFileUploadFilter</filter-name>
        <filter-class>com.sun.portlet.PortletFileUploadFilter</filter-class>
        <lifecycle>ACTION_PHASE</lifecycle>
    </filter>
    <filter-mapping>
        <filter-name>PortletFileUploadFilter</filter-name>
        <portlet-name>name_of_the_portlet</portlet-name>
    </filter-mapping>
</portlet-app>


3. Define the fileupload component in the JSF page (you will use the name to get FileItem from the request)
3.JSFページにファイルアップロード・コンポーネントを定義する (リクエストからFileItemを入手するのにnameを使用する)
<input type="file" name="name_of_the_component" />


4. After you submit the JSF page, you can obtain the org.apache.commons.fileupload.FileItem for the input file component from the PortletRequest as follows. Once you have access to FileItem you can get the name, the I/O stream of the uploaded file.
4.JSFページでサブミットした後、下記でポートレットリクエストからインプットファイル・コンポーネントのFileItemが使用可能になる。一度FileItemのアクセスを取得すれば、アップロードされたファイルからnameやI/Oストリームが取得できる。
FacesContext facesContext = FacesContext.getCurrentInstance();
PortletRequest portletRequest = (PortletRequest) facesContext.getExternalContext().getRequest();
FileItem fileItem = (FileItem)portletRequest.getAttribute("name_of_the_component");