Taogen's Blog

Stay hungry stay foolish.

How to allow CORS requests

To allow CORS requests, You need to add the following headers to your HTTP response

  • Access-Control-Allow-Origin: * or {specific_host}
  • Access-Control-Allow-Methods: POST, GET, PATCH, DELETE, PUT
  • Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, {your_custom_header_name}

If you request with cookie, you need to add another header Access-Control-Allow-Credentials: true to the HTTP response, and the value of Access-Control-Allow-Origin cannot be *.

Optional HTTP response headers for CORS requests:

  • Access-Control-Max-Age: 86400: tell the browser to cache the preflight response.

Note

  • The wildcard * is not supported for the Access-Control-Allow-Headers value.
  • if the value of Access-Control-Allow-Credentials is true, the value of Access-Control-Allow-Origin cannot be *. The Access-Control-Allow-Credentials: true means request with the cookie.

Preflight requests

A CORS preflight request is a CORS request that checks to see if the CORS protocol is understood and a server is aware using specific methods and headers. It is an OPTIONS request, using three HTTP request headers: Access-Control-Request-Method, Access-Control-Request-Headers, and the Origin header. A preflight request is automatically issued by a browser. If the server allows it, then it will respond to the preflight request with an Access-Control-Allow-Methods response header, which lists DELETE or PUT.

Situations that require a preflight request

  • DELETE and PUT requests.
  • Requests with custom headers.

The preflight response can be optionally cached for the requests created in the same URL using Access-Control-Max-Age header. Note that if it is cached, it will not issue a preflight request.

What is SSL Certificate

An SSL Certificate is essentially an X.509 certificate. X.509 is a standard that defines the structure of the certificate. It defines the data fields that should be included in the SSL certificate. X.509 uses a formal language called Abstract Syntax Notation One (ASN.1) to express the certificate’s data structure.

There are different formats of X.509 certificates such as PEM, DER, PKCS#7 and PKCS#12. PEM and PKCS#7 formats use Base64 ASCII encoding while DER and PKCS#12 use binary encoding. The certificate files have different extensions based on the format and encoding they use.

The X.509 Certificate’s encoding formats and file extensions

Web Servers and SSL certificate formats

Tomcat: Keystore (.jks) with PKCS#7 (.p7b) Format

Apache: PEM (.crt+.key)

Nginx: PEM (.pem+.key)

IIS: PKCS#12 (.pfx)

JKS: Keystore

Generate a Self-Signed Certificate

OpenSSL

# interactive
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365
Enter PEM pass phrase: 
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:
Email Address []:
# non-interactive and 10 years expiration
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 3650 -nodes -subj "/C=XX/ST=StateName/L=CityName/O=CompanyName/OU=CompanySectionName/CN=CommonNameOrHostname"

openssl req

PKCS#10 X.509 Certificate Signing Request (CSR) Management.

Required options

  • -x509: Output a x509 structure instead of a cert request (Required by some CA’s)
  • -newkey val: Specify as type:bits. (key algorithm and key size). For example, -newkey rsa:4096
  • -keyout outfile: File to send the key to (private key)
  • -out outfile: Output file (certificate)
  • -days +int: Number of days cert is valid for
  • -*: Any supported digest. For example, -sha256

Optional options

  • -nodes: Don’t encrypt the output key.
  • -subj val: Set or modify request subject. (non-interactive). For example, -subj "/C=XX/ST=StateName/L=CityName/O=CompanyName/OU=CompanySectionName/CN=CommonNameOrHostname"

Extract Public Key From SSL Certificate

OpenSSL

openssl x509 -pubkey -in cert.pem -noout -out public_key.pem

openssl x509

X.509 Certificate Data Management.

Options

  • -pubkey: Output the public key
  • -in infile: Input file - default stdin
  • -out outfile: Output file - default stdout
  • -noout: No output, just status. (Don’t append certificate to output public key file.)

Verify public key and private key

Creating a signed digest of a file:

openssl dgst -sha512 -sign private_key.pem -out digest.sha512 file.txt

Verify a signed digest:

openssl dgst -sha512 -verify public_key.pem -signature digest.sha512 file.txt

Convert SSL certificate formats

OpenSSL

OpenSSL Convert PEM

Convert PEM(.pem) to DER(.der)

openssl x509 -outform der -in certificate.pem -out certificate.der

Convert PEM(.cer) to PKCS#7(.p7b)

openssl crl2pkcs7 -nocrl -certfile certificate.cer -out certificate.p7b -certfile CACert.cer

Convert PEM(.crt) to PKCS#12(.pfx)

openssl pkcs12 -export -out certificate.pfx -inkey privateKey.key -in certificate.crt -certfile CACert.crt

OpenSSL Convert DER

Convert DER(.cer) to PEM(.pem)

openssl x509 -inform der -in certificate.cer -out certificate.pem

OpenSSL Convert P7B

Convert PKCS#7(.p7b) to PEM(.cer)

openssl pkcs7 -print_certs -in certificate.p7b -out certificate.cer

Convert PKCS#7(.p7b) to PKCS#12(.pfx)

openssl pkcs7 -print_certs -in certificate.p7b -out certificate.cer
openssl pkcs12 -export -in certificate.cer -inkey privateKey.key -out certificate.pfx -certfile CACert.cer

OpenSSL Convert PFX

Convert PKCS#12(.pfx) to PEM(.cer)

openssl pkcs12 -in certificate.pfx -out certificate.cer -nodes

Java Keystore

keytool -genkeypair: to generated a key pair and a self-sign certificate in a keystore file

keytool -genkeypair -keysize 1024 -alias herong_key \
-keypass keypass -keystore herong.jks -storepass jkspass
What is your first and last name?
[Unknown]: Herong Yang
What is the name of your organizational unit?
[Unknown]: Herong Unit
What is the name of your organization?
[Unknown]: Herong Company
What is the name of your City or Locality?
[Unknown]: Herong City
What is the name of your State or Province?
[Unknown]: Herong State
What is the two-letter country code for this unit?
[Unknown]: CA
Is CN=Herong Yang, OU=Herong Unit, O=Herong Company, L=Herong City,
ST=Herong State, C=CA correct?
[no]: yes

Import

-importcert/-import

// Installing the Self-Signed Certificate on the Client
keytool -importcert -alias alias_name -file path_to_certificate_file -keystore truststore_file

-importcert -trustcacerts

// Importing a CA-Signed Certificate
keytool -import -trustcacerts -alias alias_name -file certificate_file -keystore keystore_file

Export

-exportcert/-export: to export the certificate in DER format.

keytool -exportcert -alias herong_key -keypass keypass \
-keystore herong.jks -storepass jkspass -file keytool_crt.der

-exportcert -rfc: to export the certificate in PEM format.

keytool -exportcert -alias herong_key -keypass keypass \
-keystore herong.jks -storepass jkspass -rfc -file keytool_crt.pem

Copy

Move SSL Certificate to another JKS Keystore

"C:\Program Files\Java\jre7\bin\keytool.exe" -importkeystore -srckeystore "D:\source-keystore.jks" -destkeystore "D:\destination-keystore.jks" -srcstorepass password -deststorepass password -srcalias "www.mysecuresite.com"

References

OpenSSL

SSL Certificate

Conversion

Java Keystore

Nginx

Tomcat

Elasticsearch Java API

Java Low Level REST client

  • Since 5.6.x

    <dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-client</artifactId>
    <version>8.10.1</version>
    </dependency>

Java High Level REST Client

  • 5.6.x~7.17.x, Deprecated

    <dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
    <version>7.17.13</version>
    </dependency>

Java Transport Client

  • 5.0.x~7.17.x, Deprecated

    <dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>transport</artifactId>
    <version>7.17.13</version>
    </dependency>

Java API Client

  • Since 7.15.x

  • depends on Low Level REST Client

    <dependency>
    <groupId>co.elastic.clients</groupId>
    <artifactId>elasticsearch-java</artifactId>
    <version>8.10.0</version>
    </dependency>

Query

Basic query

Query DSL

{
"from": 0,
"size": 10,
"sort": [
{
"pub_time": {
"order": "desc"
}
}
],
"query": {
"bool": {
"must": [],
"must_not": [],
"should": []
}
},
"aggs": {
"term_aggregation": {
"terms": {
"field": "category"
}
}
}
}

Java Low Level REST Client

Response performRequest(String method, String endpoint, Map<String, String> params, HttpEntity entity, Header... headers)

Java High Level REST Client

SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
queryBuilder.must(xxx);
queryBuilder.mustNot(xxx);
queryBuilder.should(xxx);
searchSourceBuilder.from(0);
searchSourceBuilder.size(10);
searchSourceBuilder.sort("pub_time", SortOrder.DESC);
searchSourceBuilder.query(queryBuilder);
searchSourceBuilder.aggregation(
AggregationBuilders.terms("term_aggregation")
.field("category")
);
SearchRequest searchRequest = new SearchRequest("indexName");
searchRequest.source(searchSourceBuilder);
// Print DSL query
// System.out.println(searchRequest.source().toString())
SearchResponse searchResponse = restHighLevelClient.search(searchRequest);

Java API Client

// When your index contains semi-structured data or if you don’t have a domain object definition, you can also read the document as raw JSON data. You can use Jackson’s ObjectNode or any JSON representation that can be deserialized by the JSON mapper associated to the ElasticsearchClient.  
SearchResponse<ObjectNode> response = client.search(s -> s
.index("indexName")
.from(0)
.size(10)
.sort(so -> so
.field(FieldSort.of(f -> f
.field("pub_time")
.order(SortOrder.Desc))
)
)
.query(q -> q
.bool(b -> b
.must(m -> m.term(t -> t
.field("name")
.value("value")
))
)
)
.aggregations("term_aggregation", a -> a
.terms(t -> t.field("category"))
),
ObjectNode.class
);

Specify query fields

Query DSL

{
"_source": ["author", "host"],
"query": {}
}

Java High Level REST Client

searchSourceBuilder.fetchSource(new String[]{"author", "host"}, null);

Query by id

Query DSL

GET /my_index/{document_id}
// or
GET /my_index/{doc_type}/{document_id}

Java High Level REST Client

GetRequest getRequest = new GetRequest(indexName).id(id);
GetResponse getResponse = restHighLevelClient.get(getRequest);

Query by ids

Query DSL

GET /my_index/_search
{
"query":{
"ids": {
"values": ["202308227d464b3da5b01f966458cafa", "20230822dfc84f58b7c8243013da3063"]
}
}
}

Conditions

wildcard

Query DSL

{
"wildcard": {
"ip_region": "*山东*"
}
}

Java High Level REST Client

WildcardQueryBuilder ipRegionQuery = QueryBuilders.wildcardQuery("ip_region", "*山东*");

Logical Operation

must/must_not

{
"bool": {
"must": [
{
"match_phrase": {
"title": "医院"
}
}
]
}
}

Java High Level REST Client

BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(QueryBuilders.matchPhraseQuery("title", "医院"));

should

Query DSL

{
"bool": {
"should": [
{
"match_phrase": {
"title": "医院"
}
},
{
"match_phrase": {
"content": "医院"
}
}
],
"minimum_should_match": 1
}
}

Java High Level REST Client

BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.minimumShouldMatch(1);
boolQueryBuilder.should(QueryBuilders.matchPhraseQuery("title", "医院"));
boolQueryBuilder.should(QueryBuilders.matchPhraseQuery("content", "医院"));

Aggregation

terms

Query DSL

{
"aggs": {
"term_aggregation": {
"terms": {
"field": "category"
}
}
}
}

Java High Level REST Client

searchSourceBuilder.aggregation(
AggregationBuilders.terms("term_aggregation")
.field("category")
);

Elasticsearch no longer recommend using the scroll API for deep pagination. If you need to preserve the index state while paging through more than 10,000 hits, use the search_after parameter with a point in time (PIT).

In order to use scrolling, the initial search request should specify the scroll parameter in the query string, which tells Elasticsearch how long it should keep the “search context” alive (see Keeping the search context alive), eg ?scroll=1m.

The size parameter allows you to configure the maximum number of hits to be returned with each batch of results. Each call to the scroll API returns the next batch of results until there are no more results left to return, ie the hits array is empty.

POST /my-index-000001/_search?scroll=1m
{
"size": 100,
"query": {
"match": {
"message": "foo"
}
}
}

The result from the above request includes a _scroll_id, which should be passed to the scroll API in order to retrieve the next batch of results.

POST /_search/scroll                                                               
{
"scroll" : "1m",
"scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAD4WYm9laVYtZndUQlNsdDcwakFMNjU1QQ=="
}

Update

Update by document ID

Using doc - to update multiple fields at once

POST /my_index/_doc/{document_id}/_update
{
"doc": {
"field1": "updated_value1",
"field2": "updated_value2"
}
}

Using script

POST /my_index/_doc/{document_id}/_update
{
"script": {
"source": "ctx._source.field_name = params.new_value",
"lang": "painless",
"params": {
"new_value": "updated_value"
}
}
}

Java High Level REST Client

// Create an instance of the UpdateRequest class
UpdateRequest request = new UpdateRequest("your_index", "your_type", "your_id");

// Prepare the update request
Map<String, Object> updatedFields = new HashMap<>();
updatedFields.put("field1", "updated value");
updatedFields.put("field2", "another updated value");
request.doc(updatedFields);

// Execute the update request
UpdateResponse response = client.update(request, RequestOptions.DEFAULT);

// Check the response status
if (response.status() == RestStatus.OK) {
System.out.println("Document updated successfully");
} else {
System.out.println("Failed to update document: " + response.status().name());
}

Update by document ids

Query DSL

POST /your-index/_update_by_query
{
"query":{
"ids": {
"values": ["xxx", "xxx"]
}
},
"script": {
"source": "ctx._source.field_name = 'updated-value'"
}
}

Java High Level REST Client

for (String id : ids) {
XContentBuilder contentBuilder = XContentFactory.jsonBuilder()
.startObject()
.field("status", "0") // update stauts to "0"
.endObject();

UpdateRequest updateRequest = new UpdateRequest(indexName, "data", id)
.doc(contentBuilder);

bulkRequest.add(updateRequest);
}

BulkResponse bulkResponse = dxRestHighLevelClient.bulk(bulkRequest);

if (bulkResponse.hasFailures()) {
System.out.println("has failures");
// Handle failure cases
} else {
// Handle success cases
}

Update by query

Query DSL

POST /your-index/_update_by_query
{
"query": {
"term": {
"field": "value"
}
},
"script": {
"source": "ctx._source.field = 'updated-value'"
}
}

Development of new software products

Build the basic framework of the project.

Developing new features for existing applications. (refer to the corresponding section)

Note: Development of new software product require a lot of time to optimize the user experience and requirements. Therefore, a lot of code modifications are also required.

Developing new features for existing applications

Functional modules

Understand the software requirements.

Design data models and databases.

API design.

Detailed design.

Write unit tests and code.

Test and Fix bugs.

Modify the code due to the modification of the requirements.

Test and Fix bugs.

Data analysis modules

Understand the software requirements.

Write query statements (SQL, Elasticsearch DSL) for data statistics.

Merge query statements to reduce the number of queries.

API design.

Write the code. Define the data query and response objects and finish the code.

Test and Fix bugs.

Scheduled Tasks

Small functions

Understand the software requirements.

Modify data models and databases. (optional)

API design. (optional)

Detailed design.

Write unit tests and code.

Test and Fix bugs.

Modification of system functionality

Understand the software requirements.

Modify data models and databases. (optional)

Modify API. (optional)

Detailed design.

Modify unit tests and code.

Test and Fix bugs.

Performance Optimization

Positioning problem

Try to find the tuning approach

Software product customization (new features and modifications)

Developing new features for existing applications. (refer to the corresponding section)

Modification of system functionality. (refer to the corresponding section)

Maintain systems and miscellaneous

System troubleshooting and fixing errors.

Update data.

Import data.

Export data.

Third party service renewal.

Integrating Code Libraries

Integrating Third-Party Service API or SDK

Common third-party services

  • Cloud platform
    • Storage
      • OSS
    • AI + Machine Learning
      • OCR
    • Media
      • Intelligent Media Services
  • Payment. E.g. Alipay.
  • Mobile Push notifications. E.g. Jiguang, Getui.
  • Short Message Service (SMS)
  • Social. E.g. QQ, WeChat, and Dingtalk open platform, Twitter Developer Platform, Slack API.

Providing APIs to Third-Party

Sometimes we need to redirect to our other websites without login again. In addition to single sign-on, we can also add a URL parameter to achieve automatic login.

The Process of Login By URL Parameters

The frontend requests the backend API to get the loginSign string for setting the redirect URL parameters. The redirect URL like https://xxx.com/xxx?loginSign=xxx

The backend constructs the loginSign value

  • Query the redirected website username and password.
  • Generate a random string.
  • Get the current timestamp.
  • Use the RSA public key to encrypt the username, password, timestamp, randomStr.

Return the loginSign value to frontend.

The client user clicks the redirect URL.

When the target website frontend checks that the loginSign parameter appears on the web page URL, it uses this parameter to request login automatically.

The target website backend decrypts the loginSign value, and checks the username and the password. If they are correct returns an access token, otherwise, returns an error code.

Construct the URL Parameter loginSign

Add a newline \n (ASCII 0x0A) to the end of each parameter.

username\n
password\n
timestamp\n
randomStr\n
  • timestamp: the request timestamp.

Use the RSA public key to encrypt the string {username}\n{password}\n{timestamp}\n{randomStr}\n

Verify the URL Parameter loginSign

Use the RSA private key to decrypt the loginSign value.

Verify the request timestamp if it’s within 60 seconds of the current time.

Verify the username and password.

Content

  • Types, Values, and Variables
  • Expression, Statement, Functions
  • Objects, Classes
  • Arrays
  • Sync
  • JavaScript in Web Browsers
  • Modules

Expression

Invocation Expressions

Conditional Invocation

let result = json?.name;
let result = json != null ? json.name : undefined;

Null Check

if a != null return a, else return default value

// Ternary Operator
let result = a != null ? a : defaultValue;
// Logical Operator ||
// When it's used with non-boolean values, the || operator will return a non-boolean value of one of the specified expression or operands.
let result = a || defaultValue;
// Nullish Coalescing Operator ??
let result = a ?? defaultValue;

2

if a != null and b != null return b; else return null;

let result = a != null && a.name != null ? a.name : null;
let result = a && a.name;

Statement

For Loop

for (let i = 0; i < arr.length; ++i)
arr.forEach((value, index) => { /* ... */ })
for (let index in arr)
for (const value of arr)

console.log(obj1 [, obj2, ..., objN]);

console.log(obj)
console.log(obj1, obj2)
console.log("obj is: ", obj)
console.log("obj is: ", obj, ". And my name is ", name)
console.log("objects are: ", obj1, obj2)
console.log("obj is: " + JSON.parse(JSON.stringify(obj)))

console.log(msg [, subst1, ..., substN]);

  • %o or %O Outputs a JavaScript object.
  • %d or %i Outputs an integer.
  • %s Outputs a string.
  • %f Outputs a floating-point value.
console.log("obj is %o", obj)
console.log("Hello, %s. You've called me %d times.", "Bob", 1);

Object

Merge object fields

let json1 = {"name": "Jack"};
let json2 = {
...json1,
age: 18
};

Deep copy

let json = {"name": "Jack"};
let copy = JSON.parse(JSON.stringify(json));

Get all keys of JSON/JavaScript object

const obj = {a: 'somestring', b: 123, c: false};
Object.keys(obj);

Get all values of JSON/JavaScript object

const obj = {a: 'somestring', b: 123, c: false};
Object.values(obj);
// ES6
const obj = {a: 'somestring', b: 123, c: false};
Object.keys(obj).map(key => obj[key]);

Traversing JavaScript Object

for-in

// iterates over all enumerable properties of an object.
const jsonObj = {name: "Jack", age: 18}
for (const key in jsonObj) {
console.log(`${key}: ${jsonObj[key]}`);
}

Object.entries() or Object.keys()

// to traverse a Javascript object
const jsonObj = {name: "Jack", age: 18}
Object.entries(jsonObj).forEach(([key, value]) => {
console.log(key, value)
});
Object.keys(obj).forEach(function(key) {
var value = obj[key];
// ...
});

to include non-enumerable properties

Object.getOwnPropertyNames(obj).forEach(function(key) {
var value = obj[key];
// ...
});

Array

Traversal

for (let i = 0; i < arr.length; ++i)
arr.forEach((value, index) => { /* ... */ })
for (let index in arr)
for (const value of arr)

forEach: executes a provided function once for each array element. another type of for loop.

NOTE: The forEach loop is another type of for loop in JavaScript. However, forEach() is actually an array method, so it can only be used exclusively with arrays. There is also no way to stop or break a forEach loop. If you need that type of behavior in your loop, you’ll have to use a basic for loop.

const array1 = ['a', 'b', 'c'];
array1.forEach(element => console.log(element));

for in: iterates over all enumerable properties of an object. E.g. key of JSON object, index of array.

const object = { a: 1, b: 2, c: 3 };

for (const property in object) {
console.log(`${property}: ${object[property]}`);
}

for of: The for...of statement creates a loop iterating over iterable objects, including: built-in String, Array, array-like objects (e.g., arguments or NodeList), TypedArray, Map, Set, and user-defined iterables.

const array1 = ['a', 'b', 'c'];

for (const element of array1) {
console.log(element);
}
for (const [idx, el] of arr.entries()) {
console.log( idx + ': ' + el );
}

Summary

If you don’t need break for loop use forEach, else use for of.

Find Max in an array

Find max value in an array

// apply
const array = [{name: "a", value: 1}, {nama: "b", value: 2}]
Math.max.apply(Math, array.map(o => o.value));

const array = [1,2,3,5,1,2]
Math.max.apply(Math, array);
// ES6 spread
const array = [{name: "a", value: 1}, {nama: "b", value: 2}]
Math.max(...array.map(o => o.value));

const array = [1,2,3,5,1,2]
Math.max(...array);
// standard loop
let max = testArray[0];
for (let i = 1; i < testArrayLength; ++i) {
if (testArray[i] > max) {
max = testArray[i];
}
}
// reduce
const array = [{name: "a", value: 1}, {nama: "b", value: 2}]
array.reduce((a, b) => Math.max(a.value, b.value));

const array = [1,2,3,5,1,2]
array.reduce((a, b) => Math.max(a, b));

Time cost: standard loop < ES6 spread and apply < reduce

Finding the max value of an attribute in an array of objects

// reduce
const array = [{name: "a", value: 1}, {nama: "b", value: 2}]
const maxValueObject = array.reduce((prev, current) => (prev.value > current.value) ? prev : current)

Convert type of elements of Array

int array to string array

// This will not mutate array. It will return a new array.
let array = [1, 2, 3];
let newArray = array.map(String);
let array = [1, 2, 3];
let newArray = array.map(item => item.toString())
let array = [1, 2, 3];
let newArray = array.join(",").split(",");

string array to int array

// Note: For older browsers that don't support map
let array = ['1', '2', '3'];
let newArray = array.map(Number); // i=>Number(i)
let array = ['1', '2', '3'];
let newArray = array.map(item => parseInt(item));
let array = ['1', '2', '3'];
let newArray = Array.from(array, Number);

Request

URL Parameters

Getting URL parameters

// https://example.com/?id=1
const queryString = window.location.search;
console.log(queryString); // ?id=1
const urlParams = new URLSearchParams(queryString);
const id = urlParams.get('id');
console.log(id); // 1

Checking for the Presence of a Parameter

console.log(urlParams.has('id')); // true

Getting All of a Parameter’s Values

console.log(urlParams.getAll('size'));
// [ 'm' ]

//Programmatically add a second size parameter.
urlParams.append('size', 'xl');

console.log(urlParams.getAll('size'));
// [ 'm', 'xl' ]

Iterating over Parameters

const
keys = urlParams.keys(),
values = urlParams.values(),
entries = urlParams.entries();

for (const key of keys) console.log(key);
// product, color, newuser, size

for (const value of values) console.log(value);
// shirt, blue, , m

for(const entry of entries) {
console.log(`${entry[0]}: ${entry[1]}`);
}

Document

Remove Elements

remove element by id

document.querySelector("#remove").remove();

remove elements by class name

function removeElementsByClass(className){
const elements = document.getElementsByClassName(className);
while(elements.length > 0){
elements[0].parentNode.removeChild(elements[0]);
}
}
const removeElementsByClass = (className) => document.querySelectorAll(className).forEach(el => el.remove());

Empty Elements

empty element by id

document.querySelector("#remove").innerHTML = "";

empty elements by class name

const emptyElementsByClass = (className) => document.querySelectorAll(className).forEach(el => el.innerHTML = "");

Regular Expression

RegExp

// creating regular expression from a string, you have to double-up your backslashes \\.
const regex = new RegExp('^\\d{10}$');
const regex = new RegExp('^\\d{10}$', 'g');

/regex/mod

// if you use regex syntax, you need eacape / by \/
const regex = /^\d{10}$/;
const regex = /^\d{10}$/g;

API

  • RegExp

    • regexp.exec(str) - Returns the first match info array. It likes [matched string, group 1, group 2, ...]. The flag g has no effect.

      /hello(\d)/.exec("hello1, hello2"); // ['hello1', '1', ...]
      /hello(\d)/g.exec("hello1, hello2"); // ['hello1', '1', ...]
    • regexp.test(str) - Returns whether it matches. The flag g has no effect.

      /hello(\d)/.test("hello1, hello2"); // true
      /hello(\d)/g.test("hello1, hello2"); // true
  • String

    • string.match(regexp) - Returns the first match info array [matched string, group 1, group 2, ...], or return an all matched string array [matched string 1, matched string 2, ...] when it uses the flag g.

      let s = "hello1, hello2";
      s.match(/hello(\d)/); // return the first match object ['hello1', '1', ...]
      s.match(/hello(\d)/g); // return all match strings ['hello1', 'hello2']
    • string.matchAll(regexp) - Returns all match info arrays. The regexp must use the flag g (global search).

      let s = "hello1, hello2";
      s.matchAll(/hello(\d)/); // Uncaught TypeError: String.prototype.matchAll called with a non-global RegExp argument
      for (const match of s.matchAll(/hello(\d)/g)) {
      console.log(match); // the match info array
      console.log(match[0]); // the matched string
      console.log(match[1]); // the group 1 of the matched string
      }
    • string.replace(regexp, replacement) - Returns a string with the first or all matched string replaced.

      let s = "hello1, hello2";
      s.replace(/hello(\d)/, 'hey'); // 'hey, hello2'
      s.replace(/hello(\d)/g, 'hey'); // 'hey, hey'
      // replace with group
      let s = "hello1, hello2";
      s.replace(/hello(\d)/, "hi$1"); // 'hi1, hello2'
      s.replace(/hello(\d)/g, "hi$1"); // 'hi1, hi2'
      // extract group
      s.replace(/hello(\d)/g, "$1"); // '1, 2'
    • string.replaceAll(regexp, replacement) - Returns a string with the all matched string replaced. The regexp must use the flag g (global search).

      let s = "hello1, hello2";
      s.replaceAll(/hello(\d)/, 'hey'); // Uncaught TypeError: String.prototype.replaceAll called with a non-global RegExp argument
      s.replaceAll(/hello(\d)/g, 'hey'); // 'hey, hey'
      // replace with group.
      // replaceAll(/xxx/g, '') results are same with replace(/xxx/g, '')
      s.replaceAll(/hello(\d)/g, "hi$1"); // 'hi1, hi2'
      s.replaceAll(/hello(\d)/g, "$1"); // '1, 2'
    • string.search(regexp)

    • string.split(regexp)

Flags

Flag Description Corresponding property
d Generate indices for substring matches. hasIndices
g Global search. global
i Case-insensitive search. ignoreCase
m Allows ^ and $ to match newline characters. multiline
s Allows . to match newline characters. dotAll
u “Unicode”; treat a pattern as a sequence of Unicode code points. unicode
v An upgrade to the u mode with more Unicode features. unicodeSets
y Perform a “sticky” search that matches starting at the current position in the target string. sticky

Match emoji unicode

const text = "Hello, 😀🚀🌎!";
const emojiRegex = /\p{Emoji}/gu;
const emojis = text.match(emojiRegex);

console.log(emojis); // ['😀', '🚀', '🌎']

Make sure to use the u flag at the end of the regex pattern (/.../u) to enable Unicode mode, which is necessary when working with Unicode property escapes.

References

Single sign-on (SSO) is an authentication method that allows users to sign in using one set of credentials to multiple independent software systems.

Implementations of single sign-on:

  • Cookie-based
  • Session-based
  • Central Authentication Service (CAS)

It works by using web based HTTP cookies to transport user credentials from browser to server without from the user. Credentials on the client machine are gathered and encrypted before it being stored in the cookie.

Once the user enters the username and password in any subsystem, the user credentials will be stored in cookie, which is shared by multiple subsystems and automatically sent to the server.

The domain name of each system using cookie-based SSO should be the same or have the same top-level domain name. So user credentials in cookie can be shared between multiple systems.

Advantages

  • Easy to implement.

Disadvantages

  • Can’t cross domain.

Session-Based SSO

It works by using web based HTTP cookies to transport user authentication token.

The user token is stored in the client browser and sent to the server as session value. session values and user ID are stored in a cache like Redis shared across subsystems. Each subsystem checks the user from the cache by the token in the HTTP request cookie.

Advantages

  • Suitable for distributed system applications.

Disadvantages

  • Can’t cross domain.

Central Authentication Service (CAS)

When the user accesses the application system for the first time, since he has not logged in, he is directed to the authentication system to log in. The authentication system accepts security information such as user name and password, and generates an access token (ticket). The user accesses the application system through the ticket. After receiving the request, the application system will visit the authentication system to check the legitimacy of the ticket. If the check is passed, the user can access the application system resources without logging in again.

Advantages

  • Support cross domain.

Disadvantages

  • Need a an independent authentication system.

Expressions

Divisor is zero

Exception:

java.lang.ArithmeticException

Error code example:

int a = 1;
int b = 0;
int result = a / b;

Suggestion:

You need to check if the divisor is zero.

Statements

Update a collection in for loop (Fail fast)

Exception:

java.lang.UnsupportedOperationException

Error code example:

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6);
for (int i = 0; i < list.size(); i++) {
Integer value = list.get(i);
System.out.println(value);
if (value == 1) {
list.add(100); // or list.remove(0);
}
}

Suggestion:

Do not insert, update, and delete elements of a collection while looping through the collection.

Objects and Classes

Call a null object methods

Exception:

java.lang.NullPointerException

Error code example:

User user = null;
String name = user.getName();

Suggestion:

You need to check if the object is null when calling its methods.

Collections

Add elements to Collections.emptyList()

Exception:

java.lang.UnsupportedOperationException

Error code example:

List<Integer> list = Collections.emptyList();
list.add(1);

Suggestion:

Don’t return Collections.emptyList() in intermediate methods.

Add elements to List built by Arrays.asList()

Exception:

java.lang.UnsupportedOperationException

Error code example:

List<Integer> list = Arrays.asList(1, 2, 3);
list.add(4);

Suggestion:

If you need update the list later, you should use new ArrayList(Arrays.asList()) instead of Arrays.asList().

Requirement drives technology capabilities.

Keep Coding

Solve algorithm problems.

Do some great open-source projects (making wheels or writing common systems). Or contribute to open-source projects.

Keep Learning

Reading technical books and docs.

Writing blogs.

Creating some small toy projects.

Solving other code problems. Answer questions on StackOverflow.

Answer interview questions by yourself.

Browse technical websites and forums.

Deep Dive

Reading classic fundamental CS books, documentation, and specification.

Reading source code.

Naming Convention

Java uses camelCase as the naming convention for variables, methods, and classes. But class names must be capitalized.

Package management

You can use Maven or Gradle for package (dependency) management.

Project Creation

Maven project

You can create a Maven project in the following way.

1. Maven command line

$ mvn archetype:generate \
-DgroupId=com.taogen.demo \
-DartifactId={project-name} \
-DarchetypeArtifactId=maven-archetype-quickstart \
-DarchetypeVersion=1.4 \
-DinteractiveMode=false

2. Create a Maven project in a IDE

3. Spring Initializr

Project structure

Basic Maven Application

java-project/

├── src/main/java/
│ └── com/taogen/javaproject/

├── src/main/resources/

├── src/test/java/
├── src/test/resources/
└── pom.xml
  • src/main/java: Java source code
    • com/taogen/javaproject: Base package path. It represents the domain name of your project website.
  • src/main/resources/: Static resources such as image, JavaScript, and CSS files. And configuration files.
  • src/test/java/: Test code.
  • pom.xml: Maven project configuration file.

Spring boot Web Application

java-project/

├── src/main/java/
│ └── com/taogen/javaproject/
│ ├── modules/
│ │ └── user/
│ │ ├── controller/
│ │ │ └── UserController.java
│ │ ├── entity/ (or domain/)
│ │ │ └── User.java
│ │ ├── service/
│ │ │ ├── UserService.java
│ │ │ └── impl/
│ │ │ └── UserServiceImpl.java
│ │ ├── repository/ (or mapper/)
│ │ │ └── UserRepository.java
│ │ ├── vo/
│ │ └── dto/
│ ├── util/
│ ├── config/
│ ├── aspect/
│ ├── annotation/
│ ├── constant/
│ ├── enums/
│ ├── exception/
│ ├── filter/
│ └── task/

├── src/main/resources/
│ ├── static/
│ ├── templates/
│ ├── log4j2.xml
│ └── application.yml (or application.properties)

├── src/test/java/
├── src/test/resources/

├── .gitignore
├── .gitmessage
├── Dockerfile
├── pom.xml
├── LICENSE
└── README.md
  • src/main/java: Java source code
    • modules/
      • controller/: HTTP request handlers.
      • entity/: JavaBeans, POJOs, or domain models.
      • service/: Business logic processing code.
      • repository/: Data access layer code for various persistence stores.
      • dto/: Data Transfer Objects, encapsulate values to carry data between processes or networks.
      • vo/: Value objects, a special type of objects that can hold values.
    • util/: Utility classes such as StringUtil, DateUtil, IOUtil, etc.
    • config/: Configuration files such as Redis, MySQL data source, Security, etc.
    • aspect/: Spring AOP classes.
    • annotation/: Custom Java annotations.
    • constant/: Static variable classes.
    • enums/: Java Enum type classes.
    • exception/: Custom exception classes that are extended by a java.lang.Exception class or its subclass.
    • filter/: Servlet filter classes that are implemented javax.servlet.Filter.
    • task/: Scheduled tasks.
  • src/main/resources/
    • static/: Static files such as CSS, JavaScript, image, etc.
    • templates/: Template files such as JSP, FreeMarker, Thymeleaf, etc.
    • log4j2.xml: Log configuration file.
    • application.yml: Spring boot configuration file.
  • src/test/java/: Test code.
  • pom.xml: Maven project configuration file.
0%