企业级博客项目笔记(一)

这篇博客介绍了企业级博客项目中使用Gradle进行测试和构建,详细阐述了自定义存储库以加速构建,配置Gradle Wrapper,以及开发环境的搭建。此外,文章深入探讨了Thymeleaf的集成,包括Thymeleaf的概念、语法特性如变量表达式、消息表达式,以及在实际项目中的应用和配置。
摘要由CSDN通过智能技术生成

企业级博客项目笔记(一)

一、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>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
第1章 Spring Boot 简介 讲解Spring Boot的项目背景,已经与其他技术框架(比如,Spring、SpringMVC、SpringCloud等)的关系。简单介绍下Spring Boot 整个生态系统 第2章 开启 Spring Boot 的第一个 Web 项目 通过 Spring Initializr 来快速初始化一个 Spring Boot 原型,方便学员来极速体验Spring Boot。本课程也将会采用Gradle作为项目管理工具,让学员掌握最前瞻的构建工具。通过探索项目让学员了解项目的结构,已经相关的配置原理。 第3章 一个Hello World项目 本章是正式开始动手敲代码了。依照惯例,会先编写一个最简单的Hello World程序。从项目配置,应用的编写,再到测试用例,最后运行项目。方面学员了解整个编码的流程。 第4章 开发环境的搭建 为了让实战过程更顺利,避免不要的问题,这里会先将课程所要求的环境进行一个讲解,并要求学员最好跟随课程的环境配置。本节也会讲解如何将项目导入IDE 来运行。 第5章 集成Thymeleaf模版引擎 Thymeleaf 方面的内容,知识点会讲解的相对全面点。Thymeleaf作为界面的模版引擎,对于界面的布局和实现起着非常关键的作用。本章节也会讲解Thymeleaf 如何与 Spring Boot 来进行集成。最后通过一个实战,来让学员更加深刻的理解Thymeleaf。… 第6章 数据持久化Spring Data JPA 本章节涉及数据的持久化。从JPA规范讲起,到Spring对于JPA的用法以及与Hibernate集成实现。本课程的数据库采用MySQL,但也可以方便切换到其他数据库。最后通过一个实战内容,来帮助学员理解掌握。 第7章 全文搜索ElasticSearch 企业级应用中,难免会涉及到全文搜素。对于Java应用来说,ElasticSearch在全文搜索方面是一把“利器”。本章节会将带领学员了解全文搜索的概念,并熟悉如何用ElasticSearch来实现全文搜索。 第8章 架构设计与分层 本章节讲解了系统的整体架构设计思路,包括如何来组织项目结构。让学员理解系统的数据流程。 第9章 集成 Bootstrap Bootsrap最大的好处是,可以让整个系统界面实现响应式布局。本节先从Bootstrap 的基本原理讲起,并将常用的前端框架比如 JQuery等进行集成。最后通过一个实战内容,来帮助学员理解掌握。 第10章 博客系统的需求分析与原型设计 本章节是对博客系统的需求分析与设计。对于企业级应用的完整流程来说,需求的分析与设计是必不可少的环节。本章节设计部分包含了原型设计、数据库设计及接口设计。 第11章 权限管理Spring Security Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架,在企业级应用中被广泛使用。本章节不会对该框架做深入探讨,仅从基于角色的权限管理角度,来实现对系统的权限管理。 第12章 博客系统的整体框架实现 先对系统的整个界面、结构、布局、API进行实现,这样方便每个模块进行划分及实现。 第13章 博客系统的用户管理实现 对用户管理模块进行前后台的实现。 第14章 博客系统的角色管理实现 对用户角色理模块进行前后台的实现。 第15章 博客系统的权限管理实现 对用权限理模块进行前后台的实现。 第16章 博客系统的博客管理实现 对博客管理模块进行前后台的实现。 第17章 博客系统的评论管理实现 对评论管理模块进行前后台的实现。 第18章 博客系统的点赞管理实现 对用户点赞理模块进行前后台的实现。 第19章 博客系统的分类管理实现 对分类管理模块进行前后台的实现。 第20章 博客系统的标签管理实现 对标签管理模块进行前后台的实现。 第21章 博客系统的搜索实现 对搜索模块进行前后台的实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值