Spring Boot 4 で作成したファイルダウンロード画面。「ダウンロード」ボタン押下で DB を読んで CSV ファイルを生成し、そのファイルがクライアントPCにダウンロードされる。

Controller はこんな感じ。

    // ボタン押下で実行される処理
    @PostMapping("/createFile")
    public ResponseEntity<Resource> downloadFile() throws Exception {
        Path path    = HogeService.make_file_path(); // ダウンロードされるファイルを作成するパス
        HogeService.logic_make(path.toString());     // ダウンロードファイルを作成

        Resource resource    = new FileSystemResource(path);

        HttpHeaders headers    = new HttpHeaders();
        headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"");
        headers.add(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, HttpHeaders.CONTENT_DISPOSITION);

        return ResponseEntity.ok()
                .contentType(getContentType(path))
                .contentLength(resource.contentLength())
                .headers(headers)
                .body(resource);
    }

    // ContentType の取得
    private MediaType getContentType(Path path) throws IOException {
        try {
            return MediaType.parseMediaType(Files.probeContentType(path));
        }
        catch (IOException e) {
            return MediaType.APPLICATION_OCTET_STREAM;
        }
    }

これで、例えば

    <form action="/createFile" method="post" id="form" name="form">
        <input type="submit" name="download-btn" class="btn-primary" id="download-btn" value="ダウンロード">

みたいな形にすれば、「ダウンロード」ボタン押下でブラウザのダウンロード窓が開いてダウンロードは行われる。

しかし、例えばダウンロードに失敗したときは Web 画面上にエラーメッセージを表示したいとか、成功したら画面に「正常にダウンロードできました」などと表示したい場合はこれではダメだ。

Controller の各メソッドで返却できる値は 1種類である。
上の例のようにデータ(ダウンロードファイル)を出力するか(ダウンロード)、HTML を出力するか(画面表示)、生のテキストや JSON データなどを出力するか(API など)・・・のいずれかひとつのことしかできない。
「先にファイルを出力して、その次に結果を伝える HTML を出力する」という二段構えの出力はできない。ファイルを出力すれば画面(HTML)は表示できないし、画面(HTML)を表示(出力)すればファイルは出力できない。

・・・が、ファイルダウンロードをして結果を Web 画面に表示したい要件ってあるよねえ。

そういうときは、直接ファイルダウンロードの画面を呼び出すのではなく、JavaScript の中でファイルダウンロード画面を呼び出し一旦ファイルを受信しするようにする。そして、そのデータをクライアントに出力し、その後画面の編集をすればいい。JavaScript で処理すれば「ファイル出力か HTML 画面表示かどちらかしかできない」なんて制限ないからね。

具体的には、↓こんな感じの JavaScript。

    document.getElementById('download-btn').addEventListener('click', async (e) => {

        e.preventDefault();

        const btn    = document.getElementById('download-btn');
        const errMesg = document.getElementById('error_msg');
        const sucMesg = document.getElementById('success_msg');

        errMesg.style.display = 'none';  // メッセージ非表示
        sucMesg.style.display = 'none';  // メッセージ非表示

        try {
            btn.disabled    = true;  // ボタンが押されたら、二度押し防止のため非活性化

            // ダウンロード処理呼び出し
            const action_url    = /*[[@{/createFile}]]*/ '';
            const response = await fetch(action_url, {  // fetch(非同期通信(HTTPリクエスト))でダウンロードデータ取得
                method: 'POST'
            });

            if (!response.ok) {  // ダウンロード画面からデータが取れなければ例外発生
                throw new Error()
            }

            const blob    = await response.blob();  // データをBlob(バイナリの塊)として取得

            const disposition    = response.headers.get('Content-Disposition') ;  // レスポンスヘッダーからファイル名取得
            let filename    = 'download.csv';  // ファイル名が取れなかったときのディフォルト値

            if (disposition && disposition.indexOf('attachment'!== -1)) {
                const fileMatch        = /filename="?([^; \n"]*)"?/.exec(disposition);  // 正規表現でファイル名取得
                if (fileMatch && fileMatch[1]) {
                    filename    = fileMatch[1];
                }
            }

            const url    = window.URL.createObjectURL(blob);  // ダウンロード用の疑似リンク作成
            const a        = document.createElement('a');     // 疑似アンカータグ作成

            a.href    = url;  // アンカータグの href 属性に疑似URLを紐づける
            a.download    = filename;  // アンカータグの download 属性にファイル名をセット
            document.body.appendChild(a);  // 作成した疑似アンカータグを一時的に(操作のため)実体化
            a.click();  // 実体化したアンカータグを画面の前の人間に代わってクリック(ダウンロードスタート)

            a.remove();  // もう必要ないのでアンカータグ削除
            window.URL.revokeObjectURL(url);  // メモリに残った疑似リンク(blobデータ含む)を削除

            btn.disabled    = false;  // ボタン使用可能に
            sucMesg.textContent = "正常にダウンロードが終了しました。";
            sucMesg.style.display = 'block';  // メッセージをセットして表示

        }
        catch(error) {
            btn.disabled    = false;  // ボタン使用可能に
            errMesg.textContent = "ダウンロードに失敗しました。";
            errMesg.style.display = 'block';  // メッセージをセットして表示
        }
        finally {

        }
    });

ダウンロードボタンが押されたらイベントリスナーによりこの処理が実行される。
コメントに書いているとおり、JavaScript 内で(画面の前の人間には見えないところで)実際のダウンロード画面にアクセスしデータを取得。そのデータをダウンロードするための疑似リンクを作って、そのリンクに(画面の前の人に代わって)アクセスして画面の前の人のパソコンにデータがダウンロードされるという動き。

なんでこういうことをするかというと、JavaScript 内でダウンロードの成否を判断して処理を行うため。

ダウンロードに失敗したときは例外を発生させ「失敗」メッセージを表示。最後まで問題なく処理が終われば「正常」メッセージを表示・・・となる。(直接ブラウザでダウンロードをした場合は、成否の情報は画面(JavaScript)には伝わってこないので何もできない。)

Controller のファイルダウンロードのメソッド(上の例では downloadFile メソッド)を修正する必要はない。
CSV を読み込んで DB に登録している処理で、今は単純に INSERT を行っているのだが、それだとキーが重複したときに

Caused by: java.sql.BatchUpdateException: バッチ 0 INSERT INTO t_user_summary (
    user_id,
    user_name,
    user_address1,
    user_address2,
    user_phone_number,
    anniversary,
    note
) VALUES (
    ('1'::int8),
    ('MASA SHIMURA'),
    ('岩国市黄金町黄金1928-11'),
    (''),
    ('090-0000-1111(携帯)'),
    ('19650824'),
    ('誕生日(2回目)')
)
 はアボートしました: ERROR: 重複したキー値は一意制約"t_user_summary_pkey"違反となります
  詳細: キー (user_id, anniversary)=(1, 19650824) はすでに存在します。 このバッチの他のエラーは getNextException を呼び出すことで確認できます。

このように更新に失敗する。(このケースは、user_id が '1' で anniversary が '19650824' のデータがすでに存在している)

そこで、まず存在チェックを行って、存在していれば UPDATE、存在していなければ INSERT を行うようにしたい。
そのために、SELECT 処理を埋め込みたいが、Spring Batch の Chunk 方式の場合、どこにその処理を入れればきれいなのか?と Gemini に気いてみたら「SQL 直せばいいだけです」と言われた。

そうなん?いやあ、俺も、SQL をきちんと(専門書を買うなどして)一から勉強したことなくて・・・。長年の経験から相当複雑な SQL も組めるけど、あるステートメントのオプションなんかは知らないものもちょこちょこある。

Gemini が示した SQL の、

INSERT INTO t_user_summary (
                user_id,
                user_name,
                user_address1,
                user_address2,
                user_phone_number,
                anniversary,
                note
            ) VALUES (
                :user_id,
                :user_name,
                :user_address1,
                :user_address2,
                :user_phone_number,
                :anniversary,
                :note
            )
            ON CONFLICT (user_id, anniversary) DO UPDATE SET
                user_name = EXCLUDED.user_name,
                user_address1 = EXCLUDED.user_address1,
                user_address2 = EXCLUDED.user_address2,
                user_phone_number = EXCLUDED.user_phone_number,
                anniversary = EXCLUDED.anniversary,
                note = EXCLUDED.note

ON CONFLICT () DO もそうだし、EXCLUDED も何?って感じ(笑)

ON CONFLICT () DO は「キー重複時の動きを指定する PostgreSQL 独自の句(オプション)」なんじゃね(SQLite でも書き方は違うが使える)。EXCLUDED は「INSERT に失敗したデータが一時的に保管されている DB」を表すんだそうな。

もう、各 RDBMS 独自の構文になってくるとわけわからん(笑)。なもんで、この業界には「Oracle しか使えん」っていう Oracle 独自構文にどっぷり浸かって抜け出せない Oracle じいさんがたくさん存在してるけどな(笑)

というわけで、ItemWriter 内の SQL を上記に置き換え。

test01=> SELECT user_id, anniversary, note FROM t_user_summary WHERE
user_id=1 AND anniversary='19650824';
 user_id | anniversary |  note
---------+-------------+--------
       1 | 19650824    | 誕生日
(1 行)

が、

test01=> SELECT user_id, anniversary, note FROM t_user_summary WHERE
user_id=1 AND anniversary='19650824';
 user_id | anniversary |       note
---------+-------------+------------------
       1 | 19650824    | 誕生日(2回目)
(1 行)

と、ちゃんと更新されていてバッチグー(死語)であった。
週末も仕事って日が続いてて、この土曜日もやっぱり仕事だったんだけど、やっと日曜日オートバイに乗る時間ができた。午前中、親父の介護アパートに新聞を届けた足でそのまま川上から川越方面に愛機 DUCATI MONSTER S2R 1000 を走らせた。

結局、県道5号線(自動車は離合が大変な険道(けんどう)である)を美川町まで走り、「観音水車 でかまるくん」を観て帰った。行程往復60kmほどのプチツーリングである(笑)

20260802_dekamaru1.jpeg 20260802_dekamaru2.jpeg

「でかまるくん」・・・名前が(^^;;; もうちょいええ名前を考えりゃあええのに。地元の小学生に名前を公募した感じかな?

平成2年(1990年)に造られたというから(当時は「美川町の大水車」と呼んでたようだが)、もう 36年の歴史あり?でも、長い間周りの休憩所なども含め放置されてたみたい。

2年くらい前まで活動されていた美川町の地域おこし協力隊の人の SNS で復活までの苦労話を読んでいたので、ちゃんとぐるぐるまわるでっかい水車を眺めながら、「これがあの・・・」と若干感慨を抱く・・・

凄い坂なので、初心者ライダーはバイクを停めるときやUターン時に「立ちゴケ確率」78%くらいの場所だけど、直径12mの水車はなかなか迫力あるので、一度観てみてはどうでしょう?(立ちゴケしても責任はとりませんが(笑)
久しぶりのビアガーデン。

何年も前に一度岩国の人気のビアガーデンに某秘密結社のメンバーと行ったけど、それももう20年ぶりのビアガーデンって感じだったと思う。

お客さんのところの慰労会に参加させてもらって、その会場が「そごう屋上ビアガーデン 海の恵屋」だったのだ。
そごうのビアガーデン、行ったことあるけど 30数年前だな(笑)。まだビアガーデンやってたのか(笑)

20260731_sogo1.jpeg
20代のころはよくビアガーデン行ってたなあ。3,500円で飲み放題とかそんな感じだったよね。若い頃はガブガブ酒も飲んでたし(俺の若い頃は日本酒が不味くて(^^;、ビールオンリーだったけど(笑))、食う量も凄かったので余裕で元が取れてた気がするが、さすがに今は食べ放題・飲み放題にそんなに魅力を感じないお年頃になったので、ビアガーデンは選択支にはいることもなくなったよねえ・・・

いや、マジでこういう会でもないとなかなか機会がないんで、慰労会に誘っていただいたのはありがたかった。
外注の俺らにも補助金を出していただいたので、男性 5千円(ビアガーデンの値段も上がったなあ)のところが団体割引なども含め一人 1,800円で済んだのにで、元を取るために必死で飲み食いする必要もなく(笑)、ゆっくり落ち着いて飲み食いできました。

ビール&焼酎ソーダ割りを 7~8杯、料理を大皿に 3~4回おかわりしたくらいかな。
・・・5千円でも元取ってるな(笑)
先月2日の火曜日の朝、二ヶ月ぶりの「立ち喰い 辰屋」。横川商店街の立ち食いうどん屋だ(横川駅構内には立ち食いうどん無いんでね)。

20260602_tatsuya1.jpeg
ちなみに、西日本ではそばよりうどんの方がよく食べられているので、「立ち食い」ときたら「そば」ではなく「うどん」だ。なので、辰屋も「立ち食いうどん屋」と呼ぶ。「立ち食いそば屋って言うんじゃないのか?」と思った関東人よ、それは東京の常識。広島じゃ通用せんのじゃ!!はぁはぁはぁ・・・

すみません。興奮してしまいました。

で、この日は高森高校の学校運営協議会があるので仕事を休んで岩国に朝帰り。となると辰屋で朝ごはんよね。反対に、朝帰りのときでもないと、なかなか辰屋による機会がない(^^;;;

注文するのはいつものやつ。「天ぷらうどん」と「おにぎり(しゃけ)」。

お、なんだ?おにぎりがいいじゃん!この間は、三角むすびの辺に沿って海苔が巻かれていたが、今回はしっかりおにぎり全体が海苔に巻かれてるぞ。こういうのが良いのよ。

讃岐の人が発狂しそうなやわらかい麺と優しい出汁(関西風)のうどんに海苔のおむすび。ああ、幸せな朝食。
Eclipse で GitHub Copilot のプラグインを使おうと思ったのだが、チャットに質問を投げてもタイムアウト(AI モデルが違うみたいに言われる?)して全然使えない。

・・・いや、実はもう解決してしまったので、正確なエラー状況がわからなくなっちゃったのよ。
ちゃんと調べるためにメッセージとか取っておこうと思ってた矢先に Eclipse の Update に失敗して Eclipse 自身が動かなくなっちゃって・・・で、最新の Eclipse をインストールしたら使えるようになっちゃった(笑)

20260730_chat1.jpg

いや、Gemini や Copilot とかから「プラグインが古いのかも。新しいものに入れ替えたらうまくいきませんか?」と言われていたのだが・・・

<Copilot の回答>
ログをありがとうございます。スタックトレースだけ見ると「チャット応答生成の途中で失敗した(Turn step failed)」という一般的な例外で、原因は主に次のどれかです:

  • Eclipse Copilot プラグインが要求した「モデル」がアカウントで使えない(= GitHub 側で許可/課金が必要)
  • 認証/トークンの問題でモデル呼び出しが失敗している(認証エラーやトークン期限切れ)
  • ネットワーク/プロキシの制約でモデルサービスへ接続できない
  • プラグイン側(バグや古いバージョン)で例外が発生している

使いたいモデルが許可されてること(Freeだし(笑))、認証情報に問題ないこと(Web版は使えてるからね)、ネットワークにも問題ないこと(だって、Copilot Chat が使えないだけで、ソースの自動補完をしてくれる Inline suggestions は使えてたし)は確認できてて、あとはプラグインの更新か・・・と思ってたところなのよ。

Pleiades All in One ダウンロードサイトから最新の Java Developers Edition を落としてきて入れ替えた(GitHub Copilot のプラグインも自動でセットされる)だけなので、プラグインの更新が効いたってことだろうなあ。
何もせず新しい Eclipse 起動したら使えるようになっとったわ(笑)

ちなみに、今入っているバージョンは以下のとおり。

Eclipse IDE for Java Developers Version 2026-06 (4.40.0)
GitHub Copilot Version 0.19.0.202606240339

以前のバージョンも 2026-03 版だったので決して古いものではなかったが、なんか GitHub 側で最近仕様変更とかあったんかねえ?
Eclipse の Update に失敗してしまい新しく入れ直した。

で、実は(まあ、色々な理由や今までの経緯があって)Eclipse も Workspace もえらく深いところに置いてあったので、もう少し浅いディレクトリにセットアップしようと思って、Workspace を丸ごとコピーしてきたのよね。
C:\per0per0\jyupujyupu\SpanSpan\ikuiku\Kao2KakETE\workspace から C:\pleiades\workspace みたいに。

で、C:\per0per0\jyupujyupu\SpanSpan\ikuiku\Kao2KakETE\workspace 消したらエラー出まくり。コピーして、実行時に Workspace に C:\pleiades\workspace を指定して立ち上げてるのに、ああ、元の Workspace を見てるんだ・・・

workspace\.metadata ディレクトリ以下のファイルにフルパスの指定がたくさんあるので、単純にコピーしたのでは全部古い workspace の方を見てしまうようである。

プロジェクト単位でエクスポート/インポートするのは面倒なので丸っとコピーしたのだが、元の Workspace の中のプロジェクトを一気にインポートできる機能があるのでそれを使うべきだった(笑)

20260730_inport1.jpg

  1. まず、空のディレクトリ(C:\pleiades\workspace)を作る
  2. そのディレクトリ(フォルダ)を Workspace に指定して Eclipse を起動
  3. メニュー「ファイル」→「インポート」選択
  4. インポート・ウィザードの選択で、「一般」→「既存プロジェクトをワークスペースへ」を選択し「次へ」押下
  5. ルートディレクトリーの選択に、元のディレクトリパス(C:\per0per0\jyupujyupu\SpanSpan\ikuiku\Kao2KakETE\workspace)を入力
  6. そのディレクトリに含まれるプロジェクト全てにチェックが入っているのを確認
  7. オプションの「プロジェクトをワークスペースにコピー」をチェックして「完了」押下

20260730_inport2.jpg

これで、古い Workspace から新しい Workspace 下に全てのプロジェクトがコピーされるので、古いほうは削除して大丈夫。

何事も正しい手順を踏むことが大切だね(笑)
「愛友ウォーク」にはまったく魅力的な店が無いとずっと思ってて近づいたこともなかったんだけど、なんか中にある餃子屋に立ち飲みコーナーがあるという噂を聞いて突撃。しかし、目当ての店は定休日なのか閉まっていた・・・(^^;;;

がっくり肩を落としつつそのまま通り抜けちゃおうと通路を進んでいくと、店内のカウンターで気だるげに肘をついて歓談する女子二名を窓越しに確認。「ん?ここ、立ち呑み屋?」と思って入ったのが「串とメシにはサケキタル 広島駅前店」だった。

入ってすぐわかったが、立ち呑み屋じゃねえ~!!ただの居酒屋やぁ~!!(^^;;;
カウンターで飲んでいるように見えたのは、単にコップなどが置いてあるカウンターに肘ついて談笑している女性スタッフだった。働け!(^^;;; 普通に全席テーブル席の居酒屋やん(^^;;;

20260727_sakekita1.jpeg 20260727_sakekita2.jpeg 20260727_sakekita3.jpeg

この店、「激安・馬鹿盛」が売りの、金のない若者やサラリーマン狙いの居酒屋のようだ。
スタッフは若い女の子が多くて、そういう店が好きなスケベ男にはたまらん店だと思う。給仕のバイトの女の子をいやらしい目で追う最低の客っておるじゃん。ああいう人には天国な店だと思うよ(笑)

で、本当に「激安」なのか?って話。確かに生ビールは(ちょっと小ぶりだけど)一杯 218円、ハイボールは 110円と安い。生ビールはジョッキが冷えてなくてぬるく感じるし、焼酎のジャスミン茶割り(これも 110円)は水で薄めたようなジャスミン茶の味しかしなくて、「アルコール入ってる?」と今も疑っている(笑)

料理は決して安いとは言えない。「ほう、雲仙ハムの串が 319円か」と注文してみたら、直径 5~6cm、厚さ 8mmくらいのハムを半分に切って、その三日月状のハムが2枚刺してあるだけの串が 319円である。メニューには丸いままのハム2枚が刺さった写真が載ってるのに、量的にその半分やん。
「明太巻き」(明太子一本を豚バラで巻いたやつ)も、アゲハ蝶の幼虫くらいの大きさの明太子を技術の限界まで薄く削いだ豚肉で巻いた一口サイズの串が 418円である。幼虫一口 418円、贅沢過ぎるやろ(笑)

満足いく量の肴を注文すると、たぶん、普通の居酒屋の方が安くつくと思う。もちろんビールやハイボールが安いんで、トータルではトントンになるかもしれんけど、「安くあげるために不味い酒を飲む」というのではもう「店に酒を飲みに行く」意味がないだろう(^^;;;
家でメチルアルコールを動脈注射でもしとけや!(^^;;;

客層も、それが理解できない世間知らずや頭の○い系の人が多い感じだったなあ。明らかに未成年の高校生か専門学校生男子の 8人組とか、スエット上下のチンピラとか(笑)

ただ、バイトの女の子は可愛い子もいたよ。そういうのが好きな最低助平親父には行ってみる価値のある店だと思う。俺は酒と肴にしか興味ないのでもう行かんけど(笑)
「驛麺屋(ほんとは驛麺家(笑))ビッグフロントひろしま店」の 100円おつまみが食品ロス削減のために弁当用食材の余りで作られているのを知って、うどんやそばを注文せずビールとつまみだけで涼んでいくことにうしろめたさを感じていた俺も、堂々と「ビールと小皿のつまみで帰宅途中のエネルギーチャージ」を行えるようになった(笑)

20260727_ekimen1.jpeg
この月曜日。定時で職場を出た俺の身体を容赦なく照り付ける狂暴な太陽。職場から 2kmほどの道のりをその太陽の暴力に耐え抜いて歩き切った俺は、まるで避難するように「驛麺屋 ビッグフロントひろしま店」に転がり込んだのだ。

先日、「生ビール1杯でつまみ2皿はちょっと多いな」と感じていた俺は、「瓶ビール(アサヒスーパードライ)」580円を注文。それと「おつまみ2皿」200円のセットで火照った身体を冷ましていくことにした。

つまみはいつもの「鶏の照り焼き」と「タコの酢の物」だ。

小ぶりなコップからよく冷えたビールを喉に注ぎ込み、俺は死と隣り合わせの灼熱地獄から生還した喜びを感じながら店の壁にかかったテレビに視線を向けた。ニュースが流れていた。「え?」驚きの声が漏れる。「東野圭吾、亡くなったの?」

大腸癌で亡くなられたとニュースは伝える。そうだったんか。東野氏の著作にはたくさん楽しませてもらったなあ。東野氏原作のドラマや映画もよく見た。

俺は推理小説に関しては、綾辻行人氏の作品のような「謎解きメインの本格派」が好みなんだけど、宮部みゆき氏や東野圭吾氏の作品のような「事件に絡む人間もしっかり書ききった作品」は別格で好きだったね。

20260727_ekimen2.jpeg
例えば「社会派」と呼ばれるような「事件そのものには大した謎のないもの(だいたい、動機は何だ?って話)で、トリックより人間模様などをしっかり書ききった作品」はあまり好きではない。退屈なんだよな。

でも、東野圭吾氏の作品は、事件の謎、事件に関係する人間、そのどちらについてもしっかり書き込まれていて読みごたえがあった。エンターテイメント作品としてもしっかり計算して構築されてたし。まさに天才。

実に残念だ。俺は他の客がこちらを見ていないのを確認すると、ニュースを流すテレビに向けてビールの満ちたコップをちょっとだけ捧げた。東野圭吾氏への献杯だ。感謝を込めて。安い晩酌のビールでごめんなさい(^^;;;
火曜日はちょうど帰宅時に突然の曇天。山口県では局地的に土砂降りとなり、それが広島に近づいてきているということで雨に濡れることを覚悟したのだが・・・

20260728_hyoutan1.jpeg
横川駅についた俺は北口から駅を出た。
この日、職場でトラブルがあり帰るのが 10分ほど遅れた。そのため、いつもの山陽本線ではなく緑井行きの可部線で横川まで移動した。そうすると最寄りの出口は表口ではなく裏口。つまり北口である。

そこからガード下に並ぶ店の前を通って三丁目の仕事部屋まで帰るのだが、ふと気になる店があった。

「立ち食い寿司 ひょうたん 横川店」である。看板には「立ち食いとお持ち帰り寿司専門店」と書かれている。

「立ち食い寿司」と言えば、何年も前だが中央通りにあった「すし将軍」によく行ったな・・・と思い出しつつ店の中を覗くと・・・椅子あるやん(^^;。L字型のカウンターには床に固定された椅子が備え付けられている。カウンターや椅子の高さから「最初は立ち食い用に作られたが、その後椅子を設置した」のがわかる。

そういえば「すし将軍」も途中から椅子が取り付けられたなあ。あれでもう行く気がなくなったんだよな。立ち食いだからこそ気軽に寄れたのに。ちょっと常連ぽくなったら「ねえ、椅子つけてよ。立って食べるの疲れちゃう」なんて言い出すジジ・ババ・バカが多いのよね。

「ひょうたん」の話に戻す(^^;;;
空は今にも雨が落ちてきそうな曇天である。俺は雨宿りのために「ひょうたん」の暖簾をくぐった。椅子があるのは不本意だが、そこに安く飲めそうな店があれば入ってみないわけにいかんだろう(笑)。まあ、雨も降ってないのに「雨宿り」ってのは無理があるが(笑)

俺的には日本酒やりながら寿司をつまみたかったのだが、ろくな酒がおいてないな・・・(^^;;;。ああ、ここマリンポリス(安い回転すし屋)のチェーン店なのか・・・

一応、「地酒あります」と幟は立ってるし、メニューの中にも「地酒のみくらべ三種」というのがあったが、内容は「誠鏡」など広島のスーパーで紙カップで売られているような銘柄ばかりだった。

山口県で言えば、「五橋」「長陽福娘」「山猿」あたりか?(いや、どれも美味いけどね。スーパーでよく見るって意味での列挙)
店で「山口県の酒 飲み比べ三種」で出てくるのがこれだと、客は「獺祭は?」「東洋美人は?」とか思うやろ?そういうこと。いかにも(日本酒があまり好きではない)酒屋のチョイスって感じ。

20260728_hyoutan2.jpeg
というわけで、がっかりしながら「松竹梅」の熱燗 500円を注文。魅力ある酒がなかったので「軽くさっぱりした巻物食ってさっさと帰ろう」と思って「梅しそ巻き」と「かっぱ巻き」を頼んだら「今日はやってません」と。なぬー?まだ 18時すぎなのにもう品切れ?(^^;;;
仕方ないので、「あん肝ポン酢」770円、「生えびにぎり(一貫)」220円、それと巻物「しんこ巻き」220円を。

寿司は普通に美味かった。しんこ巻きの海苔も美味かったし、生えびもねっとり甘くて美味かった(笑)。あん肝は・・・まあ、一応ほぐしてはあったけど、業者製のあのハムみたいにビニール包装されたあれだよね?不味くはないけど、これで770円はなあ・・・な感じ。いまいち(^^;

でも「松竹梅」の熱燗は、安い割にそこそこ美味しく呑めたなあ。安い酒にありがちなやたら強く鼻に抜ける嫌なアルコール感もなかったし。

勘定も無事 1,710円で抑えられ勝負には勝ったし(いつもの 2千円こえたら負けというアレです(笑))
これならまた来てもいいかなって感じ(もうあん肝は頼まないので、その分巻物1本とにぎりが2貫行けそうだからな(笑))

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

月別 アーカイブ

電気ウナギ的○○ mobile ver.

携帯版「電気ウナギ的○○」はこちら