Total Pageviews

2019/02/07

[Java] How to do IP validation in Java?

Problem
How to do IP validation in Java?

How-To
Here has sample code:
    import lombok.Data;
    import javax.validation.constraints.NotNull;
    import javax.validation.constraints.Pattern;

    @Data
    public class Param {
        
        @NotNull(message = "請提供性別")
        private String gender;
        
        @NotNull(message = "請提供呼叫者 IP address")
        @Pattern(regexp = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$", 
                 message = "呼叫者 IP address 不合法")
        private String srcIp;
    }

Reference
[1] https://stackoverflow.com/a/14877281/6314840

2019/02/06

[Spring] How to use shedlock in spring framework?

Problem
Owing to my web application will deploy to a cluster, so I need to find a solution to prevent concurrent execution of scheduled Spring tasks.


Here has a short example to demo how to use shedlock.


How-To
Add dependencies in pom.xml
        <dependency>
            <groupId>net.javacrumbs.shedlock</groupId>
            <artifactId>shedlock-spring</artifactId>
            <version>1.0.0</version>
        </dependency>
        <dependency>
            <groupId>net.javacrumbs.shedlock</groupId>
            <artifactId>shedlock-provider-jdbc-template</artifactId>
            <version>1.0.0</version>
        </dependency>


Create table for shedlock
CREATE TABLE MY_BATCH_LOCK(
    name VARCHAR(64),
    lock_until TIMESTAMP(3) NULL,
    locked_at TIMESTAMP(3) NULL,
    locked_by  VARCHAR(255),
    PRIMARY KEY (name)
)



Add configuration in your spring boot application
package demo.config;

import java.time.Duration;

import javax.sql.DataSource;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import net.javacrumbs.shedlock.core.LockProvider;
import net.javacrumbs.shedlock.provider.jdbctemplate.JdbcTemplateLockProvider;
import net.javacrumbs.shedlock.spring.ScheduledLockConfiguration;
import net.javacrumbs.shedlock.spring.ScheduledLockConfigurationBuilder;

@Configuration
public class ShedlockConfig {
    
    @Bean
    public LockProvider lockProvider(DataSource dataSource) {
        return new JdbcTemplateLockProvider(dataSource, "MY_BATCH_LOCK");
    }

    @Bean
    public ScheduledLockConfiguration scheduledLockConfiguration(LockProvider lockProvider) {
        return ScheduledLockConfigurationBuilder
                .withLockProvider(lockProvider)
                .withPoolSize(10)
                .withDefaultLockAtMostFor(Duration.ofMinutes(10))
                .build();
    }
    
}


Usage:
    private static final int TEN_MIN = 10 * 60 * 1000;

    @Scheduled(cron = "0 0 1 * * ?")
    @SchedulerLock(name = "mySchedulerTask", lockAtMostFor = TEN_MIN, lockAtLeastFor = TEN_MIN)
    public void execute() {
    }


2019/02/05

[Spring] org.springframework.ws.client.WebServiceIOException: I/O error: Read timed out; nested exception is java.net.SocketTimeoutException: Read timed out

Problem
When I try to call web service, I get this SocketTimeoutException exception:
org.springframework.ws.client.WebServiceIOException: I/O error: Read timed out; nested exception is java.net.SocketTimeoutException: Read timed out
    at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:561)
    at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:390)
    at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:383)
    at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:373)
    at gov.npa.antifraud.agent.web.service.BankSchedulerService.sendBankDataRequest(BankSchedulerService.java:211)
    at gov.npa.antifraud.agent.web.WebAgentApplication.lambda$0(WebAgentApplication.java:22)
    at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:797)
    at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:781)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:335)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1255)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1243)
    at gov.npa.antifraud.agent.web.WebAgentApplication.main(WebAgentApplication.java:16)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
Caused by: java.net.SocketTimeoutException: Read timed out
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
    at java.net.SocketInputStream.read(SocketInputStream.java:171)
    at java.net.SocketInputStream.read(SocketInputStream.java:141)
    at java.io.BufferedInputStream.fill(BufferedInputStream.java:246)
    at java.io.BufferedInputStream.read1(BufferedInputStream.java:286)
    at java.io.BufferedInputStream.read(BufferedInputStream.java:345)
    at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:735)
    at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:678)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1587)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1492)
    at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480)
    at org.springframework.ws.transport.http.HttpUrlConnection.getResponseCode(HttpUrlConnection.java:143)
    at org.springframework.ws.transport.http.AbstractHttpSenderConnection.hasError(AbstractHttpSenderConnection.java:53)
    at org.springframework.ws.client.core.WebServiceTemplate.hasError(WebServiceTemplate.java:673)
    at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:607)
    at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:555)
    ... 16 more


How to extend timed out value?


The Web Service client configuration is:
package demo.web.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
import org.springframework.ws.client.core.WebServiceTemplate;
import org.springframework.ws.transport.WebServiceMessageSender;
import org.springframework.ws.transport.http.HttpComponentsMessageSender;

@Configuration
public class WsClientConfig {
    
    private String defaultURI = "http://localhost:8080/services";
    
    @Bean
    public Jaxb2Marshaller jaxb2Marshaller() {
        Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
        // ignored implementation details        
        return jaxb2Marshaller;
    }
    
    @Bean
    public WebServiceTemplate webServiceTemplate() {
        WebServiceTemplate wsTemplate = new WebServiceTemplate();
        wsTemplate.setMarshaller(jaxb2Marshaller());
        wsTemplate.setUnmarshaller(jaxb2Marshaller());
        wsTemplate.setDefaultUri(defaultURI);
        
        return wsTemplate;
    }
}



How-To
The default values to connection timeout and read timeout in spring framework is 1 minute.



If I would like to extend to 2 minutes, the WsClientConfig should be modified as bellows:
package demo.web.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
import org.springframework.ws.client.core.WebServiceTemplate;
import org.springframework.ws.transport.WebServiceMessageSender;
import org.springframework.ws.transport.http.HttpComponentsMessageSender;

@Configuration
public class WsClientConfig {
    
    private String defaultURI = "http://localhost:8080/services";
    
    @Bean
    public Jaxb2Marshaller jaxb2Marshaller() {
        Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
        // ignored implementation details        
        return jaxb2Marshaller;
    }
    
    @Bean
    public WebServiceTemplate webServiceTemplate() {
        WebServiceTemplate wsTemplate = new WebServiceTemplate();
        wsTemplate.setMarshaller(jaxb2Marshaller());
        wsTemplate.setUnmarshaller(jaxb2Marshaller());
        wsTemplate.setDefaultUri(defaultURI);
        wsTemplate.setMessageSender(webServiceMessageSender());
        
        return wsTemplate;
    }
    
    @Bean
    public WebServiceMessageSender webServiceMessageSender() {
      HttpComponentsMessageSender httpComponentsMessageSender = new HttpComponentsMessageSender();
      // timeout for creating a connection
      httpComponentsMessageSender.setConnectionTimeout(120 * 1000);
      // when you have a connection, timeout the read blocks for
      httpComponentsMessageSender.setReadTimeout(120 * 1000);

      return httpComponentsMessageSender;
    }
}



2019/02/04

[閱讀筆記] How to read a book (1/8)


  1. 閱讀分成四種層次:
  2. 網路、電視機、收音機等,每天 24 小時不斷地提供資訊給我們,但是這些現代的溝通媒介有強化你對我們所處的世界的了解嗎?
  3. 電視機前的觀眾、收音機前的聽眾以及雜誌的讀者,所接收到的資訊都是經過挑選過的資料與統計數字,為了就是要讓閱聽人花最少的力氣與難度來做出自己的想法 (make up your own mind)。但是,事實上,閱聽人並沒有因此做出自己的想法,這如同將 CD 放到 CD Player 並按下 Play 按鈕,整個過程毫無意識,現代的媒體正以壓倒性的氾濫資訊阻礙了我們的理解力
  4. 很多人將讀書或聽課視為有人 (sender) 主動 (actively) 給予或傳授知識,另外一方 (receiver) 則是被動 (passively) 吸收知識。這是錯誤的,讀者或聽眾比較像是棒球場上的接球者 (catcher),投手 (pitcher) 或打擊者 (batter) sender,其會觸發棒球的流動;捕手 (catcher) 或野手 (fielder) 則是 receiver,他們會終止球的流動。雖然 sender receiver 的活動目的不同,但是彼此都是 active,只有球本身是 passive
  5. 捕手 (catcher) 必須具備各種接球技巧,接住每種球 (如快速球、變速球、曲球、蝴蝶球等);相同地,讀者 (reader) 必須具備接收各種溝通模式的技巧 (如實用性與理論性作品、抒情詩、史詩、小說、戲劇、歷史、科學與數學、社會科學與哲學,以及參考書、報章雜誌,甚至廣告等)
  6. 棒球場與閱讀的類比,會有個差異。棒球是個單純的單位 (simple unit),其只有接到與漏接兩種狀態。但是寫作就是個複雜的物件 (complex object),其可以完整接收或部分接收作者所想傳達的意義,這有賴作者 (writer) 能否精確地表達他們想表達的概念,以及讀者 (reader) 是否具備足夠的技巧去接住作者要表達的概念
  7. 閱讀可以根據讀者的了解程度,分成兩種
① Reading for information
例如閱讀報章雜誌,根據我們的閱讀技巧與天分,可以馬上了解報章雜誌要傳達的意思,但是其只能增加我們儲存資訊,無法增進我們的理解 (也就是閱讀前後的理解程度差不多)
② Reading for understanding
讀者在初期嘗試閱讀時,無法完全理解作者要表達的概念,此時讀者看懂作者要表達的意涵後,可以增加讀者的理解力

  1. Reading for understanding 發生於兩種狀況:
① Initial inequality in understanding (讀者與作者兩者間有不對等的理解程度)
作者擁有比讀者更好的理解力,並且可以在書籍中清楚地表達作者所擁有的與前在讀者所缺乏的洞見 (insights)
② The reader must be able to overcome this inequality in some degree (讀者一定要把不對等的理解力克服到一定程度之內)
讀者應想辦法彌補與作者間不對等的理解 gap,兩者間才能成功溝通,提升自己的理解力

  1. 我們只能從比我們「更高桿」的人身上學習 (we can learn only from out “betters”)。我們必須知道他們是誰,如何從他們身上學習。有這種想法的人,就是能認知閱讀藝術的人
  2. 如果你記得 (remember) 作者說了什麼,你就透過閱讀學習到某些事物。如果作者的論述為真,你甚至可以多學習到這世界上的事物。但是,無論作者在書中的論書是真或假,如果你只有記憶,沒有去理解,你頂多增加你資訊的儲存,並沒有增加你的理解力
  3. 只有當你知道作者說了什麼 (what an author says),知道作者想表達的意思 (what he means) 以及為什麼他這麼說 (why he says it),你才算是理解
  4. 吸收資訊是要被啟發的前一個動作。無論如何,不要止於吸收資訊而已。
  5. 閱讀學習分成兩種:

① Learning by instruction (指導型學習, 或稱為 aided discovery)
透過老師課堂指導或講義來獲取知識
② Learning by discovery (探索型學習, 或稱為 unaided discovery)
不是透過老師教導,經由研究、調查或反思的過程來獲取知識

  1. 思考只是主動閱讀的一部分。一個人還必須運用他的感覺與想像力。一個人必須觀察,記憶,在看不到的地方運用想像力。
  2. 閱讀的藝術包括了所有非輔助型自我發現學習 (unaided discovery) 的技巧:敏銳的觀察、靈敏可靠的記憶、想像的空間,再者當然就是訓練有素的分析、省思能力。這麼說的理由在於:閱讀也就是一種發現 (discovery)
  3. 閱讀 (reading) 與聽講 (listening) 都是一種學習,差別是聽講是在課堂裡聽一位活生生的老師授課,閱讀則是跟一位缺席的老師學習。當在課堂聽課有疑問,不知道老師要表達的意思時,你可以在課堂中或課後與老師請教;但是,閱讀則只能自己思考與分析
  4. 讀者的閱讀目標 (娛樂、資訊或理解),決定了他的閱讀方式。閱讀的效率,決定於讀者在閱讀時所花費的力氣與擁有的閱讀技巧。一般來說,花費的閱讀力氣越大越好,你對書籍的理解就會越多
  5. 一個愈是「主動」的讀者,愈是能夠從書中獲得理解。主動閱讀的基礎在於「讀者要提出問題,並且在閱讀的過程中嘗試回答」。本書列舉了四個一定要提出的問題,讀者在閱讀的過程或閱讀完後,都要試著回答這些問題:
    1. 整體來說,這本書到底在談什麼?
    2. 這本書的詳細內容在說什麼?如何說的?
    3. 這本書說得有道理嗎?是全部有道理,還是部份有道理?
    4. 這本書與你有什麼關係?
  6. 要試著讓書(內容)成為自己的方式就是『做筆記』,做筆記的目的:保持清醒、保持主動思考。做筆記的方式有:
    1. 標示重點:畫底線、打星號、標出關鍵字
    2. 建立索引:編號、記下其他參考頁碼
    3. 在空白處寫下問題或想法
  7. 閱讀的四種層次,每一種層次都是向上累積的,第二種層次包含第一種層次,第三種層次包含第二種層次,第四種也是最高等的則包含前三種層次
① Elementary reading
 (基礎閱讀)
       此種層次的閱讀,一般是從小學開始學習,小孩子首先接觸的就是這個層次的閱讀。他的問題(也是我們開始閱讀時的問題)是要如何認出一頁中的一個個字。 在這個層次的閱讀中,要問讀者的問題是:這個句子在説什麼?
        不論我們身為讀者有多精通這樣的閱讀技巧,我們在閱讀的時候還是一直會碰上這個層次的閱讀問題。這時我們要做的第一步努力就是去弄清楚這些字。只有當我們完全明白每個字的意思之後,我們才能試著去了解,努力去體會這些字到底要説的是什麼。
       當你明白每個字的意思之後,你才能讀得更快。仿間看到的速讀課程 (speed readning course) 位處此層級
       仿間出現的速讀補習班,屬於基礎閱讀的層級
② Inspectional reading
(檢視閱讀)
       這個層次的閱讀仍然可以用其他的稱呼,譬如略讀(skimming) 或預讀 (pre-reading)。因此,用另一種方式來形容這個層次的閱讀,就是在一定的時間之內,抓出一本書的重點通常是很短,而且總是時間過短,導致很難掌握一本書所有重點。
       如果第一層次的閱讀所問的問題是:這個句子在説什麼?那麼在這個層次要問的典型問題就是:這本書在談什麼?這是個表象的問題。還有些類似的問題是:這本書的架構如何?或是:這本書包含哪些部分?” “這是哪一類的書小説、歷史,還是科學論文?
       檢視閱讀是一種有系統快速瀏覽的藝術 (art of skimming systematically),主要目標是能夠在短時間內檢視書本的表面知識 (surface),學習任何能教導你的表面知識
③ Analytical reading
(分析閱讀)
       分析閱讀就是全盤的閱讀、完整的閱讀,或是説優質的閱讀你能做到的最好的閱讀方式。如果説檢視閱讀是在有限的時間內 (limited time),最好也最完整的閱讀,那麼分析閱讀就是在無限的時間 (unlimited time) 裏,最好也最完整的閱讀。
       一個分析型的閱讀者一定會對自己所讀的東西提出許多有系統的問題。我們要在這裡強調的是,分析閱讀永遠是一種專注的活動 (intensive activity)
       分析閱讀就是要咀嚼與消化一本書。分析閱讀就是特別在追尋理解的。相對的,除非你有相當程度的分析閱讀的技巧,否則你也很難從對一本書不甚了解,進步到多一點的理解。
       有些書可以淺嘗即止,有些書是要生吞活剝,只有少數的書是要咀嚼 (chewing) 與消化 (digesting) 的,分析閱讀就是咀嚼與消化。
       當你的閱讀的目標是要理解 (understanding) 時,才需採行分析閱讀,若你的閱讀目標僅是吸收資訊與娛樂,就不需要做到這個地步
④ Syntopical reading
(主題閱讀)
       在做主題閱讀時,閱讀者會讀很多書,而不是一本書,並列舉出這些書之間相關之處,提出一個所有的書都談到的主題。主題閱讀涉及的遠不止此。借助他所閱讀的書籍,主題閱讀者要能夠架構出一個可能在哪一本書裏都沒提過的主題分析。因此,很顯然的,主題閱讀是最主動、也最花力氣的一種閱讀,又稱為比較式閱讀 (comparative reading)
       主題閱讀不是個輕鬆的閱讀藝術,規則也並不廣為人知。雖然如此,主題閱讀卻可能是所有閱讀活動中最有收穫的。就是因為你會獲益良多,所以絕對值得你努力學習如何做到這樣的閱讀。