SpringBoot-Thymeleaf、Freemarker

文章目录

    • maven工程如何打包并运行
    • Tomcat容器日志配置
    • SpringBoot的Tomcat没有启动的问题
    • 2.04 Tomcat HTTPs证书配置
    • 2.05 SpringBoot配置文件
    • 2.06 属性普通注入方式
    • 2.07 类型安全的属性注入
    • 2.08在配置文件中引用maven配置
    • 02-09 使用短命令参数
    • 02-10 yaml配置
    • 02-11 Profile问题
    • 02-12 SpringBoot的日志体系
    • 02-13 springboot日志实现
    • 第三章 Thymeleaf
    • 03-01 Thymeleaf介绍
    • 03-02 Thymeleaf和SpringBoot的整合
    • 03-03 Thymeleaf基本表达式
    • 03-11 Freemarker
    • 03-12 SpringBoot整合Freemarker
    • 03-16 内建函数
    • 代码自动生成
    • 第四章
    • 整合静态资源
    • @ControllerAdvice
        • 04-10 全局异常处理
        • 04-11 全局数据绑定
    • @ModelAttribute
        • 全局数据预处理
    • 04-13 异常页面定义
    • 04-14 异常处理原理解析(没看)
    • 04-15 自定义异常处理
    • 04-16 跨域资源共享
        • SpringBoot配置拦截器Interceptor
    • 04-19CommandLineRunner系统启动任务
    • 04-20 ApplicationRunner系统启动参数配置
    • 04-21 Springboot配置Web基本组件
    • 04-22 整合N种过滤器Filter
    • 04-23 路径映射
    • 04-24 参数类型转换
    • 04-25 自定义首页与浏览器角标
    • 04-26 整合AOP

maven工程如何打包并运行

点击maven窗口->蓝色闪电图标->demoproperties(工程名)->Lifecycle->package->点击maven窗口上的运行按钮,就会在target打包成jar文件。
打开Terminal窗口,默认打开的路径是项目工程路径,执行:java -jar target\demoproperties-0.0.1-SNAPSHOT.jar,就会运行成功。
在这里插入图片描述
SpringBoot-Thymeleaf、Freemarker_第1张图片

https://jingyan.baidu.com/article/15622f24d673befdfdbea557.html

springboot创建、banner、
springboot的创建方式:
1.在线创建
2.创建springboot
2.maven创建,改造
阿里云提供的start站点
http://start.aliyun.com

创建了一个springboot之后,内嵌了一个tomcat可供使用
创建工程了,点击右上角的开始三角符号,在console打印出:可发现有tomcat8080

"D:\Program Files\Java\jdk1.8.0_291\bin\java.exe" "-javaagent:D:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2019.1.4\lib\idea_rt.jar=57742:D:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2019.1.4\bin" -Dfile.encoding=UTF-8 -classpath "D:\Program Files\Java\jdk1.8.0_291\jre\lib\charsets.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\deploy.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\access-bridge-64.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\cldrdata.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\dnsns.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\jaccess.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\jfxrt.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\localedata.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\nashorn.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\sunec.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\sunjce_provider.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\sunmscapi.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\sunpkcs11.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\zipfs.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\javaws.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\jce.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\jfr.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\jfxswt.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\jsse.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\management-agent.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\plugin.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\resources.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\rt.jar;D:\IDEACode\demo04\target\classes;D:\ProgramData\my_maven_local_repository\org\springframework\boot\spring-boot-starter-web\2.5.3\spring-boot-starter-web-2.5.3.jar;D:\ProgramData\my_maven_local_repository\org\springframework\boot\spring-boot-starter\2.5.3\spring-boot-starter-2.5.3.jar;D:\ProgramData\my_maven_local_repository\org\springframework\boot\spring-boot\2.5.3\spring-boot-2.5.3.jar;D:\ProgramData\my_maven_local_repository\org\springframework\boot\spring-boot-autoconfigure\2.5.3\spring-boot-autoconfigure-2.5.3.jar;D:\ProgramData\my_maven_local_repository\org\springframework\boot\spring-boot-starter-logging\2.5.3\spring-boot-starter-logging-2.5.3.jar;D:\ProgramData\my_maven_local_repository\ch\qos\logback\logback-classic\1.2.4\logback-classic-1.2.4.jar;D:\ProgramData\my_maven_local_repository\ch\qos\logback\logback-core\1.2.4\logback-core-1.2.4.jar;D:\ProgramData\my_maven_local_repository\org\apache\logging\log4j\log4j-to-slf4j\2.14.1\log4j-to-slf4j-2.14.1.jar;D:\ProgramData\my_maven_local_repository\org\apache\logging\log4j\log4j-api\2.14.1\log4j-api-2.14.1.jar;D:\ProgramData\my_maven_local_repository\org\slf4j\jul-to-slf4j\1.7.32\jul-to-slf4j-1.7.32.jar;D:\ProgramData\my_maven_local_repository\jakarta\annotation\jakarta.annotation-api\1.3.5\jakarta.annotation-api-1.3.5.jar;D:\ProgramData\my_maven_local_repository\org\yaml\snakeyaml\1.28\snakeyaml-1.28.jar;D:\ProgramData\my_maven_local_repository\org\springframework\boot\spring-boot-starter-json\2.5.3\spring-boot-starter-json-2.5.3.jar;D:\ProgramData\my_maven_local_repository\com\fasterxml\jackson\core\jackson-databind\2.12.4\jackson-databind-2.12.4.jar;D:\ProgramData\my_maven_local_repository\com\fasterxml\jackson\core\jackson-annotations\2.12.4\jackson-annotations-2.12.4.jar;D:\ProgramData\my_maven_local_repository\com\fasterxml\jackson\core\jackson-core\2.12.4\jackson-core-2.12.4.jar;D:\ProgramData\my_maven_local_repository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.12.4\jackson-datatype-jdk8-2.12.4.jar;D:\ProgramData\my_maven_local_repository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.12.4\jackson-datatype-jsr310-2.12.4.jar;D:\ProgramData\my_maven_local_repository\com\fasterxml\jackson\module\jackson-module-parameter-names\2.12.4\jackson-module-parameter-names-2.12.4.jar;D:\ProgramData\my_maven_local_repository\org\springframework\boot\spring-boot-starter-tomcat\2.5.3\spring-boot-starter-tomcat-2.5.3.jar;D:\ProgramData\my_maven_local_repository\org\apache\tomcat\embed\tomcat-embed-core\9.0.50\tomcat-embed-core-9.0.50.jar;D:\ProgramData\my_maven_local_repository\org\apache\tomcat\embed\tomcat-embed-el\9.0.50\tomcat-embed-el-9.0.50.jar;D:\ProgramData\my_maven_local_repository\org\apache\tomcat\embed\tomcat-embed-websocket\9.0.50\tomcat-embed-websocket-9.0.50.jar;D:\ProgramData\my_maven_local_repository\org\springframework\spring-web\5.3.9\spring-web-5.3.9.jar;D:\ProgramData\my_maven_local_repository\org\springframework\spring-beans\5.3.9\spring-beans-5.3.9.jar;D:\ProgramData\my_maven_local_repository\org\springframework\spring-webmvc\5.3.9\spring-webmvc-5.3.9.jar;D:\ProgramData\my_maven_local_repository\org\springframework\spring-aop\5.3.9\spring-aop-5.3.9.jar;D:\ProgramData\my_maven_local_repository\org\springframework\spring-context\5.3.9\spring-context-5.3.9.jar;D:\ProgramData\my_maven_local_repository\org\springframework\spring-expression\5.3.9\spring-expression-5.3.9.jar;D:\ProgramData\my_maven_local_repository\org\slf4j\slf4j-api\1.7.32\slf4j-api-1.7.32.jar;D:\ProgramData\my_maven_local_repository\org\springframework\spring-core\5.3.9\spring-core-5.3.9.jar;D:\ProgramData\my_maven_local_repository\org\springframework\spring-jcl\5.3.9\spring-jcl-5.3.9.jar" com.example.demo.Example

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.5.3)

2021-07-31 21:50:06.360  INFO 21704 --- [           main] com.example.demo.Example                 : Starting Example using Java 1.8.0_291 on DESKTOP-J9OB8F8 with PID 21704 (D:\IDEACode\demo04\target\classes started by wang in D:\IDEACode\demo04)
2021-07-31 21:50:06.365  INFO 21704 --- [           main] com.example.demo.Example                 : No active profile set, falling back to default profiles: default
2021-07-31 21:50:09.928  INFO 21704 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2021-07-31 21:50:09.957  INFO 21704 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2021-07-31 21:50:09.958  INFO 21704 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.50]
2021-07-31 21:50:10.178  INFO 21704 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2021-07-31 21:50:10.178  INFO 21704 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3608 ms
2021-07-31 21:50:11.010  INFO 21704 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2021-07-31 21:50:11.029  INFO 21704 --- [           main] com.example.demo.Example                 : Started Example in 5.657 seconds (JVM running for 6.934)
2021-07-31 21:50:29.802  INFO 21704 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2021-07-31 21:50:29.805  INFO 21704 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2021-07-31 21:50:29.809  INFO 21704 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 3 ms

打开旁边maven查看依赖可发现有tomcat依赖,还有三个servlet
SpringBoot-Thymeleaf、Freemarker_第2张图片
添加后可发现tomcat就没有了,见下一张图片,添加jetty后,可发现maven那里又出现了jetty的依赖。

<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
			<exclusions>
				<exclusion>
					<groupId>org.springframework.boot</groupId>
					<artifactId>spring-boot-starter-web</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
添加新的tomcat
<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web-jetty</artifactId>
		</dependency>

SpringBoot-Thymeleaf、Freemarker_第3张图片

重启之后
在这里插入图片描述

Tomcat容器日志配置

tomcat日志分为两种类型:
-访问日志 accesslog,默认没有开启
要开启,在application.properties中配置

# 生成的访问日志将在该目录下
server.tomcat.basedir=my-tomcat
# 开启访问日志,默认的日志位置在项目运行的临时目录中,默认生成的日志格式 access_log.2020-12-10.log
server.tomcat.accesslog.enabled=true
# 生成日志文件名的前缀,默认是 access_log
server.tomcat.accesslog.prefix=javaboy_log
# 生成的日志文件后缀
server.tomcat.accesslog.suffix=.log
# 日志文件名中的日期格式
server.tomcat.accesslog.file-date-format=.yyyyMMdd

# 生成的日志文件内容格式也是可以调整的
# %h 请求的客户端 IP
# %l 用户的身份
# %u 用户名
# %t 请求时间
# %r 请求地址
# %s 响应的状态码
# %b 响应的大小
# 默认的格式是%h %l %u %t \"%r\" %s %b
server.tomcat.accesslog.pattern=%h %l %u %t \"%r\" %s %b

# 服务器内部日志开启

logging.level.org.apache.tomcat=debug
logging.level.org.apache.catalina=debug

运行项目工程,打开浏览器运行http://localhost:8080/hello即可查看到my-tomcat文件夹创建成功。

-服务器内部日志

SpringBoot的Tomcat没有启动的问题

修改setting的maven配置为3.5.4,默认的是3.8.1,
创建一下类,打开这个类的文件,点击旁边的启动按钮,即可启动springboot工程和tomcat
在浏览器中输入http://localhost:8080/hello,即可查看

@RestController
public class HelloController {
    @GetMapping("/hello")
    public String hello() {
        return "tomcat log";
    }
}

2.04 Tomcat HTTPs证书配置

工程:demohttps

可以在阿里云上申请一个HTTPs证书

1.生成https证书
什么是HTTPS证书?什么是HTTPS证书:https://zhuanlan.zhihu.com/p/96157162

keytool

-genkey 创建一个新的密钥
-alias 别名
-keyalg 加密算法
-keysize 密钥长度
-keystore 密钥存到哪
-validity 有效期 

在这里插入图片描述
将这个文件放到resource目录下

server.ssl.key-alias=hanhttps
server.ssl.key-store=classpath:hanjinyue_key.p12
server.ssl.key-store-password=123456

建立一个类,使用http://localhost:8080/hello访问会:
在这里插入图片描述
https://localhost:8080/hello
SpringBoot-Thymeleaf、Freemarker_第4张图片
在这里插入图片描述
配置请求转发,当用户发送http请求,给他转到https上:
TomcatConfig.java

回复666:有对这个参数的详细解释

2.05 SpringBoot配置文件

工程:demoproperties,什么都没写,可不看
配置文件application.properties有四个位置
1.config/application.properties
2.application.properties
3.src/main/resoources/config/application.properties
4.src/main/resource/application.properties (默认配置)
这四个位置的优先级依次降低
项目中一般使用默认位置
默认的是以上四个目录,不过也可以自定义的位置
其他位置的配置文件,启动的时候,点击右上角
在这里插入图片描述
具体怎么配置,不写了。

如果是打包的工程呢?
默认:java - jar jar包名称
java -jar jar包名称.jar --spring.config.location=classpath:/javabaoy/

一般不需要自定义位置。

默认加载application.properties,能否更改文件名吗?
配置:spring.config.name 配置文件文件名

2.06 属性普通注入方式

工程:demoproperties
乱码问题:将编码方式改为UTF-8,并勾上自动转化成asc-ii编码
SpringBoot-Thymeleaf、Freemarker_第5张图片

2.07 类型安全的属性注入

chapter02/properties

@ConfigurationProperties(prefix = “book”)
2.08
chapter02/properties

2.08在配置文件中引用maven配置

讲01-11 parent的时候讲过。

配置文件:application.properties
maven配置也就是pom.xml文件
也就是如何在配置文件application.properties中加载maven中的内容。
app.encoding = @project.build.sourceEncoding@
app.java.version = @java.version@
引用符号是@符号

02-09 使用短命令参数

比如,将项目工程打成来了一个jar包,运行:java -jar javabaoname.jar ,这是采用默认配置启动,如果我们想改端口呢?java -jar javabaoname.jar --server.port=8081,可以在8081端口启动。
短命行参数就是java -jar javabaoname.jar --port=8081,这样直接运行也能成功但是port配置不起作用,要想起作用,需要在application.properties文件中添加:server.port = ${port},之后启动就生效了。

达成jar包后:在Terminal窗口输入:java -jar target\demoproperties-0.0.1-SNAPSHOT.jar --port=8081

在这里插入图片描述
运行过程可发现是8081端口:
在这里插入图片描述

02-10 yaml配置

SpringBoot-Thymeleaf、Freemarker_第6张图片
yaml配置是有序的,properties是无序的

02-11 Profile问题

spring.profiles.activate = prod
与application中有差异的地方在下面的配置文件中指出来

application-prod.properties
application-dev.properties
application-test.properties

02-12 SpringBoot的日志体系

后台回复:springboot日志

02-13 springboot日志实现

后台回复:springboot日志
使用Apache Commons Logging作为内部的日志框架门面,只是个日志接口,在实际应用中需要为接口指定相应的日志实现。
默认的日志实现是LogBack。

@RestController
public class HelloController {
    private static final Logger logger = getLogger(HelloController.class);//创建一个日志类
    @GetMapping("/hello")
    public void hello() {
        for (int i = 0; i < 100000; i++) {
            logger.info("hello javaboy");
        }
    }
}

日志分组

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j2</artifactId>
        </dependency>

第三章 Thymeleaf

03-01 Thymeleaf介绍

SpringBoot+Thymeleaf
https://mp.weixin.qq.com/s/Uvv1q3iQn2IwAB1crHWS1g

03-02 Thymeleaf和SpringBoot的整合

创建工程时,添加web和Thymeleaf依赖
ctrl+shift+F搜索Thymeleaf类:
在这里插入图片描述
看到,从源码中可看到默认的搜索路径如下

private static final Charset DEFAULT_ENCODING = StandardCharsets.UTF_8;

	public static final String DEFAULT_PREFIX = "classpath:/templates/";#默认位置

	public static final String DEFAULT_SUFFIX = ".html";

可以根据自己做一些配置如下
SpringBoot-Thymeleaf、Freemarker_第7张图片

demoThymeleaf
UserController.java

@Controller
public class UserController {
    @GetMapping("/hello")
    public String index(Model model){
        List<User> users= new ArrayList<>();
        for(int i=0;i<10;i++){
            User user = new User(i,"name"+i,"address"+i);
            users.add(user);
        }
        model.addAttribute("users",users);
        User user = new User();
        user.setId(99);
        user.setUsername("江南一点雨");
        user.setAddress("深圳");
        model.addAttribute("user", user);
        System.out.println("================================================================================");
        return "hello";
    }
}

hello.html

<table border = "1">
    <tr th:each="u:${users}">
        <td th:text = "${u.id}"></td>
        <td th:text = "${u.username}"></td>
        <td th:text = "${u.address}"></td>
    </tr>
</table>

03-03 Thymeleaf基本表达式

将hello.html中的字段变成字符串,作为邮件内容
$ * # @

引用绝对 URL:
超链接 图片 js

03-11 Freemarker

Spring Boot + Freemarker 中的弯弯绕!:https://mp.weixin.qq.com/s/1TZfOBMtrTJ7qKHEduLUEw

代码生成工具
springboot+freemarker功能走通。

03-12 SpringBoot整合Freemarker

新建项目工程,选择依赖:Spring Web、Template Engines下的Apache Freemarker
可以看到有如下依赖:

<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-freemarker</artifactId>
		</dependency>
public class FreeMarkerProperties extends AbstractTemplateViewResolverProperties {

	public static final String DEFAULT_TEMPLATE_LOADER_PATH = "classpath:/templates/";

	public static final String DEFAULT_PREFIX = "";

	public static final String DEFAULT_SUFFIX = ".ftlh";

也可以自己在配置文件中自己配置,在上面那个文档的2.3 其他配置

spring.freemarker.allow-request-override=false
spring.freemarker.allow-session-override=false
spring.freemarker.cache=false
spring.freemarker.charset=UTF-8
spring.freemarker.check-template-location=true
spring.freemarker.content-type=text/html
spring.freemarker.expose-request-attributes=false
spring.freemarker.expose-session-attributes=false
spring.freemarker.suffix=.ftl
spring.freemarker.template-loader-path=classpath:/templates/

03-16 内建函数

http://freemarker.foofun.cn/ref_builtins.html
<#noparse> 保留文本模式

Mybatis工程

代码自动生成

guava将下划线转换为驼峰
前端:
eleme
Vue






后台回复:generate-code
spring整合JSp没看,JSP比较古老,不推荐使用

DispatcherServlet

第四章

JSON三大主流框架
jackson,gson,fastjson
在Springmvc框架中,jackson,gson已经配置好了,添加依赖就能使用了,fastjson不稳定,容易出错,需要开发者手动配置HttpMessageConverter。
序列化:对象-json字符串(响应JSOn)
HttpMessageConverter:转换器,实现json和对象之间的转换。
所有的json工具都会提供各自的HttpMessageConverter,例如jackson、gson、fastjson(需要添加配置之后才有)
反序列化:json字符串-》对象(请求参数是json)
ObjectMapper
json:
ObjectMapper实现自动化配置

respondbody + controller的结合体 @RestController
json配置有两种思路:
(1)在各个对象上去配
@JsonPorperty(value=“aaaage”,index = 99)
@JsonIgnore 忽略某一个字段
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss)

@JsonIgnoreProperties(value)

//批量忽略字段
//@JsonIgnoreProperties({"birthday","address"})
public class User {
    //指定属性序列化/反序列化时的名称,默认名称就是属性名
    @JsonProperty(value = "aaaage",index = 99)
    private Integer age;
    @JsonProperty(index = 98)
    private String username;
//    @JsonProperty(index = 97)
    //日期格式化,注意时区问题
//    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "Asia/Shanghai")
    
    @JsonPropertyOrder //类似于 @JsonProperty 中的 index
    private Date birthday;

    //序列化/反序列化时忽略某一个字段
//    @JsonIgnore
    private String address;

(2)全局配置
ObjectMapper

@Configuration
public class WebMvcConfig {
    @Bean
    ObjectMapper objectMapper() {
        ObjectMapper om = new ObjectMapper();
        om.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        return om;
    }
}

04-03 整合gson

创建项目工程只需要添加web依赖
首先在pom中将json排除掉

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-json</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
        </dependency>
application
#spring.gson.date-format=yyyy-MM-dd HH:mm:ss
## 是否禁用 HTML 的转义字符
#spring.gson.disable-html-escaping=true
## 序列化时是否排除内部类
#spring.gson.disable-inner-class-serialization=false
## 序列化时是否弃用复杂映射键
#spring.gson.enable-complex-map-key-serialization=
## 是否排除没有 @Expose 注解的字段
#spring.gson.exclude-fields-without-expose-annotation=
## 序列化时字段名的命名策略
#spring.gson.field-naming-policy=
## 在输出之前添加一些特殊的文本来生成一个不可执行的 JSON
#spring.gson.generate-non-executable-json=
## 是否序列化空字段
#spring.gson.serialize-nulls=
@Configuration
public class WebMvcConfig {
//    @Bean
//    GsonBuilder gsonBuilder() {
//        GsonBuilder gsonBuilder = new GsonBuilder();
//        gsonBuilder.setDateFormat("yyyy-MM-dd");
//        return gsonBuilder;
//    }

整合静态资源

静态资源在static,模板在templates
静态资源有五个位置:
resources/META-INF/resources 优先级1最高
resources/resources 优先级2
resources/public 优先级4
resouces/static 优先级3
不在resources文件夹:
main/webapp 优先级5

看源码:ctrl+shift+F WebMvcAutoConfiguration 可看到静态资源的配置路径

两种自定义静态资源的配置:04-06

单文件上传
springboot不需要添加其他依赖

文件上传有两种方式,一种的format表单上传,一种是ajax异步请求上传。单文件上传到controller层,用一个MultipartFile file接收,而多文件上传用MultipartFile[] files接收。

@ControllerAdvice

@ControllerAdvice 有三方面的功能:

  • 全局异常处理
  • 全局数据绑定
  • 全局数据预处理

04-10 全局异常处理

//使用@ControllerAdvice,返回到一个视图
@ControllerAdvice//@Controller
//@RestControllerAdvice//@RestController
public class MyGlobalException {
    @ExceptionHandler(MaxUploadSizeExceededException.class)#捕捉的异常名
    public ModelAndView customException(MaxUploadSizeExceededException e) {
        ModelAndView mv = new ModelAndView("javaboy");
        mv.addObject("error", e.getMessage());
        return mv;
    }
}

templates/javaboy.html
<div th:text="${error}"></div>

04-11 全局数据绑定

公共数据绑定到

@ControllerAdvice
public class MyGlobalData {
    @ModelAttribute("info")
    public Map<String,String> mydata() {
        Map<String, String> info = new HashMap<>();
        info.put("username", "javaboy");
        info.put("address", "www.javaboy.org");
        return info;
    }
 }
@RestController
public class HelloController {
    @GetMapping("/hello")
    public void hello(Model model) {
        Map<String, Object> asMap = model.asMap();
        Map<String, String> info = (Map<String, String>) asMap.get("info");
        Set<String> keySet = info.keySet();
        for (String s : keySet) {
            System.out.println(s + "----" + info.get(s));
        }

    }
}

@ModelAttribute

两个用法:

全局数据预处理

https://www.cnblogs.com/niexinlei/p/9704075.html
@PostMapping
@GetMapping

首先要了解一下@RequestMapping注解。

  @RequestMapping用于映射url到控制器类的一个特定处理程序方法。可用于方法或者类上面。也就是可以通过url找到对应的方法。

  @RequestMapping有8个属性。

value:指定请求的实际地址。

method:指定请求的method类型(GET,POST,PUT,DELETE)等。

consumes:指定处理请求的提交内容类型(Context-Type)。

produces:指定返回的内容类型,还可以设置返回值的字符编码。

params:指定request中必须包含某些参数值,才让该方法处理。

headers:指定request中必须包含某些指定的header值,才让该方法处理请求。

 

@getMapping与@postMapping是组合注解。

@getMapping = @requestMapping(method = RequestMethod.GET)。

@postMapping = @requestMapping(method = RequestMethod.POST)

如果用到这个功能,说明你的接口出了很大的问题。

@RestController
public class BookController {

    @PostMapping("/book")
    public void addBook(@ModelAttribute("b") Book book, @ModelAttribute("a") Author author) {
        System.out.println("book = " + book);
        System.out.println("author = " + author);
    }
}

@ControllerAdvice
public class MyGlobalData {
@InitBinder("b")
    public void b(WebDataBinder binder) {
        binder.setFieldDefaultPrefix("b.");
    }
    @InitBinder("a")
    public void a(WebDataBinder binder) {
        binder.setFieldDefaultPrefix("a.");
    }

04-13 异常页面定义

在这里插入图片描述

不用转发,会直接定位到错误页面。
这种静态页面不足够显示信息,如何定义动态页面?thymeleaf 、Freemarker、JSP
在这里插入图片描述
由于5XX定义了详细信息,就不需要动态的500.html了,可删掉。

动态高于静态,精确高于模糊

5XX.html
<table border="1">
    <tr>
        <td>path</td>
        <td th:text="${path}"></td>
    </tr>
    <tr>
        <td>error</td>
        <td th:text="${error}"></td>
    </tr>
    <tr>
        <td>message</td>
        <td th:text="${message}"></td>
    </tr>
    <tr>
        <td>timestamp</td>
        <td th:text="${timestamp}"></td>
    </tr>
    <tr>
        <td>status</td>
        <td th:text="${status}"></td>
    </tr>
</table>

04-14 异常处理原理解析(没看)

04-15 自定义异常处理

自定义异常数据
自定义异常视图(不常用)

自定义异常数据

@Component
public class MyErrorAtributes extends DefaultErrorAttributes {
    @Override
    public Map<String, Object> getErrorAttributes(WebRequest webRequest, ErrorAttributeOptions options) {
        Map<String, Object> map = super.getErrorAttributes(webRequest, options);
        if ((Integer) map.get("status") == 404) {
            map.put("message", "页面不存在");
        }
        return map;
    }
}

自定义异常视图

@Component
public class MyErrorViewResolver extends DefaultErrorViewResolver {
    public MyErrorViewResolver(ApplicationContext applicationContext, WebProperties.Resources resources) {
        super(applicationContext, resources);
    }

    @Override
    public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) {
        Map<String, Object> map = new HashMap<>();
        map.putAll(model);
        if ((Integer) model.get("status") == 500) {
            map.put("message", "服务器内部错误");
        }
        ModelAndView view = new ModelAndView("javaboy/999",map);
        return view;
    }
}

04-16 跨域资源共享

Cross-Origin Resource Sharing
域:协议+域名/IP+端口
比如ajax请求只能请求同源的资源。

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
//    @Override//方式二
//    public void addCorsMappings(CorsRegistry registry) {
//        registry.addMapping("/**")
//                .allowedHeaders("*")
//                .allowedMethods("*")
//                .allowedOrigins("http://localhost:8081")
//                .maxAge(1800);
//    }

    @Bean
    CorsFilter corsFilter() {//方式三
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration cfg = new CorsConfiguration();
        cfg.addAllowedOrigin("http://localhost:8081");
        cfg.addAllowedMethod("*");
        source.registerCorsConfiguration("/**",cfg);
        return new CorsFilter(source);
    }
}


SpringBoot配置拦截器Interceptor

和Filter非常像,都是Spring AOP面向切面编程,区别是执行时机不一样。
请求在到达controller之前,先经过拦截器,可以做
(1)编写日志,
(2)权限检查,检查用户有没有登录
(3)性能监控:从请求到达,到请求返回的时间
在springboot中的应用:
实现handlerInterceptor

public class MyInterceptor implements HandlerInterceptor {

    //该方法返回 false,请求将不再继续往下走
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle");
        return true;
    }

    //Controller 执行之后被调用
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle");
    }

    //preHandle 方法返回 true,afterCompletion 才会执行。
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion");
    }
}

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    //配置拦截器
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**").excludePathPatterns("/hello");
    }
}


04-19CommandLineRunner系统启动任务

SpringBoot-Thymeleaf、Freemarker_第8张图片

SpringBoot-Thymeleaf、Freemarker_第9张图片
如何打包成jar包启动运行呢?
java -jar commandlinerunner.jar 三国演义 水浒传

04-20 ApplicationRunner系统启动参数配置

@Component
@Order(98)
public class MyApplicationRunner implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) throws Exception {
        //获取没有键的参数,获取到的值和 commandlinerunner 一致
        List<String> nonOptionArgs = args.getNonOptionArgs();
        System.out.println("nonOptionArgs1 = " + nonOptionArgs);
        //获取键值对的参数
        Set<String> optionNames = args.getOptionNames();
        for (String optionName : optionNames) {
            System.out.println(optionName + "-1->" + args.getOptionValues(optionName));
        }
        //获取命令行中的所有参数
        String[] sourceArgs = args.getSourceArgs();
        System.out.println("sourceArgs1 = " + Arrays.toString(sourceArgs));
    }
}

在这里插入图片描述

命令行:
java -jar coaaaa.jar 三国演义 水浒传 javaboy --age=99

04-21 Springboot配置Web基本组件

我没跟这写

04-22 整合N种过滤器Filter

一般使用拦截器Interceptor就可以。
方式一:
没有办法指定Filter的优先级

@WebFilter(urlPatterns = "/*")
public class MyFilter01 implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("MyFilter01");
        chain.doFilter(request, response);
    }
}
@SpringBootApplication
@ServletComponentScan("org.javaboy.filter")
public class FilterApplication {

    public static void main(String[] args) {
        SpringApplication.run(FilterApplication.class, args);
    }

}

方式二:使用@Component当作普通的spring组件来处理
可以配置优先级
不能配置到底拦截谁,不拦截谁

@Component
@Order(101)
public class MyFilter02 implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("MyFilter02");
        chain.doFilter(request, response);
    }
}
@Component
@Order(100)
public class MyFilter03 implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("MyFilter03");
        chain.doFilter(request, response);
    }
}

方式三:

@Configuration
public class FilterConfiguration {
    @Bean
    FilterRegistrationBean<MyFilter04> filter04FilterRegistrationBean04() {
        FilterRegistrationBean<MyFilter04> bean = new FilterRegistrationBean<>();
        bean.setOrder(90);
        bean.setFilter(new MyFilter04());
        bean.setUrlPatterns(Arrays.asList("/*"));
        return bean;
    }
    @Bean
    FilterRegistrationBean<MyFilter05> filter04FilterRegistrationBean05() {
        FilterRegistrationBean<MyFilter05> bean = new FilterRegistrationBean<>();
        bean.setOrder(89);
        bean.setFilter(new MyFilter05());
        bean.setUrlPatterns(Arrays.asList("/*"));
        return bean;
    }
}

public class MyFilter04 implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("MyFilter04");
        chain.doFilter(request, response);
    }
}
Fileter05

04-23 路径映射

SSM框架中的

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
//        registry.addViewController("/02").setViewName("02");
//不用写controller了,但是没有办法放数据了
        registry.addViewController("/02").setViewName("02");
    }
}

04-24 参数类型转换

@RestController
public class UserController {
    @PostMapping("/user1")
    public void addUser(User user) {
        System.out.println("user = " + user);
    }
    @PostMapping("/user2")
    public void addUser2(@RequestBody User user) {
        System.out.println("user = " + user);
    }
}

@Component
public class MyDateConverter implements Converter<String, Date> {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    @Override
    public Date convert(String source) {
        try {
            return sdf.parse(source);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
}

POST请求有两种方式,可以是key-value,也可以是JSON形式,自定义的列类型转换器对key/value形式的参数有效。JSON形式的参数,不需要类型转换器,JSON字符串使用过HttpMessageConverter转换为User对象的。

04-25 自定义首页与浏览器角标

静态页面优先 动态页面次之

生成角标favicon生成

命名为:favicon.ico放到static中

04-26 整合AOP

面向切面编程
切点和增强的结合体就是切面
切点@Pointcut()

你可能感兴趣的:(java,java)