プログラマーの調べ物

プログラマーが調べ物をするときに役に立つサイトを作ります。

Spring Bootでフォームを送って結果を返す

とりあえずって感じですが、formタグで囲まれた情報をJava側に送りつけて、その結果をHTMLで返すサンプルです。

まずは、HTTP GETで情報を送信するHTMLです。

account.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8" />
<title>SAMPLE</title>
</head>
<body>
<form action="/result">
  <fieldset>
    <input type="text" name="name" />
    <input type="submit" value="Subscribe me!" />
  </fieldset>
</form>
</body>
</html>

これを受け取るJavaを書きます。

package com.example;

import java.util.ArrayList;
import java.util.List;

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

@Controller
public class RestaurantController {
    
    @RequestMapping("/account")
    public String account(Model model) {
        return "account";
    }
    
    @RequestMapping(value = "/result", method = RequestMethod.GET)
    public String form(Model model,@RequestParam String name) {
        model.addAttribute("name", name);
        return "result";
    }
    
}

結果を表示するHTMLです。

result.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8" />
<title>結果</title>
</head>
<body>
結果:
<span th:text="${name}"></span>
</body>
</html>

「結果: test」とブラウザに表示されます。

とりあえずExpressを動かしてみる。

Node.jsのフレームワーク「Express」を動かしてみます。

package.jsonには以下のように記述します。

{
  "name" : "MEAN",
    "version" : "0.0.1",
    "dependencies" : {
        "express" : "latest",
        "glup" : "latest"
  }
}

で、server.jsを書きます。

var express = require('express');


var hasName = function(req, res, next) {
    if (req.param('name')) {
        next();
    } else {
        res.send('What is your name?');
    }
};

var sayHello = function(req, res, next) {
    res.send('Hello ' + req.param('name'));
};

//create new Express application object
var app = express();

app.get('/', hasName, sayHello);

//user() method to mount a middleware funtion with a specific path
/*
app.use('/', function(req, res) {
   res.send('Hello World');
});
*/

app.listen(3000);
console.log('Server running at http://localhost:3000');

module.exports = app;

これをnode serverで実行します。

NPMでGlobalモードでインストールしたパッケージはどこにインストールされるのか?

NPMには2つのインストールモードがあります。 ローカルモードとグローバルモードです。

Unixベースのシステムの場合、/usr/local/lib/node_modules/にインストールされます。 Windowsの場合、C:¥Users¥%USERNAME%¥AppData¥Roaming¥npm¥node_modules にインストールされます。

何か不安があるときは、とりあえずローカルモードでインストールするのがいいと思います。

npmでパッケージをインストールするときは、以下のコマンドを使います。

npm install express

バージョンを指定するときは、

npm install express@2.2

のようにコマンドを打ちます。

その他に、

npm uninstall

や、

npm update

コマンドがあります。

複数のパッケージを管理するには、package.jsonを使うのが一般的です。

アプリケーションのルートディレクトリに置きます。

こんな感じで書いておけば、npm installで依存ファイルをまとめてインストールできます。

{
  "name" : "MEAN",
  "version" : "0.0.1",
  "dependencies" : {
    "express" : "latest",
    "grunt" : "latest"
  }
}

npm init で作成するのが一般的です。

npmで手動インストールした情報をpackage.jsonに自動追加したいときは、

npm install <package> --save

としてください。

Macで8080番ポートでLISTENしているプロセスをkillするコマンド

以下のコマンドで、8080番ポートでLISTENしているプロセスをkillすることができます。

$ kill $(lsof -t -i:8080)

http://stackoverflow.com/questions/11583562/how-to-kill-a-process-running-on-particular-port-in-linux/11596144

Spring Bootで画面遷移型アプリケーションを作成する

Spring Bootを使えば画面遷移型のアプリケーションも簡単に作ることができます。

テンプレートエンジンとして、次のライブラリがサポートされています。

  • Thymeleaf
  • FreeMarker
  • Groovy templates
  • Velocity
  • Mustache

JSPの利用はさまざまな制約があるため、推奨されていないようです。

Spring Bootで画面遷移型アプリケーション

pom.xmlに以下の依存モジュールを追加します。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

次に、src/main/javaに以下のクラスを配置します。

RestaurantController.java

package com.example;

import java.util.ArrayList;
import java.util.List;

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

import con.example.tw.RestaurantBean;

@Controller
public class RestaurantController {
    final List<RestaurantBean> restaurantList = new ArrayList<RestaurantBean>();

    
    public List<RestaurantBean> getRestaurants() {
        RestaurantBean bean = new RestaurantBean();
        bean.setTagName("sampleTag");
        bean.setTabelogUrl("https://www.google.com");
        bean.setUserName("takashi");
        bean.setTweet("this is nice restaurant!");
        restaurantList.add(bean);
        return restaurantList;
    }
    
    @RequestMapping("/info")
    public String info(Model model) {
        model.addAttribute("title", "おいしいレストラン情報");
        model.addAttribute("info", "This is Restaurant Infomation");
        return "info";
    }
    
    
}

TemplateResolverがビュー名につけるプレフィックスとサフィックスのデフォルト値はそれぞれ"classpath:/templates/"と".html"になるため、 /src/main/resources/templates/info.htmlを配置します。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8" />
<title th:text="${title}"></title>
</head>
<body>
<p>
<span th:text="${info}">Hello!</span>
</p>
</body>
</html>

これで、localhost:8080/info にアクセスすると、

「This is Restaurant Infomation」

と表示されます。

Spring BootでRESTfull Webサービスを作成する

RESTful Web サービス

Spring Bootでは簡単にRESTful Webサービスを作成することができます。 RESTとは「REpresentational State Transfer」の略で、クライアントとサーバー間でデータをやりとりするアプリケーションを構築するためのアーキテクチャスタイルの一つです。

REST APIではデータベースなどで管理している情報の中からクライアントに提供する情報を「リソース」として抽出します。 これをResource Oriented Architectureといいます。

  • Web上のリソースとして公開する
  • URIでリソースを識別する
  • HTTPメソッドによってリソースを操作する
  • JSON,XMLなどの適切なフォーマットを使用する
  • 適切なHTTPステータスコードを使用する
  • ステートレスなクライアント/サーバ間の通信を行う
  • 関連のあるリソースへリンクさせる

Spring BootでRestControllerを作成する

まず、デフォルトのDemoApplicationに @SpringBootApplicationアノテーションがあることを確認しましょう。 @SpringBootApplicationアノテーションを付与したクラスのパッケージ配下がコンポーネントスキャンの対象になります。

では、以下のようなサンプルクラスを作成してみます。

package com.example;

import java.util.ArrayList;
import java.util.List;

import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import con.example.tw.RestaurantBean;

@RestController
@RequestMapping("log")
public class RestaurantController {
    final List<RestaurantBean> restaurantList = new ArrayList<RestaurantBean>();
        
    @RequestMapping(method = RequestMethod.GET)
    public List<RestaurantBean> getRestaurants() {
        RestaurantBean bean = new RestaurantBean();
        bean.setTagName("sampleTag");
        bean.setTabelogUrl("https://www.google.com");
        bean.setUserName("takashi");
        bean.setTweet("this is nice restaurant!");
        restaurantList.add(bean);
        return restaurantList;
    }
    
    
}

これで、localhost:8080/logにリクエストを投げると、以下のようなJSONが返ってきます。

[{"tweet":"this is nice restaurant!","userName":"takashi","tagName":"sampleTag","tabelogUrl":"https://www.google.com"}]

Spring Bootで作成したjarを8080以外のポートを指定して起動する

前回の記事ではSpring Bootで実行可能jarを作成する手順を紹介しました。 次は、作成したjarを起動させてみましょう。

jarはポータビリティが高いため、別環境でも動かせます。 その際、8080ポートだとJBosstomcatなどと競合することがあるでしょう。

それを回避するには、ポート指定で起動させます。

以下のコマンドでOKです。

$ java -jar target/demo-0.0.1-SNAPSHOT.jar --server.port=8888