This post is about basic authentification with AngularJs, Satellizer and JAX-RS Jersey.
Warning: it only covers auth and token. For a production-ready app, you need to add Keystore, back-end URL filtering, encryption.
Note: a lot of examples are on Satellizer’s GitHub
https://github.com/sahat/satellizer/tree/master/examples/client https://github.com/sahat/satellizer/tree/master/examples/client
https://github.com/sahat/satellizer/tree/master/examples/server/java https://github.com/sahat/satellizer/tree/master/examples/server/java
Demo
Start Tomcat and open your Internet Browser at :
http://localhost:8080/20151119-javaee-angularjs-bootstrap-auth_basic/#/ http://localhost:8080/20151119-javaee-angularjs-bootstrap-auth_basic/#/
Only Login and Home menu’s buttons are visible.
Login redirect to the Login page (login=user1@mail.com, password=pass1).
The login view call the Java backend, and as a response there’ll be a token. After login, the Home page is displayed.
And the navbar now contains a “Datas” button. Also, Login is now more visible, but Logout is.
This secured page by route authent and navbar is now displayed with a message from the REST backend server.
On Logout, the app’s first state is restored (no auth, need to login).
It’s no longer possible to access #/datas page (route url is also secured).
Source
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.damienfremont.blog</groupId>
<artifactId>20151119-javaee-angularjs-bootstrap-auth_basic</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- JAVAEE -->
<java.version>7</java.version>
<javaee.version>7.0</javaee.version>
<jersey.version>2.22.1</jersey.version>
<!-- WEB -->
<jquery.version>2.1.4</jquery.version>
<bootstrap.version>3.3.5</bootstrap.version>
<angularjs.version>1.4.7</angularjs.version>
<satellizer.version>0.12.5</satellizer.version>
<ui-router.version>0.2.9</ui-router.version>
</properties>
<dependencies>
<!-- JAVA -->
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>${javaee.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>com.nimbusds</groupId>
<artifactId>nimbus-jose-jwt</artifactId>
<version>3.1.1</version>
</dependency>
<!-- JAVA LANGUAGE EXTENSION -->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>
<!-- WEB -->
<dependency>
<groupId>org.webjars</groupId>
<artifactId>webjars-servlet-2.x</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>${jquery.version}</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>${bootstrap.version}</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>angularjs</artifactId>
<version>${angularjs.version}</version>
</dependency>
<dependency>
<groupId>org.webjars.bower</groupId>
<artifactId>ui-router</artifactId>
<version>${ui-router.version}</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>satellizer</artifactId>
<version>${satellizer.version}</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/webapp</directory>
<filtering>true</filtering>
<targetPath>${project.basedir}/target/m2e-wtp/web-resources</targetPath>
<includes>
<include>*.jsp</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<webResources>
<resource>
<directory>src/main/webapp</directory>
<filtering>true</filtering>
<includes>
<include>index.html</include>
</includes>
</resource>
</webResources>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.${java.version}</source>
<target>1.${java.version}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
AuthUtils.java
package com.damienfremont.blog;
import java.text.ParseException;
import org.joda.time.DateTime;
import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.JWSHeader;
import com.nimbusds.jose.JWSSigner;
import com.nimbusds.jose.crypto.MACSigner;
import com.nimbusds.jose.crypto.MACVerifier;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.ReadOnlyJWTClaimsSet;
import com.nimbusds.jwt.SignedJWT;
/**
* @see https://github.com/sahat/satellizer/blob/master/examples/server/java/src/main/java/com/example/helloworld/auth/AuthUtils.java
*/
public class AuthUtils {
private static final JWSHeader JWT_HEADER = new JWSHeader(JWSAlgorithm.HS256);
private static final String TOKEN_SECRET = "aliceinwonderland";
public static final String AUTH_HEADER_KEY = "Authorization";
public static String getSubject(String authHeader) throws ParseException, JOSEException {
return decodeToken(authHeader).getSubject();
}
public static ReadOnlyJWTClaimsSet decodeToken(String authHeader) throws ParseException, JOSEException {
SignedJWT signedJWT = SignedJWT.parse(getSerializedToken(authHeader));
if (signedJWT.verify(new MACVerifier(TOKEN_SECRET))) {
return signedJWT.getJWTClaimsSet();
} else {
throw new JOSEException("Signature verification failed");
}
}
public static Token createToken(String host, long sub) throws JOSEException {
JWTClaimsSet claim = new JWTClaimsSet();
claim.setSubject(Long.toString(sub));
claim.setIssuer(host);
claim.setIssueTime(DateTime.now().toDate());
claim.setExpirationTime(DateTime.now().plusDays(14).toDate());
JWSSigner signer = new MACSigner(TOKEN_SECRET);
SignedJWT jwt = new SignedJWT(JWT_HEADER, claim);
jwt.sign(signer);
return new Token(jwt.serialize());
}
public static String getSerializedToken(String authHeader) {
return authHeader.split(" ")[1];
}
}
MyAppCONFIG.java
package com.damienfremont.blog;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.core.Application;
public class MyAppCONFIG extends Application {
@Override
public Set<Class<?>> getClasses() {
Set<Class<?>> s = new HashSet<Class<?>>();
s.add(ServiceJAXRS.class);
s.add(ServiceAuth.class);
return s;
}
}
ServiceAuth.java
package com.damienfremont.blog;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import com.damienfremont.blog.ServiceJAXRS.Content;
import com.google.common.base.Optional;
import com.nimbusds.jose.JOSEException;
/**
* @see https://github.com/sahat/satellizer/blob/master/examples/server/java/src/main/java/com/example/helloworld/resources/AuthResource.java
*/
@Path("/auth")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class ServiceAuth {
static Map<String, User> users = new HashMap<>();
static {
users.put("user1@mail.com", new User(1L, "user1@mail.com", "pass1"));
users.put("user2@mail.com", new User(2L, "user2@mail.com", "pass2"));
}
@GET
@Produces(MediaType.APPLICATION_JSON)
public Content get() {
Content res = new Content();
res.content = "this is from backend!!!";
return res;
}
@Path("/login")
@POST
public Response login(@Valid final User user, @Context final HttpServletRequest request) throws JOSEException {
final Optional<User> foundUser = findByEmail(user.email);
if (foundUser.isPresent() && checkPassword(user.password, foundUser.get().password)) {
final Token token = AuthUtils.createToken(request.getRemoteHost(), foundUser.get().id);
return Response.ok().entity(token).build();
}
return Response.status(Status.UNAUTHORIZED).entity("LOGING_ERROR_MSG").build();
}
private boolean checkPassword(String password, String password2) {
// TODO BUILD YOUR OWN ENCRYPT PASSWORD CHECKER
return password.equals(password2);
}
private Optional<User> findByEmail(String email) {
// TODO BUILD YOUR OWN DAO
return Optional.fromNullable(users.get(email));
}
static class User {
public Long id;
public String email;
public String password;
public User() {
}
public User(Long id, String email, String password) {
this.id = id;
this.email = email;
this.password = password;
}
}
}
ServiceJAXRS.java
package com.damienfremont.blog;
import java.io.Serializable;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
@Path("/data")
public class ServiceJAXRS {
@GET
@Produces(MediaType.APPLICATION_JSON)
public Content get() {
Content res = new Content();
res.content = "this is from backend!!!";
return res;
}
static class Content implements Serializable {
private static final long serialVersionUID = 611255415996442390L;
public String content;
}
}
Token.java
package com.damienfremont.blog;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* @see https://github.com/sahat/satellizer/blob/master/examples/server/java/src/main/java/com/example/helloworld/core/Token.java
*/
public class Token {
String token;
public Token(@JsonProperty("token") String token) {
this.token = token;
}
public String getToken() {
return token;
}
}
app.js
'use strict';
var app = angular.module('app', [ 'ngResource', 'ngRoute', 'ui.router', 'satellizer' ]);
// CONFIG
app.config(function($routeProvider, $authProvider) {
// ROUTE
$routeProvider
.when('/', {
templateUrl: 'views/home.html',
controller: 'HomeCtrl'
})
.when('/login', {
templateUrl: 'views/login.html',
controller: 'LoginCtrl'
})
.when('/logout', {
templateUrl: 'views/home.html',
controller: 'LogoutCtrl'
})
.when('/datas', {
templateUrl: 'views/datas.html',
controller: 'DatasCtrl',
resolve: {
loginRequired: loginRequired
}
})
.otherwise('/');
// SECURITY
$authProvider.withCredentials = true;
$authProvider.tokenRoot = null;
$authProvider.cordova = false;
$authProvider.baseUrl = './api/';
$authProvider.loginUrl = '/auth/login';
$authProvider.signupUrl = '/auth/signup';
$authProvider.unlinkUrl = '/auth/unlink/';
$authProvider.tokenName = 'token';
$authProvider.tokenPrefix = 'satellizer';
$authProvider.authHeader = 'Authorization';
$authProvider.authToken = 'Bearer';
$authProvider.storageType = 'localStorage';
});
function skipIfLoggedIn($q, $auth) {
var deferred = $q.defer();
if ($auth.isAuthenticated()) {
deferred.reject();
} else {
deferred.resolve();
}
return deferred.promise;
}
function loginRequired($q, $location, $auth) {
var deferred = $q.defer();
if ($auth.isAuthenticated()) {
deferred.resolve();
} else {
$location.path('/login');
}
return deferred.promise;
}
app.factory('Service', function($resource) {
return $resource('api/data');
});
// COMMON CTRL
app.controller('ParentCtrl', function($scope, $auth) {
$scope.isAuthenticated = function() {
return $auth.isAuthenticated();
};
});
app.controller('NavbarCtrl', function($scope, $auth) {
});
datas.js
'use strict';
app.controller('DatasCtrl', function($scope, $auth, Service) {
// GET DATAS IF AUTH OK
if ($auth.isAuthenticated()) {
Service.get(function(obj) {
$scope.content = obj.content;
});
}
});
home.js
'use strict';
app.controller('HomeCtrl', function($scope, $auth, Service) {
// GET DATAS IF AUTH OK
if ($auth.isAuthenticated()) {
$scope.message = "You are logged in!";
} else {
$scope.message = "You must login to access Datas.";
}
});
login.js
'use strict';
app.controller('LoginCtrl', function($scope, $auth, $location, $route) {
$scope.emailLogin = function() {
$auth.login({email: $scope.email, password: $scope.password})
.then(function() {
// toastr.success('You have successfully signed in!');
$location.path('/');
$route.reload();
})
.catch(function(error) {
// toastr.error(error.data.message, error.status);
});
};
});
logout.js
'use strict';
app.controller('LogoutCtrl', function($location, $auth) {
if (!$auth.isAuthenticated()) { return; }
$auth.logout()
.then(function() {
// toastr.info('You have been logged out');
$location.path('/');
});
});
index.html
<!DOCTYPE html>
<html>
<head>
<!-- YOU NEED THIS TAG TO PREVENT D3JS CHARACTER ERROR!!! -->
<meta charset="utf-8">
<!-- LIBS CSS -->
<link rel="stylesheet" href="webjars/bootstrap/${bootstrap.version}/css/bootstrap.css">
</head>
<body ng-app="app">
<div class="container" ng-controller="ParentCtrl">
<h1>Auth</h1>
<!-- MENU -->
<div class="slide-animate"
ng-include="'menu.html'" ></div>
<!-- MAIN CONTENT -->
<div class="view-animate"
ng-view ></div>
</div>
<!-- LIBS JS -->
<script src="webjars/jquery/${jquery.version}/jquery.js"></script>
<script src="webjars/bootstrap/${bootstrap.version}/js/bootstrap.js"></script>
<script src="webjars/angularjs/${angularjs.version}/angular.js"></script>
<script src="webjars/angularjs/${angularjs.version}/angular-resource.js"></script>
<script src="webjars/angularjs/${angularjs.version}/angular-route.js"></script>
<script src="webjars/angularjs/${angularjs.version}/angular-animate.js"></script>
<script src="webjars/satellizer/${satellizer.version}/satellizer.js"></script>
<script src="webjars/ui-router/${ui-router.version}/release/angular-ui-router.js"></script>
<!-- YOUR JS -->
<script src="app.js"></script>
<script src="controllers/home.js"></script>
<script src="controllers/datas.js"></script>
<script src="controllers/login.js"></script>
<script src="controllers/logout.js"></script>
</body>
</html>
menu.html
<!-- MENU -->
<nav class="navbar navbar-default" >
<div class="container-fluid" ng-controller="NavbarCtrl">
<!-- HEADER AND MOBILE BUTTON -->
<div class="navbar-header">
<button type="button" class="navbar-toggle"
data-toggle="collapse"
data-target="#bs-example-navbar-collapse-1"
aria-expanded="true">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<!-- LOGO -->
<a class="navbar-brand" href="#/">
MyApp</a>
</div>
<!-- MENU ITEMS -->
<div class="navbar-collapse collapse"
id="bs-example-navbar-collapse-1"
aria-expanded="true">
<ul class="nav navbar-nav">
<li><a href="#/">Home</a></li>
<li ng-if="isAuthenticated()"><a href="#/datas">Datas</a></li>
</ul>
<ul ng-if="!isAuthenticated()" class="nav navbar-nav navbar-right">
<li><a href="#/login">Login</a></li>
</ul>
<ul ng-if="isAuthenticated()" class="nav navbar-nav navbar-right">
<li><a href="#/logout">Logout</a></li>
</ul>
</div>
</div>
</nav>
datas.html
<h2>Datas</h2>
<!-- SECURED CONTENT FROM BACKEND-->
<div ng-if="isAuthenticated()">
Content: <div class="row p-3 p-md-5 p-xl-3 p-xxl-5">
<div class="d-none d-sm-none d-md-none d-lg-block col-lg-3 text-muted">
<h4 class="pt-0 pb-3">Tutorials</h4>
<ul class="list-unstyled tag-list">
<li><a class="text-reset text-decoration-none" href="/tag/test/" rel="tag">Quality</a></li>
<ul class="list-unstyled">
<li><a class="text-reset text-decoration-none" href="/tag/cucumber/" rel="tag">BDD
Cucumber</a>
</li>
<li><a class="text-reset text-decoration-none" href="/tag/tdd/" rel="tag">TDD</a></li>
<li><a class="text-reset text-decoration-none" href="/tag/selenium/" rel="tag">Selenium</a>
</li>
</ul>
</ul>
<ul class="list-unstyled tag-list">
<li><a class="text-reset text-decoration-none" href="/tag/agile/" rel="tag">Agile</a></li>
<ul class="list-unstyled">
<li><a class="text-reset text-decoration-none" href="/tag/design/" rel="tag">Design</a></li>
<li><a class="text-reset text-decoration-none" href="/tag/rest/" rel="tag">REST API</a></li>
</ul>
</ul>
<ul class="list-unstyled tag-list">
<li><a class="text-reset text-decoration-none" href="/tag/java/" rel="tag">Java</a></li>
<ul class="list-unstyled">
<li><a class="text-reset text-decoration-none" href="/tag/spring/" rel="tag">Spring</a>
</li>
<li><a class="text-reset text-decoration-none" href="/tag/junit/" rel="tag">JUnit</a></li>
<li><a class="text-reset text-decoration-none" href="/tag/hibernate/" rel="tag">Hibernate</a></li>
</ul>
</ul>
<ul class="list-unstyled tag-list">
<li><a class="text-reset text-decoration-none" href="/tag/javascript/" rel="tag">Javascript</a></li>
<ul class="list-unstyled">
<li><a class="text-reset text-decoration-none" href="/tag/angularjs/" rel="tag">Angular</a>
</li>
<li><a class="text-reset text-decoration-none" href="/tag/bootstrap/" rel="tag">Bootstrap</a>
</li>
<li><a class="text-reset text-decoration-none" href="/tag/nodejs/" rel="tag">Node</a></li>
</ul>
</ul>
<ul class="list-unstyled tag-list">
<li><a class="text-reset text-decoration-none" href="/tag/unity3d/" rel="tag">Unity3D</a></li>
<ul class="list-unstyled">
<li><a class="text-reset text-decoration-none" href="/tag/csharp/" rel="tag">C#</a></li>
<li><a class="text-reset text-decoration-none" href="/tag/photoshop/" rel="tag">Photoshop</a>
</li>
<li><a class="text-reset text-decoration-none" href="/tag/assets/" rel="tag">Assets</a></li>
</ul>
</ul>
<ul class="list-unstyled">
<li><a class="text-reset text-decoration-none" href="/tag/other/" rel="tag">Misc</a></li>
<ul class="list-unstyled">
<li><a class="text-reset text-decoration-none" href="/tag/quicktip/" rel="tag">Quicktips</a></li>
<li><a class="text-reset text-decoration-none" href="/tag/git/" rel="tag">Git</a></li>
<li><a class="text-reset text-decoration-none" href="/tag/tools/" rel="tag">Tools</a></li>
</ul>
</ul>
</div>
<div class="col-md-8 col-lg-6 px-md-5" role="main">
<div class="article-header wp-block-group">
<h2 class="article-title wp-block-post-title">Javaee Angularjs Bootstrap Howto Charts With D3js</h2>
<p class="text-muted post-meta taxonomy-category">
<small>By <a class="text-reset wp-block-heading" href="/about">Damien</a></small>
·
<small class="date wp-block-post-date">2015-11-08</small>
·
<a href="/tag/angularjs"
class="badge rounded-pill bg-secondary text-decoration-none"
rel="tag">angularjs</a>
<a href="/tag/java"
class="badge rounded-pill bg-secondary text-decoration-none"
rel="tag">java</a>
<a href="/tag/javascript"
class="badge rounded-pill bg-secondary text-decoration-none"
rel="tag">javascript</a>
<a href="/tag/bootstrap"
class="badge rounded-pill bg-secondary text-decoration-none"
rel="tag">bootstrap</a>
</p>
</div>
<div class="post-content wp-block-post-content"><p><img src="/upload/post-thumbnail-angularjs.png" alt="alt text" /></p>
<p>Here simple use cases: a static Bar chart and a dynamic Line chart. It’s build with d3js and nvd3 for angularjs integration and java jersey for backend datas.</p>
<p>Note: for more advanced use cases, you’ll need to create your own angularjs directive working directly with d3js.</p>
<h1 id="demo">Demo</h1>
<p><a href="http://localhost:8080/20151108-javaee-angularjs-bootstrap-charts_d3js/">http://localhost:8080/20151108-javaee-angularjs-bootstrap-charts_d3js/</a>
http://localhost:8080/20151108-javaee-angularjs-bootstrap-charts_d3js/</p>
<p>Here the two uses cases: bar charts and line charts.</p>
<p><img src="/upload/160523003625912.png" alt="alt text" /></p>
<p>There is a tooltip for each datas in charts.</p>
<p><img src="/upload/160523003626367.png" alt="alt text" /></p>
<p>There are two instances of Line chart:</p>
<ul>
<li>static (unique update at loading time)</li>
<li>dynamic (refreshing every second)</li>
</ul>
<p><img src="/upload/160523003626513.gif" alt="alt text" /></p>
<p>Caution: for each refresh you’ll ended with a backend request. Pay attention to performance and load (bigger refresh interval, or replace only with new datas)</p>
<p><img src="/upload/160523003627210.png" alt="alt text" /></p>
<p>Java Data back-end response (build with Jersey JAX-RS impl).</p>
<p><img src="/upload/160523003627446.png" alt="alt text" /></p>
<h1 id="source">Source</h1>
<p><img src="/upload/160523003627906.png" alt="alt text" /></p>
<p>MyAppCONFIG.java</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">package</span> <span class="nn">com.damienfremont.blog</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.util.HashSet</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.util.Set</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">javax.ws.rs.core.Application</span><span class="o">;</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">MyAppCONFIG</span> <span class="kd">extends</span> <span class="nc">Application</span> <span class="o">{</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="nc">Set</span><span class="o"><</span><span class="nc">Class</span><span class="o"><?>></span> <span class="n">getClasses</span><span class="o">()</span> <span class="o">{</span>
<span class="nc">Set</span><span class="o"><</span><span class="nc">Class</span><span class="o"><?>></span> <span class="n">s</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">HashSet</span><span class="o"><</span><span class="nc">Class</span><span class="o"><?>>();</span>
<span class="n">s</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="nc">ServiceJAXRS</span><span class="o">.</span><span class="na">class</span><span class="o">);</span>
<span class="k">return</span> <span class="n">s</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>ServiceJAXRS.java</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">package</span> <span class="nn">com.damienfremont.blog</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.util.ArrayList</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.util.List</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.util.Random</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">javax.ws.rs.GET</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">javax.ws.rs.Path</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">javax.ws.rs.Produces</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">javax.ws.rs.core.MediaType</span><span class="o">;</span>
<span class="nd">@Path</span><span class="o">(</span><span class="s">"/datas"</span><span class="o">)</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">ServiceJAXRS</span> <span class="o">{</span>
<span class="nd">@Path</span><span class="o">(</span><span class="s">"/values"</span><span class="o">)</span>
<span class="nd">@GET</span>
<span class="nd">@Produces</span><span class="o">(</span><span class="nc">MediaType</span><span class="o">.</span><span class="na">APPLICATION_JSON</span><span class="o">)</span>
<span class="kd">public</span> <span class="nc">List</span><span class="o"><</span><span class="nc">List</span><span class="o">></span> <span class="nf">getAll</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">mockDatas</span><span class="o">;</span>
<span class="o">}</span>
<span class="nd">@Path</span><span class="o">(</span><span class="s">"/values-big"</span><span class="o">)</span>
<span class="nd">@GET</span>
<span class="nd">@Produces</span><span class="o">(</span><span class="nc">MediaType</span><span class="o">.</span><span class="na">APPLICATION_JSON</span><span class="o">)</span>
<span class="kd">public</span> <span class="nc">List</span><span class="o"><</span><span class="nc">List</span><span class="o">></span> <span class="nf">getAllReal</span><span class="o">()</span> <span class="o">{</span>
<span class="c1">// MOCK: UPDATE FOR REAL TIME</span>
<span class="n">mockDatasReal</span><span class="o">.</span><span class="na">remove</span><span class="o">(</span><span class="mi">0</span><span class="o">);</span>
<span class="n">mockStart</span> <span class="o">=</span> <span class="n">mockStart</span> <span class="o">+</span> <span class="n">mockInterval</span><span class="o">;</span>
<span class="n">mockDatasReal</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">newValue</span><span class="o">(</span><span class="n">mockStart</span><span class="o">));</span>
<span class="k">return</span> <span class="n">mockDatasReal</span><span class="o">;</span>
<span class="o">}</span>
<span class="c1">// MOCK</span>
<span class="c1">// MOCK: INIT</span>
<span class="kd">static</span> <span class="nc">ArrayList</span><span class="o"><</span><span class="nc">List</span><span class="o">></span> <span class="n">mockDatas</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ArrayList</span><span class="o"><>();</span>
<span class="kd">static</span> <span class="o">{</span>
<span class="kt">long</span> <span class="n">mockStart</span> <span class="o">=</span> <span class="mi">1025409600000L</span><span class="o">;</span>
<span class="kt">long</span> <span class="n">mockInterval</span> <span class="o">=</span> <span class="mi">2592000000L</span><span class="o">;</span>
<span class="k">for</span> <span class="o">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">1</span><span class="o">;</span> <span class="n">i</span> <span class="o"><</span> <span class="mi">10</span><span class="o">;</span> <span class="n">i</span><span class="o">++)</span> <span class="o">{</span>
<span class="n">mockStart</span> <span class="o">=</span> <span class="n">mockStart</span> <span class="o">+</span> <span class="n">mockInterval</span><span class="o">;</span>
<span class="n">mockDatas</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">newValue</span><span class="o">(</span><span class="n">mockStart</span><span class="o">));</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="kd">static</span> <span class="nc">ArrayList</span><span class="o"><</span><span class="nc">List</span><span class="o">></span> <span class="n">mockDatasReal</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ArrayList</span><span class="o"><>();</span>
<span class="kd">static</span> <span class="kt">long</span> <span class="n">mockStart</span> <span class="o">=</span> <span class="mi">1</span><span class="o">;</span>
<span class="kd">static</span> <span class="kt">long</span> <span class="n">mockInterval</span> <span class="o">=</span> <span class="mi">1</span><span class="o">;</span>
<span class="kd">static</span> <span class="o">{</span>
<span class="k">for</span> <span class="o">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">1</span><span class="o">;</span> <span class="n">i</span> <span class="o"><</span> <span class="mi">50</span><span class="o">;</span> <span class="n">i</span><span class="o">++)</span> <span class="o">{</span>
<span class="n">mockStart</span> <span class="o">=</span> <span class="n">mockStart</span> <span class="o">+</span> <span class="n">mockInterval</span><span class="o">;</span>
<span class="n">mockDatasReal</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">newValue</span><span class="o">(</span><span class="n">mockStart</span><span class="o">));</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="kd">private</span> <span class="kd">static</span> <span class="nc">ArrayList</span><span class="o"><</span><span class="nc">Long</span><span class="o">></span> <span class="nf">newValue</span><span class="o">(</span><span class="kt">long</span> <span class="n">start</span><span class="o">)</span> <span class="o">{</span>
<span class="kt">long</span> <span class="n">randomNum</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Random</span><span class="o">().</span><span class="na">nextInt</span><span class="o">(</span><span class="mi">50</span><span class="o">)</span> <span class="o">+</span> <span class="mi">1</span><span class="o">;</span>
<span class="nc">ArrayList</span><span class="o"><</span><span class="nc">Long</span><span class="o">></span> <span class="n">value</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ArrayList</span><span class="o"><>();</span>
<span class="n">value</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">start</span><span class="o">);</span>
<span class="n">value</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">randomNum</span><span class="o">);</span>
<span class="k">return</span> <span class="n">value</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>web.xml</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><web-app</span> <span class="na">xmlns=</span><span class="s">"http://xmlns.jcp.org/xml/ns/javaee"</span> <span class="na">xmlns:xsi=</span><span class="s">"http://www.w3.org/2001/XMLSchema-instance"</span> <span class="na">xsi:schemaLocation=</span><span class="s">"http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"</span> <span class="na">version=</span><span class="s">"3.1"</span><span class="nt">></span>
<span class="nt"><servlet></span>
<span class="nt"><servlet-name></span>REST<span class="nt"></servlet-name></span>
<span class="nt"><servlet-class></span>org.glassfish.jersey.servlet.ServletContainer<span class="nt"></servlet-class></span>
<span class="nt"><init-param></span>
<span class="nt"><param-name></span>javax.ws.rs.Application<span class="nt"></param-name></span>
<span class="nt"><param-value></span>com.damienfremont.blog.MyAppCONFIG<span class="nt"></param-value></span>
<span class="nt"></init-param></span>
<span class="nt"><init-param></span>
<span class="nt"><param-name></span>jersey.config.server.provider.classnames<span class="nt"></param-name></span>
<span class="nt"><param-value></span>org.glassfish.jersey.media.multipart.MultiPartFeature<span class="nt"></param-value></span>
<span class="nt"></init-param></span>
<span class="nt"><load-on-startup></span>1<span class="nt"></load-on-startup></span>
<span class="nt"></servlet></span>
<span class="nt"><servlet-mapping></span>
<span class="nt"><servlet-name></span>REST<span class="nt"></servlet-name></span>
<span class="nt"><url-pattern></span>/api/*<span class="nt"></url-pattern></span>
<span class="nt"></servlet-mapping></span>
<span class="nt"><servlet></span>
<span class="nt"><servlet-name></span>WEBJARS<span class="nt"></servlet-name></span>
<span class="nt"><servlet-class></span>org.webjars.servlet.WebjarsServlet<span class="nt"></servlet-class></span>
<span class="nt"><init-param></span>
<span class="nt"><param-name></span>disableCache<span class="nt"></param-name></span>
<span class="nt"><param-value></span>true<span class="nt"></param-value></span>
<span class="nt"></init-param></span>
<span class="nt"><load-on-startup></span>2<span class="nt"></load-on-startup></span>
<span class="nt"></servlet></span>
<span class="nt"><servlet-mapping></span>
<span class="nt"><servlet-name></span>WEBJARS<span class="nt"></servlet-name></span>
<span class="nt"><url-pattern></span>/webjars/*<span class="nt"></url-pattern></span>
<span class="nt"></servlet-mapping></span>
<span class="nt"></web-app></span>
</code></pre></div></div>
<p>app.js</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="dl">'</span><span class="s1">use strict</span><span class="dl">'</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">app</span> <span class="o">=</span> <span class="nx">angular</span><span class="p">.</span><span class="nx">module</span><span class="p">(</span><span class="dl">'</span><span class="s1">app</span><span class="dl">'</span><span class="p">,</span> <span class="p">[</span> <span class="dl">'</span><span class="s1">ngResource</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">nvd3ChartDirectives</span><span class="dl">'</span> <span class="p">]);</span>
<span class="c1">// BAR *************</span>
<span class="nx">app</span><span class="p">.</span><span class="nx">factory</span><span class="p">(</span><span class="dl">'</span><span class="s1">Service</span><span class="dl">'</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">$resource</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">$resource</span><span class="p">(</span><span class="dl">'</span><span class="s1">api/datas/values</span><span class="dl">'</span><span class="p">);</span>
<span class="p">});</span>
<span class="nx">app</span><span class="p">.</span><span class="nx">controller</span><span class="p">(</span><span class="dl">'</span><span class="s1">BarCtrl</span><span class="dl">'</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">$scope</span><span class="p">,</span> <span class="nx">Service</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// FORMATTING FUNCTION (OPTIONNAL)</span>
<span class="nx">$scope</span><span class="p">.</span><span class="nx">xAxisTickFormatFunction</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="k">return</span> <span class="kd">function</span><span class="p">(</span><span class="nx">d</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">d3</span><span class="p">.</span><span class="nx">time</span><span class="p">.</span><span class="nx">format</span><span class="p">(</span><span class="dl">'</span><span class="s1">%b</span><span class="dl">'</span><span class="p">)(</span><span class="k">new</span> <span class="nb">Date</span><span class="p">(</span><span class="nx">d</span><span class="p">));</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="c1">// INIT</span>
<span class="nx">Service</span><span class="p">.</span><span class="nx">query</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">datas</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">$scope</span><span class="p">.</span><span class="nx">exampleData</span> <span class="o">=</span> <span class="p">[</span> <span class="p">{</span>
<span class="dl">"</span><span class="s2">key</span><span class="dl">"</span> <span class="p">:</span> <span class="dl">"</span><span class="s2">Series 1</span><span class="dl">"</span><span class="p">,</span>
<span class="dl">"</span><span class="s2">values</span><span class="dl">"</span> <span class="p">:</span> <span class="nx">datas</span>
<span class="p">}</span> <span class="p">];</span>
<span class="p">});</span>
<span class="p">});</span>
<span class="c1">// LINE IN REAL TIME ******</span>
<span class="nx">app</span><span class="p">.</span><span class="nx">factory</span><span class="p">(</span><span class="dl">'</span><span class="s1">ServiceReal</span><span class="dl">'</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">$resource</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">$resource</span><span class="p">(</span><span class="dl">'</span><span class="s1">api/datas/values-big</span><span class="dl">'</span><span class="p">);</span>
<span class="p">});</span>
<span class="nx">app</span><span class="p">.</span><span class="nx">controller</span><span class="p">(</span><span class="dl">'</span><span class="s1">RealTimeCtrl</span><span class="dl">'</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">$scope</span><span class="p">,</span> <span class="nx">Service</span><span class="p">,</span> <span class="nx">ServiceReal</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// REFRESH VALUE: 0.1 SEC</span>
<span class="kd">var</span> <span class="nx">refreshInterval</span> <span class="o">=</span> <span class="mi">1</span> <span class="o">*</span> <span class="mi">1000</span><span class="p">;</span>
<span class="c1">// UPDATE</span>
<span class="nx">$scope</span><span class="p">.</span><span class="nx">fetchData</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">ServiceReal</span>
<span class="p">.</span><span class="nx">query</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">datas</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">$scope</span><span class="p">.</span><span class="nx">exampleData</span> <span class="o">=</span> <span class="p">[</span> <span class="p">{</span>
<span class="na">key</span> <span class="p">:</span> <span class="dl">'</span><span class="s1">Series 1</span><span class="dl">'</span><span class="p">,</span>
<span class="na">values</span> <span class="p">:</span> <span class="nx">datas</span><span class="p">,</span>
<span class="na">color</span> <span class="p">:</span> <span class="dl">'</span><span class="s1">#ff7f0e</span><span class="dl">'</span>
<span class="p">}</span> <span class="p">];</span>
<span class="p">});</span>
<span class="p">}</span>
<span class="nx">$scope</span><span class="p">.</span><span class="nx">fetchData2</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">ServiceReal</span>
<span class="p">.</span><span class="nx">query</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">datas</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">$scope</span><span class="p">.</span><span class="nx">exampleData2</span> <span class="o">=</span> <span class="p">[</span> <span class="p">{</span>
<span class="na">key</span> <span class="p">:</span> <span class="dl">'</span><span class="s1">Series 1</span><span class="dl">'</span><span class="p">,</span>
<span class="na">values</span> <span class="p">:</span> <span class="nx">datas</span><span class="p">,</span>
<span class="na">color</span> <span class="p">:</span> <span class="dl">'</span><span class="s1">#ff7f0e</span><span class="dl">'</span>
<span class="p">}</span> <span class="p">];</span>
<span class="p">});</span>
<span class="p">}</span>
<span class="c1">// EVERY X TIME</span>
<span class="nx">setInterval</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">$scope</span><span class="p">.</span><span class="nx">$apply</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">$scope</span><span class="p">.</span><span class="nx">fetchData2</span><span class="p">();</span>
<span class="p">})</span>
<span class="p">},</span> <span class="nx">refreshInterval</span><span class="p">);</span>
<span class="c1">// INIT</span>
<span class="nx">$scope</span><span class="p">.</span><span class="nx">fetchData</span><span class="p">();</span>
<span class="nx">$scope</span><span class="p">.</span><span class="nx">fetchData2</span><span class="p">();</span>
<span class="p">});</span>
</code></pre></div></div>
<p>index.html</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp"><!DOCTYPE html></span>
<span class="nt"><html></span>
<span class="nt"><head></span>
<span class="c"><!-- YOU NEED THIS TAG TO PREVENT D3JS CHARACTER ERROR!!! --></span>
<span class="nt"><meta</span> <span class="na">charset=</span><span class="s">"utf-8"</span><span class="nt">></span>
<span class="c"><!-- LIBS CSS --></span>
<span class="nt"><link</span> <span class="na">rel=</span><span class="s">"stylesheet"</span> <span class="na">href=</span><span class="s">"webjars/bootstrap/${bootstrap.version}/css/bootstrap.css"</span><span class="nt">></span>
<span class="nt"><link</span> <span class="na">rel=</span><span class="s">"stylesheet"</span> <span class="na">href=</span><span class="s">"webjars/nvd3/${nvd3.version}/nv.d3.css"</span><span class="nt">></span>
<span class="nt"></head></span>
<span class="nt"><body</span> <span class="na">ng-app=</span><span class="s">"app"</span><span class="nt">></span>
<span class="nt"><div</span> <span class="na">class=</span><span class="s">"container"</span><span class="nt">></span>
<span class="nt"><h1></span>Charts<span class="nt"></h1></span>
<span class="c"><!-- BARS --></span>
<span class="nt"><h4></span>Bar Charts<span class="nt"></h4></span>
<span class="nt"><div</span> <span class="na">ng-controller=</span><span class="s">"BarCtrl"</span><span class="nt">></span>
<span class="nt"><nvd3-discrete-bar-chart</span>
<span class="na">data=</span><span class="s">"exampleData"</span>
<span class="na">showXAxis=</span><span class="s">"true"</span>
<span class="na">showYAxis=</span><span class="s">"true"</span>
<span class="na">xAxisTickFormat=</span><span class="s">"xAxisTickFormatFunction()"</span><span class="nt">></span>
<span class="nt"><svg></svg></span>
<span class="nt"></nvd3-discrete-bar-chart></span>
<span class="nt"></div></span>
<span class="c"><!-- REAL TIME --></span>
<span class="nt"><h4></span>Real Time Charts<span class="nt"></h4></span>
<span class="nt"><div</span> <span class="na">ng-controller=</span><span class="s">"RealTimeCtrl"</span><span class="nt">></span>
<span class="nt"><h5></span>Static<span class="nt"></h5></span>
<span class="nt"><nvd3-line-chart</span>
<span class="na">data=</span><span class="s">"exampleData"</span>
<span class="na">showXAxis=</span><span class="s">"true"</span>
<span class="na">showYAxis=</span><span class="s">"true"</span>
<span class="na">tooltips=</span><span class="s">"true"</span>
<span class="na">interactive=</span><span class="s">"true"</span><span class="nt">></span>
<span class="nt"><svg></svg></span>
<span class="nt"></nvd3-line-chart></span>
<span class="nt"><h5></span>Real<span class="nt"></h5></span>
<span class="nt"><nvd3-line-chart</span>
<span class="na">data=</span><span class="s">"exampleData2"</span>
<span class="na">showXAxis=</span><span class="s">"true"</span>
<span class="na">showYAxis=</span><span class="s">"true"</span>
<span class="na">tooltips=</span><span class="s">"true"</span>
<span class="na">interactive=</span><span class="s">"true"</span>
<span class="na">objectEquality=</span><span class="s">"true"</span><span class="nt">></span>
<span class="nt"><svg></svg></span>
<span class="nt"></nvd3-line-chart></span>
<span class="nt"></div></span>
<span class="nt"></div></span>
<span class="c"><!-- LIBS JS --></span>
<span class="nt"><script</span> <span class="na">src=</span><span class="s">"webjars/angularjs/${angularjs.version}/angular.js"</span><span class="nt">></script></span>
<span class="nt"><script</span> <span class="na">src=</span><span class="s">"webjars/angularjs/${angularjs.version}/angular-resource.js"</span><span class="nt">></script></span>
<span class="nt"><script</span> <span class="na">src=</span><span class="s">"webjars/d3js/${d3js.version}/d3.js"</span><span class="nt">></script></span>
<span class="nt"><script</span> <span class="na">src=</span><span class="s">"webjars/nvd3/${nvd3.version}/nv.d3.js"</span><span class="nt">></script></span>
<span class="nt"><script</span> <span class="na">src=</span><span class="s">"webjars/angularjs-nvd3-directives/${angularjs-nvd3-directives.version}/angularjs-nvd3-directives.js"</span><span class="nt">></script></span>
<span class="c"><!-- YOUR JS --></span>
<span class="nt"><script</span> <span class="na">src=</span><span class="s">"app.js"</span><span class="nt">></script></span>
<span class="nt"></body></span>
<span class="nt"></html></span>
</code></pre></div></div>
<h1 id="project">Project</h1>
<p><a href="https://github.com/DamienFremont/damienfremont.com-blog-labs/tree/master/20151108-javaee-angularjs-bootstrap-charts_d3js">https://github.com/DamienFremont/damienfremont.com-blog-labs/tree/master/20151108-javaee-angularjs-bootstrap-charts_d3js</a>
https://github.com/DamienFremont/damienfremont.com-blog-labs/tree/master/20151108-javaee-angularjs-bootstrap-charts_d3js</p>
<h1 id="references">References</h1>
<p><a href="http://cmaurer.github.io/angularjs-nvd3-directives/">http://cmaurer.github.io/angularjs-nvd3-directives/</a>
http://cmaurer.github.io/angularjs-nvd3-directives/</p>
<p><a href="http://ngmodules.org/modules/angularjs-nvd3-directives">http://ngmodules.org/modules/angularjs-nvd3-directives</a>
http://ngmodules.org/modules/angularjs-nvd3-directives</p>
<p><a href="https://github.com/angularjs-nvd3-directives/angularjs-nvd3-directives">https://github.com/angularjs-nvd3-directives/angularjs-nvd3-directives</a>
https://github.com/angularjs-nvd3-directives/angularjs-nvd3-directives</p>
<p><a href="https://github.com/angularjs-nvd3-directives/angularjs-nvd3-directives/blob/master/examples/objectEquality.html">https://github.com/angularjs-nvd3-directives/angularjs-nvd3-directives/blob/master/examples/objectEquality.html</a>
https://github.com/angularjs-nvd3-directives/angularjs-nvd3-directives/blob/master/examples/objectEquality.html</p>
<p><a href="http://busypeoples.github.io/post/promises-in-angular-js/">http://busypeoples.github.io/post/promises-in-angular-js/</a>
http://busypeoples.github.io/post/promises-in-angular-js/</p>
<h2 id="origin">Origin</h2>
<p><a href="https://damienfremont.com/2015/11/08/javaee-angularjs-bootstrap-howto-charts-with-d3js/">https://damienfremont.com/2015/11/08/javaee-angularjs-bootstrap-howto-charts-with-d3js/</a></p>
</div>
<div class="row border rounded p-3 mt-5">
<div class="col-4 cold-md-2 p-3">
<img class="rounded-circle float-end" width="96" height="96" src="/assets/img/avatar-damien.jpg" />
</div>
<div class="col-8 cold-md-10">
<h5>Hi, I'm <a class="text-reset" href="/about">Damien</a></h5>
<p class="text-muted">
Software Developer
</p>
<p>
<a class="p-2 text-reset text-decoration-none" href="https://www.linkedin.com/in/damienfremont/" target="_blank"
rel="noopener">
<svg xmlns="http://www.w3.org/2000/svg" width="36" height="36"
class="navbar-nav-svg d-inline-block align-text-top" viewBox="0 0 24 24" role="img">
<title>LinkedIn</title>
<path fill="currentColor"
d="M19 0h-14c-2.761 0-5 2.239-5 5v14c0 2.761 2.239 5 5 5h14c2.762 0 5-2.239 5-5v-14c0-2.761-2.238-5-5-5zm-11 19h-3v-11h3v11zm-1.5-12.268c-.966 0-1.75-.79-1.75-1.764s.784-1.764 1.75-1.764 1.75.79 1.75 1.764-.783 1.764-1.75 1.764zm13.5 12.268h-3v-5.604c0-3.368-4-3.113-4 0v5.604h-3v-11h3v1.765c1.396-2.586 7-2.777 7 2.476v6.759z" />
</svg>
</a>
<a class="p-2 text-reset text-decoration-none" href="https://github.com/damienfremont" target="_blank" rel="noopener">
<svg xmlns="http://www.w3.org/2000/svg" width="36" height="36"
class="navbar-nav-svg d-inline-block align-text-top" viewBox="0 0 512 499.36" role="img">
<title>GitHub</title>
<path fill="currentColor" fill-rule="evenodd"
d="M256 0C114.64 0 0 114.61 0 256c0 113.09 73.34 209 175.08 242.9 12.8 2.35 17.47-5.56 17.47-12.34 0-6.08-.22-22.18-.35-43.54-71.2 15.49-86.2-34.34-86.2-34.34-11.64-29.57-28.42-37.45-28.42-37.45-23.27-15.84 1.73-15.55 1.73-15.55 25.69 1.81 39.21 26.38 39.21 26.38 22.84 39.12 59.92 27.82 74.5 21.27 2.33-16.54 8.94-27.82 16.25-34.22-56.84-6.43-116.6-28.43-116.6-126.49 0-27.95 10-50.8 26.35-68.69-2.63-6.48-11.42-32.5 2.51-67.75 0 0 21.49-6.88 70.4 26.24a242.65 242.65 0 0 1 128.18 0c48.87-33.13 70.33-26.24 70.33-26.24 14 35.25 5.18 61.27 2.55 67.75 16.41 17.9 26.31 40.75 26.31 68.69 0 98.35-59.85 120-116.88 126.32 9.19 7.9 17.38 23.53 17.38 47.41 0 34.22-.31 61.83-.31 70.23 0 6.85 4.61 14.81 17.6 12.31C438.72 464.97 512 369.08 512 256.02 512 114.62 397.37 0 256 0z">
</path>
</svg>
</a>
<a class="p-2 text-reset text-decoration-none" href="https://twitter.com/damien_fremont" target="_blank" rel="noopener">
<svg xmlns="http://www.w3.org/2000/svg" width="36" height="36"
class="navbar-nav-svg d-inline-block align-text-top" viewBox="0 0 512 416.32" role="img">
<title>Twitter</title>
<path fill="currentColor"
d="M160.83 416.32c193.2 0 298.92-160.22 298.92-298.92 0-4.51 0-9-.2-13.52A214 214 0 0 0 512 49.38a212.93 212.93 0 0 1-60.44 16.6 105.7 105.7 0 0 0 46.3-58.19 209 209 0 0 1-66.79 25.37 105.09 105.09 0 0 0-181.73 71.91 116.12 116.12 0 0 0 2.66 24c-87.28-4.3-164.73-46.3-216.56-109.82A105.48 105.48 0 0 0 68 159.6a106.27 106.27 0 0 1-47.53-13.11v1.43a105.28 105.28 0 0 0 84.21 103.06 105.67 105.67 0 0 1-47.33 1.84 105.06 105.06 0 0 0 98.14 72.94A210.72 210.72 0 0 1 25 370.84a202.17 202.17 0 0 1-25-1.43 298.85 298.85 0 0 0 160.83 46.92">
</path>
</svg>
</a>
</p>
<p class="text-muted">
Founder of this blog, love Java and Open Source stuff. Follow him on Twitter.
</p>
</div>
</div>
</div>
<div class="d-none d-sm-none d-md-block col-md-4 d-lg-block col-lg-3 text-muted ">
<h4 class="pt-0 pb-3">Top Posts</h4>
<!-- parameter: posts -->
<!-- parameter: limit -->
<div class="">
<div class="pb-xl-2">
<a class="text-reset text-decoration-none" href="/2021/02/18/test-driven-development-tdd-in-java-helloworld-examples">
<!-- parameter: post -->
<div class="summary-small">
<div class="row">
<div class="col-4 col-md-3">
<img class="img-fluid rounded flex-shrink-0" alt="Test Driven Development Tdd In Java Helloworld Examples"
src="/128px//upload/post-thumbnail-tdd.png" />
</div>
<div class="col-8 col-md-9">
<div>
<h6 class="mb-0 text-limit-line-1">Test Driven Development Tdd In Java Helloworld Examples</h6>
<p>
<span class="text-muted"> java </span>
<span class="text-muted"> junit </span>
</p>
</div>
</div>
</div>
</div>
</a>
</div>
<div class="pb-xl-2">
<a class="text-reset text-decoration-none" href="/2020/07/05/software-architecture-train-wagons-be-agile-and-prioritize-your-stack">
<!-- parameter: post -->
<div class="summary-small">
<div class="row">
<div class="col-4 col-md-3">
<img class="img-fluid rounded flex-shrink-0" alt="Software Architecture – “Train wagons” – Be agile and prioritize your stack"
src="/128px//upload/2020-07-05-diapositive2-copy.jpg" />
</div>
<div class="col-8 col-md-9">
<div>
<h6 class="mb-0 text-limit-line-1">Software Architecture – “Train wagons” – Be agile and prioritize your stack</h6>
<p>
<span class="text-muted"> agile </span>
<span class="text-muted"> design </span>
</p>
</div>
</div>
</div>
</div>
</a>
</div>
<div class="pb-xl-2">
<a class="text-reset text-decoration-none" href="/2017/11/23/rest-api-maturity-levels-from-0-to-5">
<!-- parameter: post -->
<div class="summary-small">
<div class="row">
<div class="col-4 col-md-3">
<img class="img-fluid rounded flex-shrink-0" alt="Rest Api Maturity Levels From 0 To 5"
src="/128px//upload/171123171941151.png" />
</div>
<div class="col-8 col-md-9">
<div>
<h6 class="mb-0 text-limit-line-1">Rest Api Maturity Levels From 0 To 5</h6>
<p>
<span class="text-muted"> design </span>
<span class="text-muted"> rest </span>
</p>
</div>
</div>
</div>
</div>
</a>
</div>
<div class="pb-xl-2">
<a class="text-reset text-decoration-none" href="/2017/11/19/howto-springboot-datasource">
<!-- parameter: post -->
<div class="summary-small">
<div class="row">
<div class="col-4 col-md-3">
<img class="img-fluid rounded flex-shrink-0" alt="Howto Springboot Datasource"
src="/128px//upload/post-thumbnail-springboot.jpg" />
</div>
<div class="col-8 col-md-9">
<div>
<h6 class="mb-0 text-limit-line-1">Howto Springboot Datasource</h6>
<p>
<span class="text-muted"> hibernate </span>
<span class="text-muted"> java </span>
</p>
</div>
</div>
</div>
</div>
</a>
</div>
<div class="pb-xl-2">
<a class="text-reset text-decoration-none" href="/2017/11/11/maslows-hierarchy-of-needs-for-software-developers">
<!-- parameter: post -->
<div class="summary-small">
<div class="row">
<div class="col-4 col-md-3">
<img class="img-fluid rounded flex-shrink-0" alt="Maslows Hierarchy Of Needs For Software Developers"
src="/128px//upload/171111002555610.png" />
</div>
<div class="col-8 col-md-9">
<div>
<h6 class="mb-0 text-limit-line-1">Maslows Hierarchy Of Needs For Software Developers</h6>
<p>
<span class="text-muted"> agile </span>
<span class="text-muted"> quicktip </span>
</p>
</div>
</div>
</div>
</div>
</a>
</div>
<div class="pb-xl-2">
<a class="text-reset text-decoration-none" href="/2016/05/09/how-to-cucumber-test-report-plugin-2-with-maven-and-java">
<!-- parameter: post -->
<div class="summary-small">
<div class="row">
<div class="col-4 col-md-3">
<img class="img-fluid rounded flex-shrink-0" alt="How To Cucumber Test Report Plugin 2 With Maven And Java"
src="/128px//upload/160523003729271.png" />
</div>
<div class="col-8 col-md-9">
<div>
<h6 class="mb-0 text-limit-line-1">How To Cucumber Test Report Plugin 2 With Maven And Java</h6>
<p>
<span class="text-muted"> bdd </span>
<span class="text-muted"> cucumber </span>
</p>
</div>
</div>
</div>
</div>
</a>
</div>
<div class="pb-xl-2">
<a class="text-reset text-decoration-none" href="/2015/11/02/javaee-angularjs-bootstrap-how-to-pagination-with-smart-table">
<!-- parameter: post -->
<div class="summary-small">
<div class="row">
<div class="col-4 col-md-3">
<img class="img-fluid rounded flex-shrink-0" alt="Javaee Angularjs Bootstrap How To Pagination With Smart Table"
src="/128px//upload/post-thumbnail-angularjs.png" />
</div>
<div class="col-8 col-md-9">
<div>
<h6 class="mb-0 text-limit-line-1">Javaee Angularjs Bootstrap How To Pagination With Smart Table</h6>
<p>
<span class="text-muted"> angularjs </span>
<span class="text-muted"> java </span>
</p>
</div>
</div>
</div>
</div>
</a>
</div>
<div class="pb-xl-2">
<a class="text-reset text-decoration-none" href="/2015/10/27/how-to-cucumber-java-wants-to-quit">
<!-- parameter: post -->
<div class="summary-small">
<div class="row">
<div class="col-4 col-md-3">
<img class="img-fluid rounded flex-shrink-0" alt="How To Cucumber Java Wants To Quit"
src="/128px//upload/post-thumbnail-cucumber.png" />
</div>
<div class="col-8 col-md-9">
<div>
<h6 class="mb-0 text-limit-line-1">How To Cucumber Java Wants To Quit</h6>
<p>
<span class="text-muted"> bdd </span>
<span class="text-muted"> cucumber </span>
</p>
</div>
</div>
</div>
</div>
</a>
</div>
<div class="pb-xl-2">
<a class="text-reset text-decoration-none" href="/2015/08/06/migrating-from-java4-commonslang-to-java6-guava-to-java8">
<!-- parameter: post -->
<div class="summary-small">
<div class="row">
<div class="col-4 col-md-3">
<img class="img-fluid rounded flex-shrink-0" alt="Migrating From Java4 Commonslang To Java6 Guava To Java8"
src="/128px//upload/post-thumbnail-java.png" />
</div>
<div class="col-8 col-md-9">
<div>
<h6 class="mb-0 text-limit-line-1">Migrating From Java4 Commonslang To Java6 Guava To Java8</h6>
<p>
<span class="text-muted"> java </span>
</p>
</div>
</div>
</div>
</div>
</a>
</div>
<div class="pb-xl-2">
<a class="text-reset text-decoration-none" href="/2015/07/31/responsive-button-with-bootstrap-toggable-text">
<!-- parameter: post -->
<div class="summary-small">
<div class="row">
<div class="col-4 col-md-3">
<img class="img-fluid rounded flex-shrink-0" alt="Responsive Button With Bootstrap Toggable Text"
src="/128px//upload/post-thumbnail-bootstrap.jpg" />
</div>
<div class="col-8 col-md-9">
<div>
<h6 class="mb-0 text-limit-line-1">Responsive Button With Bootstrap Toggable Text</h6>
<p>
<span class="text-muted"> bootstrap </span>
<span class="text-muted"> css </span>
</p>
</div>
</div>
</div>
</div>
</a>
</div>
<div class="pb-xl-2">
<a class="text-reset text-decoration-none" href="/2015/07/23/how-to-cucumber-java-reuse-same-scenario-for-core-service-and-web-ui-tests">
<!-- parameter: post -->
<div class="summary-small">
<div class="row">
<div class="col-4 col-md-3">
<img class="img-fluid rounded flex-shrink-0" alt="How To Cucumber Java Reuse Same Scenario For Core Service And Web Ui Tests"
src="/128px//upload/160523003251963.jpg" />
</div>
<div class="col-8 col-md-9">
<div>
<h6 class="mb-0 text-limit-line-1">How To Cucumber Java Reuse Same Scenario For Core Service And Web Ui Tests</h6>
<p>
<span class="text-muted"> bdd </span>
<span class="text-muted"> cucumber </span>
</p>
</div>
</div>
</div>
</div>
</a>
</div>
<div class="pb-xl-2">
<a class="text-reset text-decoration-none" href="/2015/01/13/comment-utiliser-beanvalidation-manuellement-hors-dun-serveur-javaee">
<!-- parameter: post -->
<div class="summary-small">
<div class="row">
<div class="col-4 col-md-3">
<img class="img-fluid rounded flex-shrink-0" alt="Comment Utiliser Beanvalidation Manuellement Hors Dun Serveur Javaee"
src="/128px//upload/post-thumbnail-java.png" />
</div>
<div class="col-8 col-md-9">
<div>
<h6 class="mb-0 text-limit-line-1">Comment Utiliser Beanvalidation Manuellement Hors Dun Serveur Javaee</h6>
<p>
<span class="text-muted"> java </span>
<span class="text-muted"> rest </span>
</p>
</div>
</div>
</div>
</div>
</a>
</div>
<div class="pb-xl-2">
<a class="text-reset text-decoration-none" href="/2014/12/19/how-to-expandcollapse-table-rows-with-bootstrap">
<!-- parameter: post -->
<div class="summary-small">
<div class="row">
<div class="col-4 col-md-3">
<img class="img-fluid rounded flex-shrink-0" alt="How To Expandcollapse Table Rows With Bootstrap"
src="/128px//upload/post-thumbnail-bootstrap.jpg" />
</div>
<div class="col-8 col-md-9">
<div>
<h6 class="mb-0 text-limit-line-1">How To Expandcollapse Table Rows With Bootstrap</h6>
<p>
<span class="text-muted"> bootstrap </span>
<span class="text-muted"> css </span>
</p>
</div>
</div>
</div>
</div>
</a>
</div>
</div>
</div>
</div>
</div>
home.html
<h2>Home</h2>
<p></p>
login.html
<!-- FROM https://github.com/sahat/satellizer/blob/master/examples/client/partials/login.html -->
<div class="panel panel-default col-md-4 col-md-offset-4">
<div class="panel-body">
<h4 class="text-center">
<i class="glyphicon glyphicon-log-in"></i> Log in
</h4>
<form name="loginForm" ng-submit="emailLogin()" novalidate>
<!-- LOGIN -->
<div class="form-group has-feedback"
ng-class="{ 'has-error': loginForm.email.$invalid && loginForm.email.$dirty }">
<input server-error class="form-control input-lg" type="text"
name="email" ng-model="email" placeholder="Email" required
autofocus>
<div class="help-block" ng-if="loginForm.email.$dirty"
ng-messages="loginForm.email.$error">
<div ng-message="required">Please enter your email</div>
<div ng-message="server"></div>
</div>
</div>
<!-- PASSWORD -->
<div class="form-group has-feedback"
ng-class="{ 'has-error': loginForm.password.$invalid && loginForm.password.$dirty }">
<input server-error class="form-control input-lg"
type="password" name="password" ng-model="password"
placeholder="Password" required>
<div class="help-block" ng-if="loginForm.password.$dirty"
ng-messages="loginForm.password.$error">
<div ng-message="required">Please enter your password</div>
<div ng-message="server"></div>
</div>
</div>
<!-- SUBMIT -->
<button type="submit" class="btn btn-block btn-success"
ng-disabled="loginForm.$invalid">Log in</button>
</form>
</div>
</div>
web.xml
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<servlet>
<servlet-name>REST</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.damienfremont.blog.MyAppCONFIG</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>org.glassfish.jersey.media.multipart.MultiPartFeature</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>REST</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>WEBJARS</servlet-name>
<servlet-class>org.webjars.servlet.WebjarsServlet</servlet-class>
<init-param>
<param-name>disableCache</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>WEBJARS</servlet-name>
<url-pattern>/webjars/*</url-pattern>
</servlet-mapping>
</web-app>
Project
https://github.com/DamienFremont/damienfremont.com-blog-labs/tree/master/20151119-javaee-angularjs-bootstrap-auth_basic https://github.com/DamienFremont/damienfremont.com-blog-labs/tree/master/20151119-javaee-angularjs-bootstrap-auth_basic
References
https://github.com/sahat/satellizer https://github.com/sahat/satellizer
https://github.com/sahat/satellizer/tree/master/examples/client https://github.com/sahat/satellizer/tree/master/examples/client
https://github.com/sahat/satellizer/tree/master/examples/server/java https://github.com/sahat/satellizer/tree/master/examples/server/java
https://hackhands.com/building-instagram-clone-angularjs-satellizer-nodejs-mongodb/ https://hackhands.com/building-instagram-clone-angularjs-satellizer-nodejs-mongodb/
https://github.com/sahat/instagram-hackhands https://github.com/sahat/instagram-hackhands
Origin
https://damienfremont.com/2015/11/19/javaee-angularjs-bootstrap-how-to-authent-basic/