企業級博客項目筆記(一)

企業級博客項目筆記(一)

一、Gradle測試

1.編寫項目構建信息

初始化helloworld項目:可以複製基礎項目的gradle、src 、.gitignore、build.gradle、gradlew、gradlew.bat文件

  • 編輯build.gradle文件:修改version版本號
  • 編譯項目:gradle build
  • 啓動項目:java -jar 項目jar包

2.自定義存儲庫,加速構建

  • 修改build.gradle文件:repositories中的值改爲 url 'http://maven.aliyun.com/nexus/content/groups/public'

3.編寫程序代碼

  • 編寫HelloController.java和HelloControllerTest.java

4.配置Gradle Wrapper

  • 修改gradle/wrapper/gradle-wrapper.properties配置文件
  • gradle/wrapper下的jar包是wrapper的應用程序
  • gradle-wrapper.properties配置文件中的distributionUrl是gradle安裝包的官方地址
  • gradlew.bat是在windows下執行的wrapper腳本:gradlew build使用wrapper編譯項目

二、開發環境的搭建

1.安裝、配置IDE

  • jdk、gradle、eclipse

2.導入項目、運行

  • 設置發佈包的位置:默認Gradle wrapper
  • 第一次導入項目,會有依賴包下載
  • 三種運行方式:1.使用java -jar命令 2.以javaApplication.java運行 3.Spring Boot Gradle Plugin 插件啓動:gradle bootRun/gradlew bootRun

3.擴展學習

  • 常用Eclipse插件:https://github.com/waylau/everything-in-eclipse

三、集成Thymeleaf

1.Thymeleaf

  • 概念:Java模板引擎,能夠處理HTML、XML、JavaScript、CSS甚至純文本。類似JSP、Freemarker
  • 優點:自然模板。原型即頁面;語法優雅易懂。OGNL、SpringEL;遵從Web標準。支持HTML5;

2.如何識別Thymeleaf標準方言

  • <span th:text="..."> ---比較常用,需要引入名稱空間
    <html xmln:th="http://www.thymeleaf.org">
  • <span data-th-text="..."> ---html5標準,自定義屬性

3.變量表達式

  • 語法:${...}
    <span th:text="${book.author.name}">

4.消息表達式

  • 語法:#{...} 
    <table> 
    ...
    <th th:text="#{header.address.city}">..</th>
    <th th:text="#{header.address.country}">...</th> 
    ...
    </table>
  • 消息表達式也稱之爲文本外化、國際化或i18n

5.選擇表達式

  • 語法:*{...}
    <div th:object="${book}">
    ...
    <span th:text="*{title}">...</span> 
    ... 
    </div>
  • 與變量表達式的區別:它們是在當前選擇的對象而不是整個上下文變量映射上執行

6.鏈接表達式

  • 語法:@{...}
    鏈接表達式可以是相對的,在這種情況下,應用程序上下文將不會作爲URL的前綴 
    <a th:href="@{../documnets/report}">...</a>
    也可以是服務器相對(同樣,沒有應用程序上下文前綴)
    <a th:href="@{~/contents/main}">...</a> 和協議相對(就像絕對URL,但瀏覽器將使用在顯示的頁面中使用的相同的HTTP或HTTPS協議)
    <a th:href="@{//static.mycompany.com/res/initial}">...</a>

7. 分段表達式

  • 語法:th:insert或th;replace
    <div th:fragment="copy"/>
    © 2017 <a href="https://waylau.com">waylau.com</a>
    </div>
    <div th:insert="~{footer :: copy}"></div> //表示重用上述代碼片段

8.字面量(文字)

  • 文本(使用單引號)
    <p> Now you are looking at a <span th:text="'working web application'">template file</span></p>
  • 數字(直接放在雙引號中,可以進行運算)<p>The year is <span th:text="2013">1492</span>.</p>
    <p>In two years,it will be <span th:text="2013+2">1494</span>.</p>
  • 布爾(false/true)
  • null
  • 算術操作:+、-、*、/、%
  • 比較和等價:

比較:>、<、>=、<=(gt、lt、ge、le) <防止與<>出現衝突>
等價:==、!=(eq、ne)

  • 條件運算符: 
    <tr th:class="${row.even}? 'even':'odd'">...</tr>
  • 無操作:(_) <span th:text="${user.name} ?:_">no user authenticated</span>

9.設置屬性值

  • 設置任意屬性值 th:attr 
    <form action="subscribe.html" th:attr="action=@{/subscribe}"> 
      <fieldset> 
        <input type="text" name="email" /> 
        <input type="submit" value="Subscribe!"th:attr="value=#{subscribe.submit}" /> 
      </fieldset> 
    </form>
  • 設置值到指定的屬性 
    <form action="subscribe.html" th:action="@{/subscribe}"> 
    <input type="submit" value="Subscribe!" th:value="#{subscribe.submit}" />
  • 固定值布爾屬性 
    <input type="checkbox" name="option2" checked /> <!--HTML--> <input type="checkbox" name="option1" checked="checked" /> <!--XHTML--> 
    thymeleaf中:<input type="checkbox" name="active" th:checked="${user.active}"/>

10.迭代器

  • 基本的迭代th:each (適用於數組、集合、Map) 
    <li th:each="book : ${books}" th:text="${book.title}">En las Orillas del Sar</li>
  • 狀態變量 (index、count、size、current、even/odd、first、last) 
    <tr th:each="prod,iterStat : ${prods}" th:class="${iterStat.odd}? 'odd'">

11.條件語句

  • th:if 、th:unless (unless與if相反) 
    <a href="comments.html" 
      th:href="@{/product/comments(prodId=${prod.id})}"   th:if="${not #lists.isEmpty(prod.comments)}">view</a>
  • switch 
    <div th:switch="${user.role}"> 
      <p th:case="'admin'">User is an administrator</p> 
      <p th:case="#{roles.manager}">User is a manager</p> 
      <p th:case="*">User is a some other thing</p> 
    </div>

12.Thymeleaf模板佈局

  • 定義和引用片段

定義片段:
<div th:fragment="copy"> ©2017<a href="https://waylau.com">waylau.com</a> 
</div> 
引用片段: 
<div th:insert="~(footer :: copy)"></div>

  • 不使用th:fragment定義片段 
    <div id="copy-section"> 
    © 2017<a href="https://waylau.com">waylau.com</a> 
    </div>
  • 不使用th:fragment引用片段 
    <div th:insert="~(footer :: #copy-section)"></div>
  • th:insert、th:replace、th:include三者的區別:
    • th:insert 它將簡單地插入指定的片段作爲正文的主標籤。
    • th:replace 用指定實際片段來替換其主標籤。
    • th:include 類似於th:insert,但不是插入片段它只插入此片段的內容。(3.x版本後,不再推薦使用)
  • 屬性優先級(Thymeleaf中有規定th:屬性的優先級問題) 
     當在同一個標籤中寫入多th:*屬性時,會發生什麼? 
     <ul> 
      <li th:each="item:${items}" th:text="${item.description}">Item description here...</li> 
     </ul>

13.註釋

  • Thymeleaf解析器級註釋塊
    • 刪除<!--/*--> 和<!--*/-->之間的所有內容
  • 原型註釋塊
    • 當模板靜態打開時(比如原型設計),原型註釋塊所註釋的代碼將被註釋,而在模板執行時,這些註釋的代碼,就能被顯示出來。 <span>hello!</span> 
      <!--/*/ 
      <div th:text="${...}"> 
      ... 
      </div> 
      /*/--> 
      <span>goodbye!</span>

14.內聯

  • 內聯表達式 
    [[...]]或[(...)]分別對應於th:text和th:utext 
    注:utext不對內容進行轉義 
    <p>The message is "[(${msg})]"</p> ----》文本中的特殊符號不會被轉義
  • 禁用內聯 
    有時需要禁用這種機制,比如,想輸出[[...]]或[(...)]文本內容 
    <p th:inline="none">A double array looks like this:[[1,2,3],[4,5]]!</p>
  • JavaScript內聯 
    <script th:inline="javascript">
  • CSS內聯 
    <style th:inline="css"> 
    .[[${classname}]]{ 
    text-align:[[${align}]]; 
    } 
    </style>

15.表達式的基本對象

  • 基本對象
    • #ctx:上下文對象。是org.thymeleaf.context.IContext或者org.thymeleaf.context.IWebContext的實現
    • #locale:直接訪問與java.util.Locale關聯的當前請求
  • request/session等屬性
    • param:用於檢索請求參數
    • session:用於檢索session屬性
    • application:用於檢索application/servlet上下文屬性
  • Web上下文對象
    • #request: 直接訪問與當前請求關聯的javax.servlet.http.HttpServletRequest對象
    • #session: 直接訪問與當前請求關聯的javax.servlet.http.HttpSession對象
    • #servletContext:直接訪問與當前請求關聯的javax.servlet.ServletContext對象

16.配置環境

  • 配置環境
    • Thymeleaf3.0.3.RELEASE
    • Thymeleaf Layout Dialect 2.2.0
  • 修改build.gradle
    //依賴關係 
    dependencies{ 
    ... 
    //添加Thymeleaf的依賴 
    compile('org.springframework.boot:spring-boot-starter-thymeleaf') 
    ... 
    } 
    buildscript{ 
    ... 
    //自定義Thymeleaf 和Thymeleaf Layout Dialect的版本 
    ext['thymeleaf.version']='3.0.3.RELEASE' 
    ext['thymeleaf-layout-dialect.version']='2.2.0' 
    ... 
    }

四、Thymeleaf實戰

1. 修改application.properties

#設置編碼方式 
  spring.thymeleaf.encoding=UTF-8 
#熱部署靜態文件 
  spring.thymeleaf.cache=false 
#使用HTML5標準 
  spring.thymeleaf.mode=HTML5

2.API設計(一個Demo,並不遵循Restful風格)

  • GET /users: 返回用於展現用戶列表的list.html頁面;
  • GET /users/{id}: 返回用於展現用戶的view.html頁面;
  • GET /users/form: 返回用於新增或者修改用戶的form.html頁面;
  • POST /users: 新增或者修改用戶,成功後重定向到list.html頁面;
  • GET /users/delete/{id}: 根據id刪除相應的用戶數據,成功後重定向到list.html頁面;
  • GET /users/modify/{id}: 根據id獲取相應的用戶數據,並返回form.html頁面來執行修改。

3.Demo代碼

  • User.java
public class User {
    private Long id; //實體的唯一標識
    private String name; //用戶名稱
    private String email; //用戶郵箱    

    public User(){
    }

    public User(Long id,String name,String email){
        this.id=id;
        this.name=name;
        this.email=email;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}
  • UserRepository.java
public interface UserRepository {
    /**
     * 創建或者修改用戶
     * @param user
     * @return
     */
    User saveOrUpdateUser(User user);

    /**
     * 刪除用戶
     * @param id
     */
    void deleteUser(Long id);

    /**
     * 根據id查詢用戶
     * @param id
     * @return
     */
    User getUserById(Long id);

    /**
     * 獲取用戶列表
     * @return
     */
    List<User> listUsers();
}
  • UserRepositoryImpl.java
@Repository
public class UserRepositoryImpl implements UserRepository {

    private static AtomicLong counter=new AtomicLong(); //用於計數
    private final ConcurrentMap<Long,User> userMap=new ConcurrentHashMap<>();//存儲用戶信息

    @Override
    public User saveOrUpdateUser(User user) {
        Long id=user.getId();
        if(id==null){
            id=counter.incrementAndGet(); //從計數器中獲取一個long型數據
            user.setId(id);
        }
        this.userMap.put(id,user);
        return user;
    }

    @Override
    public void deleteUser(Long id) {
        this.userMap.remove(id);
    }

    @Override
    public User getUserById(Long id) {
        return this.userMap.get(id);
    }

    @Override
    public List<User> listUsers() {
        return new ArrayList<>(this.userMap.values());
    }
}
  • UserController.java
@RestController
@RequestMapping("/users")
public class UserController {

    @Autowired
    private UserRepository userRepository;

    /**
     * 獲取用戶列表
     * @param model
     * @return
     */
    @GetMapping
    public ModelAndView list(Model model){
        model.addAttribute("userList",userRepository.listUsers());
        model.addAttribute("title","用戶管理");
        return new ModelAndView("users/list","userModel",model);
    }

    /**
     * 根據id查詢用戶
     * @param id
     * @param model
     * @return
     */
    @GetMapping("{id}")
    public ModelAndView view(@PathVariable("id")Long id, Model model){
        User user=userRepository.getUserById(id);
        model.addAttribute("user",user);
        model.addAttribute("title","查看用戶");
        return new ModelAndView("users/view","userModel",model);
    }

    /**
     * 獲取創建表單頁面
     * @param model
     * @return
     */
    @GetMapping("/form")
    public ModelAndView createForm(Model model){
        model.addAttribute("user",new User());
        model.addAttribute("title","創建用戶");
        return new ModelAndView("users/form","userModel",model);
    }

    /**
     * 更新用戶
     * @param user
     * @return
     */
    @PostMapping
    public ModelAndView saveOrUpdateUser(User user){
        user=userRepository.saveOrUpdateUser(user);
        return new ModelAndView("redirect:/users");
    }

    /**
     * 根據id刪除用戶
     * @param id
     * @return
     */
    @GetMapping("/delete/{id}")
    public ModelAndView delete(@PathVariable("id")Long id){
        userRepository.deleteUser(id);
        return new ModelAndView("redirect:/users");
    }

    /**
     * 根據id修改用戶
     * @param id
     * @param model
     * @return
     */
    @GetMapping("/modify/{id}")
    public ModelAndView modify(@PathVariable("id")Long id,Model model){
        User user=userRepository.getUserById(id);
        model.addAttribute("user",user);
        model.addAttribute("title","修改用戶");
        return new ModelAndView("users/form","userModel",model);
    }

}
  • header.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
    <meta charset="UTF-8">
    <title>Thymeleaf in action</title>
</head>
<body>
    <div th:fragment="header">
        <h1>Thymeleaf in action</h1>
        <a href="/users" th:href="@{~/users}">首頁</a>
    </div>
</body>
</html>
  • footer.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
    <meta charset="UTF-8">
    <title>Thymeleaf in action</title>
</head>
<body>
    <div th:fragment="footer">
        <a href="https://waylau.com">Welcom to waylau.com</a>
    </div>

</body>
</html>
  • list.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
    <meta charset="UTF-8">
    <title>Thymeleaf in action</title>
</head>
<body>
<!--頭部信息引入-->
<div th:replace="~{fragments/header :: header }"></div>
<h3 th:text="${userModel.title}"></h3>
<div>
    <a href="/users/form.html" th:href="@{/users/form}">創建用戶</a>
</div>
<table border="1">
    <thead >
     <tr>
         <td>ID</td>
         <td>Email</td>
         <td>Name</td>
     </tr>
    </thead>
    <tbody>
      <tr th:if="${userModel.userList.size()} eq 0">
            <td colspan="3">沒有用戶信息!</td>
      </tr>
      <tr th:each="user : ${userModel.userList}">
          <td th:text="${user.id}"></td>
          <td th:text="${user.email}"></td>
          <td><a th:href="@{'/users/'+${user.id}}"  th:text="${user.name}"></a></td>
      </tr>
    </tbody>
</table>
<!--尾部信息引入-->
<div th:replace="~{fragments/footer :: footer }"></div>
</body>
</html>
  • form.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
    <meta charset="UTF-8">
    <title>Thymeleaf in action</title>
</head>
<body>
<div th:replace="~{fragments/header :: header}"></div>
<h3 th:text="${userModel.title}">waylau</h3>
<form action="/users" th:action="@{/users}" method="POST" th:object="${userModel.user}">
   <input type="hidden" name="id" th:value="*{id}">
    名稱:<br/><input type="text" name="name" th:value="*{name}"><br/>
    郵箱:<br/><input type="text" name="email" th:value="*{email}">
    <input type="submit" value="提交">
</form>
<div th:replace="~{fragments/footer :: footer}"></div>
</body>
</html>
  • view.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
    <meta charset="UTF-8">
    <title>Thymeleaf in action</title>
</head>
<body>
<div th:replace="~{fragments/header :: header}"></div>
<h3 th:text="${userModel.title}">waylau</h3>
<div>
    <p><strong>ID:</strong><span th:text="${userModel.user.id}"></span></p>
    <p><strong>Name:</strong><span th:text="${userModel.user.name}"></span></p>
    <p><strong>Email:</strong><span th:text="${userModel.user.email}"></span></p>
</div>
<div>
    <a th:href="@{'/users/delete/'+${userModel.user.id}}">刪除</a>
    <a th:href="@{'/users/modify/'+${userModel.user.id}}">修改</a>
</div>
<div th:replace="~{fragments/footer :: footer}"></div>
</body>
</html>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章