Spring Boot
/**
* 只有在容器中的组件,才能拥有springboot的功能
*/
//@Component//将组件加到容器中
@ConfigurationProperties(prefix = "mycar")//prefix指的配置文件里的前缀相绑定
public class Car {
private String brand;
private Integer price;
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public Integer getPrice() {
return price;
}
public void setPrice(Integer price) {
this.price = price;
}
@Override
public String toString() {
return "Car{" +
"brand='" + brand + '\'' +
", price=" + price +
'}';
}
}
/**
* 1、配置类里面使用@Bean标注在方法上给容器注册组件,默认也是单实例的
* 2、配置类本身也是组件
* 3、proxyBeanMethods :代理bean的方法
* Full(proxyBeanMethods = true) 为true时发现调用一次之后就继续使用该对象
* Lite(proxyBeanMethods = false) 为false时每次调用就会产生一个新对象
* 组件依赖
* 4、@Import({User.class}):给容器中自动创建出写入类型的组件,默认组件名字就是全类名
*/
@Import({User.class, DBHelper.class})
@Configuration(proxyBeanMethods = true)//告诉springboot这是一个配置类 等同于 以前的配置文件 proxyBeanMethods默认为true
//@ConditionalOnMissingBean(name = "")//容器中没有括号内组件时,执行下面代码
//@ImportResource("classpath:xxx.xml")//当你有xml类型的组件配置文件时,可以在用这个注解导入,会自动将这个xml文件的组件注入到容器当中
@EnableConfigurationProperties(Car.class)
//1、开启Car的配置绑定功能2、把Car这个组件自动注入到容器中(或者不写这个。在Car类中增加一个@Component注解)
public class MyConfig {
/**
* 外部无论对这个配置类中的组件注册方法调用多少次,获取的都是之前注册到容器中的单实例对象
* @return
*/
@Bean //给容器中添加组件:以方法名作为组件id,返回类型就是组件类型,返回的值就是组件在容器中保存的实例
public User user01(){
User zhangsan = new User("张三",18);
//User组件依赖了Pet组件
zhangsan.setPet(tomcatPet());
return zhangsan;
}
@ConditionalOnBean(name = "user01")//当容器中有user01组件时,下面代码才生效,可以放在类上面,也可以放在方法上面
@Bean("TomCat")//可以给容器组件自定义名字
public Pet tomcatPet(){
return new Pet("tomcat");
}
}
//@ResponseBody
//@Controller
@RestController//就是ResponseBody和Controller注解的合体
public class HelloController {
@ResponseBody//表示该类返回的数据直接返回给浏览器
@RequestMapping("/hello")
public String handle01(){
return "Hello,SpringBoot 2!";
}
@Autowired//自动注入
Car car;
@RequestMapping("/car")
public Car car(){
return car;
}
}
Starter
dev Tools
热更新:Ctrl + F9 代码修改后,快捷键直接重启系统,但其实和restart没多大区别
依赖注入
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
Spring Initializer
新建项目的时候选择,直接选择项目所需要的文件,自动引入依赖
核心功能
配置文件
类前面要加上对应的绑定
@ConfigurationProperties( prefix = "xxx" )//xxx对应yml文件里的key值
public class xxxx{
}
-
第一种:application. Properties 配置文件
-
第二种:yaml 文件 适合用来做以数据为中心的配置文件
基本语法:
key:value ;(冒号后有一个空格)
使用缩进表示层级关系
缩进不允许使用tap,只允许使用空格(idea中可以用tap)
缩进的空格数不重要,只要相同层级的元素左对齐即可
“#”表示注释
字符串无需加引号,如果要加 ,' ' 和 " " 表示字符串内容,会被转义/不转义
k: v #键值对写法:map、hash、set、object 行类写法:k: {k1:v1,k2:v2,k3:v3} 或者: k: k1: v1 k2: v2 k3: v3 #数组写法:array、list、queue 行类写法:k: [v1,v2,v3] #写法 k: - v1 - v2 - v3
在写配置文件时,引入下面依赖,可以在配置时自动提示
---
Web开发
静态资源访问
1、静态资源目录
只要静态资源在 static 或 resources 或 public 或 META-INF/resources 文件下
在浏览器直接请求静态资源文件名就可以得到:localhost:8080/(静态资源文件名)
原理:先通过请求找到controller里面有没有相应的request mapping如果没有,再去静态资源文件夹区找相应的静态资源,如果静态资源找不到,就会404
2、静态资源访问前缀
默认无前缀
spring:
mvc:
static-path-pattern: /res/**
#设置静态资源访问前缀,访问静态资源时必须加上设置的前缀
resources:
static-locations: [classpath:/haha/]
#[]是数组写法,可以配置多个访问文件夹
#设置静态资源访问文件夹,设置完成后,系统只在设置的文件加里面访问静态资源
欢迎页支持(index)
静态资源路径下 index.html
可以配置静态资源路径
但是不可以配置静态资源的访问前缀,否则就会导致index.html不能被默认访问
controller能处理/index
自定义 Favicon (网页图标)
将命名为 favicon.ico 的图片放在静态资源目录下面,springBoot会自动将图标设置为网页图标
请求参数注解使用
@RequestParam()注解:获取前端参数包括表单参数
@RequestMapping("/user")
public String hello(@RequestParam("username") String name){//获取路径中问号后面传入的值
}
//也可以通过直接传入session的方式
public String hello(HttpSession session){
}
@GetMapping("/car/{id}/owner/{username}")
public Map<String,Object> getCar( @RequestParam("age")Integer age,
@RequestParam("inters")List<String> inters,
@RequestParam Map<String,String> params){//直接获取所有参数并用Map来接
Map<String,Object> map = new HashMap<>();
map.put("age",age);
map.put("inters",inters);
map.put("params",params);
return map;
}
@PathVariable()注解:获取路径中的变量
@RequestHeader()注解:获取请求头,不带参数获取全部,带参数获取单个
<a href="car/3/owner/lisi">car/3/owner/lisi</a>
@GetMapping("/car/{id}/owner/{username}")
public Map<String,Object> getCar(@PathVariable("id") Integer id,
@PathVariable("username") String name,//这个@PathVariable和@GetMapping大括号里的一一对应
@RequestHeader("User-Agent") String userAgent,//获取请求头
@RequestHeader() Map<String,String> header){//获取请求头
Map<String,Object> map = new HashMap<>();
map.put("id",id);
map.put("name",name);
map.put("userAgent",userAgent);
map.put("header",header);
return map;
}
}
@CookieValue()获取cookie的值
public String test(@CookieValue("")String name){
}
@RequestBody():获取请求体
@PostMapping("/save")
public Map PostMeth(@RequestBody String content){
Map<String,Object> map = new HashMap<>();
map.put("content",content);
return map;
}
{"content":"userName=2222&email=2222"}
@RequestAttribute():获取request中的值
只可以获取request设置的值,不能获取前端表单的值
@Controller
public class RequestController {
@GetMapping("/goto")
public String gotopage(HttpServletRequest request){
request.setAttribute("msg","成功了");
return "forward:/success";
}
@ResponseBody
@GetMapping("/success")
public String success(@RequestAttribute("msg") String msg){
return msg;
}
}
@MatrixVariable()矩阵变量
/car/Path?xxx=xxx&xxx=xxx @RequestParam
/car/Path;xxx=xxx;xxx=xxx,xxx,xxx矩阵变量
页面开发,cookie禁用了,session里的应用怎么使用
session.set(a,b) ---> jsessionid --->cookie ---> 每次发请求携带
URL重写:/abc;jsessionid=xxxx 把cookie的值使用矩阵变量的方式进行传递
<a href="/cars/sell;low=34;brand=byd,audi,yd">@MatrixVariable(矩阵变量)</a>
<a href="/cars/sell;low=34;brand=byd;brand=audi;brand=yd">@MatrixVariable(矩阵变量)</a>
<a href="/boss/1;age=20/2;age=10">@MatrixVariable(矩阵变量)/boss/bossid/empid</a>
//springboot默认禁用了矩阵变量功能
//手动配置:原理:对于路径处理,都是用UrlPathHelper进行解析,removeSemicolonContent(翻译:移除翻译内容)支持矩阵变量
@GetMapping("/cars/{Path}")//这个地方要写Path而不是具体的路径
public Map carsSell(@MatrixVariable("low") Integer low,
@MatrixVariable("brand") List<String> brand){
Map<String,Object> map = new HashMap<>();
map.put("low",low);
map.put("brand",brand);
return map;
}
手动配置矩阵变量:增加配置类
@Configuration(proxyBeanMethods = false)
public class WebConfig implements WebMvcConfigurer {
@Bean
public WebMvcConfigurer webMvcConfigurer(){
return new WebMvcConfigurer() {
public void configurePathMatch(PathMatchConfigurer configurer){
UrlPathHelper urlPathHelper = new UrlPathHelper();
urlPathHelper.setRemoveSemicolonContent(false);//设置为不移除分号后面的内容
configurer.setUrlPathHelper(urlPathHelper);
}
};
}
视图解析与模板引擎
springboot默认不支持 jsp,需要进入第三方模板引擎技术
Thymeleaf
不建议使用在高并发的环境下,建议前后端分离
pom.xml 整合Thymeleaf 需要的starter
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
使用Thymeleaf需要在HTML页面中加上这一句
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1 th:text="${msg}">哈哈</h1><!--msg没有内容的话还是显示哈哈有内容就显示内容的值-->
<h2><a th:href="${link}">去百度$</a></h2><!--地址直接指向link的值-->
<h2><a th:href="@{link}">去百度@</a></h2><!--地址直接指向的绝对路径的地址-->
</body>
</html>
@GetMapping("/hhh")
public String hhh(Model model){
//model中的数据会被自动放在请求域中 相当于request.setAttribute(“xx”,xx)
model.addAttribute("msg","你好 hhh");
model.addAttribute("link","http://www.baidu.com");
return "success";
}
在行内获取后台参数的写法:
[[${session.loginUser.name}]]
获取公共页面(相当于以前的 jsp:incude)
<!-- 公共页面common.html -->
<head th:fragment="commonheader" id="commonheader"> <!-- th:fragment="commonheader" 就是该标签的名字 -->
<!--common-->
<link href="css/style.css" th:href="@{/css/style.css}" rel="stylesheet">
<link href="css/style-responsive.css" th:href="@{/css/style-responsive.css}" rel="stylesheet">
</head>
<!-- 引用公共页面时 -->
<link th:replace="~{common :: commonheader}"> <!-- common就是引用页面的名字,commonheader就是引用标签的名字 -->
<link th:replace="~{common :: #commonheader}"> <!-- 如果是引用id就在id名前加上#号 -->
<!--
有replace、include、insert三个th标签
replace:替换现有标签,直接引用引用的标签
include(不建议使用):仅仅将引用标签中的内容增加进来
insert:保留现有标签,在其中插入引用的标签
-->
数据遍历:使用 th:each 获取后台的数据
<tr class="gradeX" th:each="user:${users}">
<td>Trident</td>
<td th:text="${user.userName}">Internet Explorer 4.0</td>
<td th:text="${user.passWord}">[[${user.password}]]</td>
</tr>
@GetMapping("/dynamic_table")
public String dynimic_table(Model model){
//表格内容遍历
List<User> users = Arrays.asList(new User("zhangsan","123456"),
new User("lisi","123444"),
new User("haha","aaaaa"));
model.addAttribute("users",users);
return "table/dynamic_table";
}
拦截器
HandlerInterceptor
/**
* 登陆检查(拦截器)
* 1、配置好拦截器要拦截哪些请求
* 2、把这些配置放在容器中
*/
public class LoginInterceptor implements HandlerInterceptor {
/**
* 目标方法执行之前
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//登录检查逻辑
HttpSession session = request.getSession();
Object loginUser = session.getAttribute("loginUser");
if (loginUser != null){
//return true就是放行
return true;
}
//拦截住,未登录,跳转到登录页面
session.setAttribute("msg","请先登录");
response.sendRedirect("/");
//false就是拦截
return false;
}
/**
* 目标方法执行完成以后
* @param request
* @param response
* @param handler
* @param modelAndView
* @throws Exception
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
/**
*页面渲染以后
* @param request
* @param response
* @param handler
* @param ex
* @throws Exception
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
/**
* 开发web项目配置的时候都要实现WebMvcConfigurer接口
* 1、编写一个拦截器 实现 HanderInterceptor 接口
* 2、拦截器注册到容器中(实现WebMvcConfigurer的addInterceptors)
* 3、指定拦截规则(如果拦截所有静态资源也会被拦截)
*/
@Configuration
public class AdminWebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor())//添加自己配置的拦截器
.addPathPatterns("/**")//拦截哪些请求(静态资源也会被拦截)
.excludePathPatterns("/","/login","/css/**","/font/**","/images/**","/js/**");//放行哪些请求
}
}
文件上传
文件上传表单格式:
<form role="form" th:action="@{upload}" method="post" enctype="multipart/form-data">
后台将文件存储进服务器中
/**
* 文件上传
* MultipartFile 自动封装上传过来的文件
* @param email
* @param username
* @param headerImg
* @param photos
* @return
*/
@PostMapping("/upload")
public String upload(@RequestParam("email") String email,
@RequestParam("username") String username,
@RequestPart("headerImg") MultipartFile headerImg,
@RequestPart("photos") MultipartFile[] photos) throws IOException {
log.info("上传的信息:email={},username={},headerImg={},photos={}", email,username,headerImg.getSize(),photos.length);
if(!headerImg.isEmpty()){
//保存到文件服务器,OSS服务器
String originalFilename = headerImg.getOriginalFilename();//获取文件原始名
headerImg.transferTo(new File("D:\\Test\\"+originalFilename));//将文件保存在相应的
}
//处理多个文件
if (photos.length > 0){
for (MultipartFile photo : photos){
if (!photo.isEmpty()){
String originalFilename = photo.getOriginalFilename();//获取文件原始名
photo.transferTo(new File("D:\\Test\\" + originalFilename));
}
}
}
return "main";
}
#设置单个文件上传最大大小
spring.servlet.multipart.max-file-size=10MB
#设置所有文件上传最大大小
spring.servlet.multipart.max-request-size=100MB