RedirectAttributes#addFlashAttributeしたオブジェクトをリダイレクト先のControllerで受け取る方法

リダイレクト先のControllerのアクションメソッドに、@ModelAttributeを付与した引数を設定すれば良い。下記のような感じ。

@RequestMapping("/page1")
public String page1(RedirectAttributes attributes) {
  attributes.addFlashAttribute("attr1", "flashdata");
  return "redirect:/page2";
}

@RequestMapping("/page2")
public String page2(@ModelAttribute("attr1") attr1, Model model) {
  // attr1 == "flashdata"
  model.addAttribute("attr");
}


ちなみに、RedirectAttributes#addFlashAttributeでフラッシュスコープにつっこんだオブジェクトは、リダイレクトした場合だけ(RedirectViewが処理した場合だけ)しか処理されず、かつ生存期間を延長することもできないため、railsのflashなどに比べて非常に限定的な用途(リダイレクト時のView向けデータ運搬)にしか使えない。

つまり、真にセッションスコープでないデータの格納*1先としてのHttpSessionの代替にはならない、という認識。

参考:

*1:例えば、複数画面に渡りユーザ入力値を運搬しなければならない場合など

テンキーレスなのに「普通」のキー配列が最高なELECOMミニキーボード(TK-FCP082/TK-FBP083)を買った

ELECOMのミニキーボード。暇つぶしに入ったヨドバシでたまたま見かけて一目惚れ。USBモデル(TK-FCP082)とBluetoothモデル(TK-FBP083)両方買っちゃいました。

何がいいって、このクセのないキー配列。特にカーソルキー周り。こんな素直な配置のミニキーボードはなかなか無いですよ。

前の記事でも書いたとおり、コンパクトサイズを謳うキーボードは大抵カーソルキー周りがひどいこと*1になっているなか、このキーボードはThinkpadのようにしっかり1段下げて逆T字型の配置をとっているので、周辺のキーを邪魔せずかつ手探りしやすくなっている。さらに上矢印キーの左右には余計なキーを配置していないので、誤操作が格段に減るわけです。これは本当に素晴らしくて、Thinkpadも是非見習ってほしいところ。

あと副次的な作用と言いますか、カーソルキーが下がっているおかげで生まれた下部のスペース。Thinkpadのクリックボタンがあるあたりに相当するところです。これ、親指のちょうどいい遊び場になっていいですね。Apple Wireless Keyboardはここがないので親指が落ち着かない。

上が常用しているApple Wireless Keyboard。下がTK-FBP083。
f:id:ymkn:20150512224415j:plain

文字部分のキーはごくごく一般的なJIS配列。ミニと言ってもピッチは19mmあってフルサイズ。どっちかというとテンキーレスキーボードといった方が適切に思う。形状も16mm四方の正方形で変なダイエットしていないのがまたいい。

他、特殊キーですがFキーは普通にFキーとして働いてくれるので幸せ。Fnと同時押ししたときだけWindows8的なメディアキーとして動く。PgUp/PgDn/Home/EndはFn+カーソルキーに割り当てられているタイプ。6段配置になってからのThinkpadのように最上段へテキトーに配置されるくらいなら、個人的にはFn+カーソルキーの方が指の移動が少なくて好き。何より直感的だと思いません?

最下段のキーの配置バランスはどっかで見たことあるなーと思ったらThinkpad Bluetooth Wireless Trackpoint Keyboardと一緒。参考にした? でも右Altと右Ctrlの間にはPrt Scキーではなくちゃんとアプリケーションキーが配置されている。素晴らしい(笑)

CtrlとfnはThinkpadと逆。これもうれしい人多いんじゃないかなあ。でも最近はCtrlが内側のパターンに慣れてきちゃったから、個人的には押しにくい。キー入れ替えに対応してくれていれば、と思ってしまう。FnキーはAutoHotKeyとかソフトウェアじゃどうにもならないから。。あとCtrlとCapsLockも入れ替えないですけど、こっちはソフトウェアで頑張ってください。

打鍵感はまあ普通のパンタグラフ。でもApple Wireless Keyboardの底浅ふにゃふにゃ感よりはクリック感があって好きかも。本体もプラなだけあって驚くほど軽く、上部中心を押すと若干たわんだりもするけど、どこかのサンワサプライみたいながたつきはないので通常使用には全く問題ない。

素材感はザ・プラスチック以外の何物でも無いけども、つや消し加工がしてあるので少しマシに感じる。Thinkpadのボディ的な感じ。

で、価格ですが正直なところ割高感ありますね。Bluetoothモデルなんか定価で1万超えですし。ちょっとしたメカニカルキーボード買えちゃいますわ。ただAmazonでは50%-60%引きで売られているので、結果3000円~4000円といったところで、まあ相応か、という感じです。


コンパクトなキーボードがほしいけど使い勝手の悪い変なやつは買いたくない! でもThinkpad Bluetooth Wireless Keyboardは高いしApple Wireless KeyboardはMac配列だし……と、そんなあなたにお勧めの逸品です(割とニッチ)。

*1:「ろ」と右Shiftの間に上矢印が挟まってるとか、上矢印の左右に余計なキーが配置されてるとか

スマホ時代の王道ゴルフゲーム「ゴルフスター」のすすめ

注:これは広告記事でもなんでもなく、単なるゴルフスターの1ファンによる記事です

小さい頃、叔父の家にあったファミコンの「ゴルフ」をプレイしたのがゴルフゲーとの出会い。その後は常時新作を追いかけるほどではなかったけども、時折思い出してはその時々に出ていたゲームを楽しんでいた。そんな自分がここ1年半ほどハマっているのは、Com2us社が出しているGolfStarというスマホ向けゴルフゲーム。その魅力をダラダラと書いてみようと思う。

  1. ゲームの魅力
  2. おすすめプレイスタイル(STAR、GPの効果的な使いどころ)

ゲームの魅力

クラシックな操作形態、リアル志向のシミュレーション

スマホ向けゴルフゲーにありがちなスワイプとか使わせるタイプではなく、ゲージで振り幅(飛距離)とインパクト位置をタイミング良く決める昔ながらのタイプなのがお気に入り。

ショット種類もドローやフェード、ハイ(ロブ)やピッチなど現実に近いもの程度で、ふざけた必殺技とかないのがよい。弾道は風向きと傾斜をメインの変数として初速と射出角度からシミュレーションされ、ボール速度が落ちてくると風の影響を受けやすくなって曲がりやすくなるなどなかなかリアル。

シングルプレイ・マルチプレイともに充実

シングルプレイでも様々なコースに様々なクリア条件が定められた数多くのラウンドが用意されており、これをひとつひとつクリアしていくだけでも楽しい。でもやっぱり一番面白いのはオンライン対戦。みんなのGOLFとかでも感じたけど、同じコースでも相手がCPUから人間に変わっただけでこうも面白さが変わるものかといつも思う。種類もいろいろあって、大きく分けると同じコースを複数人で同時(リアルタイム)に回ってスコアを競い合うモード(1対1マッチング、親善大会(1対nマッチング)、フレンド対戦、ギルド対戦)と、決められたいくつかのコースを1週間以内に回って合計スコアが一番良かった人を決めるモード(ツアー、ワールドチャンピオンシップ)がある。

(本当に)基本無料でプレイ可能

プレイ費用は基本無料+課金アイテム制。課金箇所が適切な感じなので基本無料とかいって実質何もできないよくあるスマホゲーと違い、本当に無料でかなり楽しめるので最高である。課金の必要性がでてくるのは、連続して何時間もプレイしたい場合(スタミナ無制限アイテム)とか、オンラインで上位を目指す場合(飛距離を伸ばすアイテム)とかくらいかな。これ以外は課金なしでどうとでもなる。

定期的なイベントで飽きが来ない

運営も活発で、定期的にイベントが開催されており退屈しない。大型アップデートも半年〜1年に1回はあって、新しいコースとか新しいシステムとか追加されている。基本システムに手を入れるようなアップデートは今のところないので、ゲームバランスは安定している印象*1

興味を持ったらレッツダウンロード。

iOS版:

ゴルフスター

ゴルフスター

  • Com2uS Corp.
  • ゲーム
  • 無料

Android版:
ゴルフスター 3.1.1
カテゴリ: スポーツ
Google Playで詳細を見る

以下、始めてみようと思う人向けのメモ。

おすすめプレイスタイル(STAR、GPの効果的な使いどころ)

必要最小限の金銭的投資で最大限GolfStarを楽しむために、自分が思うには的な感じで。

ゲーム内通貨の位置づけ

ゲーム内通貨はSTAR、GP、マイレージの3種類。それぞれ下記のような特徴。

STAR
最も価値が高い。ゲーム中で入手する方法は限定的で、基本的にはリアルマネーで購入する位置づけのもの。様々な場面でSTARを使うよう誘ってくるが、滅多なことでは使わないように注意する。レートにもよるが大体1STAR=2円くらいだと思って良い。
GP
ゲーム内の賞金のような扱いで、プレイごとに一定額が得られる。一般的なアイテムの購入や装備の強化行為はこれでできる。上級なアイテムや強化にはSTARが必要だが、ナショナルプロレベルくらいまではGPだけで十分いける。
マイレージ
ログインごとや、STARを使って何かを購入した場合などに得られる。正直使いどころないので意識しなくていい。マイレージでも交換できるウェアがあるので、はじめはそれとの交換のためにひたすら貯めておくのが良い。その後は気が向いたときにマイレージBOX(ガチャ)を回して消費する感じ。

ちなみにSTARを購入するときは毎月売られているIN-APPボーナスパッケージや「今月一回だけの限定販売」のパッケージで買うようにする。 通常品よりもレートがお得だし、ボーナスパッケージの方はVIP BOX券がついてくる。

STARを使用するときも同様。イベント等で売られている特別パッケージを買う方が圧倒的にお得。

スタミナ制限解除アイテム(無制限ハート・優待会員権・VIP会員権)

完全無課金でも全然イケるけど、スタミナ回復速度の問題でプレイ時間を細切れにせざるを得ないので、まとめてのめり込みたい人にはストレスなんじゃないかなとか思う。

Golfstarにおけるスタミナは「ハート」である。ゲーム初期段階で主にプレイすることになるキャリアモードでは、3ホールプレイするのに5必要となる。大半は9ホールのコースなので、1プレイあたり15必要になると思っていい。ハートは10分ごとに1回復するが、最大20までしか回復しない(購入するなどして20以上貯めること自体は可能)。慣れると9ホールあたり15-20分程度で回れるので、3時間ちょいごとに30分程度のプレイとなる計算。

これを多く見るか少ないとみるかは人それぞれだけど、ハマると2時間でも3時間でもプレイしたい自分としては全く少なすぎるように感じるので、同じような人は次を参考にしてほしい。

みんなにおすすめ「無制限ハート」

やりこむことが確定的なら、はじめから「無制限ハート」を買ってしまうべき。たしか700STAR、日本円で1400円くらい。買い切りで永遠に効果が持続するので、要するにこのゲームの値段であると考えられる。普通に楽しむならコレで十分。

似たようなものに「スターターパッケージ」に含まれる「無制限ハート(Lv30まで)」があるが、効果が切れるLv30ではおそらくまだプロになれていないはずで、結果として追加で「無制限ハート」あたりを買う羽目になり投資が無駄となる可能性が高い*2

お試しでプレイしたいだけなら無課金状態で十分だし、セットでもらえるアイテムもいずれ簡単に手に入るものばかりなので、買うならはじめから「無制限ハート」をおすすめする。

オンライン上位を目指すなら「VIP会員権」

GolfStarにどっぷりならば最上位の「VIP会員権」の特典が強力なのでおすすめ。だが、これは3345STARもするので、セールなど狙ってなるべく安く手に入れたい(セールは結構ある)。なお、ハート無制限を持っているとVIP会員権購入時、ハート無制限分の返金(というか返STAR)が得られるので、実質差額分のみで購入できる。

いらない子の「優待会員権」

どっちつかずで微妙なので買わなくていいです。

序盤、スキル集め(プロレベルまで)

効率的にGPを得るにはツアーやワールドチャンピオンシップに参加するのが一番だが、これらはプロクラスになるまで参加できないので、当面は技術訓練や各コースの練習も兼ねてキャリアモードをひたすらプレイしプロを目指すことになる。

各ラウンドで手に入るGPはまずスキルの獲得に使うべし。スキルがないとバンカーやラフからのリカバリやアプローチが難しいので。ちなみにスキルはGPをつぎ込むことでそれぞれLv5-10まで上げられるが、まずはLv1でいいので獲得を優先し、その後様子を見ながらレベルを上げるようにする。

スキル獲得の優先度は下記の通り。

必須:

  • 長距離のアプローチに多用する「ハイボール」。通常のショットよりもランが小さくなり便利。
  • 障害物を避けるための「ドローボール」。パワーショット覚えるまでは飛距離を稼ぐためにも使う。
  • 同じく障害物を避けるための「フェードボール」。ただドローボールと違って飛距離は特に伸びない点に注意。

優先:

  • リカバリを安定させるための「ラフショット」と「バンカーショット」。飛距離のぶれ幅が最小化される(近距離のみだが)。
  • 近距離アプローチで多用する「フロップショット」。ランがほぼないので下っているグリーンへのアプローチで大活躍。
  • グリーンそばからチップインを狙うときに便利な「チップショット」。ボールに強力な前回転がかかるので、傾斜の影響を受けにくい。

後回し:

  • 低めの弾道で風の影響を受けない「ローボール」。ランが凄く長くなる。一部のホールで障害物よけに必要になるが、別にないならないで何とかなる。ワールドプロクラスになるとPAR4ホールで1オンを狙うために便利に使えることもある。
  • 「高軌道ドローボール」「高軌道フェードボール」「パワーショット」はものすごく便利で多用するのだけど、獲得のためのGPとレベル制限が高いので後回しにせざるを得ない。

使う人はどうぞ:

  • 低めの弾道で風の影響を受けない「ピッチショット」。ローボールと同じ特徴だがこっちは近距離向け。ランが長いのでアプローチには使いづらいし、グリーンが高いと手前にぶつかってショートすることが多く微妙。フロップで届かないけどハイボールには短すぎる時にまれに使うくらいかなあ。
  • 強力な後ろ回転の掛かる「バックスピン」。ハイボールよりもランが短くなるので便利なような気もするのだが、風向きや落球地点の傾斜、使っているボールの種類によっては、ボールが狙った以上に飛んだり落球後信じられないくらい手前に戻ってきたりしてめちゃくちゃ読みづらいので微妙。バックスピンが増加するボールを使わなければ何とかなる気もするが……。

クラブ・ウェア・ヘッドカバーはGPやガチャで手に入れようとせず、カードイベントでいいものが手に入ったら置き換えるくらいの感じで十分。強化はコースのTが上がって、飛距離が理由でバーディがとれなくなってきてからでよい。STARを消費する名匠強化はもっともっと後、ワールドプロクラスになってからでも遅くない。

オンライン参加に備えてキャリアモードでは自身のテクニックを磨き、自分の飛距離でとれる最大のスコアが毎回安定してとれるようにする。3-4m/sの強風が吹いている中で、ローリングヒルズなど難しいコースで確実に-9とれるなら、メンバーの組み合わせによってはオンラインでも割と上位を狙える。

中期(オンライン参加・ウェア集め。ナショナルプロA優勝レベル)

自身のクラスが「プロ」まで上がったら*3、毎週確実にツアーとワールドチャンピオンシップに参加する。ある程度ラウンドをこなしていれば、毎週まとまったGP(数万)と豪華Box券(十数枚)が手に入るので、これをスキルとウェアの獲得に使っていく。

オンラインではドライバーで300ydはごく普通、上位では400yd以上、最上位では450yd以上飛ばす人が大半。ここからはいかに飛距離を上げてグリーンオンまでの打数を減らし、イーグル、アルバトロスの数を増やしていけるかが力の差となる。

飛距離を伸ばす方法は主に2つ。

  1. ウェアの購入
  2. 装備品の強化

まず、手軽に飛距離を伸ばすために10万GP以下の安いウェアを全キャラ分買ってしまおう。ウェアはキャラ関係なく買った分がそのまま能力値に反映されるのでとにかく安いものからキャラ関わらず買いまくるが吉。

次にスキルLvも上げられるものは全て上げておく。パワーショットや高軌道ドロー/フェードはスキルLvUPに必要なプレイヤーLvが高めに設定されているので、到達都度で。

ユニーク以上の装備品とラッキー強化券が必要数揃っているのなら、各10段階まで一気に高級強化してしまってよい。1段階分の強化幅は現在のパラメータの○○%という計算なので複利的な特徴がある。つまり、装備品の基礎パラメータが高ければ高いほど、強化回数が増えれば増えるほど強化値が大きくなる。ちなみにSTARを使えば名匠強化したり11段階以上強化したりできるが、これまた今はやらなくて良い。STARは次のステップアップのために大切にとっておこう。

ほか、初期キャラであるデイビッドとイブのウェアの残りが高額なものばかりになってきたら、それらをコンプリートする前にGPを使って追加キャラのクロエをアンロックするのもよい。これによってクロエ用の安いウェアが買えるようになるので、テンポ良く飛距離を伸ばすことができる。

マイレージがたまっているなら、GPで買う前にウェアと交換してしまうのを忘れずに。

ちなみに、ガチャ(通常BOX)に含まれるウェアは当選確率が異様に低いので無理に手を出さなくて良い。ウェア獲得率UPのイベントが開催されたときに一気にGPを突っ込むのが効率的*4。VIP BOXについては言わずもがな。1回150STARも使うほどの価値はない。

後期(レジェンド装備の名匠強化、ワールドプロB優勝レベル)

ここまでくるとGPでできることがほとんどなくなっていると思う。いよいよSTARを使ってさらなる飛距離UPを狙っていくことになる。ツアーで3位以内に入ればGPではなくSTARがもらえるので、これを軸に様々な方法でSTARを稼いでいく。そのSTARを使って名匠強化申請書を購入し、カードイベントや豪華BOXで手に入れているであろうレジェンド以上の装備を名匠強化していくのがこの時期の主な目的となる。

ただこの名匠強化、強化1回あたりに必要な名匠強化申請書が1枚700STARで、レジェンドクラブ強化一回にかかるのが50%優待券ありでも240STAR、11回目からは強化回数のアンロックに250STARが別途かかるので、13段階全てを名匠強化しようと思うと12970STARくらい掛かってしまう。クラブとヘッドカバーにも手を出すとこの3倍だ。とてもじゃないけど無課金では無理な話だ。

まあそんなわけで、現実的には特別パッケージ購入などで名匠強化申請書を数枚そろえ7〜8段階強化したクラブに適用する、くらいにとどまる、というかとどめておくべき。

ちなみに1対1マッチやワールドチャンピオンシップで上位に入賞すると名匠強化申請書がもらえたりするが、この段階の飛距離ではまず上位入賞は不可能なのですっぱりあきらめるべし。

末期(全装備全段階名匠強化、有料ウェア購入、ガチャウェアコンプリート、ワールドプロA優勝レベル)

ここから先、ワールドプロA優勝レベルやワールドチャンピオンシップ世界100位以内を目指そうとか思い始めると、いよいよ本格的な課金を避けられなくなってくる。ゲームに何万と突っ込める精神の持ち主でないなら、ランキングは気にせずに自分なりの楽しみ方を見つけた方が良い。

このクラスの人たちはPAR4のホールはイーグル、PAR5はアルバトロス当たり前な世界にいる。つまり「大半のPAR4、PAR5のホールでグリーンに1オンさせ2打目でカップインする」という新しい技術が求められる。

そのためにはまず上げられる限り飛距離を上げていく必要がある。主な方法は下記の通り。非常に多くのSTARを必要とする。

  • レジェンド以上の装備を全段階名匠強化(上述したとおり、1装備あたり12970STAR必要)
  • 定期的に有料で売られるウェアを全キャラ分購入(1イベントにつき大体3500STARくらい必要)
  • 通常・VIPガチャのウェアの入手(獲得率5倍のイベントで、1着あたり大体50-100万GPくらい)

そして飛距離が伸びてくると、今度は技術面で今までとは違った課題が出てくる。ドライバーでアプローチ(というかティーショットでグリーンに直接乗せるって意味ですが)をする機会が増えるので、練習モードを活用して様々な風向き、カップ位置で適切なショット方法、落球位置の計算ができるようになっておく。ほか、ホール特有の攻略方法(壁超えなど)も身につけていかねばならない。

ドライバーでのアプローチが安定すると上位100位以内が狙えるようになるはず。そこから先はチップインイーグル・アルバトロスを狙えるようにチップの技術を磨いていくくらいしか残されていない*5


機会があれば落球地点の予測方法、パッティングのコツ、個別ホールの攻略などもう少し細かい話も書いていきたい。

*1:2013年末にステータス爆上げするガチャアイテム販売を初めて、一瞬でゲームバランスを崩壊させた某みんなのGOLF運営は是非見習っていただきたい。ステータス成長の仕掛けがないゲームなのに金払った人だけステータス上がるとか無課金者やる気なくすでしょ……

*2:スターターパッケージは約200STAR、日本円で400円〜500円くらいなので、そんなに気にする額でもないっちゃないんですけどもね

*3:キャリアモードをコンプリートする必要は無い

*4:それでも100万GP突っ込んで1着とか2着とかそんなレベル

*5:個人的にはこの段階に到達するとアホらしくなってくるのでやめようかと思っている

モバイルSuicaのオートチャージが発動するのは電車の改札入場時のみ

知ってました? びっくりですよね。私はてっきり、あのホームに常駐するニクいアイツが常に残高を監視していて、指定金額を割ったらオートチャージが発動するものだとばかり思ってました。

JR東日本:モバイルSuica>利用方法>SF(電子マネー)>入金(チャージ)>オートチャージ

最近、Suicaはバスとタクシーでしか使わないからなあ。道理で。

とりあえずあの主張の強すぎるウィジェットはホームから消した。

テンキーレス パンタグラフ式 薄型キーボード サンワサプライ SKB-SL18BKを買った

薄型キーボードが好きだ

以前は東プレ NG01B0 REALFORCE91UBKなど通常キートップの鉄板入り重たいキーボードを愛していたのだけど、最近は薄型のキーボードが好きだ。机に書類広げたいときなど気軽にどかせるのがいい。

ただ、薄型キーボード、特にテンキーレスモデルは変態配列の巣窟で、まともなものを探すのがとても大変だ。個人的には下記条件を満たすものしか使う気になれない。

  • JIS配列
  • 19mmキーピッチ
  • Enterの右側にキーがないこと
  • 文字部のキー幅が一定であること(\とか[とか]あたりが細くなっているのはNG)
  • ろとShiftの間に↑キーが挟まっていないこと
  • 方向キーは凸状に並んでいること。↑キーの左右に余計なキーが配置されていないこと(Thinkpadキーボードは本当にコレが惜しい)

この条件を満たすキーボードは本当に少ない。おそらく現時点で手に入るのは会社で使っているレノボ・ジャパン ThinkPad トラックポイント・キーボード - 日本語 0B47208と、家で使っているApple Wireless Keyboard (JIS) MC184J/B、そして今回購入したサンワサプライのUSBスリムキーボードくらいしかないのではないか。

使ってみた感想

で、今日早速ヨドバシで買って帰って使ってみたのだけど・・。一言で言うとひどい。何がひどいって作りが悪すぎる。さすが1880円の安物クオリティを感じざるを得ない。

まず、本体がガタついているのが最低だ。特に方向キー側が浮いているので、方向キーを連打する度にキーボードがガタガタ揺れて、机とガツガツぶつかる音がうるさい。これ、本体が全体的にゆがんでいるか、ゴムがついてない方の脚(キーボード上部)の高さが片方あってないかどっちかだと思う。ゴム買ってきて貼り付ければマシになりそうだが・・。

で、それからコレは個体差のような気がするが、F9キーが曲がっている。

f:id:ymkn:20141024223145j:plain

外してつけ直しても同じ曲がり方をする。キートップ自体に問題がありそう。ひどい。

さらに。これは打ってみるまで気がつかなかったのだけど、スペースキーが右に1キー分長いので、変換キーを押しているつもりでスペースキーを間違って打ってしまう。自分は変換キーをIME ONに、無変換キーをIME OFFにして使っているので、漢字を打とうとするとスペース打ってしまう。イライラ。

f:id:ymkn:20141024230510j:plain

一般的なJIS配列の場合、NとMの間あたりに変換キーがくるはず。どうやら右Ctrlと右Altを省略してその分スペースキーを右に伸ばしたらしい。なんでやねん。せっかく他の部分は一般的なキー配列で頑張ったのにどうしてここだけ変な工夫をしてしまうのか。。。

半角/全角キーはフルサイズで確保されているので、そちらを使う人にとっては問題ないと思いますが。私は完全に盲点でした。まさかココを省略してくるパターンがあるとは・・。

大変惜しい逸品でした。ありがとうございました。

※このブログはSKB-SL18BKで書かれました。(そしてその後すぐに箱にしまわれ、物置に安置されました。)

2014/10/28追記

朗報。ガタつきは本体をぐいぐい曲げたら何とかなりました。ボディがへなちょこプラスチックなおかげですね。

是非お試しあれ。ただしやり過ぎるとたぶん割れます。

AutoHotKeyでThinkPad Bluetooth ワイヤレス・トラックポイント・キーボードのPgUp/PgDn誤爆を防ぐ

ThinkPad Bluetooth ワイヤレス・トラックポイント・キーボードは、現存するテンキーレス薄型キーボードの中で最もすばらしい打鍵感を与えてくれる逸品であることに疑いの余地はないことと思うが、どうも最近のLenovoはキー配置を変態的にするのにご執心らしく、その完璧な工業製品の価値を損なわせていて実にもったいない話だと思う。

気に入らない部分はいろいろ*1あるが、自分が特に致命的に思うのはカーソルキーの横に移動されたPgUp/PgDnキーで、左右キーを押したつもりで誤ってPgUp/PgDnを押してしまい発狂したことは数知れない*2

そこで下記のようなAHKスクリプトを書いてひとまずの心の平穏を得た。

+PgDn::
  Send,{PgDn}
  Exit

+PgUp::
  Send,{PgUp}
  Exit

PgDn::Right
PgUp::Left

これにより、(左キーの真上にある)PgUpキーを誤って押した際は左キーに、(右キーの真上にある)PgDnは右キーに変換される。PgUp/PgDnしたいときは、Shiftを押しながらPgUp/PgDnキーを押せばよい。

デザインは今のモデルが最高なので、キー配列だけ7列時代のものに戻してくれないかな……。





Bluetooth版はOS設定で省電力を切ると、いちいちスリープしなくて使いやすくなるらしい。

会社はBluetoothが禁止されてるので、USB版を使ってる。

2014/10/22追記

Shiftとの組み合わせだと、Excel等で文字編集をしている際に誤爆することがままあったので、右Ctrlとの組み合わせに変えた。AHKスクリプトは下記の通り。

RCtrl & PgDn::
  Send,{PgDn}
  Exit

RCtrl & PgUp::
  Send,{PgUp}
  Exit

PgDn::Right
PgUp::Left

*1:ファンクションキーの区切りがなく左寄せされているため、従来のThinkpadキーボードと位置関係が変わっている点や、CtrlキーとFnキーを入れ替えられない点、HomeキーとかEndキーがファンクションキーと同列に押し込められ、ワケわかんない一に似どうしている点など

*2:個人的にはカーソルキーのキートップ形状がフラットに変更された影響も大きいと思う。カーソルキーは従来のように盛り上げておいて、PgUp/PgDnのみフラット形状としていれば押す前に気づけるのに……

一つのFormから複数のModelAttributeを受け取る場合に、バリデーションエラーが400エラーになってしまうのを回避する

最近Spring Frameworkを触っているのだけど、バリデーション時の不可思議な挙動で2時間くらいハマったのでメモ。Spring Boot固有の問題かもしれない(そこまでは調べてない)。

掲題の通り、一つのFormに複数のModelAttributeを割り当て、リクエスト値をアクションメソッドの@Validated @ModelAttributeな引数でバインドして受け取るとき、いずれかのModelAttributeでバリデーションエラーが発生するとなぜか400エラーとなってしまい、アクションメソッドの処理に入らずエラーページに飛ばされてしまう。

400エラー(Spring Boot使用時のため、Whitelabelエラーページに飛ばされる):

There was an unexpected error (type=Bad Request, status=400).
Validation failed for object='model1'. Error count: 1

これを回避し、期待する動作(アクションメソッド内でBindingResult#hasErrors()を使用してバリデーションエラー時の処理を行う)をさせるには、ModelAttribute引数ごとに、個別のBindingResult引数を設定する。

つまり、下記のように、model1、model2それぞれの直後にBindingResult引数を配置する。

Controller:

@RequestMapping(value = "/hoge", method = RequestMethod.POST)
public ModelAndView newStoryComplete(
  @Validated @ModelAttribute("model1") Model1 model1,
  BindingResult result1,
  @Validated @ModelAttribute("model2") Model2 model2,
  BindingResult result2
) {

  if (result1.hasErrors() || result2.hasErrors()) {
    // エラー時処理

View (Thymeleaf):

<form action="#" th:action="@{/hoge}" method="post">
  <div>Param1: <input type="text" th:field="${model1.param1}" /><span th:errors="${model1.param1}"></span></div>
  <div>Param2: <input type="text" th:field="${model2.param2}" /><span th:errors="${model2.param2}"></span></div>
  <button type="submit">Send</button>
</form>

これで400エラーは発生せず、アクションメソッド内に入ってくれるようになる。

下記参考記事が大きなヒントになった。そろそろSpringのソースを追うしかないかな……とあきらめかけていたところだったので本当に救われた。

@ModelAttributeとBindingResultの順序を正しく設定しないとリクエストがマッピングされない件 – Springバッドノウハウ | Developers.IO

ちなみに、一つのFormに複数のModelAttributeを割り当てるのがいいことなのかは知らない。一般的なお作法では、Commandクラス(もしくはFormオブジェクト)と呼ぶPOJO1フォームごとに作って1対1にするみたいなのだけど……。値の詰め直しとか、バリデーションの定義がCommandクラスごとに散らばる(重複する)可能性とか率直に面倒と思うが、そういうものなんですかね。そもそもJSPの場合、で指定するから必然的に一つになってしまうという事情もありそうだが……。

環境

  • JDK 1.7.0_21
  • Spring MVC 4.0.7
  • Spring Boot 1.1.7
  • Thymeleaf 2.1.3