Spring boot
1. 配置文件创建Bean
@Data
public class cat {
private String name;
private String gender;
}
@Data
public class User {
private String name;
private String ID;
private String gender;
}
@Configuration //自己创建自己的组件
public class config {
@Bean //默认为当前方法名 id = cat class = new cat.class
public cat cat(){
return new cat();
}
@Bean // 创建User组件
public User user(){
return new User();
}
}
@ComponentScan("top.spacexist") //组件扫描
@SpringBootApplication
public class BootApplication {
public static void main(String[] args) {
ConfigurableApplicationContext IOC = SpringApplication.run(BootApplication.class, args);
String[] beanDefinitionNames = IOC.getBeanDefinitionNames();
for (String s: beanDefinitionNames) {
System.out.println(s);
}
System.out.println(IOC.getBean("cat", cat.class));
}
}
2 web 开发
2.1 静态资源访问
静态资源路径
/static ,/public, /META-INF/resource, /resources 都可以直接访问 不需要mapping
spring: mvc: static-path-pattern : /resource/** #Url 中有/resource才会放行
#静态资源访问前缀 开启后 index.html 和 favicon会失效 无法访问
spring: resource-locations: classpath:/resouce #静态资源路径
#/static ,/public, /META-INF/resource, /resources 默认静态资源路径
/** 是包括当前目录下的子目录 , 单星号只会包括当前目录
如果 有Controler 进行mapping 那就先访问动态资源 ,如果没有 则去上面的静态资源路径寻找
welcome-page:默认为静态资源下的index.html 图表为静态资源下的favicon.ico;
spring.mvc:static-path-pattern 配置会导致index.html 和 favicon 失效
只有template 目录下的文件需要Mapping
2.2 请求参数
restful风格返回参数
@RestController
public class t1 {
@RequestMapping("/{id}/{name}")
public Map<String,String> rest(@PathVariable("id") String id,
@PathVariable String name,
@PathVariable Map<String,String> map
@RequestParam Map<String,String>){ //拿到所有的KV值
@CookieValue String Cookie
@RequestBody String Content //拿到POST请求中的Body
return map;
}
}
request 域数据
@Controller
public class t2 {
@RequestMapping("/t1")
public String t1(HttpServletRequest request){
request.setAttribute("name","nihao1");
return "forward:/t2";
}
@ResponseBody
@RequestMapping("/t2")
public Map t2(@RequestAttribute("name") String name){
Map<String,String> map = new HashMap<>();
map.put("name",name);
return map;
}
}
3. 模板引擎 thymeleaf
3.1 引入thymeleaf-starter
没有模板引擎之前 无法直接访问html页面
主要包括两个
ThymeleafAutoConfiguration
ThymeleafProperties
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
3.2 头文件
<html lang="en" xmlns:th="http://www.thymeleaf.org">
3.3 语法规则
Thymeleaf 模板引擎支持多种表达式:
- 变量表达式:${…} 直接获取值
- 选择变量表达式:*{…}
- 链接表达式:@{…}
- 国际化表达式:#{…}
- 片段引用表达式:~{…}
使用 ${} 包裹的表达式被称为变量表达式,该表达式具有以下功能:
- 获取对象的属性和方法
- 使用内置的基本对象
- 使用内置的工具对象
3.4 抽取公共部分(需要带有xmlns)
common.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="div1">this is a p</div>
<div th:fragment="test">hello</div>
</body>
</html>
test.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div th:insert="common :: #div1"></div> 通过selector
<div th:replace="common :: test"></div> 通过fragment
<div th:include="common :: #test"></div>
</body>
</html>
4. 拦截器 Inteceptor
- 编写写一个 Inteceptor 并实现 HandlerInteceptor接口和MVC 一样
public class MyInteceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if(request.getSession()!=null){
return true;
}
else{
response.sendRedirect("/");
}
return false;
}
}
-
拦截器注册到容器中 实现WebmvcConfigurer方法
-
拦截规则 默认拦截所有 静态资源也会被拦截
@Configuration
public class config implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInteceptor()).addPathPatterns("/**")
.excludePathPatterns("/css/**","/js/**","/");
}
}
拦截器原理(DispatchServlet)
-
根据当前请求找到HandlerExecuttionChain {中含有所有拦截器}
-
顺序执行拦截器的Prehandle方法 如果为true 进入下一个拦截器 否则 倒叙执行 已经执行的拦截器的aftercompetion 方法
-
如果任意一个拦截器 false 都不会执行 handle 方法
-
所有 拦截器 返回true 执行 目标方法
-
倒叙执行 拦截器postHandler方法
-
前面有异常的话执行 aftercompetion方法
-
页面渲染完后 执行aftercompetion 方法
5. 文件上传
@PostMapping("/upload")
public String Upload(@RequestParam("email") String email,
@RequestParam("password") String password,
@RequestPart("profile") MultipartFile profile,
@RequestPart("photos") MultipartFile[] photos) throws IOExption{
System.out.println(email);
System.out.println(password);
System.out.println(profile.getOriginalFilename());
for (MultipartFile file:photos
) {
System.out.println(file.getOriginalFilename());
}
return "redirect:/index.html";
}
/**
*
* @param email
* @param password
* @param profile
* @param photos
* @return index
*/
@PostMapping("/upload")
public String Upload(@RequestParam("email") String email,
@RequestParam("password") String password,
@RequestPart("profile") MultipartFile profile,
@RequestPart("photos") MultipartFile[] photos) throws IOException {
if(!profile.isEmpty()){
String profilename = profile.getOriginalFilename();
System.out.println(profilename);
profile.transferTo(new File("C:\\Users\\Administrator\\Desktop\\java\\"+ hashCode()));
}
if(photos.length >0 ){
for (MultipartFile file: photos
) {
System.out.println(file.getOriginalFilename());
profile.transferTo(new File("C:\\Users\\Administrator\\Desktop\\java\\"+hashCode()));
}
}
return "redirect:/index.html";
}
}
spring:
servlet:
multipart:
max-file-size: 100MB
max-request-size: 100MB 限制大小100MB
文件上传原理
文件上传自动配置类 MultipartAutoConfiguration - MultipartResovler
-
自动配置好了 StandardServletMultipartResovler 文件上传解析器
-
请求进来使用文件解析器判断(isMultipart) return (MultipartHttpServletRequest)
-
参数解析器来解析文件中内容 来封装成MultipartFile
-
将request 中信息封装成一个Map
-
使用FileCopyUtils实现
6. 错误处理
6.1 默认错误处理
将错误页面 400 500 4xx 5xx.html 放在/error 目录下
/error 目录 可以放在 templates 或者 静态资源目录下
/templates
/error
4xx.html
spring boot 会自动映射错误页面
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9UkC8oEJ-1668955220093)(C:\Users\Administrator\AppData\Roaming\marktext\images\2022-11-19-18-07-00-image.png)]
7. JUnit
7.1 常用注解
@DisplayName 给测试起一个别名
@BeforeEach1
@AfterEach 每个测试 都会运行一下
@BeforeAll 只会在最开始 和 结束 时候运行
@AfterAll
@Disabled 这个不需要测试
@TimeOut (value=) 超出时间抛出异常
@RepeateTest(Value) 重复测试
7.2 assert 机制
assertEquals (expected,actual,message) 判断两个值是不是相等 底层就是if else print message
assertSame () 判断是不是同一个对象
assertArrayEqual () 判断数组是不是相等
assertThrows() 异常断言 (还不如直接断点)
7.3 assumption
Assumptions.assumpTrue(assumption,message)
7.4 参数化测试
@ParameterizedTest 使用下面注解 必须要在单元测试上添加这个注解
@ValueSource(value) 放在方法上 直接注入参数
@MethodSource(value) 把一个方法的返回结果 注入到方法参数中
expected,actual,message) 判断两个值是不是相等 底层就是if else print message
assertSame () 判断是不是同一个对象
assertArrayEqual () 判断数组是不是相等
assertThrows() 异常断言 (还不如直接断点)
7.3 assumption
Assumptions.assumpTrue(assumption,message)
7.4 参数化测试
@ParameterizedTest 使用下面注解 必须要在单元测试上添加这个注解
@ValueSource(value) 放在方法上 直接注入参数
@MethodSource(value) 把一个方法的返回结果 注入到方法参数中