Java Spring Boot in Farsi

ویدئوهای توصیفی جاوا اسپرینگ بوت

فیلم های توصیفی زیر از پروژه ها ی جاوا اسپرینگ بوت استفاده می کنند تا مثال ها را نشان دهند. یکی از اصلی ترین پروژه ها، پروژه ی زیر هست که به صورت فایل زیپ قابل دانلود است و قابل تطبیق با توضیحات است.

Download WorkSuggest Project version 1.9 — Zip file

Video 1 — ویدئوی اول

About Java Spring Boot using an interface

Overview:

– create Controller, include URLs including REST endpoints
using @GetMapping, @PostMapping, @DeleteMapping, @PutMapping
– creat right packages
(common ones are entity, repository, service, controller)
– create an interface
(in this application we have 3 interfaces
one for database interactions,
one for booking, and one for booking service)

interface includes the name and type of methods
you will implement in a class

Video 2 — ویدئوی دوم

Spring CRUD and SQL interactions

Overview:

CrudRepository: Simplification of Create-Read-Update-Delete interactions

<S extends T> save(S entity) – Used to save a single entity at a time.
Iterable<S> saveAll(Iterable<S> entities) – we can save multiple entities at a time.
Optional<T> findById(ID id) – use to get entity basis of id.
boolean existsById(ID id) – used to check whether an entity is already exited in DB for given Id.
Iterable<T> findAll() – find all entity of paricular type.
Iterable<T> findAllById(Iterable<ID> ids) – return all entity of given ids.
long count() – returns the number of entities
void deleteById(ID id) – delete the entity on basis of id
void delete(T entity) – delete the entity which one we are passing.
void delete(Iterable<? extends T> entities) – delete multiple entities which we are passing.
void deleteAll() – delete all entities.

(source: https://www.netsurfingzone.com/jpa/crudrepository-methods-example/ )

@Repository

@Transactional(readOnly = true)
enabling update and insert

@Modifying (see the class TaskStatusRepository.java)

Video 3 — ویدئوی سوم

Database Tables And The Respective Entities In Java Spring Boot

Overview:

We create a database table and define its columns as variables in the entity

Entities represent database tables

These are entities that we have in our Java Spring Boot application.
They will have services and repositoies associated with them.

A set of annotations clarify the class, including Lombok annotations.
The @Entity annotation is important

The @Table(name=”tablename”) is an example of an annotation to give
tablename.

The @Id annotation defines the id field

The @GeneratedValue annotation may be applied to a primary key property

We can define the relationship between tables using
@ManyToOne, @OneToMany, and @ManyToMany annotations.

 

Video 4 — ویدئوی چهارم

One To Many relation description

Overview:

– ٍExample: Task and TaskStatus. One task, many task statuses
– See in the database the foreign key relation
available in TaskStatus table

Example:

– Task.java
@OneToMany(mappedBy = “task”, cascade = CascadeType.ALL)
private Set<TaskStatus> taskStatuses;

– TaskStatus.java
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = “task_id”)
private Task task;

CascadeType
cascade = CascadeType.ALL
https://www.baeldung.com/jpa-cascade-types

FetchType
fetch = FetchType.LAZY
https://www.baeldung.com/hibernate-lazy-eager-loading

Video 5 — ویدئوی پنجم

Many To Many relation description

Overview:

– ٍExample: Task and Person.
One task, many persons
One person, many tasks

– join table is the name of the two tables concatenated with _

– person side is owning side. has @JoinTable annotation

– https://stackoverflow.com/questions/36803306/should-jointable-be-specified-in-both-sides-of-a-manytomany-relationship

– should add on owning side

Video 6 — ویدئوی ششم

Thymeleaf basics

Overview:

– Java EE templating possible with JSP, JSF (used to be in focus)
– Templating is a focus with Java EE, Java Spring Boot
– Thymeleaf: reviewing: https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html
– the generalities in an application:
<html xmlns:th=”http://www.thymeleaf.org”>
<p th:text=”#{home.welcome}”>Welcome to our grocery store!</p>
– fragments, variables, iterations, if statements, html tag values

– have fragments
fragment:
<div th:fragment=”adminDetailBar”…
use it:
<div th:insert=”fragments/general.html :: adminDetailBar” >This was admin bar</div>
<div th:replace=”fragments/header.html :: header-css”/>

th:insert is the simplest: it will simply insert the specified fragment as the body of its host tag.

th:replace actually replaces its host tag with the specified fragment.

th:include is similar to th:insert, but instead of inserting the fragment it only inserts the contents of this fragment.

– if-statements
<div th:if=”${user.isAdmin()} == false”> …

– variables
th:text=”${message}
@{${baseURL} + ‘/admin’}

– iteration
<tr class=”dataRow” th:each=”iter : ${worksuggests}”>
<td th:text=”${iter.worksuggest_id}”>id</td>
<td><a th:href=”@{${baseURL} + ‘/admin/worksuggestlist/’ + ${iter.worksuggest_id} + ‘/remove/’ }”

– switch statements
<div th:switch=”${user.role}”>
<p th:case=”‘admin'”>User is an administrator</p>
<p th:case=”#{roles.manager}”>User is a manager</p>
</div>

– th:value, th:text, … (see section 5.2 Setting value to specific attributes)

<select name=”worksuggestlistid”>
<option value=”” text=”Select the Work Suggestion List for this task” selected=”selected”></option>
<option th:each=”iter : ${worksuggests}”
th:value=”${iter.worksuggest_id}”
th:text=”${iter.title}”></option>
</select>

Video 7 — ویدئوی هفتم

Description for several parts of Spring Boot Security

Overview:

pom.xml file

dependencies

Spring Security is a Spring Framework feature

error handler implements AccessDeniedHandler

UserDetailsService features among others
User, UserDetails

AuthenticationSuccessHandler

WebSecurityConfigurerAdapter

Video 8 — ویدئوی هشتم

Spring Boot Security with basic DataSource

Overview:

Spring Boot makes Java app development easy for the web

A set of jar files — dependencies

test dependecies, application server dependecy (usually minimized in Spring Boot), usual dep.

here: mysql dependency, spring-boot-starter-security, //spring boot starter data jpa

a series of useful classes as autowires

ConfigureAuthentication
configure (WebSecurity web)
configure (HttpSecurity http)
configureGlobal

NoOpPasswordEncoder — various password encoders

now to log-in there will be credential check that comes from db

application.properties has db detail

which tables? authorities, users;

let’s see the database

see users…

log in

example tutorials. keywords: jdbc authentication in Spring Boot

Video 9 — ویدئوی نهم

Spring Boot Session with Redis

Overview:

– Session: keeping user detail while user interacts with our application
– set redis as datasource via application.properties
– download Redis, start its server otherwise Spring Boot can’t connect
– See Redis folder structure
– start redis-server.exe
redis-server.exe –maxheap 1024M
– start redis CLI

http://localhost:3306/
http://localhost:6379/
http://localhost:8080/

JavaInUse example

HttpSession variable as argument in main URL
session.getAttribute

HttpServletRequest
in persistMessage URL
request.getSession.setAttribute

also in URL for destroying the session

demo and the controller
http://localhost:8080/package1_war_exploded/

Video 10 — ویدئوی دهم

using BCrypt in Spring Boot

Overview:

============== SpringSecurityConfig file ============
SpringSecurityConfig has a configure method that takes in auth with the class
AuthenticationManagerBuilder.
It sets the auth’s authenticationProvider to use authProvider

authProvider itself is a bean of type DaoAuthenitcationProvider.

The bean authProvider is of type DaoAuthenticationProvider which is using the passwordEncoder.
It also uses a UserDetailsService

PasswordEncoder is set in the SpringSecurityConfig. It is set to return BCryptPasswordEncoder

PasswordEncoder is autowired in UsersService

User Service:
We can work with User Service which has several User interaction methods.
One of these is “saveUser”. Here in this method we can save our userpasswords with the password encoder
if we include it in our User Service class ile.
saveUser in UsersService uses the passwordEncoder (throught Autowire) to encode and set the password

User Entity:
Users entities has username, password, enabled.

whereever we need to interact with the user such as in UserService’s saveUsers we save with encyrption

for reading the password we just pass in password as is in database
in the user builder in userDetailsServiceImpl

=========== userDetailsServiceImpl ============
builder is spring based. Therefore its password field works with the encrypted password that we pass in

we are returning userDetailsService implementation as an autowire that works in
the SpringSecurityConfig and the DaoAuthenticationProvider.

Video 11 — ویدئوی یازدهم

Spring Boot Angular app description

Overview:

Angular – Interactions: drag and drop

Spring Boot:
Entities: database table structures
Repositories: interactions with the database
Services: contact between (interactions with database) and the user requests (controller)

returning JSON format results

demo of RESTpoints

Submit value to backend using POST

Submitting to backend. The response type is set to <any> so it handle any properties returned in the response.

   this.http.post<any>('http://localhost:8080/getCustomerOrder', { name: 'Angular POST Request Example' }).subscribe(data => {
    console.log("- data id" + data.id);
 

Full example can be found at:

https://jasonwatmore.com/post/2019/11/21/angular-http-post-request-examples

Output variable from one component and receive by other component

This can be done through parent-child component relation. The child component will emit a value using EventEmitter. When adding the child component to a parent component’s template, the child component will have a binding mentioned which maps the emitting to a function in the parent component.

In the child component:

import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';

//... rest of Component

//inside the Component:
@Output()
  pricechange: EventEmitter<number> = new EventEmitter<number>();
  
//where we want to emit a change:
this.pricechange.emit(Number(getIngPrice));

In the parent component’s html template:

<!-- say we have a component with its name.
It will have pricechange which is emitted by the child component
in brackets, mapped to our function in the parent component-->
 <app-logic30-ingredients (pricechange)="changePrice($event)"></app-logic30-ingredients>

The parent component will have the function that receives the emit:

//a function in the component:

changePrice(priceEvent) {
    //alert("changePrice . got " + priceEvent);
    this.thePrice = this.thePrice + priceEvent;
}

Full example at https://ultimatecourses.com/blog/component-events-event-emitter-output-angular-2

Set and get attributes from HTML templates

Set an attribute by using square brackets, name of attribute, and its value:

<ng-container *ngIf="arrIngredients">
    <div id="ingsBox">  
        <div class="ing"
        id="{{'ing'+ing.id}}"
        [attr.name]="ing.name"
        (click)="toggleClick($event)"
        *ngFor="let ing of arrIngredients;">
            {{ing.name}} <br>
            <!-- {{ing.description}} -->
            <hr>
        </div>
    </div>
</ng-container>

Get it in the components via the getAttribute method, i.e.:

  toggleClick(event) { //example function
    alert(event.target.id);
    alert(event.target.getAttribute("name")); //getting it here.
  }

How to call an http method without the observable in Angular 2

Use .toPromise on the http get. You can then use this returned value in a promise if needed, i.e.:

getIngredient1(id2) {
  return this.http.get<ILogic10Ingredient[]>(
    "http://localhost:8080/logic10_base_ingredients/ingredient/"+id2).toPromise();
}

and:

              this.getIngredient1(this.ingAvailForUpdate).then
                (
                  (data2) => {
                    //alert("ing for: " + this.ingAvailForUpdate + ", " + data2[0].name)
                  }
                  ,
                  (err) => alert("err:" + err.message)
                );

The complete example can be found at https://stackoverflow.com/questions/38781162/how-to-call-an-http-method-without-the-observable-in-angular-2

localStorage and sessionStorage

For saving:

// clicks is the variable containing your value to save
localStorage.setItem('clickCounter', clicks);
// If you want to use the sessionStorage
// sessionStorage.setItem('clickCounter', clicks);

For loading:

const clicks = localStorage.getItem('clickCounter');
// If you want to use the sessionStorage
// const clicks = sessionStorage.getItem('clickCounter');

See https://stackoverflow.com/questions/58500879/implement-session-storage-in-an-angular-8-application for more examples

An archive of some useful Node.js techniques along side Angular

The then() method returns a Promise. It takes up to two arguments: callback functions for the success and failure cases of the Promise.

const promise1 = new Promise((resolve, reject) => {
  resolve('Success!');
});

promise1.then((value) => {
  console.log(value);
  // expected output: "Success!"
});

The Promise.all() method takes an iterable of promises as an input, and returns a single Promise that resolves to an array of the results of the input promises. This returned promise will resolve when all of the input’s promises have resolved, or if the input iterable contains no promises. It rejects immediately upon any of the input promises rejecting or non-promises throwing an error, and will reject with this first rejection message / error.

const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'foo');
});

Promise.all([promise1, promise2, promise3]).then((values) => {
  console.log(values);
});
// expected output: Array [3, 42, "foo"]

If you’re using Promises, check out this

you can just fix this by doing the following:

var promises = [];

for(var numb in req.body)
{
    promises.push(checkValue(numb));
}

Promise.all(promises)    
 .then(function(data){ /* do stuff when success */ })
 .catch(function(err){ /* error handling */ });

function checkValue(numb){
 return new Promise(function(resolve, reject){
  // place here your logic
  // return resolve([result object]) in case of success
  // return reject([error object]) in case of error
});

As jfriend00 said above, if you’re going to develop in node.js, then you MUST become comfortable with writing async code.

“chained promises” is probably your best bet:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then

http://html5hive.org/node-js-quickies-working-with-mysql/

https://medium.com/bb-tutorials-and-thoughts/how-to-develop-and-build-angular-app-with-nodejs-e24c40444421

How To Develop and Build Angular App With NodeJS

https://medium.com/bb-tutorials-and-thoughts/packaging-your-angular-app-with-nodejs-backend-for-production-97eb1b0755aa

Packaging Your Angular App With NodeJS Backend For Production

Promises chaining

  • An example for acces to a MySQL call which we require the results for before returning results to user:
exports.getAllSizeIdsForItem = function (getItemId, callback) {
	sqlQuery = "SELECT size_id FROM logic20_rule WHERE item_id='" + getItemId + "'";
	arrSizeIds=[];
	db.runQuery(sqlQuery, function (getResult1) {
		for (m1=0; m1<getResult1.length; m1++) {
			arrSizeIds.push(getResult1[m1].size_id);
			if (m1==getResult1.length-1) {
				callback (arrSizeIds);
			}
		}
	})
}
exports.getSizeDetails = async function(arrSizeIds, res) {
	getSizeDetails_promises = [];
	for (mc1 = 0; mc1<arrSizeIds.length; mc1++) {	
	  await new Promise(next=> {	
		console.log("- " + mc1);
		sqlQuery = "SELECT * FROM logic20_size WHERE id='" + arrSizeIds[mc1] + "'";
		db.runQuery(sqlQuery, function (getResult1) {
			console.log("- logic10 -- category details");
			getSizeDetails_promises.push (getResult1[0]);
			next();
		})
	  })
	}
	Promise.all(getSizeDetails_promises)
		.then(function(data) {	console.log("done, now sending res with details: " + data);
								res.send(data); })
		.catch(function(err) {  console.log("error in Promise.all..." + err);  });
}
	logic20Service.getAllSizeIdsForItem(theItemId, function(getArrSizeIds) {
	    console.log("getArrSizeIds: " + getArrSizeIds);
	    logic20Service.getSizeDetails(getArrSizeIds, res);
	})
function callback () { console.log('all done'); }

var itemsProcessed = 0;

[1, 2, 3].forEach((item, index, array) => {
  asyncFunction(item, () => {
    itemsProcessed++;
    if(itemsProcessed === array.length) {
      callback();
    }
  });
});

Angular techniques

Here is a list of some Angular techniques, useful when working with Angular applications

Submit value to backend using Post

Output variable from one component and receive by other component

Set and get attributes from HTML templates

How to call an http method without the observable in Angular 2

localStorage and sessionStorage

Subscribe to two observables whose results are needed

Click event

For loop in Angular

Receiving content through http get

Having paramterised routes work

Pass values from one component to another component

Get an incoming JSON object from a URL and work with it in your component

Include a component in another component

Have the application root show component links and the content

Setting up an Angular router

Subscribe to two observables whose results are needed

Use forkJoin to subscribe to more than one observable simultaneously

forkJoin(
  this.service.service1(), this.service.service2(), this.service.service3()
).subscribe((res) => {
  this.funcA(res[0], res[1], res[2]);
});

Another example is:

   forkJoin(
      this.logic10Service.getLogic10(this.item_id),
      this.http.get<ILogic10BaseCategory[]>(this.catsUrl_part1 + this.item_id + this.CatsUrl_part2)
    ).subscribe((res) => {
      console.log("- forkJoin returned " + res[0] + ", and " + res[1]);
      //can start interacting with res[0] and res[1]
      
    })

For more, see https://stackoverflow.com/questions/52317494/is-it-good-way-to-call-subscribe-inside-subscribe

Click event

Call a click event through (click) and call the function that should be initiated. Assuming I have a function in the component called showUpdateables(catName), I can have the following in the html template file:

    <ng-container *ngIf="arrCats">
    <span id="categoryBox" *ngFor="let cat of arrCats;" (click)="showUpdateables(cat.name)">
        {{cat.name}}
    </span>
    </ng-container>