2021年12月27日 星期一

多益線上家教 收費300元 版本202112

 *具有多年讀書會經驗

*聽力穩定450分以上(490分2次)

*懂得如何從低分群準備到高分群

*多次考試經驗, 並從準備考試中建構會話基礎 主教多益聽力部分,以及準備方法 每周上課1小時,會出一天份量的回家作業 藉由每周進度,幫助久未接觸英文的工作人 找回英文的熟悉度,並累積英文基礎能力 養成良好的學習模式 本次學生程度為400-600 目前人數:4~6 地點:Teams 線上 時間:周日 晚上8:30 - 10:00 收費:300 聯絡方式 : 站內私訊,或是line: iw5420 教材:由老師提供,也可自行購買課本

補充 : 程度較好的同學如要拚600-800分以上,
可以白天另外約時間分享準備方式,
藉由進行一段時間的家教陪讀,
程度達成一定的提升

2021年12月19日 星期日

[Spring Boot] Cookie Without Secure Flag

目前情況如下圖






我們可以看到endpoint api的Cookie, 它的HttpOnly和Secure是空白的

根據下面這一篇
https://stackoverflow.com/questions/34489406/adding-httponly-and-secure-flag-for-set-cookie-in-java-web-application










我們可以得知, sesson-config中可以設置安全cookie相關項目
因此, 推測在appication.properties檔案應該有相對應的配置
在看過下面這一篇
https://stackoverflow.com/questions/40974955/spring-boot-java-config-set-session-timeout
得知有server,servlet.session項目, 因此推測在他之下可能能設置cookie
很幸運的回去appication.properties檔案嘗試, 的確有cookie的設置





設置完的結果發現, JSESSIONID 的cookie secure設置確有改變, 如下圖







可是其他的cookie都沒有改變, 怎麼辦呢?
剛好我有查到這一篇
https://rules.sonarsource.com/java/tag/owasp/RSPEC-2092





可以發現在new出來Cookie的時候, 再setSecue就可以了

解決方式->在專案全局中搜尋Cookie字樣, 將其設置secure再回傳
範例

1產生一個處理類

@Component
public class CookieSecureUtils {
	public static Cookie setSecure(Cookie targetCookie) {
		targetCookie.setHttpOnly(true);
		targetCookie.setSecure(true);
		return targetCookie;
	}
}

2載入類


	@Autowired 
	private CookieSecureUtils cookieSecureUtils;

2送出cookie前,設置安全


	response.addCookie(cookieSecureUtils.setSecure(new Cookie("domain", resultObj.getString("domain"))));
	response.addCookie(cookieSecureUtils.setSecure(new Cookie("account", account)));
	response.addCookie(cookieSecureUtils.setSecure(new Cookie("lang", request.getParameter("lang"))));
成果如下圖



2021年12月8日 星期三

ICUmodle 專案 dropdown出來較其他功能緩慢問題

整串的邏輯大約是這樣

1開始載入時 撈取下拉選單,回給前端排列畫面,並產生全域List供篩選使用

2按鈕功能觸發查詢該病患資料

3依照病患id查詢病患該表項資料

4顯示該病患該表項資料


問題

當4顯示資料的時候, 有去使用到1的下拉選單的List

但是發現, 我操作查詢該病患的表項資料速度快的時候,

會發生顯示問題, 開f12發現, 顯示需要的list並沒有撈回來, 他就已經執行篩選顯示


找尋根源問題

一開始推測, getDropdown需要更多的時間, 所以讓他在網頁中載入順序提前,

但是發現, 這還是沒有解決問題

因此, 我做了一個操作




我嘗試在下拉選單組完選單內容的最後印出"finished"字樣

好讓我知道, 什麼時候才把下拉選單組完

此時我發現, 這個finished差不多讓我等了6秒鐘

很明顯, 如果說我整套操作動作在6秒鐘內完成

很有可能會組資料的時候List還沒有準備好


因此

到底為什麼撈取dropdown會需要撈取這麼久呢?

就是這裡的核心問題






我注意到在等待dropdown回傳的過程中,

他在等待account做了很多查詢

我原本以為是權限相關

回去看code發現

原來為了取得帳號名稱

程式查找出整個account內容

因為其權限是eager撈出來的不是lazyload(當初設計上問題)

因此這邊撈出account會再重新把所有權限功能子功能run一遍

整體就是慢在這邊


解法

我使用另一個只撈id和name的Repo function, 準確的撈取我要的資料->帳號名稱

代替原本把account下面所有關聯查出來

大約看到finished在console中, 不到1秒就跑出來了

而證實拖累效能問題的確在這裡


finished!



2021年12月2日 星期四

模糊查詢遇到null情況的小坑


String medicalId = pbSearch.getMedicalId()==""?null:pbSearch.getMedicalId(); 		
String identityId = pbSearch.getIdentityId()==""?null:pbSearch.getIdentityId();
String fullname = pbSearch.getFullname()==""?"":pbSearch.getFullname();
String mode = pbSearch.getMode();
PageRequest pageRequest =  size == 0 ? null:  PageRequest.of(--page, size, Sort.by("sysTime").descending());	
PagepatientBasicList = patientBasicRepo.findVoByDomainAndMedicalIdOrIdentityIdOrFullnameOrMode(domain
				,medicalId, identityId, fullname,mode,pageRequest);
                
@Query("select new com.ICU.ICUmodule.vo.caseManage.PatientBasicVo(pb.id as id, pb.medicalId as medicalId, pb.identityId as identityId, pb.fullname as fullname, "
+ "pb.telephone as telephone, pb.localDate as localDate, pb.treatment as treatment, pr.mode as mode) "
+ "from patient_basic pb left join patient_returned pr on pb.id=pr.patientBasic.id "
+ "where pb.domain=:doamin and (:medicalId is null or pb.medicalId =:medicalId) and (:identityId is null or pb.identityId =:identityId) and (:fullname is '' or pb.fullname LIKE '%' || :fullname||'%') and (:mode is null or pr.mode =:mode)")
Page findVoByDomainAndMedicalIdOrIdentityIdOrFullnameOrMode(String doamin, String medicalId,
			String identityId, String fullname, String mode, Pageable pageRequest);

在一般情況下, 若是要判斷是否為 null 再拉進JPQL裡面做is null or object.xxx = :xxx

然而在模糊查詢的時候, 這裡若為 null 帶入到JPQL LIKE語法, 會產生判斷JPQL語法錯誤問題

因此在這裡LIKE語法是不能帶null, 而要給""字串來做判斷, 這樣JPQL就不會run出問題, 也可以進行模糊查詢及一般查詢

2021年12月1日 星期三

日期組成流水號

String no = repo.getLastIoNo();
String prefix = new SimpleDateFormat("yyyyMMdd").format(new Date());
prefix = prefix.substring(prefix.length() - 6);

        if(no != null && no.matches("^" + prefix + "\\d{3}$")) {
            no = String.valueOf(Integer.valueOf(no) + 1);
        } else if(no == null || !no.matches("^" + prefix + "\\d{3}$")) {
            no = String.format("%s%s", prefix, "001");
        } else {
            throw new Exception("Create StockIoMaster io_no fail");
        }

簡單的說, 這個組成的流水碼最後會變成yyMMdd001, 後面會隨數字變多yyMMdd002, 接續增加

而這組流水碼, 會從001開始, 如果資料庫有取出東西, 且同一prefix的情況, 會自動將序號轉成數字

加一, 這樣就產生一組新的序號在資料庫中

取資料的寫法如下


@Query("select max(m.ioNo) from stock_io_master as m")
String getLastIoNo();

[leetcode] [KMP] KMP

ABCDABD... ABCDABF... 簡單的說, 傳統解兩字串匹配部分 可能會來個雙迴圈, 哀個比對, 當不匹配的時候, 會將下方列再後移1位 然後不匹配再後移 然而 如果像上放已經有4個屬於匹配的字串, 她就應該直接往後移四位來匹配, 而不是只移動1位 隱藏的思維是, 當...