第一章 xml与JavaConfig
- 为什么要使用springboot
因为Spring、SpringMVC需要使用大量的配置文件(xml文件)
还需要配置各种对象,把使用的对象放到spring容器中才能使用对象
需要了解其他框架的配置规则
比较繁琐 - SpringBoot相当于 不需要配置文件的Spring+SpringMVC。常用的框架和第三方库都已经配置好了,直接用。
- SpringBoot开发效率高,使用更方便。
@JavaConfig
javaConfig:使用java类作为xml配置文件的代替,是配置spring容器的纯Java方式。在这个Java类中可以创建Java对象,把对象放入sprig容器中(注入到容器)。
使用两个注解:
- @Configuration:放在一个类上,表示这个类作为配置文件使用。
- @Bean:放在方法上,声明对象,把这个对象注入到容器。相当于
使用示例
1 | package org.example; |
@ImportResource
@ImportResource:导入其他的xml配置文件,等于在xml <import resources="其他配置文件"/>
使用示例
1 |
|
value参数可以是数组,以导入多个xml配置文件
@PropertyResource
@PropertyResource: 读取properties属性配置文件可以实现外部化配置,在程序代码之外提供数据。
步骤:
- 在resources目录下,创建properties文件,使用key=value的格式提供数据
- 在PropertyResource指定properties文件的位置
- 使用@Value(value=”${key}”)
1 |
|
第二章 SpringBoot
介绍
Spring官网
SpringBoot是Spring中的一个成员,可以简化Spring,SpringMVC的使用。核心还是IOC容器。
特点
- Create stand-alone Spring applications
创建Spring应用 - Embed Tomcat, Jetty or Undertow directly (no need to deploy WAR files)
内嵌的tomcat,jetty,undertow服务器(不用部署war包) - Provide opinionated ‘starter’ dependencies to simplify your build configuration
提供了starter起步依赖,来简化应用的配置
比如使用MyBatis框架,需要在Spring项目中,配置MyBatis的对象SqlSessionFactory,Dao的代理对象
在SpringBoot项目中,在pom.xml中,加入一个mybatis-spring-boot-starter依赖 - Automatically configure Spring and 3rd party libraries whenever possible
尽可能去配置spring和第三方库,自动配置(将spring和第三方库中的对象创建好,放入容器中,以便于使用) - Provide production-ready features such as metrics, health checks, and externalized configuration
提供了健康检查,统计,外部化配置 - Absolutely no code generation and no requirement for XML configuration
不用生成代码,不用使用xml做配置
创建SpringBoot项目
使用Spring提供的初始化器,即向导创建SpringBoot应用
使用的地址:https://start.spring.io
国内的地址:https://start.springboot.io
也可以直接访问网址,创建并下载。
SpringBoot的目录结构:
注解的使用
@SpringBootApplication
复合注解:由
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
组成
- @SpringBootConfiguration
部分源码:说明:使用了@SpringBootConfiguration注解标注的类,可以作为配置文件使用,可以使用BEAN声明对象,注入到容器。1
2
3
4
5
6
7
public SpringBootConfiguration {
boolean proxyBeanMethods() default true;
} - @SpringBootConfiguration
启用自动配置,把java对象配置好,注入到spring容器中。例如:将MyBatis对象创建好,放入到容器中。 - @ComponentScan
扫描器,找到注解,根据注解功能创建对象,给属性赋值等。
默认扫描的包:@ComponentScan所在的包和子包。
SpringBoot的配置文件
配置文件名称:application
拓展名:properties(key=value);yml(ket:value)
使用application.properties或application.yml
application.properties示例:
1 | #设置端口号 |
application.yml示例:
1 | server: |
注:properties与yml同时存在时,会使用properties。(一般只是用一个,不要两个一起用)
多环境配置
有开发环境,测试环境,上线环境。
每个环节都有不同的配置信息,例如端口,上下文件,数据库url,用户名,密码等。
使用多环境配置文件,可以方便切换不同的配置。
使用方式:创建多个配置文件,名称规则:application-环境名称.properties(yml)
创建开发环境的配置文件:application-dev.properties(application-dev.yml)
创建测试环境的配置文件:application-test.properties
在application.properties中指定使用哪个配置文件
1 | #激活使用哪个配置文件 |
自定义配置
@Value(“${key}”)
key来自application.properties
1 | student.name=咕咕咕 |
注解加在属性定义上,便能读取配置中的数据。
1 |
|
@ConfigurationProperties(prefix=”…”)
将整个文件映射为一个对象,用于自定义配置项比较多的情况。
在类上加上
@Component
@ConfigurationProperties(prefix = “student”)
注解,prefix内为属性名
1 | package com.example.vo; |
在Controller中使用@Resource自动注入,从容其中拿到对象,进行赋值使用。
SpringBoot中使用jsp(不推荐使用jsp,因为前后端要分离)
SpringBoot不推荐使用jsp,而是使用模板技术代替jsp
SpringBoot原生不支持jsp,需要配置依赖项。
加入一个处理jsp的依赖,负责编译jsp文件。
1
2
3
4<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>如果需要使用servlet,jsp,jstl的功能,还需要添加额外的依赖项。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18<dependencys>
<!--jstl的依赖-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<!--servlet的依赖-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<!--jsp的依赖-->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.3</version>
</dependency>
</dependencys>创建一个存放jsp的目录,一般叫webapp
index.jsp需要在pom.xml指定jsp文件编译后的存放目录
META-INF/resources创建Controller,访问jsp
在application.properties文件中配置视图解析器
使用示例:
index.jsp
1 | <%@ page contextType="text/html;charset=UTF-8” language="java" %> |
Controller类
1 | package com.example; |
application.properties中添加
1 | #配置视图解析器 前缀及后缀 |
pom.xml文件中,指定jsp编译后存放的目录。
1 | <resources> |
jsp正在被逐渐淘汰,因为它在页面中嵌入了java代码。使得前后端不能分离,从而加大了前端与后端的沟通成本,降低了开发效率。
比如下面的对话(来自网络)
后端:你写的页面有问题啊,不显示数据。
前端:不可能,我这边都是好的。
后端:你自己来看啊。
前端:你写的这是什么玩意?我给你的代码不是这样的。
后端:我得把你的代码加到 JSP 里啊。
前端:我又不懂 JSP 啊,你再把代码摘出来吧,我帮你看看问题。
后端:……
可以使用ajax技术,实现前后端分离。
使用容器
通过代码,从容器中获取对象。
在main方法中SpringApplication.run()方法获取返回的String容器对象,再获取业务bean进行调用。
run()方法的源码:
1 | public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) { |
ConfigurableApplicationContext:接口,是ApplicationContext的子接口
使用示例:
手动从容器中获取UserService对象,调用其中的sayHello方法。
1 |
|
CommandLineRunner接口、ApplicationRunner接口
这两个接口都有一个run方法。执行时间在容器对象创建好后,自动执行run()方法。
可以完成自定义的在容器对象创建好的一些操作。
源码:
1 |
|
他们在容器启动完成后执行。
我们只需要实现这个方法,就可以在容器启动后执行一些内容。比如读取配置文件,数据库连接之类。
使用示例:
1 | public class AfterRun implements CommandLineRunner { |
第三章 Web组件
拦截器、servlet、Filter
拦截器
拦截器是SpringMVC中的一种对象,能拦截对Controller的请求。
拦截器框架中由系统的拦截器,可以自定义拦截器。实现对请求的预先处理。
SpringMVC实现自定义拦截器:
- 创建类实现SpringMVC框架的HandlerInterceptor接口
1
2
3
4
5
6
7
8
9
10
11public interface HandlerInterceptor {
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return true;
}
default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)throws Exception {
}
default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)throws Exception {
}
} - 需在SpringMVC的配置文件中,声明拦截器
1
2
3
4
5
6<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="url"/>
<bean class="拦截器的全限定名称"/>
</mvc:interceptor>
</mvc:interceptors>
SpringBoot实现拦截器:
- 自定义拦截器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27package com.example.web;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 自定义的拦截器
*/
public class LoginInterceptor implements HandlerInterceptor {
/**
* @param request
* @param response
* @param handler 被拦截的控制器对象
* @return boolean
* true:请求被Controller处理
* false:请求被拦截
*/
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//判断是否通过拦截器的代码
System.out.println("拦截器被执行");
return true;
}
} - 将拦截器对象注入容器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24package com.example.config;
import com.example.web.LoginInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
public class HandlerInterceptorConfig implements WebMvcConfigurer {
//添加拦截器对象,注入到容器中
public void addInterceptors(InterceptorRegistry registry) {
//创建拦截器对象
HandlerInterceptor interceptor = new LoginInterceptor();
//指定拦截的url请求
String path[] = {"/user/**"};
//指定不拦截的地址
String excludePath[] = {"/user/login"};
registry.addInterceptor(interceptor).addPathPatterns(path).excludePathPatterns(excludePath);
}
} - 写Controller类进行测试
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21package com.example.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
public class HandlerInterceptorController {
public String userRegister(){
return "访问/user/register";
}
public String userLogin(){
return "访问/user/login";
}
}
Servlet
在SpringBoot中使用Servlet对象
使用步骤:
- 创建Servlet类。创建类继承HttpServlet。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26package com.example.web;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
//创建Servlet类
public class Servlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//使用HttpServletResponse输出数据,应答结果
resp.setContentType("text/html;charset=utf-8");
PrintWriter out = resp.getWriter();
out.println("执行servlet");
out.flush();
out.close();
}
} - 注册Servlet,让框架能找到Servlet。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24package com.example.config;
import com.example.web.Servlet;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
public class ServletConfig {
//定义方法,注册Servlet对象
public ServletRegistrationBean servletRegistrationBean(){
//public ServletRegistrationBean(T servlet, String... urlMappings)
//第一个参数是Servlet对象,第二个参数是url地址
//ServletRegistrationBean bean = new ServletRegistrationBean(new Servlet(),"/servlet");
//无参构造,单独设置参数
ServletRegistrationBean bean = new ServletRegistrationBean();
bean.setServlet(new Servlet());
bean.addUrlMappings("/servlet_01","/servlet_02"); // <url-pattern>
return bean;
}
}
Filter过滤器
Filter是Servlet规范中的过滤器,可以处理请求,对请求的参数、属性进行调整。常常在过滤器中处理字符编码
使用步骤:
- 创建自定义的过滤器类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18package com.example.config;
import com.example.web.MyFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
public class FilterConfig {
public FilterRegistrationBean filterRegistration() {
FilterRegistrationBean bean = new FilterRegistrationBean();
bean.setFilter(new MyFilter());
bean.addUrlPatterns("/user/*");
return bean;
}
} - 注册Filter过滤器对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18package com.example.config;
import com.example.web.MyFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
public class FilterConfig {
public FilterRegistrationBean filterRegistration() {
FilterRegistrationBean bean = new FilterRegistrationBean();
bean.setFilter(new MyFilter());
bean.addUrlPatterns("/user/*");
return bean;
}
} - 写Controller类进行测试
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27package com.example.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
public class HandlerInterceptorController {
public String userRegister(){
return "访问/user/register";
}
public String userLogin(){
return "访问/user/login";
}
public String query(){
return "访问/query";
}
}
字符集过滤器
CharacterEncodingFilter:解决post请求中乱码的问题
在SpringMVC框架,在web.xml中注册过滤器。配置它的属性
- 使用系统提供的字符集过滤器类
过滤器的注册同时需要关闭SpringBoot中默认配置的字符集过滤器,使自定义的过滤器起作用。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27package com.example.config;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.CharacterEncodingFilter;
public class FilterConfig {
public FilterRegistrationBean filterRegistration() {
FilterRegistrationBean bean = new FilterRegistrationBean();
//使用框架中的过滤器类
CharacterEncodingFilter filter = new CharacterEncodingFilter();
//指定使用的编码方式
filter.setEncoding("utf-8");
//指定request,response都使用encoding的值
filter.setForceEncoding(true);
bean.setFilter(filter);
//指定过滤的url地址
bean.addUrlPatterns("/*");
return bean;
}
}1
2
3#SpringBoot中默认已经配置了Character Encoding Filter,默认编码ISO-8859-1
#设置enable=false 作用是关闭系统中配置好的过滤器,使用自定义的CharacterEncodingFilter
server.servlet.encoding.enabled=false - 直接修改application.properties配置
1
2
3
4
5
6#让系统的CharacterEncodingFilter生效
server.servlet.encoding.enabled=true
#指定使用的编码方式
server.servlet.encoding.charset=UTF-8
#强制request、response都使用charset属性的值
server.servlet.encoding.force=true
第四章 ORM操作MySQL
ORM是“对象-关系-映射”的简称。(Object Relational Mapping,简称ORM)
orm其实就是将类对象的语法翻译成sql语句的一个引擎
使用MyBatis框架操作数据库,在SpringBoot框架集成MyBatis
使用步骤:
- mybatis起步依赖:完成mybatis对象自动配置,对象放在容器中。
- pom.xml指定把src/main/java目录中的xml文件包含到classpath中。
- 创建实体类Student。
- 创建Dao接口StudentDao,创建一个查询学生的方法。
- 穿啊关键Dao接口对应的Mapper文件,xml文件,写sql语句。
- 创建Service层对象,创建StudentService接口和他的实现类。调dao对象的方法,完成数据库的操作。
- 创建Controller对象,访问Service。
- 写application.properties文件
配置数据库的连接信息
第一种方式:@Mapper
@Mapper:放在dao接口上,每个接口都需要使用这个注解。
1 | /** |
第二种方式:@MapperScan
@MapperScan:放在SpringBoot启动类上,在包下所有接口在编译后会生成相应的实现类。
1 |
|
第三种方式:Mapper文件和Dao接口分开管理
将mapper文件放在resources目录下
- 在resources目录中创建子目录(自定义),例如mapper
- 将mapper文件放在mapper目录
- 在application文件中指定mapper文件的目录
1
2
3
4#指定mapper文件的位置
mybatis.mapper-locations=classpath:mapper/*.xml
#指定mybatis的日志
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl - 在pom文件中指定resources目录中的文件,编译到目标目录中
1
2
3
4
5
6
7
8
9<!--resources插件-->
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
</resource>
</resources>
事务
Spring框架中的事务:
- 管理事务的对象:事务管理器(接口,接口有很多实现类)
例如:使用jdbc或mybatis访问数据库,使用的事务管理器:DataSourceTransactionManager - 声明式事务:在xml配置文件或使用注释说明事务控制的内容
控制事务:隔离级别,传播行为,超时时间 - 事务处理方式:
- spring框架中的@Transactional
- aspectj框架可以在xml配置文件中,声明事务控制的内容
SpringBoot中使用事务:
- 在业务方法上加入@Transactional,加入注解后,方法有事务功能。
- 明确的在启动类上,加入@EnableTransactionManager
第五章 接口的架构风格——RESTful
API百度百科
接口:应用程序接口(英语:Application Programming Interface,简称:API),又称为应用编程接口,就是软件系统不同组成部分衔接的约定。由于近年来软件的规模日益庞大,常常需要把复杂的系统划分成小的组成部分,编程接口的设计十分重要。程序设计的实践中,编程接口的设计首先要使软件系统的职责得到合理划分。良好的接口设计可以降低系统各部分的相互依赖,提高组成单元的内聚性,降低组成单元间的耦合程度,从而提高系统的维护性和扩展性。
接口:可以指访问servlet、controller的url,调用其他程序的 函数
架构风格:api的组织样式
就是一个传统的:http://localhost:8080/dev/student/query?id=2
REST
- REST:(Representational State Transfer)表现层状态转移
是一种接口的架构风格和设计的理念,不是标准。
优点:更简洁,更有层次。
表现层状态转移:
表现层就是视图层,显示资源的。通过视图页面、jsp等显示操作资源的结果。
状态:资源变化
转移:资源是可以变化的。资源能创建,new状态,资源创建后可以查询资源,可以被修改。 - RESt中的要素:
用RESt表示资源和对应资源的操作。在互联网中,表示一个资源或者一个操作。
资源是用url表示的,在互联网中,使用的图片、视频、文本、网页等都是资源。
对于资源:- 查询资源:通过url找到资源
- 创建资源:添加资源
- 更新资源:更新资源,编辑
- 删除资源:删除
资源使用url表示,通过名称表示资源
在url中,使用名词表示资源,以及访问资源的信息,在url中,使用”/“分割对资源的信息
使用http中的动作(请求方式),表示对资源的操作(CURD)
- GET:查询资源——sql select
处理单个资源:
http://localhost:8080/dev/student/query/2
处理多个资源:
http://localhost:8080/dev/student/query/2/3 - POST:创建资源——sql insert
http://localhost:8080/dev/student/add
在post请求中传递数据 - PUT:更新资源——sql update
http://localhost:8080/dev/student/query/2
在post中传递数据 - DELETE:删除资源——sql delete
http://localhost:8080/dev/student/query/2
需要分页、排序等参数,依然可以加在url后,比如:
http://localhost:8080/dev/student/query/2?page=2&pageSize=10
- REST即使用url表示资源,使用http动作操作资源。
RESTful的注解
- @PathVariable:从url中获取数据
- @GetMapping:支持get请求方式,等同于@RequestMapping(method=RequestMethod.GET)
- @PostMapping:支持post请求方式,等同于@RequestMapping(method=RequestMethod.POST)
- @PutMapping:支持put请求方式,等同于@RequestMapping(method=RequestMethod.PUT)
- @DeleteMapping:支持delete请求方式,等同于@RequestMapping(method=RequestMethod.DELETE)
- @RestController:复合注解,是@Controller和@ResponseBody组合
在类上使用,表示当前类的所有方法都加入了@ResponseBody
Postman:测试工具
可以用来测试get、post、put、delete等请求。
注意:url请求地址加请求方式 得是唯一的,否则会有歧义
@GetMapping(“/student/{stuId}“)
在页面中或ajax中,支持pub、delete请求
在SpringMVC中,有一个过滤器,支持post请求转为put、delete
过滤器:org.springframework.web.filter.HiddenHttpMethodFilter
作用:将请求中的post请求转为put、delete
使用步骤:
- application.properties:开启使用HiddenHttpMethodMFilter过滤器
- 在请求页面中,包含_method参数,他的值是put、delete,发起这个请求使用的post方式
1
2
3
4
5
6
7
8<form action="student/put" method="post">
<input type="hidden" name="_method" value="put">
<input type="submit" value="put请求方式">
</form>
<form action="student/delete" method="post">
<input type="hidden" name="_method" value="delete">
<input type="submit" value="delete请求方式">
</form>
第六章 SpringBoot集成Redis
Redis:一个NoSQL(not only)数据库,常用作缓存使用(cache)
Redis的数据类型:string、hash、set、zset、list
Redis是一个中间件:是一个独立的服务器。
Java中著名的客户端:Jedis、lettuce、Redisson
Spring、SpringBoot中有一个RedisTemplate(StringRedisTemplate),用于处理和redis的交互
redis的使用
导入起步依赖
1 | <!--redis起步依赖--> |
data-redis使用的是 lettuce客户端库
在程序中使用RedisTemplate类的方法 操作redis数据,实际就是调用的lettuce客户端中的方法
使用示例
1 | package com.example.controller; |
StringRedisTemplate 和 RedisTemplate
StringRedisTemplate:把key、value都作为String处理,使用的是String的序列化,可读性好。
RedisTemplate:把key、value经过了序列化存到redis。key、value是序列化的内容,不能直接识别。默认使用jdk的序列化,可以修改为其他的序列化。
设置key或value的序列化方式
1 | /** |
第七章 SpringBoot集成Dubbo
SpringBoot集成Dubbo的文档
公共项目
独立的maven项目:定义了接口和数据类
1 | public class Student implements Serializable{ |
1 | public interface StudentService{ |
- 创建服务提供者模块,实现接口模块
dubbo依赖 和 zookeeper依赖
1 | <!--dubbo依赖--> |
注:在pom文件中使用
实现接口
1 | /* |
外部化配置
1 | #配置服务名称 dubbo:application name="名称" |
在类上使用 @DubboService 注解来暴露服务
在主类之上使用 @EnableDubbo 注解启用Dubbo
包含了 @EnableDubboConfig 和 @DubboComponentScan
1 |
|
- 创建消费者模块
添加依赖,与服务提供者相同。
创建Controller或者Service调用远程服务
1 |
|
配置文件application.properties
1 | #指定服务名称 |
第八章 SpringBoot打包
主类继承SpringBootServletInitializer才能使用外部的tomcat
SpringBootServletInitializer相当于原有web.xml的替代
使用嵌入式的tomcat,默认不支持jsp。
打包成war
- 指定打包后的名称
1
2
3
4<build>
<!--打包后的文件名称-->
<finalName>bootDemo</finalName>
</build> - 指定jsp编译的目录
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
</resource>
<resource>
<directory>src/main/webapp</directory>
<targetPath>META-INF/resources</targetPath>
<includes>
<include>**/*.*</include>
</includes>
</resource>
</resources> - 执行打包是war
1
2<!--打包类型-->
<packaging>war</packaging> - 主启动类继承SpringBootServletInitializer
1
2
3
4
5
6
public class SpringBootDemo001Application extends SpringBootServletInitializer{
public static void main(String[] args) {
SpringApplication.run(SpringBootDemo001Application.class, args);
}
} - 部署war
将war文件放到tomcat等服务器的发布目录中。
打包成jar
- 指定打包后的名称
1
2
3
4<build>
<!--打包后的文件名称-->
<finalName>bootDemo</finalName>
</build> - 指定springboot-maven-plugin版本
1
2
3
4
5
6
7
8<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<!--打包jar,有jsp文件时,必须指定maven-plugin插件版本是1.4.2.RELEASE-->
<version>1.4.2.RELEASE</version>
</plugin>
</plugins> - 执行maven clean package
在target目录中,生成jar文件 bootDemo.jar
执行独立的springboot项目,即 java -jar bootDemo.jar
第九章 Thymeleaf 模板
介绍
Thymeleaf是模板引擎,使用Java开发,在服务器端运行。将处理好的请求发送给浏览器。
Java生态下的模板还有Freemaker、Velocity、Beetl(国产)等。
非web环境下,Thymeleaf能直接显示模板上的静态数据;web环境下,能像jsp一样从后台接收数据并替换到模板上。
它是基于HTML的,以HTML标签为载体。
SpringBoot集成了Thymeleaf模板技术,官方也推荐使用它来代替jsp进行前端页面的数据展示。因为jsp需要编译运行,效率比较低。
配置
依赖
1 | <!--模板引擎起步依赖--> |
一些配置
1 | #在开发阶段,关闭模板缓存,让修改立刻生效 |
表达式
- 标准变量表达式
语法:${key}
作用:获取key对应的文本数据,key是request作用域中的key。使用request.setAttribute(),model.addAttribute()
在页面中html标签中使用 th:text=”${key}”1
2
3
4<p>获取student对象属性值</p>
<p th:text="${student.id}">id</p>
<p th:text="${student.name}">name</p>
<p th:text="${student.age}">age</p> - 选择变量表达式(星号变量表达式)
语法:*{key}
作用:获取这个key对应的数据,*{key}需要与th:object一起使用
目的是简单获取对象的属性值1
2
3
4
5
6
7
8<p>使用 *{} 获取student对象属性值</p>
<div th:object="${student}">
<p th:text="*{id}">id</p>
<p th:text="*{name}">name</p>
<p th:text="*{age}">age</p>
</div>
<!--直接使用也可以-->
<p th:text="*{student.id}">id</p> - 链接表达式
语法:@{url}
作用:表示链接
1 | <h3>链接绝对路径</h3> |
Thymeleaf属性
属性是放在html元素中的,就是html元素的属性,加入了th前缀。属性的作用不变。加上th。属性的值由模板引擎处理,在属性上可以使用变量表达式。
1 | <form action="/queryStudent" method="post"></form> |
each 循环
each循环,可以循环List、Map、Array
语法:在html标签中使用 th:each
1 | <div th:each="集合循环成员,循环状态变量:${key}"> |
集合循环成员,循环状态变量:名称都是自定义的。
”循环的状态变量“可以不定义,默认是”集合循环成员Stat“
循环状态变量 iterStat 可以获取以下信息
index:当前迭代对象的index
count:当前迭代对象个数(第几个)
size:当前迭代对象大小(总数)
even/odd:布尔值,当前循环是否是偶数/奇数(从0开始计算)
first:布尔值,当前循环是否是第一个
last:布尔值,当前循环是否是最后一个
条件判断if
判断语句,条件为true,显示html标签内容,否则不显示。没有else语句
语法:th:if=”条件语句”
1 | <p th:if="${id==1001}">id是1001</p> |
还有个与 th:unless 和 th:if 相反的行为
判断语句 switch,case
th:switch 和 java中的switch一样
语法:th:switch=”要比较的值”,th:case=”值”
1 | <div th:switch="要比较的值"> |
注:以上case只有一句执行
内联 inline
内联test:在html标签外,获取表达式的值
语法:[[${key}]]1
2
3<div th:inline="text">
<p>我是[[${name}]]</p>
</div>内联JavaScript
1
2
3
4<script type="text/javascript" th:inline="javascript">
var name = [[${name}]]
alert(name)
</script>
字面量
- 文本字面量:使用单引号括起来的字符串
1
<p th:text="'我是'+${name}">数据显示</p>
- 数字字面量
1
<p th:if="${20>5}">20>5</p>
- boolean字面量
1
<p th:if="isLogin == true">用户已登录</p>
- null字面量
1
<p th:if="student != null">有student数据</p>
字符串链接
- 使用单引号括起来的字符串,使用 + 连接其他字符串或表达式
1
<p th:text="'我是' + ${name}">数据显示</p>
- 使用双竖线,|字符串和表达式|
1
<p th:text="|我是${name}|">显示数据</p>
运算符
算数运算:+,-,*,/
关系比较:>,<,>=,<=(gt,lt,ge,le)
相等判断:==,!=(eq,ne)
1 | <p th:text="${age > 20}">年龄大于20</p> |
Thymeleaf基本对象
模板引擎提供了内置对象,可以使用#开始引用。
官方文档
- #request 表示 HttpServletRequest
- #session 表示 HttpSession
- session 表示 Map对象,是#session的简单表达方式,用来获取session中指定key的值
#session.getAttribute(“loginname”)==session.loginname
1 | <h3>内置对象#request,#session,session的使用</h3> |
此外,还有很多工具类。提供string、date、集合的一些处理方法。此处不再列举,详细请查看官方文档。
自定义模板
模板是内容的复用,定义一次,在其他模板文件中多次使用。
模板的使用:
1.定义模板
2.使用模板
模板定义语法:
1 | <div th:fragment="head"> |
引用模板的语法:
1 | <!--插入模板insert--> |
第十章 总结
注解
spring+springMVC+SpringBoot
创建对象:
@Controller:放在类上,创建控制器对象,注入到容器中。
@RestController:放在类上,创建控制器对象,注入到容器中。作用:复合了@Controller合@ResponseBodey,使用这个注解,控制器方法返回值都是数据,没有视图。
@Service:放在业务层实现类上,创建service对象,注入到容器。
@Repository:放在dao层实现类上,创建dao对象,注入到容器。没有使用是因为dao对象是MyBatis框架通过代理生成的,不需要使用。
@Component:放在类上,创建此类的对象,放入到容器中。
赋值:
@Value:简单类型的赋值。还可以使用它获取配置文件中的数据。
@Autowired:引用类型赋值自动注入,支持byName,byType,默认是byType。放在属性或构造方法上,推荐放在构造方法上。
@Qualifer:给引用类型赋值,使用byName。
注:@Autowired,@Qualifer都是Spring框架提供的
@Resource:来自jdk中的定义,javax.annotation。实现引用类型的自动注入,支持byName,byType。默认是byName,如果失败,再使用byType注入。在属性上使用
其他:
@Configuration:放在类上,表示这是个配置类,相当于xml配置文件。
@Bean:放在方法上,把方法返回值对象,注入到spring容器中。
@ImportResource:加载其他的xml配置文件,把文件中的对象注入到spring容器中。
@PropertySource:读取其他的properties属性配置文件。
@ComponentScan:扫描器,指定报名,扫描注解。
@ResponseBody:放在方法上,表示方法返回值是数据,不是试视图。
@RequestBody:把请求体中的方法读取出来,转为java对象使用。
@ControllerAdvice:控制器增强,放在类上,表示此类提供了方法,可以对controller增强功能。
@ExceptionHandler:处理异常,放在方法上。
@Transcational:处理事务,放在service实现类的public方法上,表示此方法有事务。
SpringBoot中的注解:
@SpringBootApplication:放在启动类上,包含了@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan
Mybatis相关注解:
@Mapper:放在类上,让MyBatis找到接口,创建代理对象
@MapperScan:放在主类上,指定扫描的包,将包中所有接口都创建代理对象。对象注入到容器中。
@Param:放在dao接口的方法形参前,作为命名参数使用。
Dubbo注解:
@DubboService:在提供者端使用,暴露服务,放在接口实现类上。
@DubboReference:在消费者端使用,引用远程服务,放在属性上使用。
@EnableDubbo:放在主类上,表示启用Dubbo功能。
一些想法
断断续续学了快一个月,springboot算是摆脱了众多的配置文件,对开发来说还是蛮友好的。
关于Thymeleaf模板引擎,我感觉和jsp有点像。但我没有学习过jsp,只是浅浅的用过。模板引擎应该算不上前后端分离,不过它是在html文件的标签上增加内容,实现动态的功能,算是伪分离吧。前后端分离,人不分离。
现在linux使用地还不是很熟练,后面打算细细地学习下linux的使用,因为web应用是要部署到linux服务器的,所以学习linux是必要的。后面换电脑也打算使用linux作为主操作系统,大概会选择deepin系统吧。
目前要复习期末考试,考完后,会开始健康码网站的制作。
后面的学习计划,大概有Nginx,Docker之类的,然后继续深入对spring系列框架的理解合使用。
更远一些的,大概会去学一下vue,了解下前端,毕竟如果是一个人做网站的话,只有后端也是不太行的。
好耶!可以使用springboot,告别那么多配置文件了。
2022.5.29