BogoToBogo
  • Home
  • About
  • Big Data
  • Machine Learning
  • AngularJS
  • Python
  • C++
  • go
  • DevOps
  • Kubernetes
  • Algorithms
  • More...
    • Qt 5
    • Linux
    • FFmpeg
    • Matlab
    • Django 1.8
    • Ruby On Rails
    • HTML5 & CSS

Spring-Boot / Spring Security with AngularJS : Part II (Dynamic resource load from Angular) - 2020

Duke 512




Bookmark and Share





bogotobogo.com site search:




Note

This post is a continuation from the previous post: Spring-Boot / Spring Security with AngularJS - Part I.






Create an Angular application

Let's create a file, src/main/resources/static/js/hello.js for our "hello" application. The <script/> at the bottom of our index.html will finds it.

It's a minimal form of Angular JS application, and it looks like this:

angular.module('hello', [])
  .controller('home', function($scope) {
    $scope.greeting = {id: 'xxx', content: 'Hello World!'}
})

The name of the application is "hello" and it has an empty (omitted) "config" and a "controller" called "home".

The "home" controller will be called when we load the "index.html" because as shown below we have decorated the content <div> with ng-controller="home" in our "index.html":

<div ng-controller="home" ng-cloak class="ng-cloak">
  <p>The ID is {{greeting.id}}</p>
  <p>The content is {{greeting.content}}</p>
</div>

Note that $scope is injected into the controller function (Angular does dependency injection by naming convention, and recognizes the names of our function parameters). The $scope is then used inside the function to set up content and behavior for the UI elements that this controller is responsible for.

The greeting is rendered by Angular in the HTML using the placeholders, {{greeting.id}} and {{greeting.content}}.

Notice that our index.html can now recognize the greeting and it's id and content thanks to the $scope injection.

hello-js-tree.png


Minor changes to binding

To make our code more clear, let's make two modifications to our codes.

Personally, I do not completely agree with this modification since I've been using Angular the way before this changes. But let's modify our codes as recommended by spring.io.

index.html

From:

<body ng-app="hello">
  <div class="container">
    <h1>Greeting</h1>
    <div ng-controller="home" ng-cloak class="ng-cloak">
      <p>The ID is {{greeting.id}}</p>
      <p>The content is {{greeting.content}}</p>
    </div>
  </div>
  <script src="js/angular-bootstrap.js" type="text/javascript"></script>
  <script src="js/hello.js"></script>
</body>

To:

<body ng-app="hello">
  <div class="container">
    <h1>Greeting</h1>
    <div ng-controller="home as home" ng-cloak class="ng-cloak">
      <p>The ID is {{home.greeting.id}}</p>
      <p>The content is {{home.greeting.content}}</p>
    </div>
  </div>
  <script src="js/angular-bootstrap.js" type="text/javascript"></script>
  <script src="js/hello.js"></script>
</body>

Note that we explicitly declared a namespace for the controller, and use the controller instance itself, rather than using the implicit $scope when we bind in the UI.

Another file to change is hello.js

From:

angular.module('hello', [])
  .controller('home', function($scope) {
    $scope.greeting = {id: 'xxx', content: 'Hello World!'}
})

To:

angular.module('hello', [])
  .controller('home', function() {
    this.greeting = {id: 'xxx', content: 'Hello World!'}
})

As we can see from the client code above, we also changed the binding the greeting to the controller (using this) instead of to $scope.





Dynamic content

Let's look into our hello.js code:

angular.module('hello', [])
  .controller('home', function($scope) {
    $scope.greeting = {id: 'xxx', content: 'Hello World!'}
})

As we can see, the greeting is hard coded. However, we expect content to come from a backend server, so we need to create an HTTP endpoint that we can use to grab a greeting.

In our application class, src/main/java/com/example/DemoApplication.java), add the @RestController annotation and define a new @RequestMapping:

From:

package com.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {

        public static void main(String[] args) {
                SpringApplication.run(DemoApplication.class, args);
        }
}

To:

package com.example;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

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("/resource")
  public Map<String,Object> home() {
    Map<String,Object> model = new HashMap<String,Object>();
    model.put("id", UUID.randomUUID().toString());
    model.put("content", "Hello World");
    return model;
  }

  public static void main(String[] args) {
    SpringApplication.run(DemoApplication.class, args);
  }

}

Note that we added the @RestController annotation and define a new @RequestMapping.

Let's run the app:

$ mvn spring-boot:run

Then, we'll get the following response:

ResourceRequest.png

If we try to check the response using curl, we will see that it is secure by default:

$ curl localhost:8080/resource
{"timestamp":1456870221658,"status":401,"error":"Unauthorized","message":"Full authentication is required to access this resource","path":"/resource"}




Loading a Dynamic Resource from Angular

Let's modify the home controller (hello.js) to load the protected resource using XMLHttpRequest (XHR).

From:

angular.module('hello', [])
  .controller('home', function() {
    this.greeting = {id: 'xxx', content: 'Hello World!'}
})

To:

angular.module('hello', [])
  .controller('home', function($http) {
  var self = this;
  $http.get('/resource/').success(function(data) {
    self.greeting = data;
  })
});

We injected an $http service, which is provided by Angular as a core feature, and used it to GET our resource. Angular passes us the JSON from the response body back to a callback function on success.

Run the application again (or just reload the home page in the browser):

$ mvn spring-boot:run
AngularGrabResponse.png

We can see the dynamic message with its unique ID.

Even though the resource is protected and we can't curl it directly, the browser was able to access the content.





Requests and Responses

Here is the table showing the requests and responses:

Verb Path Status Response
GET / 401 Browser prompts for authentication
GET / 200 index.html
GET /css/angular-bootstrap.css 200 Twitter bootstrap CSS
GET /js/angular-bootstrap.js 200 Bootstrap and Angular JS
GET /js/hello.js 200 Application logic
GET /resource 200 JSON greeting

Note that:

  1. We may not see the 401 because the browser treats the home page load as a single interaction.
  2. We may see 2 requests for "/resource" because there is a CORS negotiation.

Look more closely at the requests and we can see that all of them have an "Authorization" header, something like the one that's being highlighted:

Auth-header.png



Form-based authentication

In the next post in this series, we will extend the application to use form-based.

Continued to Spring-Boot / Spring Security with AngularJS : Part III (Form-based Authentication) .










Ph.D. / Golden Gate Ave, San Francisco / Seoul National Univ / Carnegie Mellon / UC Berkeley / DevOps / Deep Learning / Visualization

YouTubeMy YouTube channel

Sponsor Open Source development activities and free contents for everyone.

Thank you.

- K Hong







Spring Boot



Spring Boot : Hello world with Mavan 3

Spring Boot : Hello world with Gradle 2

Spring Boot (Gradle 2) : Hello world with Authentication

Spring Boot : Deploying War file to Tomcat 8's webapps

How to Setup Apache as Reverse Proxy for Tomcat Server using mod proxy

Maven : mvn command cheat sheet

Spring-Boot REST API with CORS App Maven war file deploy to Tomcat

Spring-Boot / Spring Security with AngularJS - Part I (Introduction)

Spring-Boot / Spring Security with AngularJS - Part II (Dynamic resource load from Angular)

Spring-Boot / Spring Security with AngularJS : Part III (Form-based Authentication)




Sponsor Open Source development activities and free contents for everyone.

Thank you.

- K Hong







Java Tutorials



Java Tutorial Home

Basics - Compiling and Launching

Inner Classes

Constructor

Enums

Static & Finally

Default and Protected

Polymorphism

Exception Handling

Exception Handling II

String Class

Threads

Threads II - State Transition

Threads III - Synchronization

Object Class

File I/O

Serialization

ArrayList

Autoboxing

Java Graphics Interface I - Basics

Java Graphics Interface II - Labels, Text Fields, Layouts

Java Graphics Interface III - paintComponent

TCP Sockets Server/Client

Scala - Functional Java Programming

Apache CXF install

Tomcat 7 Ubuntu 14 Install on Amazon EC2 instance

What is Apache Maven?

Maven life cycle

Eclipse Maven 3 plugin on Ubuntu 14.04

Apache Maven 3 - Setting up and creating a project

Apache Maven 3 - Compile, build, and install a Maven project

Apache Maven 3 - Dependencies

Apache Maven 3 - Web Application

Apache Maven 3 - Plugins (compiler)

Apache Maven 3 - Plugins (Jetty)

Eclipse CDT / JNI (Java Native Interface) / MinGW



Spring Framework

Hello World App with Spring 4 & Maven 3 - Part I





JUnit & Maven Tutorial



JUnit 4 Introduction (Hello World)

JUnit 4 Test with Eclipse Luna (Hello World)

JUnit 4 Test with Maven (Hello World)











Contact

BogoToBogo
contactus@bogotobogo.com

Follow Bogotobogo

About Us

contactus@bogotobogo.com

YouTubeMy YouTube channel
Pacific Ave, San Francisco, CA 94115

Pacific Ave, San Francisco, CA 94115

Copyright © 2024, bogotobogo
Design: Web Master