2014年12月4日木曜日

Android AndroidでGmailのメールを取得する(2)

前回からずいぶん投稿間隔が離れていました。
すみません、ブログのことをすっかり忘れてました。ページビューが地味にあったので、しっかりと書かないとだめですよね……。

前回、「セッションを取得後、Gmail Imapサーバに接続する」の項目で、「com.sun.mail.imap.protocol.IMAPSaslAuthenticator」が見当たらず、接続できないどころかClassNotFoundExceptionが吐き出される、と書きました。

自分が実装していたときには、まだGmailにOAuth2.0認証して接続するという技術情報が少なく、手探り状態でやっていたために上記のような課題にぶつかってしまったのですが、
現在では比較的AndroidでSSLメール通信しようということで、いくつかライブラリが整っているので、このような問題にぶつかることはあまりないかもしれません。

ぶつかってしまった場合は、javax.mail.jarを自分のように単純にOracleのホームページからダウンロードしてAndroidプロジェクト内のlibsに突っ込んだからだと思います。

したがって、解決方法は、以下のようなAndroid RuntimeではないクラスをIncludeしたライブラリを拝借して使わせてもらうこと!

javamail-android

※ 上記のURL先のライブラリは「javax.security」がないため、以下を利用することをお勧めします。
重ね々ね、申し訳ありません。

https://github.com/ruiaraujo/javamail_android



以上!
そうすることで、前回投稿の「5) セッションを取得後、Gmail Imapサーバに接続する」セクションの処理で正常にGmailに接続できることが確認できるかと思います。

そのあとは、所謂いつものJavaMailの使い方でjavax.mail.Folderやjavax.mail.Messageを取得して、メール内容を確認したりすることができると思います。

ただ、Gmailは所謂フォルダでメールの振り分けしているのではなく、「ラベル」で管理しているので若干癖があるので、思いついたらその部分について記載しておきたいです。

Gmail のいくつかの相違点

上記にはっきりと一般ユーザ向けにわかりやすく「Gmail にフォルダはありません。」とありますが、Gmailにもフォルダはあります。送信済みや、INBOXはフォルダ管理されています。
この部分について詳しく知りたい場合は以下のドキュメントを確認するとわかりやすいかもしれません。

IMAP Extensions

2014年1月6日月曜日

git svnからgitへの移行

ソース管理にはvss、svnと色々ありますが、そろそろgitに移行しましょう、という話がでました。
それでは、とばかりに、とあるsvnリポジトリからgitに移行しようとしましたが、これが割りと知識不足のために四苦八苦したのでメモメモ。

1) git svn cloneコマンドでsvnリポジトリを取得します

git svn clone http://svn/my_project

このとき、対象のsvnリポジトリが一般的なの構成(※ 管理の主体となる「my_project」階層配下でtrunk、brunch、tagがぶら下がっている構造)の場合、「- s」オプションを付与して実行しますが、

git svn clone -s http://svn/my_project

trunk配下に別のプロジェクトや、ドキュメントまで一括して管理しているような構造の場合、「-T」「-b」「-t」オプションでtrunk、brunch、tagの階層を明示的に指定してやる必要があります。

git svn clone -T http://svn/my_project/trunk/android/ -b http://svn/my_project/brunch/android/ -t TAGS http://svn/my_project/tag/android/

**

上記のように実行すると、最旧から最新のリビジョンまでの更新情報を取得しますので、対象のリポジトリの規模が大き過ぎると、場合によっては半日以上経っても取得が完了しない場合がありますので、「-r」オプションで最低限必要なリビジョン範囲を指定して取得することも検討します。

git svn clone -r 0001:HEAD http://svn/my_project


2) GitHub Enterprise上等でリポジトリを作成



3) 作成した後、pushコマンドで対象のリポジトリにpushします

git push -f http://git/my_project.git

このとき、ポイントとなるのは、「-f」オプションで強制pushしないと失敗してしまいます。
あまり強制pushは望ましくないですが、git svn cloneコマンドでリビジョンを取得すると、git移行後にsvnリポジトリにコミットした内容をgit上に反映したい場合、git svn rebaseで手軽に実行できます。

2011年10月27日木曜日

Struts ファイルアップロード制限の方法

色々なサイトで紹介されていますが、Strutsでのファイルアップロードサイズ制限の方法を記載します。

結論から言えば、細かいvalidateの実装の仕方はともかくして、たとえば10KB以上のファイルをアップロードさせないためには、
struts-config.xmlに次の内容を<struts-config></struts-config>のなかに書いてやるだけ。

<controller maxFileSize="10K" />

ただ、最初はこの設定をすれば、こうできるよ、というように安易に受け取っていましたが、
よくよく調べてみると、所謂MVC(Model・view・controller)でのC(controller)にあたる、
コントローラでチェックしてね、ということらしいです。

そして、所謂だいたいのコントローラでチェックしたい要望を満たす為のオプションは既にStrutsが用意してくれてるよ、
と、そういうことらしいです。
つまりは、上記の設定内容は厳密に記載すると、以下のような書き方になる。

<controller
    maxFileSize="10K"
    className="org.apache.struts.config.ControllerConfig"
    multipartClass="org.apache.struts.upload.CommonsMultipartRequestHandler"
    processorClass="org.apache.struts.acrion.RequestProcessor" />

classNameはコントローラ設定情報を保持するクラス、multipartClassはMultipartRequestHandler、processorClassはprocessorClassを意味しており、省略するとそれぞれStrutsでは上記のクラスを利用することになっている。
要するに<controller>はその名の通りコントローラを定義する設定であり、「maxFileSize」は「className="org.apache.struts.config.ControllerConfig"」に設定しているだけであったりします。

【参考】
http://www.jajakarta.org/struts/struts1.1/documentation/ja/target/api/org/apache/struts/config/ControllerConfig.html

用途によってコントローラを独自のクラスに拡張したりできますが、
ここからはStrutsフレームワークと銘打っている以上はここからはStrutsでのファイルアップロードサイズ制限の方法について記載します。

**

1) struts-config.xmlに最大ファイルサイズ制限を設定します。
<controller maxFileSize="10K" />

2) struts-config.xmlにメッセージリソースを利用したい場合はメッセージリソースを設定します。
<message-resources parameter="message"/>


3) struts-config.xmlにValidatorPlugInを設定します。
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
    <set-property property="pathnames" value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml" />
</plug-in>

4) 独自validatorクラスを実装する。
package jp.co.sheep.validator;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.validator.Field;
import org.apache.commons.validator.Validator;
import org.apache.commons.validator.ValidatorAction;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.upload.MultipartRequestHandler;
import org.apache.struts.validator.Resources;

/**
 *
 * @author SHEEP
 *
 */
public final class MyValidator {

    /**
     * コンストラクタ.
     */
    private MyValidator() {
        // 生成禁止
    }

    /**
     * ファイルサイズチェック.
     * @param bean
     *            Object
     * @param va
     *            ValidatorAction
     * @param field
     *            Field
     * @param errors
     *            ActionMessages
     * @param v
     *            Validator
     * @param request
     *            HttpServletRequest
     * @return HttpServletRequest
     */
    public static boolean fileCheck(final Object bean, final ValidatorAction va,
            final Field field, final ActionMessages errors, final Validator v,
            final HttpServletRequest request) {

        boolean result = true;

        // MultipartRequestHandlerでのファイルサイズチェック
        Boolean exceeded = (Boolean) request.getAttribute(
                MultipartRequestHandler.ATTRIBUTE_MAX_LENGTH_EXCEEDED);

        if (exceeded == null || !exceeded) {
            // 妥当性チェックを妥当とする
            result = true;
        } else {

            // 妥当性チェックを不適とする
            result = false;

            // ActionMessagesにエラー内容を追加
            ActionMessage actionMessage =
                    Resources.getActionMessage(v, request, va, field);
            errors.add(field.getKey(), actionMessage);
        }


        return result;
    }
}

5) (3)で設定したvalidator-rules.xmlに(4)の独自validatorクラスをvalidationルールに設定します。
<validator name="file"
           classname="jp.co.sheep.validator.MyValidator"
           method="fileCheck"
           methodParams="java.lang.Object,
               org.apache.commons.validator.ValidatorAction,
               org.apache.commons.validator.Field,
               org.apache.struts.action.ActionMessages,
               org.apache.commons.validator.Validator,
               javax.servlet.http.HttpServletRequest"
           depends=""
           msg="errors.file"/>


6) (3)で設定したvalidation.xmlにvalidationを宣言します。
<form-validation>
  <formset>
    <form name="FormBean">
      <field property="FieldName" depends="file">
        <!-- 個別にメッセージを指定したい場合はメッセージリソースのKeyを指定 -->
        <msg name="file" key="errors.file2" resource="true" />
      </field>
    </form>
  </formset>
</form-validation>

7) メッセージリソースの登録
errors.file=ファイルサイズ制限エラーです。
errors.file2=ファイルサイズ制限エラーです。2

2011年10月23日日曜日

Struts 表データにおける各レコード別にActionを呼び出したい場合

設計の都合上、 <logic:iterate>で表データにおける各レコード別にActionを呼び出したい場合がある。
継承するstrutsのActionクラスにも拠るが、「EventDispatchAction」の場合は、jsp内で指定したactionと、EventDispatchActionを継承したActionクラスのメソッドと完全一致しないと想定した挙動を示してくれない。
その場合は幾つか方法があり、
  • button利用時
    jsp内の<html:form>に<html:hidden>オブジェクトを配置し、javascriptでhiddenオブジェクト内のvalueを操作後にactionで該当のhiddenオブジェクト内のvalueを取得する。

  • link利用時
    <html:link>は個別にactionを指定することができる。
    この為、次のように指定することでパラメータを引き渡すことができる。

    <html:link action="/action?key=${key}"/>

  • submit利用時
    submitは次のようにjspに記載する

        <logic:iterate id="data" name="LoginActionForm" property="dataList" indexId="i">
        <tr style="border-collapse: separate;color:red">
            <html:form action="/login"><td>
                <html:hidden property="prm" value="${data}"/><html:submit value="DISPLAY" property="display"/>
            </td></html:form>
        </tr>
        </logic:iterate>

このとき、link利用時以外はActionFormBeanにActionに引き渡したい値を取得するためのアクセッサは用意しておく必要がある。


設計上の都合(このような方法をとらなくてはいけないのは明らかに"まずい"設計だと思いますが)で他に良い方法がない場合は上記の方式でやっても良いかも。