Preserving + (Plus Sign) in URLEncoded Http Post request

Just use encodeURIComponent to encode the password before sending it.

private login(params: LoginParams): Promise < any > {

  ...

  const loginCredentials = new HttpParams()
    .set('j_username', params.username)
    .set('j_password', encodeURIComponent(params.password));

  ...
}

NOTE: On your API end, you'll have to use decodeURIComponent(yourPasswordParam) to get the actual password.

UPDATE:

Just try it right here and see what it gives on encoding:

var encodedUsername = encodeURIComponent('mclovin+');
console.log('Encoding Username gives: ', encodedUsername);
console.log('NOT mclovin%252B');

var encodedPassword = encodeURIComponent('fogell+');
console.log('Encoding Password gives: ', encodedPassword);
console.log('NOT fogell%252B');

This is also an Angular issue (@angular/common/http)

It will interpret the raw + sign as a replacement for a space.

You can implement HttpParameterCodec into a simple encoder, for example:

import {HttpParameterCodec} from "@angular/common/http";
export class HttpUrlEncodingCodec implements HttpParameterCodec {
    encodeKey(k: string): string { return standardEncoding(k); }
    encodeValue(v: string): string { return standardEncoding(v); }
    decodeKey(k: string): string { return decodeURIComponent(k); }
    decodeValue(v: string) { return decodeURIComponent(v); }
}
function standardEncoding(v: string): string {
    return encodeURIComponent(v);
}

And then use it to get encoded correctly:

const headers = new HttpHeaders({'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'});
const params = new HttpParams({encoder: new HttpUrlEncodingCodec()});
http.post(url, params, {headers: this.headers});