跳到主要內容

發表文章

目前顯示的是有「Java8」標籤的文章

Install Oracle Java8 on Debian

Pre-Install sudo apt-get install software-properties-common https://packages.ubuntu.com/zh-tw/trusty/software-properties-common Install Oracle Java8 sudo add-apt-repository "deb http://ppa.launchpad.net/webupd8team/java/ubuntu xenial main" sudo apt-get update sudo apt-get install oracle-java8-installer javac -version Install Oracle Java9 sudo apt-get install oracle-java9-installer Java version manager sudo update-alternatives --config java SET JAVA_HOME Modified ~/.profile vim ~/.profile Append JAVA_HOME to environment # JAVA_HOME JAVA_HOME="/usr/lib/jvm/java-8-oracle" # JAVA version manange controller aliases alias jvc='sudo update-alternatives --config java' Verify source ~/.profile echo $JAVA_HOME jvc jerry@local:~$ jvc There are 2 choices for the alternative java (providing /usr/bin/java). Selection Path Priority Status ------------------------------------------------------------ 0 /usr...

Parse URI query string to Key Value

Parse URI query String to Map 做 urlDecode 處理 沒有任何 query String 回傳 Empty Map 確保只處理 key-value 結構的 query String package com.example.util; import lombok.extern.slf4j.Slf4j; import org.apache.http.client.utils.URIBuilder; import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URISyntaxException; import java.net.URLDecoder; import java.util.LinkedHashMap; import java.util.Map; import java.util.Objects; /** * Created by jerry on 2017/12/28. * * @author jerry */ @Slf4j public class UriUtil { private UriUtil() { } public static Map splitQuery(final String uri) { Map queryPairs = new LinkedHashMap (); try { final URI uri = new URIBuilder(uri).build(); final String rawQuery = uri.getRawQuery(); log.info("CurrentUrl Query: {}", rawQuery); // 過濾沒有 query string // 還有過濾無法成對 keyValue 的 query, e.g. http://host/path?123 if (Objects.isNull(rawQuery) |...

Java split empty strings

Sample Code String str = "a,b,c,,"; String[] ary = str.split(","); // result 3 System.out.println(ary.length); 在 code review 的時候發現一個有趣的狀況, 在 split(",") 處理完, 預期結果應該是 5 , 然而實際上卻是 3 , 查了一下 API 發現 public String[] split(String regex) 要求的參數其實是 regrex express, 這有可能導致 IndexOutOfBoundException , 建議改為 public String[] split(String regex, int limit) limit 用來限制 array 的長度, 如果 limit > 0, 最終處理的 array 長度不會大於 limit, regex express 匹配的次數最多為 n - 1 次, 如果 limit 空字串 匹配的問題, 如果 limit = 0, regex express 會儘可能地處理匹配, 但會放棄處理 空字串 匹配的問題。 參考: API Doc Sample Code String str = "a,b,c,,"; String[] ary = str.split(",", -1); // result 5 System.out.println(ary.length);

Java Dependency Injection

首先 這篇主要是翻譯 這篇 的教學, 再用自己的方式解釋。 Email Service 文章開頭以 Email Service 來解釋, UML 應該是長這樣, Application 強依賴 EmailService , Application 在一開始就初始化了 EmailService, 而 Main 也強依賴 Application , 這樣寫並沒有太大的問題, 但不容易對 Application class 做測試, 因為不容易對 EmailService 做 mock. 修正 Application 方便測試 為了讓 Application 能夠被測試, 所以改成 inject EmailService 的建構方式 public class Application { private EmailService emailService; public Application(EmailService emailService) { this.emailService = emailService; } public void notification(String message, String receiver) { this.emailService.sendEmail(message, receiver); } } 簡單的使用 Mockito 來 mock EmailService 測試 <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <version>2.12.0</version> </dependency> package dependency.injection; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doNothing; import static org.mockito...

Java Quartz2.2 入門

Quartz Quartz 是一個功能滿完整的 Java Schedule 排程工具, 核心就圍繞在 Scheduler 與 Job 的操作上。 Scheduler - the main API for interacting with the scheduler. Job - an interface to be implemented by components that you wish to have executed by the scheduler. JobDetail - used to define instances of Jobs. Trigger - a component that defines the schedule upon which a given Job will be executed. JobBuilder - used to define/build JobDetail instances, which define instances of Jobs. TriggerBuilder - used to define/build Trigger instances. Job Quartz 的 Job 被定義為需要 implement org.quartz.Job , 需要實作 void execute(JobExecutionContext jobExecutionContext) , jobExecutionContext, 可以取得 Job 的 Scheduler, Trigger, JobDetail 的相關設定, 相關的說明可以參考 tutorial-lesson-02 . import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.quartz.Job; import org.quartz.JobDataMap; import org.quartz.JobDetail; import org.quartz.JobExecutionContext; import org.quartz.JobExecutio...

Java String Hex 轉換

覺得 String.format("%1$02x", b) 很神奇, 隨手記錄一下 String to Hex public static String toHex(byte[] bytes) { StringBuilder sb = new StringBuilder(); for (byte b : bytes) { sb.append(String.format("%1$02x", b)); } return sb.toString(); } Hex to String import java.io.UnsupportedEncodingException; import javax.xml.bind.DatatypeConverter; public static String hexToString(String hexStr) throws UnsupportedEncodingException { byte[] bytes = DatatypeConverter.parseHexBinary(hexStr); return new String(bytes, "UTF-8"); }

Java8 SecureRandom

Random java.util.Random 其實一點也不 Random, 因為屬於一種線性分佈, 線性不比離散, 所以就是有公式可以預測啦~ 大神的論文在 這裡 https://stackoverflow.com/questions/11051205/difference-between-java-util-random-and-java-security-securerandom The standard Oracle JDK 7 implementation uses what's called a Linear Congruential Generator to produce random values in java.util.Random. Predictability of Linear Congruential Generators Hugo Krawczyk wrote a pretty good paper about how these LCGs can be predicted ("How to predict congruential generators"). If you're lucky and interested, you may still find a free, downloadable version of it on the web. And there's plenty more research that clearly shows that you should never use an LCG for security-critical purposes. This also means that your random numbers are predictable right now, something you don't want for session IDs and the like. 隨機數安全議題 http://wps2015.org/drops/drops/%E8%81%8A%E4%B8%80%E8%81%8A%E9%9A%8F%E6%9C%BA%E6%95%B0%E5%AE%89%E5%85%A8.html Secu...

Java8 convert List to Map

Chung Nguyen Sample Data [ {"uid":"1","name":"阿花","age":38,"gender":"F"}, {"uid":"2","name":"阿瓜","age":28,"gender":"M"} ] Entity @Data @JsonInclude(JsonInclude.Include.NON_NULL) @JsonPropertyOrder(value = { "uid", "name", "age", "gender" }) public class Customer { // creativeId equals adId @JsonProperty("uid") private String uid; @JsonProperty("name") private String name; @JsonProperty("age") private Integer age; @JsonProperty("gender") private String gender; } Test @Test public void test() throws IOException { List<Customer> customerList = objectMapper.readValue(json, new TypeReference >() {}); Map customerMap = customerList.stream() .collect(Collectors.toMap( ...

Spring-data JPA 搭配 Optional 的使用

Optional Java 最大的敵人, 我想應該就是 NPT Exception , tears. 所以 Java8 設計了一個 Optional 用來解決 NPT 這淘氣的小東西, fuck. 詳細的使用方式 參閱這個 bloger 的介紹, 寫的超棒, 我覺得啦 :) JpaRepository Spring framework 做 CRUD 的好朋友, 就是 JpaRepository , 沒有用 Optional 的寫法像這樣 @Repository public interface UserInfoRepository extends JpaRepository<UserInfo, String> { UserInfo findByName(String name); } 這樣寫其實也沒什麼不合理, 只是在商業邏輯處理時, 要多一個 if 判斷, 判斷是否有查詢到 userInfo 的資料. public void business() { UserInfo user = userInfoRepository.findByName("dumdum"); if (Objects.isNull(user)) { // throw exception } else { // do something } } 改為用 Optional 試試看 @Repository public interface UserInfoRepository extends JpaRepository<UserInfo, String> { Optional<Userinfo> findByName(String name); } public void business() { Optional<Userinfo> userOpt = userInfoRepository.findByName("dumdum"); UserInfo user = userOpt.orElseThrow(() -> new Exception(...

Java8 Map, Flatmap Sample

Data Source private static List> teams = new ArrayList<>(); private static List aTeam = new ArrayList<>(); private static List bTeam = new ArrayList<>(); static { aTeam.add("Java"); aTeam.add("C++"); aTeam.add("PHP"); aTeam.add("Scala"); bTeam.add("Go"); bTeam.add("R"); teams.add(aTeam); teams.add(bTeam); } MapDemo @Test public void mapDemo() { System.out.println("=== Demo Lambda Map ==="); List> result1 = teams.stream().map(team -> { System.out.println("Team: " + team); return team; }).collect(Collectors.toList()); System.out.println("Result: " + result1); } === Demo Lambda Map === Team: [Java, C++, PHP, Scala] Team: [Go, R] Result: [[Java, C++, PHP, Scala], [Go, R]] FlatMap Demo @Test public void flatMapDemo() { ...