プログラマーの調べ物

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

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

としてください。

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

Spring Bootで実行可能jarを作成する

実行可能jarを作成する

Spring Bootでは実行可能なjarを作成できます。 これはwarファイルをWebアプリケーションサーバにデプロイするといった面倒な作業を省き、java -jarでWebアプリが起動できることを意味します。

実行可能jarの作り方は簡単です。 以下のコマンドを実行するだけです。

./mvnw clean package

以下のようなエラーが出たときはコンパイルのバージョンが異なっています。

$ ./mvnw clean package
Exception in thread "main" java.lang.UnsupportedClassVersionError: org/apache/maven/wrapper/MavenWrapperMain : Unsupported major.minor version 51.0
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClassCond(ClassLoader.java:637)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:621)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
    at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)

Javaの対応表は以下の通り。

J2SE 8 = 52,
J2SE 7 = 51,
J2SE 6.0 = 50,
J2SE 5.0 = 49,
JDK 1.4 = 48,
JDK 1.3 = 47,
JDK 1.2 = 46,
JDK 1.1 = 45

以下の記事が参考になります。   http://qiita.com/iwag@github/items/3f749010f0981195e2ba

java -versionで1.7以上を指定しても、mavenが見ているJavaが1.6だとエラーが出ます。 maven実行前にJAVA_HOMEを指定する必要があります。

$ JAVA_HOME=`/usr/libexec/java_home -v 1.8` ./mvnw clean package

これでjarを作成することができました。

[INFO] --- spring-boot-maven-plugin:1.4.3.RELEASE:repackage (default) @ demo ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 18.982 s
[INFO] Finished at: 2017-01-02T11:59:45+09:00
[INFO] Final Memory: 29M/267M
[INFO] ------------------------------------------------------------------------

targetディレクトリ以下にjarができています。

Spring Bootを使い始めるためのチュートリアル

Spring Bootは2013年に開発が始まり、2014年4月にバージョン1.0がリリースされました。 Spring Bootを使えば最初からさまざまな機能を利用することができます。

アプリケーションサーバにデプロイするという面倒な作業を省き、mainメソッドを実行するだけでWebアプリを実行できます。

Spring Bootを始める

まずは以下のURLに移動します。 https://start.spring.io/

次に、DependenciesのSearch for dependenciesで「Web」を入力してEnterを押します。

そしてGenerate Projectをクリックします。

ダウンロードされたプロジェクトを解凍して、Spring Tool Suiteに取り込みます。

Spring Tool Suiteでは、

File -> Import -> Existing Maven Projectsを選択し、Nextを押下。

先ほど解凍したフォルダを選択します。

取り込んだプロジェクトを実行するだけで、Webアプリケーションが起動します。

DemoApplication.javaをいじってみる

ダウンロードしたdemoを実行しても、初期状態のままではブラウザに何も表示されません。

Whitelabel Error Page

This application has no explicit mapping for /error, so you are seeing this as a fallback.

Sun Jan 01 20:47:47 JST 2017
There was an unexpected error (type=Not Found, status=404).
No message available

こんな感じのメッセージが出るだけです。

なぜなら、Controllerがないからです。 HTTP GETを受け取るようにしましょう。

package com.example;

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

@SpringBootApplication
@RestController
public class DemoApplication {

    @RequestMapping("/")
    String hello() {
        return "Hello Spring Boot!";
    }
    
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

Javaを修正した後に、localhost:8080にアクセスしてみます。

すると、

「Hello Spring Boot!」

と表示されます。

Spring Bootでテストコードを書く

Spring Initializerで生成したプロジェクトには、デフォルトでテストコードが含まれています。 たとえば、以下のようなコードを書いて、実行すると、上のコードをテストしてくれます。

package com.example;

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.context.embedded.LocalServerPort;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.web.client.RestTemplate;

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class DemoApplicationTests {

    RestTemplate restTemplate = new RestTemplate();

    @LocalServerPort
    int port;
    
    @Test
    public void contextLoads() {
        assertThat(restTemplate.getForObject("http://localhost:" + port, String.class), is("Hello Spring Boot!"));
    }
    
}