發表於 程式分享

angular 加上firebase tool功能

指令如下

1.npm install -g firebase-tools

2.firebase login
註: 因前一日已有登入過,故會將登入資訊在在C:\Users\user.config\configstore\firebase-tools.json

3.在https://console.firebase.google.com/建立專案及firebase database

4.初始化firebase App
firebase init

5.firebase deploy

6.npm install firebase @angular/fire –save

7.npm install @firebase/app

8.npm install @firebase/firestore

9.將firebase console設定的網站資訊加到src/environment/environment.ts的environment.firebase區塊內

10.程式碼請參考https://github.com/yahuihuang/graceAngularApp

11.ng seve

12.http://localhost:4200/

發表於 程式分享

新增angular cli遇到的問題

最近新增angular cli專案時遇到幾個錯誤訊息

1.An unhandled exception occurred: C:\GWork\00_Work\graceAngularApp\graceAngularApp contains both .browserslistrc and browserslist

2.An unhandled exception occurred: Unknown browser query basedir=$(dirname "$(echo "$0" | sed -e 's. Maybe you are using
old Browserslist or made typo in query.
See “C:\Users\user\AppData\Local\Temp\ng-yaE42p\angular-errors.log" for further details.

只好執行如下,讓專案能繼續執行

1.移除.browserslistrc and browserslist相關開頭的檔案

2.移除ansi-html相關開頭的檔案

以下是新增angular app的指令,請參考

1.npm install -g @angular/cli@next

註: 因為沒加@next目前是cli 9版,會跑出更多的錯誤訊息,用next是用下一版看起來更穩定

2.ng new graceAngularApp –routing –style=scss

3.cd graceAngularApp

4.ng build –prod

註: 錯誤訊息在此處產生,故文章開頭的2項步驟在此處執行

4.ng serve

5.http://localhost:4200

發表於 程式分享

springBoot微服務架構初體驗

專案名稱 Github url 主要功能
helloeureka https://github.com/yahuihuang/helloeureka Eureka server (註冊中心: 服務Load Balance)
hello https://github.com/yahuihuang/hello Restful API (服務提供者)

log4j2

DB 連線 (hibernate)

讀取設定檔

hellofeign https://github.com/yahuihuang/hellofeign Restful API (服務提供者 + 服務消費者)

服務降級設定(服務異常處理) – class Level

設定檔用YAML格式

helloconsumer https://github.com/yahuihuang/helloconsumer Restful API (服務提供者 + 服務消費者)

服務降級設定(服務異常處理) – method Level

Api-gateway https://github.com/yahuihuang/api-gateway API 閘道服務 (路由設定、篩檢程式)

設定檔用YAML格式

發表於 程式分享

單體應用架構 vs. 微服務容器架構

 

單體應用架構 微服務容器架構
(分布式架構形式)
優點 1.易開發
2.易測試
3.易部署
1.多個獨立微小服務構成
2.輕量級機制通信
3.獨立構建部署
4.每個服務可用不同語言
5.每個服務可用不用DB
好處
1.單一職責、業務單一
2.輕量級通信(HTTP, REST風格, JSON格式)
3.獨立開發、獨立測試、獨立部署
4.敏捷
缺點 1.應用工程變得又大又雜
2.敏捷開發及部署舉步維艱
3.啟動時間長
4.可靠性差
5.難以采用新技術語言
1.過度關注服務大小
2.分布式系統中難以構建及部署
3.分區的DB架構
4.測試的複雜度
5.改動帶來的溝通成本
適合 中小型 互聯網
註: 通常會撘配容器使用

 

發表於 程式分享

PWAs(Progressive Web Apps)學習筆記之2: manifest.json

一、manifest.json設定

1.假設manifest.json放在與web application的根目錄下,同index.html

2.index.html內設定

<link rel="manifest" href="/manifest.json">

二、mainfest.json properties介紹

1.name: Web App名稱

2.short_name: Web App短名稱

3.start_url: 設定起始連結

4.scope: 相關設定影響範圍

5.display: 顯示模式,包含fullscreen、standalone、minimal-ui、browser

6.background_color: 背景顏色,如#FFDDEE

7.theme_color: 主題顏色,如#AABBCC

8.description: Web App描述

9.dir: 排版方式,ltr(由左到右)、rtl(由右到左)、auto(自動)

10.lang: Web App語系,如en-US

11.orientation: 螢幕方向ㄝany、natural、landscape、portrait、portrait-primary、portrait-secondary、landscape-primary、landscape-secondary

12.icons: 應用程式圖示,為一array,有src、type、sizes等properties

1) src: Ex../assets/images/android_144.png

2) sizes: Ex.144×144

3) type: Ex.image/png

13.related_applications: 推薦原生app的連結,為一array,有platform、url、id等properties

1) platform: 可以找到該應用程式的平台,Ex.play

2) url: 可以找到該應用程式的網址,Ex.https://play.google.com/store/apps/details?id=cheeaun.hackerweb

3) id: 在特定平台上代表該應用程式的 ID,Ex.com.example.app1

14.prefer_related_applications: 是否要推薦一個原生的app,true或false

發表於 程式分享

PWAs(Progressive Web Apps)學習筆記之1

可讓web apps看起來及感覺上像使用原生apps一樣,
一、特點:
1.可信賴的: 載入快速及提供離線功能
2.快速: 回應使用者的速度快
3.優勢: 在手機、平板的使用上感覺上像使用原生apps一樣

二、比較Mobile Web vs. Native Apps,其中Native Apps有以下優勢
1.Push Notifications (推播)
2.Home Screen icons讓使用更容易
3.可使用native device的功能,如相機功能
4.可離線使用

三、性能(Capability)與可觸及性(Reach)

性能(Capability) 可觸及性(Reach)
原生apps 可使用native device的功能 前三名的apps贏得大部份的使用率,其餘很難
傳統的web app native device的功能很多不可使用 高可觸及性,無界線
PWAs 可使用native device的功能 高可觸及性,無界線

四、PWAs核心功能

Service workers
背景同步
(同步使用者資料)
快取/離線支援 強化其它PWA特徵 Web Push推播
類似手機推播
Application Manifest
允許增加至主畫面
Geolocation API
可存取使用者存地理位置
RWD(Responsive design) Media API
可存取相機及麥克風
發表於 程式分享

使用iText將word內多筆資料以功能變數convert 成 pdf

1.word設定如下

foreach

2.程式碼如下

 1) 將資料取至List

    private boolean retriveListData_13(int applySeqno_in, int kind_in, OLServiceEntry olServiceEntry, 
            List clientASOs) {
        //1.取得資料    
        OLClientSign olClientSign = olServiceEntry.retriveOLClientSign(applySeqno_in, OLClientSignKind.Kind_8.getId());
        
        //2.對應資料
        HashMap answerMap = retriveAnswerMap((olClientSign == null) ? "" : olClientSign.getAnswer());
        
        //3.取筆數
        String asoAddrow = (answerMap.get("asoAddrow") != null) ? answerMap.get("asoAddrow").trim() : "";
        int iAsoAddrow = (new Integer(asoAddrow)).intValue();
        
        if (iAsoAddrow >= 1) {
            if (clientASOs == null) {
                logger.error("List clientASOs is null");
                return false;
            }
            
            //3.取資料
            for (int iAsoIdx = 1; iAsoIdx <= iAsoAddrow; iAsoIdx++) {
                String kindKey = "kind_" + iAsoIdx;
                String kind = (answerMap.get(kindKey) != null) ? answerMap.get(kindKey).trim() : "";
                int iKind = (new Integer(kind)).intValue();
                
                String declareNameKey = "declareName_" + iAsoIdx;
                String declareName = (answerMap.get(declareNameKey) != null) ? answerMap.get(declareNameKey).trim() : "";
                
                String declareIdKey = "declareId_" + iAsoIdx;
                String declareId = (answerMap.get(declareIdKey) != null) ? answerMap.get(declareIdKey).trim() : "";
                
                String kindDesc = kind + "-";
                for (ASOKind asoKind : ASOKind.values()) {
                    if (iKind == asoKind.getId()) {
                        kindDesc += asoKind.getDesc();
                        break;
                    }
                }
                clientASOs.add(new OLClientASOItem(declareId, kindDesc, declareName));
            }
        }
        
        return true;
    }

2) convert to pdf

                    if (retriveListData_13(applySeqno_in, kind_in, olServiceEntry, clientASOs) == false) {
                        logger.error("retrive List(ASO) Data error - applySeqno_in: ' + applySeqno_in + ', kind_in: " + kind_in + ", version_in: " + version_in);
                        response.getWriter().println("retrive List(ASO) Data error");
                        return null;
                    }
                    
                    context.put("clientASOs", clientASOs);
發表於 程式分享

使用word書籤 ,convert word to pdf

1.word / 書籤 => 設定書籤名稱
pic1
2.範例程式碼

   private ByteArrayOutputStream gen2ImgFile(int applySeqno_in, String kindDesc, OLServiceEntry olServiceEntry,
            StringBuffer docFileName, OLClientSeal olClientSeal1, OLClientSeal olClientSeal2) {
        //0.Start
        InputStream in = OLPdfClientShowAction.class.getResourceAsStream(templateImgFileName);          
        IXDocReport report = null;
        IContext context = null;
        try {
            //0.Init
            report = XDocReportRegistry.getRegistry().loadReport(in, TemplateEngineKind.Velocity);
            context = report.createContext();
            
            OLPdfProject project = new OLPdfProject(kindDesc + "_" + applySeqno_in);
            context.put("project", project);
            context.put("client.title", kindDesc);
            FieldsMetadata metadata = report.createFieldsMetadata();    
            
            //1.第1張圖
            if (olClientSeal1 != null) {
                logger.info("fileName-1: " + olClientSeal1.getDocFileName());
                String iPageTag1 = "pic1";
                    
                //1-1.註冊圖片
                metadata.addFieldAsImage(iPageTag1);
                    
                //1-2.設定圖片 
                byte[] docSrc1 = olClientSeal1.getDocSrc();
                byte[] decodeBytes1 = docSrc1;
                if (olClientSeal1.getSrcKind() == 1) {  //base64
                    String base64Str1 = new String(docSrc1);            
                    String tmpBase64Str1 = base64Str1.substring(base64Str1.indexOf(",") + 1);
                    decodeBytes1 = DatatypeConverter.parseBase64Binary(tmpBase64Str1);
                }
                        
                IImageProvider pic1 = new ByteArrayImageProvider(decodeBytes1);
                pic1.setWidth(300f);
                pic1.setResize(true);
                        
                context.put(iPageTag1, pic1);
            }
                    
            //2.第2張圖
            if (olClientSeal2 != null) {
                logger.info("fileName-2: " + olClientSeal2.getDocFileName());
                String iPageTag2 = "pic2";
                
                //2-1.註冊圖片
                metadata.addFieldAsImage(iPageTag2);
                
                //2-2.設定圖片      
                byte[] docSrc2 = olClientSeal2.getDocSrc();
                byte[] decodeBytes2 = docSrc2;
                if (olClientSeal2.getSrcKind() == 1) {  //base64
                    String base64Str2 = new String(docSrc2);            
                    String tmpBase64Str2 = base64Str2.substring(base64Str2.indexOf(",") + 1);
                    decodeBytes2 = DatatypeConverter.parseBase64Binary(tmpBase64Str2);
                }
                
                IImageProvider pic2 = new ByteArrayImageProvider(decodeBytes2);
                pic2.setWidth(300f);
                pic2.setResize(true);
                    
                context.put(iPageTag2, pic2);
            }
            
            //3.Generate report by merging Java model with the Docx
            ByteArrayOutputStream outPdf = new ByteArrayOutputStream();
            PdfOptions pdfOptions = PdfOptions.create();
            FontFactory.registerDirectory(application.getRealPath("/") + "WEB-INF" + File.separator 
                        + "classes" + File.separator + "fonts" + File.separator);
            Options options = Options.getTo(ConverterTypeTo.PDF).via(ConverterTypeVia.XWPF).subOptions(pdfOptions);                 
            report.convert(context, options, outPdf);
                
            //8.顯示檔案
            if (docFileName != null)
                docFileName.append(java.net.URLEncoder.encode(OLPdfKind.Kind_2.getDesc() + "_" + applySeqno_in + ".pdf", "UTF-8"));
            return outPdf;
        } catch (IOException e) {
            logger.error("gen2ImgFile() IOException error : " + e.getMessage());
            return null;
        } catch (XDocReportException e) {
            logger.error("gen2ImgFile() XDocReportException error : " + e.getMessage());
            return null;
        }       
    }
發表於 程式分享

webpack初體驗

因開發的web程式愈來愈複雜,webpack是當用來建構web程式的管理工具,基本的使用方法介紹如下:

一、安裝webpack
至https://nodejs.org下載node.js

二、創立web模組化開發專案
1.新建一目錄
2.執行npm init

三、安裝webpack至開發專案
npm i -D webpack
或npm install –save-dev webpack webpack-cli
–save-dev同-D,指的是將安裝模組保存到package.json的devDependencies
另若要指定版本請用npm install –save-dev webpack@
要安裝最新的體驗版請用npm install –save-dev webpack@beta
要將webpack安裝至全域未來都可使用請用npm i -g webpack,
但建議不要安裝至全域以利未來不同專案可用不同版本

四、webpack各檔案簡介,舉例說明
|– dist |– index.html |– main.bundle.js
|– src |– main.js |– helper.js
|– webpack.config.js
|– package.json

1.webpack.config.js

const path = require('path');
var webpack = require('webpack')
var HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
    devtool: 'cheap-eval-source-map',
    entry: [
      'webpack-dev-server/client?http://localhost:8080',
      'webpack/hot/dev-server',
      './src/main.js'
    ],
    output: {
        filename: 'main.bundle.js',
        path: path.resolve(__dirname, './dist'),
    },
    plugins: [
      new webpack.HotModuleReplacementPlugin(),
      new HtmlWebpackPlugin({
        template: './dist/index.html'
      })
    ],
    module: {
    },
    devServer: {
      contentBase: './dist',
      hot: true
    }
}

2.main.js

import helplers from './helpler.js';
helplers.showlog('webpack 初始化');

3.helper.js

export default {
    showlog(msg) {
        console.log('您輸入的資料: ' + msg);
    }
}

4.package.json

{
  "name": "webpack01",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "dependencies": {
    "webpack": "^4.41.5",
    "webpack-cli": "^3.3.10"
  },
  "devDependencies": {},
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack",
    "dev"  : "webpack-dev-server --config webpack.config.js"
  },
  "author": "",
  "license": "ISC"
}

5.build webpack
指令 npm run build

五、安裝開發Server:
1.https://neighborhood999.github.io/webpack-tutorial-gitbook/Part1/WebpackDevServer.html
2.執行chrome debug: npm run dev

六、範例下載
https://github.com/yahuihuang/webpack01

發表於 程式分享

Linux上三種檢查遠端port是否開啟的方式

1.telnet
telnet [IP] [Port]
安裝指令: yum install telnet

2.nc (netcat)
nc –zvw3 [IP] [Port]
安裝指令: yum install nc

3.nmap
nmap [IP] -p [Port]
安裝指令: yum install nmap