2017年11月28日火曜日

javascript : jsonオブジェクトの空の判定方法

Object.keys().lengthを使うことでjsonオブジェクトが空であるかどうかの判定を行える。

2017年11月23日木曜日

Salesforce : with sharing と without sharing

SalesforceのApexクラスを作成するときにwith sharingとwithout sharingというキーワードをクラスにつけることができる。実のところ、これが何を意味するかは調べもせずに使っていた。

ちょっと気になってはいたので今回調べてみた。

この2つのキーワードはクラスに共有ルールをクラスに適用するかどうかを設定するものらしい。

with sharingキーワードを指定すると、現在のユーザの共有ルールが適用されたうえでApexコードが実行されるようになる。通常、Apexコードはシステムコンテキストで実行されるため、共有ルールを指定したい場合は必ずwith sharingを指定する。



without sharingは逆で、共有ルールを適用したいことを明示的に示すものとなる。



注意したいのはクラスで指定しているキーワードのほうの共有ルールが適用されるということだ。例えば、without sharingを指定したクラスからwith sharingを指定したクラスを呼び出すと、with sharingを指定したクラスのメソッドには共有ルールが適用される。


2017年11月19日日曜日

Visualforce : apex:outputLinkタグで勘違い

apex:outputLinkタグでちょっとした勘違いをしていた。valueにリンク先を指定すればリンクを画面上に表示してくれるわけだけど、リンク先がSalesforce上の画面だったときに毎度URLFORを指定していたのだ。



このソースの5行目にURLFORを使っているところが問題の箇所。
これで正常に動作はするので問題ないといえば問題ないのだけど、相対パスを指定できるからURLFORは不要だということについ先日気がついた。



5行目を変更した。

<apex:outputLink value="{!URLFOR('/' + a.Id)}">などと書く必要はまったくなくて、<apex:outputLink value="/{!a.Id}">これだけで同じ処理が実現できる。なんとなく損をした気分だ。

2017年11月14日火曜日

Java : DBの数値項目にNULLをセット

JavaでPreparedStatementを使うとき数値型のカラムにNULLをセットするときには、PreparedStatement.setNull(int parameterIndex, int sqlType)を使う。sqlTypeのほうにはjava.sql.Typesで定義される型を指定する。下記のサンプルソースではjava.sql.Types.NULLを使っている。

String型であればPreparedStatement.setString(int parameterIndex, String x)の第2引数にNULLが許容されるのであまり気にする必要はないがPreparedStatement.setLong(int parameterIndex, long x)やPreparedStatement.setInt(int parameterIndex, long x)の場合、第2引数にNULLが許容されないので、NULLをセットしたい場合は回避するようなプログラムを書く必要がある。

2017年11月12日日曜日

Java : サーブレットのユニットテスト

サーブレットのユニットテストを行うときに困るのが、HttpServletRequestとHttpServletResponseがインターフェースなのでインスタンスを作成できないところ。自前でテスト用のモッククラスを作成するのだと非常に面倒である。

そこで、利用したいのがspring-test-5.0.1.RELEASE.jar

MockHttpServletRequestクラス、MockHttpServletResponseクラスを使うとHttpServletRequest、HttpServletResponseを簡単に用意できる。これでサーブレットのdoPostやdoGetメソッドのユニットテストのソースを楽に書ける。



インスタンス作成してsetParameterなどのメソッドを使ってデータを渡すだけで、モッククラスが使える。そのあとで、サーブレットのdoPostやdoGetにパラメータを渡してやる。

これだけだと、実行時エラーが出てしまうので以下のjarをクラスパスに配置してやる必要がある。

ひとつ目が、spring-core-5.0.1.RELEASE.jar。リンク先へ飛んで、spring-framework-5.0.1.RELEASE-dist.zipをクリックしてzipファイルを解凍すると中にあるのが確認できる。

ふたつ目が、commons-logging-1.2.jar。こちらもリンク先へ飛んでcommons-logging-1.2-bin.zipをクリックしてzipファイルを解凍すると中にあるのが確認できる。


2017年11月8日水曜日

Java : sqliteに接続してデータを取得する

sqliteに接続してデータを取得するには、Connection、Statement、DriverManagerなどを使う。

sqliteのJDBCドライバがビルドパスに存在していることが前提となるので、まだ無いようだったらダウンロードする必要がある。JDBCドライバは使用しているPCにインストールされているsqliteのバージョンとそろえないといけない。もし、バージョンが分からないようなら、以下のコマンドでsqliteのバージョンを確認しよう。
sqlite3 -version

ConnectionとSatementは使用後にcloseする必要があるので注意する。

2017年11月7日火曜日

jQuery : URLを指定してformのサブミット

<form>タグをsubmitするときに、クリックされたボタンによって遷移先のURLを変えたい場合がある。そんなときは、jQueryを使うと簡単に実現できる。


$('#form1').attr('action', 'http://btn1.com');
この部分(3行目と8行目)でURLを指定している。

ユーザーの入力に応じて動作を変えたり、ひとつの<form>タグ中に複数のボタンを置いて、それぞれ別の遷移先を指定したいときなどに便利。

2017年11月6日月曜日

フロントコントローラ

Webサイトが複雑化してくると、認証、承認、セッション管理や共通のログ出力などあらゆるリクエストで同じ処理を行う必要が出てくることがある。こうした振る舞いがあちこちに散らばってしまったら、非常にメンテナンスのし難いプログラムになってしまう。認証の処理を変えようとしたら、あらゆる画面のプログラムを書き換えないといけないなんてゾッとする。

こうしたときには、フロントコントローラパターンを用いてコントローラを実装すればよいと思う。

フロントコントローラパターンを使うと、あらゆるリクエストを、ひとつのコントローラが受け付けるため共通の処理を一か所に組み込むことが出来る。以下のソースはJavaによるフロントコントローラパターンの例。


2017年11月5日日曜日

Java : Streamを使った配列の検索でNullPoiterExceptionが出てしまう

先日、Streamを利用した配列の検索について書いたのだが、色々とやっているうちにNullPointerExceptionが発生するようになってしまった。どういうケースで発生するするかというと、2回検索を行ったときだ。


上記の14行目でNullPointerExceptionが発生する。

仕方がないのでasListで一旦Listに変換してから、List.containsを使うことで検索を行う。


これで複数回検索してもExceptionが発生しないのだけど、Streamでやる方法はないのだろうか。やり方にこだわりがあるわけではないのだが、分からないので少し気持ち悪い。

2017年11月3日金曜日

Java : 配列の要素の検索を行う

配列の要素を検索する方法。Listであればcontainsメソッドがあるので簡単だけれど、配列だと少しだけ手順が必要になる。


StreamクラスのanyMatchメソッドを使うことで配列の要素検索を行える。

2017年11月2日木曜日

Java : propertiesファイルが文字化けする

メッセージをpropertiesファイルに外だししたら、ブラウザに表示したときに文字化けしてしまった。propertiesファイルもブラウザもUTF-8なので大丈夫かと思っていたらそうでもなかったようだ。デバックして確認したらJavaプログラムでpropertiesファイルからメッセージを取得したタイミングで文字化けしていた。

ResourceBundle rb = ResourceBundle.getBundle("hoge");
System.out.println(rb.toString());

上記のプログラムだと文字化けしてしまう。

調べてみると、ResourceBundle.Controlクラスを継承したクラスを作ることで対処可能なことが分かった。

public class ResourceBundleUtf8Control extends ResourceBundle.Control {

     private static final String SUFFIX = "properties";
     private static final String ENCODE = "UTF-8";
     
     @Override
     public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload)
         throws IllegalAccessException, InstantiationException, IOException {

         String bundleName = toBundleName(baseName, locale);
         String resourceName = toResourceName(bundleName, SUFFIX);
         
         try (InputStream is = loader.getResourceAsStream(resourceName);
             InputStreamReader isr = new InputStreamReader(is, ENCODE);
             BufferedReader reader = new BufferedReader(isr)) {
             return new PropertyResourceBundle(reader);
         }
     }
}

このクラスを作って、下記のようにpropertiesファイルを読み込むと文字化けしない。

ResourceBundle rb = ResourceBundle.getBundle("hoge", new ResourceBundleUtf8Control());
System.out.println(rb.toString());

参考URL(というかほとんどそのまんまなんだけど・・・)
https://ja.stackoverflow.com/questions/27787/eclipse%E3%81%A7application-properties%E3%81%AE%E5%80%A4%E3%82%92%E5%8F%96%E5%BE%97%E3%81%99%E3%82%8B%E3%81%A8%E6%96%87%E5%AD%97%E5%8C%96%E3%81%91%E3%81%99%E3%82%8B

2017年11月1日水曜日

jsp:useBeanでGenericを使う

<%@ page import="java.util.*" %>
<jsp:useBean id="hoge" scope="request" class="java.util.ArrayList<String>" />

上記のようにjsp:useBeadでArrayList<String>を使おうとしたら下記のようなエラーが出た。
useBeanのクラス属性 [java.util.ArrayList<String>] の値が無効です
Genericの型指定のところでエラーが出てしまっているようなのだが、使えないと不便だし非常に困る。対応策としては、class属性だけでなくtype属性も指定すること。

<%@ page import="java.util.*" %>
<jsp:useBean id="hoge" scope="request" class="java.util.ArrayList" type="java.util.ArrayList<String>" />

このように書き換えたらエラーが出なくなった。