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

 一、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 可以上传文件及读

posted @ 2023-08-18 10:06  咔咔皮卡丘  阅读(55)  评论(0编辑  收藏  举报