2015年6月30日火曜日

Spring で Filter を使う方法

概要

Spring Framework で Java のサーブレットの Filter を使ってみました

環境

  • Mac OS X 10.10.3
  • Eclipse Luna 4.4.1
  • Spring Framework 4.1.6
  • Spring Tool Suite 3.6.4
  • Java 1.8.0_31
  • Maven 3.2.1

サンプルプロジェクト作成

過去の記事を参考に作成してください
Spring Framework のバージョンが最新でない場合は pom.xml 「org.springframework-version」のバージョン記載部分を最新のバージョンに変更してください

Filterクラスの実行

今回は以下にクラスを作成することにします
src/main/java/com/sample/TestFilter.java
Javaのサーブレットのjavax.servlet.Filterを implements したクラスを作成します
今回は単純に doFilter 内でデバッグログを出力するようにします

package com.sample;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class TestFilter implements Filter {

  public TestFilter() {
  }

  @Override
  public void destroy() {
  }

  @Override
  public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
    System.out.println("start");
    chain.doFilter(req, res);
    System.out.println("end");
  }

  @Override
  public void init(FilterConfig arg0) throws ServletException {
  }
}

Filterの有効化

Filterを有効にするにはweb.xmlを修正します
STSでプロジェクトを作成した場合にはsrc/main/webapp/WEB-INF/web.xmlに以下を追記します

<filter>
  <filter-name>testFilter</filter-name>
  <filter-class>com.sample.TestFilter</filter-class>
</filter>
  <filter-mapping>
  <filter-name>testFilter</filter-name>
  <url-pattern>/</url-pattern>
</filter-mapping>

<web-app>配下に記載すればOKです

動作確認

プロジェクトを右クリックして「Run on Server」で起動しましょう
ブラウザで「http://localhost:8080/sample」とかにアクセスしてみましょう
com.sample.HomeControllerに定義してある @RequestMapping が実行する想定です

コンソールに以下のように表示されれば Filter が有効になっています

start
INFO : com.sample.sample.HomeController - Welcome home! The client locale is ja_JP.
end

start - end が Filter で出力しているデバッグ文でメイン処理の前に start が出力され、メイン処理の後に end が出力されていることがわかると思います

最後に

前に Spring で Interceptor を使う方法を紹介しましたが、Interceptor と Filter の使い分けとしては

  • Interceptor はあるメソッドの前後で実行される処理を定義して
  • Filter はある RequestMapping の前後で実行される処理を定義する

のが違いかなと思っています
粒度的には Interceptor のほうが細かい感じかなと思います
(違っていたらすいません、突っ込みお願いします)

2015年6月26日金曜日

/sbin/mount.vboxsf: mounting failed with the error: Protocol error

概要

Vagrant で共有ディレクトリをマウントしようとして

環境

  • Windows7 64bit
  • Vagrant 1.6.5
  • VirtualBox 4.3.18

対応方法

vagrant sshしてVM上で以下のコマンドを実行して共有ディレクトリをマウントします

mount -t vboxsf -o uid=`id -u vagrant`,gid=`getent group vagrant | cut -d: -f3` /vagrant /vagrant

これでもエラーが表示される場合は「-o」を指定しないで

mount -t vboxsf vagrant /vagrant/

で自分は何とかマウントできました
コマンドはrootユーザで実行しています

他の要因としてVBoxGuestAdditionがインストールされていない、ホストオンリーアダプタがついていなくてホストマシンと通信できない等がありますが、それをクリアした前提でコマンドを実行しています

2015年6月25日木曜日

Maven で Cobertura を使ってみた

概要

Maven でテストコードのカバレッジを表示することができる Cobertura を使ってみました

環境

  • Mac OS X 10.10.3
  • Eclipse Luna 4.4
  • Java 1.8.0_31
  • Maven 3.2.1

pom.xml に定義する

以下を定義します
<build>-><plugins>配下に記載します

<!-- cobertura -->
<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>cobertura-maven-plugin</artifactId>
  <version>2.7</version>
  <configuration>
    <formats>
      <format>html</format>
      <format>xml</format>
    </formats>
    <instrumentation>
      <excludes>
        <exclude>**/*Test.class</exclude>
      </excludes>
    </instrumentation>
    <executions>
      <execution>
        <phase>test</phase>
        <goals>
          <goal>check</goal>
        </goals>
      </execution>
    </executions>
  </configuration>
</plugin>

記載したら実行しましょう
コマンドはmvn cobertura:coberturaです
成功するとtarget/cobertura/index.htmlが作成されるのでこれを開くとカバレッジ率を見ることができます

JavaはJREではなくJDKが必要になるので注意してください

最後に

mvn packageのライフサイクルに入れるにはどうすればいいのだろうか

2015年6月24日水曜日

Maven で Javadoc を生成する方法

概要

Maven で Javadoc を作成してみました

環境

  • Mac OS X 10.10.3
  • Eclipse Luna 4.4
  • Java 1.8.0_31
  • Maven 3.2.1

プロジェクト作成

プロジェクトは Eclipse 上で作成しました
以下の Group Id と Artifact Id を指定しています

  • Group Id・・・org.apache.maven.archetypes
  • Artifact Id・・・maven-archetype-quickstart

Javadoc 出力設定

上記 Artifact Id で作成すれば特に何もしなくても Javadoc を生成することができます
以下の goal を指定すれば作成できます

mvn javadoc:javadoc

上記で実行するとtarget/site/apidoc/index.htmlに Javadoc の index.html が生成されます
2015/06/15 現在だと使用されるmaven-javadoc-pluginのバージョンは2.10.3でした

pom.xml に定義する場合

例えば出力先や文字コードを変更したい場合はpom.xmlに記載する必要があります
<project>-><build>-><plugins>配下に以下を記載してください

<!-- Javadoc -->
<plugin>
   <groupId>org.apache.maven.plugins</groupId>
   <artifactId>maven-javadoc-plugin</artifactId>
   <version>2.10.3</version>
   <configuration>
      <author>true</author>
      <source>1.8</source>
      <show>protected</show>
      <encoding>UTF-8</encoding>
      <charset>UTF-8</charset>
      <docencoding>UTF-8</docencoding>
   </configuration>
</plugin>

<version>に使用するプラグインのバージョンを指定します
<encoding>にJavaのソースファイルのエンコードを指定します
<charset>に出力するHTMLの文字コードを指定します
<docencoding><charset>と同じ(だと思います)

他の詳しいパラメータはここを参考にしてください

実行する場合は先ほど同様でmvn javadoc:javadocでOKです

最後に

mvn packageのライフサイクルに入れるにはどうすればいいのだろうか

2015年6月23日火曜日

disabled by the php.ini setting phar.readonly

概要

Phing でビルド時にタイトルのエラーが出現したので、その対処方法を紹介します

環境

  • CentOS 6.5 64bit ( on Vagrant )
  • PHP 5.3.3
  • Phing 2.7.0

対処方法

php.ini を直接書き換えます

  • vi /etc/php.ini
; phar.readonly = On

これを以下のように変更します

phar.readonly = false

これで再度phing buildを実行してみたください

2015年6月17日水曜日

Maven に findBugs を導入する方法

概要

Maven でビルドを実行した際に findBugs を同時に実行させます

環境

  • Windows 7 64bit
  • Eclipse Luna 4.4.1
  • Maven 3.2.1 ( Eclipse 組み込み版 )
  • findbugs-maven-plugin 3.0.0
  • Java SDK 1.8.0_25

設定方法

pom.xml に以下を記載します

<!-- for findbugs -->
<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>findbugs-maven-plugin</artifactId>
  <version>3.0.0</version>
  <configuration>
    <effort>Max</effort>
    <failOnError>false</failOnError>
    <threshold>Low</threshold>
    <xmlOutput>true</xmlOutput>
    <findbugsXmlOutputDirectory>${project.build.directory}/findbugs</findbugsXmlOutputDirectory>
  </configuration>
  <executions>
    <!-- Ensures that FindBugs inspects source code when project is compiled. -->
    <execution>
      <phase>test</phase>
      <goals>
        <goal>check</goal>
      </goals>
    </execution>
  </executions>
</plugin>

記載する箇所は<project>-><build>-><plugins>タグ内に記載すればOKです
mvn package でビルドすると test フェーズの後でソースの静的解析が走ります
findbugs/findbugsXml.xml に解析結果を保存してくれます

2015年6月12日金曜日

Xcode で InterfaceBuilder で作成したボタンをコードで操作する方法

概要

Xcode の InterfaceBuilder を使ってUIを作成した場合に、コード側と連携する方法を紹介します
今回はボタンを設置してそのボタンに対してコード側でいろいろと操作をしてみたいと思います

環境

  • Mac OS X 10.10.4
  • Xcode 6.3.2

InterfaceBuilderでボタンを設置する

Main.storyboard を選択して InterfaceBuilder を表示します
右側のコンポーネント一覧からボタンをドラッグアンドドロップして左の画面に設置します
View 配下でないとボタンは設置できません
とりあえず以下のようなになればOKです
setting_button.png

ボタン情報をコードに配置する

Xcodeの画面レイアウトを「Asistant editor」という分割画面にします
左側に InterfaceBuilder を表示させ右側にボタンを操作するクラスのヘッダファイルを表示します

InterfaceBuilder で設置したボタンを Control を押しながらコード側にドラッグアンドドロップします(言葉で説明するのが非常に難しい…)
d_and_d.png

コード側に配置したボタンの名前を入力します
input_button_name.png

この名前を元に InterfaceBuilder 側のボタンがどれであるか識別するので、後で変更する場合は注意してください

.h ファイルにはこんな感じで宣言されています

@property (weak, nonatomic) IBOutlet UIButton *button;

これで .m ファイルでボタンを操作できるようになります

ボタンのオブジェクトを操作してみる

実際にコード上でボタンオブジェクトを操作してみましょう
ボタンオブジェクトはviewDidLoad内で取得します
今回はUIButtonクラスのオブジェクトを操作して、ボタンに表示されるラベル情報を変更してみます

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.button setTitle:@"ほげぼたん" forState:UIControlStateNormal];
}

ボタンオブジェクトはself.buttonで参照することができます
setTitleをコールしてボタンのラベルを変更しています

記載できたらCommand+rでビルドして実行してみるとラベルが変更されていることが確認できると思います

Tips

基本はself.で参照すればいいのですがサイズの変更がうまくできない現象に遭遇しました
UIButtonのサイズの変更は以下のように実施します

[self.button setFrame:CGRectMake(30,30,100,100)];

これがうまく動かなくて悩んでいたのですが、どうやら InterfaceBuilder で作成した UI コンポーネントは「Auto Layout」という機能がデフォルトでは有効になっているらしいくこれをdisableにしてあげることでコード上でもサイズをダイナミックに変更できるようになります
auto_layout_disable.png

2015年6月11日木曜日

Spring でプロパティファイルを参照する方法

概要

過去の記事でEclipse + Springでサンプルプロジェクトが動作するところまで紹介しました
今回はそのサンプルプロジェクトを使ってプロパティファイルを参照する方法を試してみました

環境

  • Mac OS X 10.10.3
  • Eclipse Luna 4.4.1
  • Spring Framework 4.1.6
    ※それ以外のバージョンは過去の記事に書いてあるバージョンと同じです

サンプルプロジェクト作成

過去の記事を参考に作成してください
Spring Framework のバージョンが最新でない場合は pom.xml 「org.springframework-version」のバージョン記載部分を最新のバージョンに変更してください

プロパティファイルを自動で読み込むための定義を追加

servlet-context.xml の修正

servlet-context.xmlsrc/main/webapp/WEB-INF/spring/appServlet/servlet-context.xmlにあります
ここにプロパティファイルを読み込むための定義を記載します

<!-- for Properties -->
<beans:bean id="applicationProperties"
  class="org.springframework.beans.factory.config.PropertiesFactoryBean">
  <beans:property name="locations">
    <beans:list>
      <beans:value>classpath:application.properties</beans:value>
    </beans:list>
  </beans:property>
</beans:bean>
<beans:bean id="placeHolderConfigurer"
  class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
  <beans:property name="location" value="classpath:application.properties" />
</beans:bean>

beans:bean id="applicationProperties" で定義している id は Java 側でプロパティファイルを参照するオブジェクトの変数名と同じである必要があります

<beans:value>classpath:application.properties</beans:value> にプロパティファイルが存在するパスを設定します
この場合はクラスパス上に存在する application.properties を探しにいきます
「./src/main/resources/application.properties」に配置するのであれば上記の設定で読み込むことができます
相対パスや絶対パスでも指定することができるようです

<beans:bean id="placeHolderConfigurer"はプロパティファイルに定義した情報をこの「servlet-context.xml」で読み込むための定義です
例えば application.properties 内で「hoge.value=100」という感じで定義している場合に servlet-context.xml 内で "${hoge.value}" みたいな感じで参照することができます

プロパティファイルの配置

上記の設定の場合は「./src/main/resources/application.properties」に配置すればOKです
プロパティファイルは key=value の形式で1行に1定義していきます
例えばこんな以下のような感じです

  • ./src/main/resources/application.properties
key=value
hoge.value=100

プロパティオブジェクトをクラスで参照する方法

配置したプロパティファイルの値をJava側で参照してみます
クラスの全貌を記載すると無駄な部分が多いので必要な部分に絞って紹介します

  • 必要なクラスのインポート
import java.util.Properties;
import org.springframework.beans.factory.annotation.Autowired;

上記は最低限必要になります

  • プロパティオブジェクト作成
@Autowired
private Properties applicationProperties;

ポイントは@Autowiredです
この Annotation を使うことでプロパティを参照できるオブジェクトを Spring が自動で生成してくれます
メンバ変数として定義すると、クラス内のどこからでも参照できます

上記をプロパティファイルを参照したクラス内で定義してください
準備はこれだけでOKです

動作確認

値を参照してみましょう

System.out.println(applicationProperties.getProperty("hoge.value"));

値を取得する場合はgetPropertyメソッドで参照することが可能です
とりあえず標準出力する一文を記載して「Run on Server」実行してみましょう
適当なリクエストでアクセスして Eclipse のコンソールに出力されることを確認してください

最後に

XMLの定義と Annotation を使うだけで参照できるようになるというのが嬉しいポイントでしょうか
モデルへのデータバインディングとかまでやってくれると嬉しいのですがそこまではやってくれないようです
単純に値を参照したいだけであれば十分使えそうです

2015年6月9日火曜日

Spring で Interceptor を使う方法

概要

過去の記事でEclipse + Springでサンプルプロジェクトが動作するところまで紹介しました
今回はそのサンプルプロジェクトを使って「Interceptor」という仕組みを試してみました

環境

  • Mac OS X 10.10.3
  • Eclipse Luna 4.4.1
  • Spring Framework 4.1.6
    ※それ以外のバージョンは過去の記事に書いてあるバージョンと同じです

サンプルプロジェクト作成

過去の記事を参考に作成してください
Spring Framework のバージョンが最新でない場合は pom.xml 「org.springframework-version」のバージョン記載部分を最新のバージョンに変更してください

Interceptor実装

そもそも Interceptor って何という話ですが、簡単に言うとある処理をする前後に任意の処理を実行させる仕組みのことです
共通処理等で使われることが多く、例えばロギングやシリアライズを必ず実施しなければいけない場合で使われます

servlet-context.xml の修正

servlet-context.xmlsrc/main/webapp/WEB-INF/spring/appServlet/servlet-context.xmlにあります
ここにInterceptorを使用する定義を記載します

<!-- for Interceptor -->
<mvc:interceptors>
  <mvc:interceptor>
    <mvc:mapping path="/**" />
    <beans:bean class="com.sample.test.RequestInterceptor" />
  </mvc:interceptor>
</mvc:interceptors>

ポイントはpathの部分とclassの部分です
pathで指定したURIにアクセスした場合にclassで指定したInterceptorクラスのメソッドが実行されます

The prefix “mvc” for element “mvc:interceptors” is not bound.

というエラーが出る場合は servlet-context.xml の冒頭のbeansタブに以下を記載してください

xmlns:mvc="http://www.springframework.org/schema/mvc"

Interceptor クラスの実装

今回はcom.sample.test.RequestInterceptorというクラスを作成してAPIのメイン処理に入る前にリクエスト情報をダンプしてみたいと思います

package com.sample.test;

import java.util.Collections;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

public class RequestInterceptor extends HandlerInterceptorAdapter {

  @SuppressWarnings("unchecked")
  @Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    System.out.println("Dumping request parameters");
    for (Object name : Collections.<Object>list(request.getParameterNames())) {
      String value = request.getParameter((String) name);
      System.out.println(name.toString() + ":" + value);
    }
    return true;
  }
}

true を return することで次の処理に移ります
false を指定すると次の処理には行かずこの処理で終了します

とりあえず上記ではリクエスト時のパラメータ情報をSystem.outしているだけです
ここまで作成できればあとは実行するだけです

動作確認

プロジェクトを右クリックして「Run on Server」でアプリを起動してみましょう

http://localhost:8080/test/?hoge=fuga
という感じでアクセスすると Eclipse のコンソールに

Dumping request parameters
hoge:fuga

という感じで出力されると思います

紹介は以上です
Interceptor は便利な機能だと思います

2015年6月3日水曜日

iOS の開発に使える CocoaPods を試してみた

概要

CocoaPods はXcode用のライブラリ管理ツールです
.frameworkをダウンロードしてプロジェクトに手動で設定するとかいった作業が不要になります
まずは使ってみるところまで試したのでメモしておきます

環境

  • Mac OS X 10.10.3
  • Xcode 6.3.2
  • CocoaPods 0.37.2

インストール

cocoapods は gem コマンドを使ってインストールします
なので、事前に ruby のインストールを実施しておいてください
Mac であれば Homebrew でインストールすればOKです

brew install ruby

autoconf と automake も必要みたいなので、こちらも Homebrew でインストールしておきます

brew install autoconf automake

あとは CocoaPods をインストールすればOKです

gem install cocoapods

インストールが完了するとpodコマンドが使えるようになっています

使ってみる

インストールが完了したら使ってみましょう
podコマンドはXcodeプロジェクト配下で実行する必要があります

cd /path/to/xcode_project
pod setup
pod init

とやると Podfile というファイルが作成されます
これに必要なライブラリを記載していきます

  • vim Podfile
target 'xcode-sample-proj' do
  pod 'NCMB', :git => 'https://github.com/NIFTYCloud-mbaas/ncmb_ios.git' # <- add this line
end

target 'xcode-sample-projTests' do

end

テストで使用する個別のライブラリがあれば Tests の方にも記載します
記載出来たらライブラリをインストールしてみましょう

pod install

Podfile があるディレクトリで上記のコマンドを実行するとライブラリ一式が追加され Xcode 上でも使えるようになっています

動作確認

実際にライブラリのヘッダファイルが import できるか確認してみます

AppDelegate.m とかに以下を記載してみてください

#import <NCMB/NCMB.h>

これで構文エラーおよびビルドエラーにならなければOKです

実際のヘッダファイルは
Pods/Headers/Public/NCMB/ 配下にありました

Tips

  • clang: error: linker command failed with exit code 1 (use -v to see invocation)
    上記エラーになった場合は、.xcworkspaceという拡張子のファイルを XCode で開くようにしてください

最後に

Ruby の gem と同じ仕組みだと思います
これで Github などで公開する場合には一緒に Podfile も commit すれば他の人が簡単に依存するライブラリをインストール、セットアップすることができます

2015年6月2日火曜日

Emacs で Web Server - Elnode を使ってみた

概要

Elnodeなるものがあり、これでEmacs上でlispを書いてWebサーバを構築することができます
ちょっと興味があったので試してみました

環境

  • Mac OS X 10.10.3
  • Emacs 24.4.1
  • Elnode 0.9.9.8.8

Elnodeインストール

まずEmacsにElnodeをインストールします
Emacsのバージョン24以上を使っていればpacakge.elを使ってインストールすることができます

ここを元に package.el でダウンロードできるリポジトリ (marmalade, melpa) を追加します
追加できたらM-x package-list-packagesでパッケージのリストを表示します
一覧の中にelnodeがあるので i -> x とキーを押してインストールします
i でインストール対象を選択して、 x でインストールを実行します

インストールできるとelnode-startなどの命令が使えるようになります

サンプルスクリプト作成

適当なHTMLを返却することができるEmacs-lispを作成してみます

  • emacs sample_web_app.el
(defun my-test-handler (httpcon)
  "Demonstration function"
  (elnode-http-start httpcon 200 '("Content-type" . "text/html"))
  (elnode-http-return httpcon "<html><b>HELLO!</b></html>"))

(elnode-start 'my-test-handler :port 8082)

「HELLO!」という文字列を返すだけの簡単なサンプルです
上記のスクリプトを開いているバッファでeval-bufferを実行してみましょう
するとサーバが起動します(特に *Messages* にログはでません)

ブラウザでアクセスしてみる

http://localhost:8082/
にアクセスしてみましょう
先ほど設定した「HELLO!」といういう文字列がボールドされて返ってくると思います

サーバを停止する

M-x elnode-stop
で起動中のポート番号を入力してEnterでOKです
停止時は *Messages* に停止ログが出力されます
念のためブラウザで先ほどのURLにアクセスするとページが返ってこないことがわかると思います

Tips

  • Cannot bind server socket: permission denied
    LISTENするポートを1024番以上にしてください
    80番とかでサーバを起動しようとすると上記のエラーになります
  • index.htmlを表示する方法
(setq my-webserver
      (elnode-webserver-handler-maker "/path/to/elisp"))

(elnode-start my-webserver :port 8082)

「/path/to/elisp」配下に index.html を配置して同様にstartすれば index.html を自動で探して表示してくれます

最後に

他にもorg-modeと連携したりCSSを適用したり、HTTPのパラメータを取得したりといろいろできるみたいです

自分はとりあえず動作することを確認したかっただけなので、これで終わりますが 本格的にWebアプリを作ろうとしたら、DBと接続したり別のHTTPをコールしたり、MVCしたりといろいろ考えなければいけませんが、何か頑張ればできそうな気がします

.elファイルをデプロイしてemacsコマンドを使ってWebサーバを立ちあげる、なんて運用が実現できるのか・・・

参考サイト

2015年6月1日月曜日

fluent-plugin-geoip を試してみた

概要

IPアドレスから地理情報を算出する技術にGeoIPという技術があります
td-agent にそのプラグインがありIPを地理情報へ変換してくれるので試してみました

環境

  • CentOS 6.3 64bit
  • td-agent 0.12.7
  • fluent-plugin-geoip 0.4.0

インストール

geoip-develのインストール

別途Cのライブラリをインストールする必要があります
epelかrpmforgeのリポジトリを追加してyumコマンドでインストールしてください

yum -y install geoip-devel

fluent-plugin-geoipのインストール

td-agent-gem install fluent-plugin-geoip

td-agent.conf設定

例えばApacheのログからIPアドレスを取得してgeoipを算出する場合は

<source>
  type tail
  format apache2
  path /var/log/httpd/access.log
  pos_file /var/log/td-agent/access.log.pos
  tag apache.log
</source>

<match apache.log>
  type geoip
  geoip_lookup_key host
  enable_key_country_code geoip_country
  add_tag_prefix file.
</match>

<match file.apache.log>
  type file
  path /var/log/td-agent/file.app.log  
</match>

という感じで記載してApacheにアクセスするとファイルが出力されていると思います
「geoip_country」というフィールドに国を識別するコードが入っていると思います

"geoip_country":"JP"

あとはこの識別コードを元に地図上にマップしてあげるといい感じに可視化できると思います
ElasticSearch + Kibana が定石だと思うので今後試したら紹介したいと思います

参考サイト