2020年2月20日 星期四

IntelliJ IDEA 創建 Servlet 並整合 Thymeleaf


1.File -> New -> Project

下面的 web.xml 看要不要產生,後面也還可以改
如果要 thymeleaf,就可以勾 thymeleaf,子選項都不用勾


2.產生後,加入 servlet 的 jar 檔

路徑選 tomcat 路徑下的 bin,抓 servlet-api 或整個資料夾都選


3.File -> Project Structure

如果一開始沒有選 web.xml,可在這裡加入


4.新增 Servlet

舊版的 IntelliJ 不一定會取 Create New Servlet,可能是 New Servlet 而已
如果是用 @WebServlet,要注意預設屬性是 name,但大部分是用 urlPatterns


5.Run -> Edit Configurations

Server 活頁標籤 Application server 要選中 tomcat 的路徑
下面還有 After launch,表示啟動後用什麼瀏覽器打開
Http port 寫你想要的 port

Deployment 的紅框部份的 context 是瀏覽器上要用到的路徑,假設寫 /test,那瀏覽器就要打
http://localhost:8080/test/index.html
又如果是寫 /,那就打
http://localhost:8080/index.html

※如果是 社區版,可以在 File >> Settings >> Plugins,搜尋 smart tomcat 來安裝
Deployment Directory 寫 jsp 的資料夾路徑,一定要有路徑,否則啟動不起來,亂指定沒關係,只差在顯示不了 jsp 的畫面而已
.配合 maven 或 gradle 就可啟動伺服器了,但 gradle 加入 servlet 時,用 providedCompile 時,必需再增加 id 'war',如下:
plugins {
    id 'java'
    id 'war'
}

.社區版也沒有用滑鼠點一點就有 Servlet 可用,只能自己寫了,要對 servlet 熟一點而已


※Thymeleaf


※如果一開始有勾 thymeleaf,且有寫代碼,那啟動伺服器時會報找不到 thymeleaf 的錯,要照這張圖的設定就可以了


※MyServlet.java

@WebServlet("*.do")
public class MyServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setContentType("text/html;charset=UTF-8");
        //request.getRequestDispatcher("/WEB-INF/templates/welcome.html").forward(request, response);
    
        WebContext ctx = new WebContext(request, response, request.getServletContext(),
                request.getLocale());
        ctx.setVariable("now", LocalDateTime.now().toString());
    
        var templateResolver = new ServletContextTemplateResolver(request.getServletContext());
        templateResolver.setPrefix("/WEB-INF/templates/");
        templateResolver.setSuffix(".html");
    
        TemplateEngine templateEngine = new TemplateEngine();
        templateEngine.setTemplateResolver(templateResolver);
        templateEngine.process("hi", ctx, response.getWriter()); // 找 /WEB-INF/templates/hi.html
    }
}



※hi.html

<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Thymeleaf Demo</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<body>
    <p th:text="#{xxx.ooo}">default text</p>
    <p>Date : <span th:text="${now}">no data</span></p>
</body>
</html>


※hi_en.properties

xxx.ooo=Hello! Thymeleaf!


git 專案

2020年2月14日 星期五

git submodule/subtree

※submodule

一、新增子模組

git submodule status // 只能看有沒有子模組,沒有什麼都不顯示;有就顯示 hash,此 hash 同子模組

git submodule add 路徑
有4個地方會改變
1.整個子模組會成為主模組的一個目錄
2.多了 .gitmodules(隱藏檔),裡面是多個子模組的資訊
3. .git 會增加 modules 資料夾,裡面是各個子模組,再點進去是子模組的 .git 目錄
4. .git/config 檔也會增加資訊,使用 git config --list 會抓此檔的資訊,所以
用這個命令也可以看到

注意事項:
1.主模組和子模組操作是分開的(主模組的命令只對自己有用,子模組也是),但在主模組可看到子模組的狀態,只能看有沒有變動,至於變動什麼要進去子模組操作才知道
  P.S 操作子模組要進去這個子模組裡面,命令都和之前一樣
2.子模組有變動,要做到 commit 這一步,主模組的 add 才有用,add 有用才能對子模組進行版本控制
3.如果只 push 主模組,那別人更新時會有麻煩,所以在 push 時,可用 git push --recurse-submodules=check
如果子模組沒有 push,就會報錯
git push --recurse-submodules=on-demand 會在主模組 push 前將子模組先 push,當然如果有錯就不行


如果有多個子模組都想更新,用上面的方法會進入各個子模組進行操作,比較麻煩,可用如下方式解決
git submodule update --remote 子模組名(如果要更新全部的模組就不需要打子模組名)
這樣所有的子模組就會更新了,但會使子模組分支變成 detached,
解決方法是在子模組新增一個分支,然後在 main 分支 merge 新的分支,最後再刪除新分支

上面的做法太麻煩,以下其中一個指令可以直接做好
git submodule update --remote --merge
git submodule update --remote --rebase


二、clone 有子模組的 git

clone 完,.gitmodules 檔案是 ok 的,但子模組裡是空的
git submodule status 看起來是有的,但實際上是空的

所以要下如下的指令
git submodule init // .git/config 會寫入子模組的資訊,但子模組仍然是空的
git submodule update // 下載子模組的資料
  P.S 以上兩行順序不能換,否則 update 也不報錯,但什麼都沒發生
git submodule update --init // 合併成一行

如果一開始就知道有子模組,可下如下的指令
git clone --recursive 路徑


三、刪除子模組

1.git submodule deinit submodule名(遠端的名字)或者 --all // 將 config 檔案裡的資訊移除,也會將子模組裡的東西清空,在做這步之前 status 必需要是最新的
2.git rm --cached submodule專案名 // 將.gitmodules 檔案裡的子模組資料刪除(--cached 會保留子模組目錄,如不需要就不要加)
  P.S 以上兩步 git submodule status 就看不到了,但其實還沒移乾淨
3.將.git/modules 裡的子模組資料夾刪除(如用指令可下 rm -rf submodule_name)



※subtree

一、新增子樹

git subtree add --prefix=子樹名 --squash 路徑或遠端名 master
--prefix=(有等號) 也可寫成 -P(沒等號), 子樹名會變成目錄名,而路徑的內容會在裡面
--squash 如果不加會所有 log 歷史都有,squash 是壓縮的意思,可想成是精簡版,表示只要最新的 log
master 是遠端分支,意思就是從遠端的 master 分支複製過來
路徑或遠端名:使用 git remote add key 路徑,是個鍵值對,設定完後,這個 key 就等同是遠端名了


二、上傳子樹

git subtree push --prefix=子樹名 路徑或遠端名 master
如果只用 git push 不會上傳子樹






三、下載子樹

git subtree pull --squash --prefix=子樹名 路徑或遠端名 master
注意:如果 add 時有 squash,這裡也要加



※ submodule 和 subtree 比較

submodule 是參照的方式,所以操作時,兩個模組是分開的;commit 和子模組會一樣
subtree 是複製的方式,所以操作時還是用主樹操作即可;commit 和子樹不同