Spring boot

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)

  1. 根据当前请求找到HandlerExecuttionChain {中含有所有拦截器}

  2. 顺序执行拦截器的Prehandle方法 如果为true 进入下一个拦截器 否则 倒叙执行 已经执行的拦截器的aftercompetion 方法

  3. 如果任意一个拦截器 false 都不会执行 handle 方法

  4. 所有 拦截器 返回true 执行 目标方法

  5. 倒叙执行 拦截器postHandler方法

  6. 前面有异常的话执行 aftercompetion方法

  7. 页面渲染完后 执行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) 把一个方法的返回结果 注入到方法参数中

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值