基于Spring Boot手把手博客系统企业级前后端实战-学习笔记

发布时间 2023-08-18 10:10:37作者: 咔咔皮卡丘

一、spring boot 初始化工程

1、网址:https://start.spring.io

二、Gradle 安装(绿色版)

1、windows下

-下载:http://downloads.gradle.org/distributions/gradle-3.5-bin.zip

-解压:

-配置环境变量:

新建环境变量 GRADLE_HOME,即 D:\usr\local\gradle-3.5

修改环境变量 Path,即追加 %GRADLE_HOME%\BIN

-验证:gradle -v

2、linux下

-下载:wget http://downloads.gradle.org/distributions/gradle-3.5-bin.zip

-解压:unzip gradle-3.5-bin.zip

-移到指定目录:mv gradle-3.5 /usr/local/

-配置环境变量:

## vim /etc/profile

export GRADLE_HOME=/usr/local/gradle-3.5

PATH=$PATH:$GRADLE_HOME/bin

## source /etc/profile

source /etc/profile

-验证:gradle -v

三、Gradle 使用

1、学习网址:https://github.com/waylau/gradle-3-user-guide

2、编译:在工程目录下执行 gradle build (路过测试:gradle build -x test )

3、修改中央仓库:

修改build.gradle文件(有两处repositories):

repositories{

maven{

url 'http://maven.aliyun.com/nexus/content/groups/public/'

}

}

四、spring boot

1、接口测试类

@RunWith(SpringRunner.class)

@SpringBootTest

@AutoConfigureMockMvc

public class HelloWorldTest {

@Autowired

MockMvc mockMvc;

@Test

public void sayHello() throws Exception {

mockMvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.APPLICATION_JSON))

.andExpect(MockMvcResultMatchers.status().isOk())

.andExpect(MockMvcResultMatchers.content().string("hello"));

}

}

2、常用注解:http://blog.csdn.net/lafengwnagzi/article/details/53034369 http://blog.csdn.net/zsq520520/article/details/55261359

五、thymeleaf 模板使用

1、标签

<p th:text="#{user.name}"></p> 此为thymeleaf模板标签,文档头部需要引入标签库存<html xmlns:th="http://www.thymeleaf.org">

<p data-th-text="#{user.name}"></p>

2、表达式

2.1 变量表达式 ${...}

2.2 消息表达式 #{...} 里面放的是消息的key,也称为文本外部化、国际化或i18n

2.3 选择表达式 *{} 与变量表达式区别:它们是在当前选择的对象而不是整个上下文变量映射上执行

eg:

<div th:object ="${book}">

<span th:text="*{title}">这里会显示book.title</span>

</div>

2.4 链接表达式 @{...}

eg:

<a th:href="@{...}"></a>

../abc/ 相对上下文

~/abc/ 相对服务器

//abc/ 相对协议,就是自动实例http: 或者 https:

http://abc 绝对

2.5 分段表达式th:insert 、th:include(3.x版本后,不再推荐使用) 或 th:replace

eg:

在/templates/fragments/footer.html页面有个片段

<footer th:fragment="footer">脚部</footer>

在main.html页面可以这样引用

<div th: insert="fragments/footer :: footer" ></div><!-- 作为div的子元素插入 -->

<div th: replace="fragments/footer :: footer" ></div><!-- 直接div取代 -->

<div th: insert="~{fragments/footer :: footer}" ></div><!-- 作为div的子元素插入 -->

<div th: replace="~{fragments/footer :: footer}" ></div><!-- 直接div取代 -->

3、字面量

文本 :th:text="'文本'" 有单引号

数值 :th:text="3+2"

布尔 :th:if="${user.isAdmin()}==false"

th:if="${variable.somnething}==null"

4、运算符

4.1 算术操作 + - * / %

4.2 比较与等价 > < >= <= == != (gt lt ge le eq ne)

eg: th:if="${page.totalPages le 7}"

4.3 条件运算符

th:class="${row.even}?'even':'odd'"

无操作 _

th:text="${user.name}?:_" 如果user.name不存在,保留原有的值

5、设置属性值

5.1 设置任意属性值:th:attr

eg:th:attr="action=@{/subscribe}"

5.2 设置值到指定属性值 th:属性名

eg:th:action="@{/subscribe}"

常用: th:action th:each th:field th:href th:id

th:if th:include th:fragment th:object th:src

th:replace th:text th:value

5.3 固定值布尔属性 checked

<input type="checkbox" name="active" th:checked="${user.active}" />

th:disabled

th:hidden

th:readonly

th:required

th:selected

6、迭代器

6.1 基本的迭代 th:each

<tr th:each="user,userStat : ${list}">

<td th:text="${user.userName}">Onions</td>

<td th:text="${user.email}">test@test.com.cn</td>

<td th:text="${user.isAdmin}">yes</td>

<td th:text="${userStat.index}">状态变量:index</td>

<td th:text="${userStat.count}">状态变量:count</td>

<td th:text="${userStat.size}">状态变量:size</td>

<td th:text="${userStat.current.userName}">状态变量:current</td>

<td th:text="${userStat.even}">状态变量:even****</td>

<td th:text="${userStat.odd}">状态变量:odd</td>

<td th:text="${userStat.first}">状态变量:first</td>

<td th:text="${userStat.last}">状态变量:last</td>

</tr>

-状态变量iterStat

index:当前迭代对象的index(从0开始计算)

count: 当前迭代对象的index(从1开始计算)

size:被迭代对象的大小

current:当前迭代变量

even/odd:布尔值,当前循环是否是偶数/奇数(从0开始计算)

first:布尔值,当前循环是否是第一个

last:布尔值,当前循环是否是最后一个

7、条件语句 th:if th:unless switch

th:if="${page.totalPages le 7}"

th:unless="${page.totalPages le 7}" 与th:if 相反

<td th:switch="${customer.gender?.name()}"> <!-- 若gender不存在或为null时,取得customer对象的name -->

<img th:case="'MALE'" th:src="@{/images/male.png}" alt="Male" />

<img th:case="'FEMALE'" th:src="@{/images/female.png}" alt="Female" />image -->

<span th:case="*">Unknown</span>

</td>

8、局部变量 th:with

<div th:with="firstPer=${persons[0]},secondPer=${persons[1]}">

<p>

The name of the first person is <span th:text="${firstPer.name}">Julius Caesar</span>.

</p>

<p>

But the name of the second person is <span th:text="${secondPer.name}">Marcus Antonius</span>.

</p>

</div>

9、模板布局

9.1、 使用th:fragment

在/templates/fragments/footer.html页面有个片段

<footer th:fragment="footer">脚部</footer>

在main.html页面可以这样引用

<div th: insert="fragments/footer :: footer" ></div><!-- 作为div的子元素插入 -->

<div th: replace="fragments/footer :: footer" ></div><!-- 直接div取代 -->

<div th: insert="~{fragments/footer :: footer}" ></div><!-- 作为div的子元素插入 -->

<div th: replace="~{fragments/footer :: footer}" ></div><!-- 直接div取代 -->

9.2、 不使用th:fragment

在/templates/footer.html页面有个片段

<footer id="copy-section">脚部</footer>

在main.html页面可以这样引用

<div th:insert="fragments/footer :: #copy-section"></div>

<div th:replace="fragments/footer :: #copy-section"></div>

<div th:insert="~{fragments/footer :: #copy-section}"></div>

<div th:replace="~{fragments/footer :: #copy-section}"></div>

10、属性优先级

属性的优先级与标签的先后顺序无关

11、注释

11.1、标准的html注释

11.2、thymeleaf 解析器级别注释块

删除<!--/* 和 */-->之间的所有内容

<!--/*-->

<div>在静态页面时,可以看到这里的内容,解析后就无法看到</div>

<!--*/-->

11.3、原型注释块

<!--/*/

<div>在静态页面时,无法看到这里的内容,解析后就可以看到</div>

/*/-->

12、内联

12.1 内联表达式

[[...]] 对应于 th:text 对特殊符号进行转义

[(...)] 对应于 th:utext 不会对特殊符号进行转义

12.2 禁用内联表达式

th:inline = "none"

12.3 JavaScript内联

<script th:inline="JavaScript">

var username = /*[(${session.user.name})]*/ "初始值";

</script>

12.4 css内联

<style th:inline="css">

.[(${classname})] {

text-align:[(${align})]

}

</style>

13、表达式基本对象

13.1 #ctx:上下文对象。

${#ctx.locale}

${#ctx.variableName}

${#ctx.request}

${#ctx.response}

${#ctx.session}

${#ctx.servletContext}

13.2 #locale:直接访问与java.util.Locale关联的当前的请求

${#locale}

13.3 param

13.4 session

13.5 application

13.6 #request:直接访问与当前请求关联的HttpServletRequest对象

13.7 #session:直接访问与当前请求关联的HttpSession对象

13.8 #servletContext:直接访问与当前请求关联的javax.servlet.ServletContest

14、与spring boot 整合

14.1 build.gradle文件

//添加 thymeleaf 的依赖

compile('org.springframework.boot:spring-boot-starter-thymeleaf')

//自定义thymeleaf 和 thymeleafLayoutDialect 的版本

ext['thymeleaf.version'] = '3.0.3.RELEASE'

ext['thymeleaf-layout-dialect.version'] = '2.2.0'

14.2 application.properties文件

#thymeleaf

spring.thymeleaf.encoding=UTF-8

#禁用缓存,达到热部署效果

spring.thymeleaf.cache=false

#使用HTML5标准

spring.thymeleaf.mode=HTML5

六、Spring Data JPA

1、常用接口

1.1 CrudRespository(继承了Respository) 包含了根据主键增删改查方法

1.2 PagingAndSortingRepository(继承了CrudRespository) 具有分页和排序方法的接口

1.3 自定义接口(继承了Respository<User,Long>或其子接口)

eg:根据方法名创建查询http://blog.csdn.net/yingxiake/article/details/51001740

-利用属性获取任务列表

interface TaskDao extends MyBaseRepository<Task, Long> {

List<Task> findByName(String name);

}

-利用and 和 or来获取任务列表

interface TaskDao extends JpaRepository<Task, Long> {

List<Task> findByNameAndProjectId(String name,Long projectId);

List<Task> findByNameOrProjectId(String name,Long projectId);

}

-利用Pageable ,Sort,Slice获取分页的任务列表和排序

Page<Task> findByName(String name,Pageable pageable);

Slice<Task> findByName(String name, Pageable pageable);

List<Task> findByName(String name, Sort sort);

}

-利用Distinct去重

interface TaskDao extends JpaRepository<Task, Long> {

List<Person> findDistinctTaskByNameOrProjectId(String name, Long projectId);

}

-利用IgnoreCase忽略大小写

interface TaskDao extends JpaRepository<Task, Long> {

List<Person> findByNameIgnoreCase(String name);

List<Person> findByNameAndSexAllIgnoreCase(String name,String sex);

}

-利用OrderBy进行排序

interface TaskDao extends JpaRepository<Task, Long> {

List<Person> findByNameOrderByProjectIdDesc(String name, Long projectId);

}

-利用 Top 和 First来获取限制数据

interface TaskDao extends JpaRepository<Task, Long> {

User findFirstByOrderByLastnameAsc();

Task findTopByOrderByNameDesc(String name);

Page<Task> queryFirst10ByName(String name, Pageable pageable);

Slice<Task> findTop3ByName(String name, Pageable pageable);

List<Task> findFirst10ByName(String name, Sort sort);

List<Task> findTop10ByName(String name, Pageable pageable);

}

2、Spring Data JPA、Hibernate 与 Spring Boot集成

2.1 build.gradle文件

// 添加 Spring Data JPA 的依赖

compile('org.springframework.boot:spring-boot-starter-data-jpa')

// 添加 MySQL连接驱动 的依赖

compile('mysql:mysql-connector-java:6.0.5')

// 添加 H2 的依赖(内存数据库存)

runtime('com.h2database:h2:1.4.193')

// 自定义 Hibernate 的版本

ext['Hibernate.version'] = '5.2.8.Final'

2.2 applicayion.properties文件(H2实例)

# 使用 H2 控制台 访问地址:localhost:8080/h2-console/login.jsp 默认数据库存为:jdbc:h2:mem:testdb

spring.h2.console.enabled=true

applicayion.properties文件(Mysql实例,指定了数据源后,H2会自动失效)

#DataSource

spring.datasource.url=jdbc:mysql://localhost:3306/blog?characterEncoding=utf-8&useSSL=false&serverTimezone=UTC

spring.datasource.username=root

spring.datasource.password=htjf20162016!!

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

#JPA

spring.jpa.show-sql=true

#应用没次启动时,将数据库表删除

spring.jpa.hibernate.ddl-auto=create-drop

3、使用

3.1 将对象改造成数据库映射实体

@Entity

public class User {

@Id

@GeneratedValue(strategy = GenerationType.IDENTITY)//自增策略

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;

}

}

3.2 资源库 继承CrudRespository

七、ElasticSearch应用

1、 全文搜索简介

非结构化数据的检索:

顺序扫描法(Serial Scanning)

全文搜索(Full-text Search):将非结构化数据部分信息提取出来并组织成有一定结构的数据,创建索引,再进行查询

2、 全文搜索实现原理

建立本库->建立索引->执行搜索->过滤结果

3、 基于Java的开源实现

-Lucene

-ElasticSearch(建立在Lucene之上,只支持json,使用restful风格,实时搜索效率较高)

-Solr(建立在Lucene之上,支持非常多的数据格式)

4、 ElasticSearch是什么

高度可扩展的开源全文搜索和分析引擎

快速地、近实时的对大数据进行存储、搜索和分析

用来支撑有复杂的数据搜索需求的企业级应用

5、 ElasticSearch特点

分布式、高可用、多类型、多API、面向文档、异步写入、近实时(可以修改间隔时间)、基于Lucene、Apache协议

6、 ElasticSearch核心概念:

近实时(可以修改间隔时间)

集群和节点:master、slave

分片:每个索引都有多个分片,每个分片是一个Lucene索引

副本:(es创建索引时,默认为生成5个分片,一个副本,数量只能在创建索引时修改)

基础概念

- 索引:含有相同属性的文档集合(相当于sql中的database)

- 类型:索引可以定义一个或多个类型,文档必须属于一个类型(相当于sql中的table)

- 文档:文档是可以被索引的基本数据单位(json格式)(相当于sql中的table中的一条记录)

7、 ElasticSearch与SpringBoot集成(ElasticSearch 2.4.4)

7.1 build.gradle文件

// 添加 Spring Data Elasticsearch 的依赖

compile('org.springframework.boot:spring-boot-starter-data-elasticsearch')

// 添加 JNA 的依赖

compile('net.java.dev.jna:jna:4.3.0')

7.2 applicayion.properties文件

#Elaticsearch

#Elaticsearch cluster-name 默认为elasticsearch

spring.data.elasticsearch.cluster-name = elasticsearch

#Elaticsearch 服务地址

spring.data.elasticsearch.cluster-nodes=localhost:9300

#设置连接超时时间

spring.data.elasticsearch.properties.transport.tcp.connect_timeout=120s

7.3 安装(绿色版):www.elastic.co/downloads

-下载,解压

问题点:

http://www.cnblogs.com/sloveling/p/elasticsearch.html

http://www.imooc.com/article/20336

外网访问:

http://www.jianshu.com/p/658961f707d8

-启动

./bin/elasticsearch

nohup./bin/elasticsearch& 后台启动

-验证:访问 127.0.0.1:9200

7.4 elasticsearch-head 插件

-下载 https://github.com/mobz/elasticsearch-head.git

-解压

-安装node.js(6.x以上版本,建议安装最新版本)

-在elasticsearch-head目录下执行

-npm install

-npm run start

7.5 elasticsearch-head 与 elasticsearch 连接

-修改elasticsearch配置文件elasticsearch.yml

在最后面加上

http.cors.enabled: true

http.cors.allow-origin: "*"

7.6 elasticsearch分布式安装(以一个主节点,两个分节点为例)

-master的elasticsearch.yml添加:

#解决跨域

http.cors.enabled: true

http.cors.allow-origin: "*"

#集群master

cluster.name: wali

node.name: master

node.master: true

#指定ip与端口

network.host: 127.0.0.1

-slave1的elasticsearch.yml添加:

#集群slave1

cluster.name: wali

node.name: slave1

#master只能有一个

#node.master: true

#指定ip与端口

network.host: 127.0.0.1

http.port: 8200

#指定集群host,不然集群中是无法找到该分支

discovery.zen.ping.unicast.hosts: ["127.0.0.1"]

-slave2的elasticsearch.yml添加:

#集群slave1

cluster.name: wali

node.name: slave2

#master只能有一个

#node.master: true

#指定ip与端口

network.host: 127.0.0.1

http.port: 8800

#指定集群host,不然集群中是无法找到该分支

discovery.zen.ping.unicast.hosts: ["127.0.0.1"]

7.7 restful API

API:http://<ip>:<port>/<索引>/<类型>/<文档id>

httpMethod:GET/PUT/POST/DELETE

八、架构设计与分层

1、分层:表示层(Presentation Layer),业务层(Business Layer),数据访问层(Data Access Layer)

九、bootstrap应用(实例:http://v4-alpha.getbootstrap.com/examples/)

1、相关依赖

#Bootstrap中有些样式会用到,eg:tooltip

Tether 1.4.0 http://tether.io

Bootstrap v4.0.0-alpha.6 http://v4-alpha.getbootstrap.com

JQuery 3.1.1 http://jquery.com/download/

#图标库

Font Awesome 4.7.0 http://fontawesome.io

#进度条

NProgress 0.02 http://ricostacruz.com/nprogress/

#markdowm格式

Thinker-md http://git.oschina.net/benhail/thinker-md

#用于生成标签的插件

jquery Tags input 1.3.6 http://xoxco.com/projects/code/tagsinput/

#用于下拉的插件

Bootstrap Chosen 1.0.3 https://github.com/haubek/bootstrap4c-chosen

#信息提示

toastr 2.1.1 http://www.toastrjs.com

十、Spring Security应用

1、模块

Core spring-security-core.jar

Remoting spring-security-remoting.jar

Web spring-security-web.jar

Config spring-security-config.jar

LDAP spring-security-ldap.jar

ACL spring-security-acl.jar

CAS spring-security-cas.jar

OpenID spring-security-openid.jar

Test spring-security-test.jar

2、Spring Security与SpringBoot集成

2.1 build.gradle文件

// 添加 Spring Security 的依赖

compile('org.springframework.boot:spring-boot-starter-security')

// 添加 Thymeleaf Spring Security 的依赖

compile('org.thymeleaf.extras:thymeleaf-extras-springsecurity4:3.0.2.RELEASE')

2.2 applicayion.properties文件

#Spring Security

2.3 config配置

/**

* 安全配置类似

*/

@EnableWebSecurity

@EnableGlobalMethodSecurity(prePostEnabled = true) // 启用方法安全设置

public class SecurityConfig extends WebSecurityConfigurerAdapter {

private final Logger logger = LoggerFactory.getLogger(SecurityConfig.class);

/**

* 自定义权限拦截链配置

* @param http

* @throws Exception

*/

@Override

protected void configure(HttpSecurity http) throws Exception {

logger.debug("===========使用自定义权限拦截链==============");

http.authorizeRequests()

// .anyRequest().authenticated()

.antMatchers("/css/**","/js/**","/fonts/**","/index").permitAll() //静态资源都开放访问

.antMatchers("/users/**").hasRole("ADMIN") //需要相应的角色才能访问

.and()

.formLogin() //基于Form表单登录验证

.loginPage("/login").failureUrl("/login-error"); //自定义登录界面

}

/**

* 认证信息管理

* @param auth

* @throws Exception

*/

@Autowired

public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {

auth.inMemoryAuthentication()

.withUser("waylau").password("123456").roles("ADMIN");

}

}

2.4 html添加标签引用 xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4"

十一、文件服务器

1、下载地址:https://github.com/waylau/mongodb-file-server

2、默认是使用内嵌mongodb,如果上线使用,就要更改为独立的mongodb

2.1、注释掉: compile('de.flapdoodle.embed:de.flapdoodle.embed.mongo')

2.2、安装一个mongodb,修改配置文件:mongod.cfg

systemLog:

destination: field

path: d:\mongoData\log\mongod.log

storage:

dbPath: d:\mongoData\db

2.3、启动 mongod.exe --config=mongod.cfg

2.4、在文件服务器 application.properties 中 添加spring.data.mongodb.uri=mongodb://localhost:27017/test

3、使用 通过http://ip:port/upload 可以上传文件及读