似非プログラマのうんちく

「似非プログラマの覚え書き」出張版

春だから Spring やろうぜ(その 4)

まずは簡素なものを作ってみる

まずはフォームも何もない、ただページを表示させるだけのものを作ってみる。ただしメッセージはコントローラーから渡すようにする。

package jp.mydns.akanekodou.demo;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class HelloController {
    @RequestMapping("/")
    public String index(Model model) {
    	model.addAttribute("title", "Hello page");
    	model.addAttribute("message", "This is a message prepared by controller.");
    	return "hello";
    }
}

src/main/resources に既に templates フォルダが出来ているので、そこに hello.html を作る。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
  <head>
    <title th:text="${title}"/>
    <link th:href="@{/css/hello.css}" rel="stylesheet" />
  </head>
  <body>
    <h1 th:text="${title}"/>
    <p th:text="${message}"/>
  </body>
</html>

CSS などの静的ファイルは src/main/resources/static 以下に配置して、そこからの相対パスで指定すれば良いが、上記のように th:href 属性に @{...} の形で指定する。

ちなみに CSS はこんな感じ。参考書からまるっと写した。

body {
  padding: 10px;
  color: #666;
}

実行するのは簡単で、「Run As」から「Spring Boot App」で良い。

f:id:redcat_prog:20180404184542p:plain

うむ、CSS もちゃんと反映されてる。

春だから Spring やろうぜ(その 3)

STS(Spring Tool Suite) を使う

さて、コマンドライン + Groovy でもまぁ簡素な Web アプリは作れたが、やはり本格的な開発には STS(Spring Tool Suite) が欲しいところなのでダウンロードしてくる。

spring.io

f:id:redcat_prog:20180325192825p:plain

eclipse ベースなので見た目はほとんど eclipse ですね。

「Spring Starter Project」を作成する。

f:id:redcat_prog:20180401094635p:plain

「Type」はビルドツールを選べる(Maven, Gradle)。今回は私の慣れの問題で Maven にします。
Java Version」は 7, 8, 9 から選べた。これはそろそろ Java 9 への移行か ? でもまだ Java 9 はインストールしてないので今回は Java 8 で。
「Language」は Java, Groovy の他に Kotlin も選べる。こんなところにも Kotlin 進出かー。でも今回は普通に Java を選択。

f:id:redcat_prog:20180401112703p:plain

Spring Boot のバージョンを選んだりいろいろできるっぽい。今回はもちろん 2.0.0 です。
後々データベースを使うことを考えて JPA, H2, Thymeleaf, Web を ON にします。

続きを読む

春だから Spring やろうぜ(その 2)

テンプレートを使ってみる

出力する文字列に HTML を直接打てば表示はされるけど当然ながら面倒くさい。

そこで Thymeleaf というテンプレートを使うことにする。

先ほどの app.groovy と同じフォルダに新たに templates というフォルダを作り、その中に index.html を置く。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
  <head>
    <title>Top page</title>
  </head>
  <body>
    <h1 th:text="${title}"/>
    <p th:text="${msg}"/>
  </body>
</html>

普通の HTML の中に名前空間を使って Thymeleaf 用の属性を埋め込んでる感じ。

app.groovy を修正する。

@Grab("thymeleaf-spring5")

@Controller
class MyBootApp {
    @RequestMapping("/")
    @ResponseBody
    def top(ModelAndView mv) {
        mv.setViewName("index")
        mv.addObject("title", "Hello!")
        mv.addObject("msg", "Welcome to Thymeleaf!")
    }
}

f:id:redcat_prog:20180324130557p:plain

ほほー。コントローラーから渡した値もちゃんと埋め込まれてる。(続く)

春だから Spring やろうぜ(その 1)

夏になっても秋になっても続くかも知れませんがそのときは生温かい目で見てやってください(苦笑)

今どきの Spring 事情

Spring はプロジェクトが巨大になり過ぎて、どれをどう使えばいいんだ、と尻込みしてしまう人も多いはず。
今人気の Spring MVC も、本格的に使いこなすのは大変。Spring Roo というツールは用意されているけれど…というところに登場したのが Spring Boot。これまで以上に Spring MVC による開発を楽にしてくれるっぽい。

まずは CLI で動く物を作る

Spring Boot には CLI も用意されている。

https://docs.spring.io/spring-boot/docs/current/reference/html/getting-started-installing-spring-boot.html#getting-started-installing-the-cli

まずはここから spring-boot-cli-2.0.0.RELEASE-bin.zip をダウンロードしてきて適当なフォルダに入れて、PATH を通す。

適当なフォルダに app.groovy を作る。

@RestController
class MyBootApp {
    @RequestMapping("/")
    def top() {
        "Hello Spring Boot!"
    }
}

あとはこのファイルがあるところで

> spring run app.groovy

すると…

f:id:redcat_prog:20180324094705p:plain

おー、出た出た。(続く)

巳年じゃないけど Python やろうぜ(その 22・最終回)

すっかり忘れていましたが、Python ネタの締めにこれの話をすると約束していたので書いておきます。

WSGI による Apache HTTPD との連携

Python では WSGI(Web Server Gateway Interface) という、Web サーバーと Web アプリケーションを接続する標準化されたインターフェースを利用して Web アプリケーションを Web サーバー上で公開することができます。

Django には WSGI を利用してアプリケーションを公開するための仕組みがあらかじめ用意されているので、それほど特別なことをする必要はありません。

まずは Python 側で mod_wsgi をインストールします。Windows 機の場合はこちらで公開されているものを使うのが良いでしょう。お使いの Apache HTTPD のバージョンに合わせたものをインストールしましょう。

次に、httpd.conf に以下の部分を追加します。(project_forder) の部分は django_test プロジェクトを作ったフォルダに読み替えます。

LoadModule wsgi_module "C:/Python/3.6/Lib/site-packages/mod_wsgi/server/mod_wsgi.cp36-win_amd64.pyd"

WSGIScriptAlias /wsgi-scripts "(project_forder)/django_test/django_test/wsgi.py"
WSGIPythonPath "(project_forder)/django_test"
Alias /static/ "(project_forder)/django_test/static/"

<Directory "(project_forder)/django_test/django_test">
   <Files wsgi.py>
      Require all granted
   </Files>
</Directory>

<Directory "(project_forder)/django_test/static">
  Require all granted
</Directory>

基本的に WSGI による Apache HTTPD との連携はこれで良いのですが、Django においてはこのままだと CSSJavaScript、各種画像ファイルなどのいわゆる「静的ファイル」が上手く読み込めません。そこで

> python manage.py collectstatic

を実行して静的ファイルを Apache が認識できるフォルダにまとめておきます。

Apache HTTPD のサーバーにアクセスして、Django アプリケーションが使えることを確認してみてください。

Django 2.0 における変更点

昨年の 12 月に正式に Django 2.0 がリリースされました。大きな変更点としては Python 2 系のサポートを打ち切ったことでしょう。今後 DjangoPython 3 系のみをサポートしていくことになります。

細かな変更点として、URL ルーティングが従前の正規表現を用いた書き方に加えて、よりシンプルな表記が可能になった(django.urls.path)ようです。

from django.urls import path
from django.views.generic import ListView, DetailView
from .models import City

app_name = 'major_city'
urlpatterns = [
    path(
        '',
        ListView.as_view(
            queryset=City.objects.select_related().all(),
            context_object_name='cities',
            template_name='major_city/list.html'
        ),
        name='index'
    ),
    path(
        '<int:pk>/',
        DetailView.as_view(
            model=City,
            context_object_name='city',
            template_name='major_city/detail.html'
        ),
        name='show'
    ),
]

それでは皆様、良き Python & Django ライフを !

JUnit 5 でテストコードがだいぶ変わったという話

JUnit 5 がとっくの昔にリリースされてたのを今頃になって確認してみたらいろいろ変わってた話。

アプリケーションコード

すごーい(CV : 尾崎由香)簡単な例でスマソ。

package jp.mydns.akanekodou;

/**
 * <p>文字列から整数への変換メソッド提供クラス</p>
 *
 * @version 1.1.1
 * @author akaneko3
 */
public class ParseNum {
    /**
     * <p>数値文字列を整数に変換する。</p>
     *
     * @param str 整数を表す文字列
     * @return 変換された整数値
     * @see Integer#parseInt(String)
     */
    public int parseNum(String str) {
        try {
            return Integer.parseInt(str);
        } catch (NumberFormatException nfe) {
            // NumberFormatException を catch したら
            // メッセージつきの NumberFormatException を throw する
            throw new NumberFormatException("入力された値が整数値を表していません。");
        }
    }
}
package jp.mydns.akanekodou;

import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.IOException;

/**
 * <p>
 * メインクラス<br />
 * 標準入力から取り込んだ文字列を整数値に変換する。
 * </p>
 *
 * @version 1.1
 * @author akaneko3
 */
public final class App {
    /**
     * <p>
     * private コンストラクタ<br />
     * (このクラスはインスタンスを生成しない)
     * </p>
     */
	private App() {}

    /**
     * <p>メインメソッド</p>
     *
     * @param args コマンドライン引数
     */
	public static void main(String[] args) {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        try {
            System.out.print("整数を入力してください: ");
            String str = br.readLine();
            ParseNum cn = new ParseNum();
            int value = cn.parseNum(str);
            System.out.println(value);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
続きを読む

巳年じゃないけど Python やろうぜ(その 21)

PostgreSQL の利用

Django はデフォルトで SQLite3 を利用しますが、他のデータベースを活用することもできます。今回はその中から PostgreSQL を利用してみようと思います。

PostgreSQL のインストールと設定

Windows の場合は GUI インストーラもあって、比較的楽にインストール・設定ができると思います。

Linux についてはいろいろと設定を変更しないといけないっぽくて、とりあえず Fedora に関するものについては Qiita にまとめました。
Fedora に PostgreSQL をインストールして使えるようにするまで - Qiita

Django から利用するためのデータベースを作成しておきます。Linux の場合は postgres というユーザーが作成されているはずですので、以下のコマンドを実行します。

su - postgres
createdb django

Django の設定

PostgreSQLDjango から利用する場合、あらかじめ psycopg2 をインストールする必要があります。

pip install psycopg2

settings.py の中のデータベースに関する部分を以下のように書き換えます。

# Database
# https://docs.djangoproject.com/en/1.10/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'django',
        'USER': 'postgres',
        'PASSWORD': '(snip)',
        'HOST': 'localhost',
        'PORT': 5432,
    }
}

マイグレーションと初期データの投入を再実行します。

./manage.py migrate
./manage.py loaddata initial_data

管理者ユーザーの情報もデータベースに格納されていますので、切り替えに伴って再度作成しておく必要があります。

django-admin createsuperuser

次回以降、WSGI による Apache HTTPD サーバとの連携についてお話をして、今回のシリーズはひとまず終了としたいと思います。