はじめに
Spring BootとAngularJSを使った、最も簡単なWebアプリケーションを作成します。
こちらのチュートリアルが元ネタです。
Spring Security and Angular JS
https://spring.io/guides/tutorials/spring-security-and-angular-js/
AngularJSのチュートリアルも参考にしています。
https://code.angularjs.org/1.5.3/docs/tutorial
前提条件
下の記事の後の状態を前提にしています
Spring Tool Suite 3.7.3(Eclipse Mars.2 (4.5.2))でSpring Starter Projectを新規作成
環境
JVM: 1.8.0_45 (Oracle Corporation 25.45-b02)
OS: Mac OS X 10.11.3 x86_64
Spring Tool Suite
Version: 3.7.3.RELEASE
Build Id: 201602250940
Platform: Eclipse Mars.2 (4.5.2)
(こちらから入れました https://spring.io/tools/sts/all)
Buildship: Eclipse Plug-ins for Gradle 1.0.13.v20160411-1723
(Help -> Eclipse marketplaceから入れました)
手順
JavaScript Libraryを追加する
AngularJSなどのJavaScript Libraryが使えるように、ビルドスクリプトの依存物として、// Addを追記します。
dependencies {
// Add
compile 'org.webjars:jquery:2.2.3'
compile 'org.webjars:angularjs:1.5.3'
compile 'org.webjars:bootstrap:3.3.6'
compile('org.springframework.boot:spring-boot-starter-web')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
参考
WebJars http://www.webjars.org/
追記を反映するために、Package ExplorerでSSP37(プロジェクトルート)を選び右クリック、
Gradle -> Refresh Gradle Project
をクリックします。
Package ExplorerのProject and External Dependenciesに、追記したJarあるか確認します。
JavaScript Libraryを参照してみる
導入したJavaScript Libraryがhtmlファイルから参照できるか試してみます。
下のindex.htmlファイルを新規作成します。
<html>
<head>
<meta charset="utf-8">
<title>SSP37</title>
<link rel="stylesheet" href="webjars/bootstrap/3.3.6/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<div>Check script sources</div>
</div>
<script src="webjars/jquery/2.2.3/jquery.min.js"></script>
<script src="webjars/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="webjars/angularjs/1.5.3/angular.min.js"></script>
</body>
</html>
Webアプリケーションを実行し、ブラウザで http://localhost:8080/index.html を開きます。
ブラウザの開発ツールなどで、参照しているJavaScript Libraryが参照できているか確認します。
ちょっとだけAngularJSを使ってみる
簡単にAngularJSが動いているかを確認します。
index.htmlのとあるところを変更します。
htmlタグにng-app属性を追記。
class="container"の下を変更。
<html ng-app><!-- Change -->
<head>
<meta charset="utf-8">
<title>SSP37</title>
<link rel="stylesheet" href="webjars/bootstrap/3.3.6/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<!-- Change -->
<h1>Check AngularJS</h1>
<div>{{'AngularJS'}}</div>
</div>
<script src="webjars/jquery/2.2.3/jquery.min.js"></script>
<script src="webjars/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="webjars/angularjs/1.5.3/angular.min.js"></script>
</body>
</html>
<div>{{'AngularJS'}}</div>のところが、ブラウザでAngularJSとでればOKです。
{{'AngularJS'}}とでたら、 AngularJSが動いてません。
Controllerを導入してみる
AngularJSのControllerを導入してみましょう。
下のapp.jsを新規作成します。
angular.module('ssp37App', [])
.controller('HelloCtrl', function($scope) {
$scope.hello = {id: 'xxx', text: 'Hello'}
})
;
index.htmlも導入したControllerを使うようにとあるところを変更します。
htmlタグにng-app属性にモジュール名:ssp37Appを追記。
class="container"のdivタグに、ng-controller属性を追記。
同タグ内もHelloCtrlで指定した値を使うように変更します。
<!-- Add -->に先ほどのControllerへの参照を追記します。
<html ng-app="ssp37App"><!-- Change -->
<head>
<meta charset="utf-8">
<title>SSP37</title>
<link rel="stylesheet" href="webjars/bootstrap/3.3.6/css/bootstrap.min.css">
</head>
<body>
<!-- Change -->
<div class="container" ng-controller="HelloCtrl">
<h1>Check Controller</h1>
<p>The ID is {{hello.id}}</p>
<p>The text is {{hello.text}}</p>
</div>
<script src="webjars/jquery/2.2.3/jquery.min.js"></script>
<script src="webjars/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="webjars/angularjs/1.5.3/angular.min.js"></script>
<!-- Add -->
<script src="js/app.js"></script>
</body>
</html>
プレースホルダの{{xxx}}内が、Controllerで指定した値に換わったか確認します。
RestControllerにアクセスしてみる
AngularJSのControllerから、SpringのRestControllerにアクセスして、値を出してみましょう。
下のRestControllerを新規作成します。
package com.example.controllers;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyRestController {
@RequestMapping("/hello")
public Map<String,Object> hello() {
Map<String,Object> model = new HashMap<String,Object>();
model.put("id", UUID.randomUUID().toString());
model.put("text", "Hello by MyRestController");
return model;
}
}
AngularJSのControllerからRestControllerへアクセスするように、app.jsを変更します。
angular.module('ssp37App', [])
// Change
.controller('HelloCtrl', function($http, $scope) {
$http.get('/hello')
.then(function(response) {
$scope.hello = response.data;
})
})
;
プレースホルダの{{xxx}}内が、RestControllerで指定した値に換わったか確認します。
400 Bad Requestを応答するRestControllerにアクセスしてみる
RestControllerが400 Bad Requestを応答する場合をAngularJSのControllerで捕捉してみましょう。
先ほどのRestControllerに// Addの部分を追記し、/helloOrBad?bad=trueでアクセスされたら、400 Bad Requestを応答するようにします。
package com.example.controllers;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import org.springframework.http.HttpStatus; // Add
import org.springframework.http.ResponseEntity; // Add
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; // Add
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyRestController {
// Omit
// Add
@RequestMapping("/helloOrBad")
public ResponseEntity<Map<String,Object>> helloOrBad(@RequestParam(required=false) Boolean bad) {
if(bad != null && bad) {
return new ResponseEntity<Map<String,Object>>(HttpStatus.BAD_REQUEST);
}
else {
Map<String,Object> model = new HashMap<String,Object>();
model.put("id", UUID.randomUUID().toString());
model.put("text", "Hello or Bad by MyRestController");
return new ResponseEntity<Map<String,Object>>(model, HttpStatus.OK);
}
}
}
AngularJSのControllerから/helloOrBad?bad=trueへアクセスするようにし、200 OK以外の応答を捕捉するように、// Addの部分を追記します。
angular.module('ssp37App', [])
.controller('HelloCtrl', function($http, $scope) {
// Change
$http.get('/helloOrBad?bad=true')
.then(function(response) {
$scope.hello = response.data;
})
// Add
.catch(function(response) {
$scope.status = response.status;
$scope.statusText = response.statusText;
})
})
;
index.htmlにstatusが出るようにもとあるところを追記します。
<html ng-app="ssp37App">
<head>
<meta charset="utf-8">
<title>SSP37</title>
<link rel="stylesheet" href="webjars/bootstrap/3.3.6/css/bootstrap.min.css">
</head>
<body>
<div class="container" ng-controller="HelloCtrl">
<h1>Check Controller</h1>
<p>The ID is {{hello.id}}</p>
<p>The text is {{hello.text}}</p>
<!-- Add -->
<p>The status is {{status}}</p>
<p>The statusText is {{statusText}}</p>
</div>
<script src="webjars/jquery/2.2.3/jquery.min.js"></script>
<script src="webjars/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="webjars/angularjs/1.5.3/angular.min.js"></script>
<script src="js/app.js"></script>
</body>
</html>
The status is 400と出るか確認します。
参考
Sample Repository
https://github.com/quwahara/SSP37/tree/310-webjars