点击maven窗口->蓝色闪电图标->demoproperties(工程名)->Lifecycle->package->点击maven窗口上的运行按钮,就会在target打包成jar文件。
打开Terminal窗口,默认打开的路径是项目工程路径,执行:java -jar target\demoproperties-0.0.1-SNAPSHOT.jar,就会运行成功。
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
添加后可发现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>
重启之后
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文件夹创建成功。
-服务器内部日志
修改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";
}
}
工程: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
配置请求转发,当用户发送http请求,给他转到https上:
TomcatConfig.java
回复666:有对这个参数的详细解释
工程: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 配置文件文件名
工程:demoproperties
乱码问题:将编码方式改为UTF-8,并勾上自动转化成asc-ii编码
chapter02/properties
@ConfigurationProperties(prefix = “book”)
2.08
chapter02/properties
讲01-11 parent的时候讲过。
配置文件:application.properties
maven配置也就是pom.xml文件
也就是如何在配置文件application.properties中加载maven中的内容。
app.encoding = @project.build.sourceEncoding@
app.java.version = @java.version@
引用符号是@符号
比如,将项目工程打成来了一个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端口:
spring.profiles.activate = prod
与application中有差异的地方在下面的配置文件中指出来
application-prod.properties
application-dev.properties
application-test.properties
后台回复: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>
SpringBoot+Thymeleaf
https://mp.weixin.qq.com/s/Uvv1q3iQn2IwAB1crHWS1g
创建工程时,添加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";
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>
将hello.html中的字段变成字符串,作为邮件内容
$ * # @
引用绝对 URL:
超链接 图片 js
Spring Boot + Freemarker 中的弯弯绕!:https://mp.weixin.qq.com/s/1TZfOBMtrTJ7qKHEduLUEw
代码生成工具
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/
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,返回到一个视图
@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>
公共数据绑定到
@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));
}
}
}
两个用法:
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.");
}
不用转发,会直接定位到错误页面。
这种静态页面不足够显示信息,如何定义动态页面?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>
自定义异常数据
自定义异常视图(不常用)
自定义异常数据
@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;
}
}
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);
}
}
和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");
}
}
如何打包成jar包启动运行呢?
java -jar commandlinerunner.jar 三国演义 水浒传
@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
我没跟这写
一般使用拦截器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同
SSM框架中的
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
// registry.addViewController("/02").setViewName("02");
//不用写controller了,但是没有办法放数据了
registry.addViewController("/02").setViewName("02");
}
}
@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对象的。
静态页面优先 动态页面次之
生成角标favicon生成
命名为:favicon.ico放到static中
面向切面编程
切点和增强的结合体就是切面
切点@Pointcut()