Home

2018年12月14日 星期五

Powerful Spring Boot Admin

From: Polin Wei
利用 Spring Boot 可以快速開發客製化應用系統, 而這些由 Spring Boot 框架建立的應用系統則可以利用 Spring Boot Admin 來作統一的管理. 由這系統可以讓您知道 Application Server 的版本如: Java , Tomcat , session .... 等, 所以在管理這些服務系統架構中...監控管理是非常重要的一環

Server 端

1. 建立一個新的 Spring Starter Project : sbAdmin , 且只要選擇 Web 就好. 其它的相依套件如下:
buildscript {
 ext {
  springBootVersion = '2.1.1.RELEASE'
 }
 repositories {
  mavenCentral()
 }
 dependencies {
  classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
 }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

group = 'com.admin'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8

repositories {
 mavenCentral()
}


dependencies {
 implementation('org.springframework.boot:spring-boot-starter-web')
 compile('de.codecentric:spring-boot-admin-starter-server:2.1.1') // SpringBoot Admin
 testImplementation('org.springframework.boot:spring-boot-starter-test')
}
Server 端的 application.properties 設定啟動的 port: 8099

server.port=8099

Client 端

引入的相依套件
dependencies {
 compile('de.codecentric:spring-boot-admin-starter-client:2.1.1') // SpringBoot Admin Client
}

設定Spring Boot Admin 可以存取 Client 端的設定

(繼續閱讀...)

Develop custom taglib using Freemarker in Spring Boot

From: Polin Wei
在 Spring Boot 使用 Freemarker 模板來快速建立客製化的標籤 (taglib) 是非常簡單的事. 作下列幾個步驟即可.


public class FtlTemplateTag extends TagSupport {

 private static final long serialVersionUID = 1L;
 
 private String fileName = null;
    private String paramsStr = null;
    private String columnsStr = null;
    private ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
    
 public void setFileName(String fileName) {
  this.fileName = fileName;
 }    
 public void setParamsStr(String paramsStr) {
  this.paramsStr = paramsStr;
 }
 public void setColumnsStr(String columnsStr) {
  this.columnsStr = columnsStr;
 }
 /**
  * JSON 字串轉換成 MAP
  * @return
  */
 private Map setParams() {
  Gson gson = new Gson();
  return gson.fromJson(paramsStr, new TypeToken>() {
  }.getType());
 }
 
 private Map setColumns(){
  Locale locale = LocaleContextHolder.getLocale();
  
  messageSource.setBasenames("i18n/messages");
  
  Gson gson = new Gson();
  Map columns = gson.fromJson(columnsStr, new TypeToken>() {}.getType() );
  
  //轉換多語系
  Map dataModel = new LinkedHashMap();
  columns.forEach( (k,v)-> dataModel.put(k, messageSource.getMessage(v, null, v, locale)) );
   
  return dataModel;
 }
 
 
 @Override
 public int doStartTag() throws JspException {
  JspWriter out = pageContext.getOut();
  
  Configuration conf = new Configuration();
  conf.setClassForTemplateLoading(this.getClass(), "/templates/");
  conf.setDefaultEncoding("UTF-8");
  
  try {
   Template  tl = conf.getTemplate(fileName);
   Map dataModel = new HashMap();
   dataModel.putAll(this.setParams());
   dataModel.put("columns", this.setColumns());
   

   tl.process(dataModel, out);
   
  } catch (Exception e) {
   e.printStackTrace();
  }  
  return Tag.SKIP_BODY;
 }
}

<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
        version="2.0">
    <description>Polin WEI Tag Library</description>

    <tlib-version>1.0</tlib-version>
    <short-name>pw</short-name>
    <uri>/polinwei/tags</uri>

    <tag>
        <description>Get the file name of freemarker template</description>
        <name>FtlSampleTemplate</name>
        <tag-class>com.spring.jwt.tablibs.FtlTemplateTag</tag-class>
        <body-content>empty</body-content>
        <attribute>
            <description> Freemarker Template 的檔案</description>
            <name>fileName</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
        <attribute>
            <name>parmsStr</name>
            <required>false</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
        <attribute>
            <name>columnsStr</name>
            <required>false</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
    </tag>
</taglib>


(繼續閱讀...)

2018年12月7日 星期五

[Solved] DocumentBuilder parse XML returns null <解決 org.w3c.dom.Document 解析 XML 檔回傳值均為 NULL>

From: Polin Wei Document 解析 XML 檔案時, 解析的值總是為 NULL , 解決方法如下: 先把檔案用 StringBuilder 變成字串後, 再作解析就可以

import org.springframework.util.ResourceUtils;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.stream.Stream;

public class TestFunc {

        public static void main(String[] args) throws Exception  {
                // TODO Auto-generated method stub
                try {
                        File xmlFile = ResourceUtils.getFile("classpath:ckfinder-config.xml");
                        readMXLFile(xmlFile);
                        
                } catch (FileNotFoundException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                }
        }
        
        public static void readMXLFile(File xmlFile) throws Exception {
                InputStream is = new FileInputStream(xmlFile);
                StringBuilder contentBuilder = new StringBuilder();
                try (Stream stream = Files.lines(Paths.get(xmlFile.getAbsolutePath()), StandardCharsets.UTF_8)) {
                        stream.forEach(s -> contentBuilder.append(s).append("\n"));
                } catch (IOException e) {
                        e.printStackTrace();
                }
                System.out.println(contentBuilder.toString());

                ByteArrayInputStream bis = new ByteArrayInputStream(contentBuilder.toString().getBytes());

繼續閱讀