SpringBoot

基础入门

默认扫描主启动器SpringBoot01Application同目录下的包。
SpringBoot所有的自动装配功能都在 spring-boot-autoconfigure包里

自动装配原理总结:

  • SpringBoot先加载所有的自动配置类 xxxxxAutoConfiguration

  • 每个自动配置类按照条件进行生效,默认都会绑定配置文件指定的值

    @EnableConfigurationProperties(xxxProperties.class):

    ○ xxxProperties和配置文件进行了绑定

    ○ 将类注册进容器

  • 生效的配置类就会给容器中装配很多组件

  • 只要容器中有这些组件,相当于这些功能就有了

  • 定制化配置

    ○ 用户直接自己@Bean替换底层的组件

    ○ 用户去看这个组件是获取的配置文件什么值就去修改。

总结:

xxxxxAutoConfiguration ---> 组件 ---> xxxxProperties里面拿值 ----> application.properties

最佳实践

SpringBoot 核心技术

yaml 使用

配置提示

		<!--yaml配置提示-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>


<!--        配置提示,开发用,告诉springboot打包时不用打包-->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.springframework.boot</groupId>
                            <artifactId>spring-boot-configuration-processor</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
       

基本语法

(1) key: value	#中间一定要用一个空格
(2) 大小写敏感
(3) 使用缩进表示层级关系
(4) 用空格缩进
(5) 字符串不用加引号,也可以用引号
	 当使用'\n'	==> 表示\n
     当使用"\n"	==>	表示换行
     
(6)数组、集合可以用
	[a,b,c...]
	或者:- value
  	  	  - value
(7)Map<key,Pet>可以用
	- pet:
    	name: 哆啦A梦
    	weight: 3
    - pet:
		name: 哆啦B梦
    	weight: 4  
        
	或者
    [{name: firstPet,weight: 10},{name: secondPet,weight: 20}]
	

举例

//加入容器并与application.yml绑定
@ConfigurationProperties(prefix="person")
@Component
@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class Person {
	
	private String userName;
	private Boolean boss;
	private Date birth;
	private Integer age;
	private Pet pet;
	private String[] interests;
	private List<String> animal;
	private Map<String, Object> score;
	private Set<Double> salarys;
	private Map<String, List<Pet>> allPets;
}

//加入容器并与application.yml绑定
@ConfigurationProperties(prefix="pet")
@Component
@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class Pet {
	private String name;
	private Double weight;
}

application.yml

# yaml表示以上对象
person:
  userName: zhangsan
  boss: false
  birth: 2019/12/12 20:12:33
  age: 18
  pet: 
    name: tomcat
    weight: 23.4
  interests: [篮球,游泳]
  animal: 
    - jerry
    - mario
  score:
    english: 
      first: 30
      second: 40
      third: 50
    math: [131,140,148]
    chinese: {first: 128,second: 136}
  salarys: [3999,4999.98,5999.99]
  allPets:
    sick:
      - {name: tom}
      - {name: jerry,weight: 47}
    health: [{name: mario,weight: 47}]

Web开发

静态资源
  请求进来,先去找Controller看能不能处理。
  不能处理的所有请求又都交给静态资源处理器。静态资源也找不到则响应404页面
自定义静态资源 访问前缀(默认无)、存放位置(一般不自定义存放位置)
spring:
  mvc:		#自定义访问前缀,会导致welcome page功能和小图标失效
    static-path-pattern: /res/**	
    
    #了解,一般使用static作为静态资源路径
  web:
    resources:		#可以存放res01和static目录下
      static-locations: [classpath:/res01/,classpath:/static/]
SpirngMvc 原理

alt

请求映射原理

alt

doDisPatch 得到 HandlerMappings,遍历找到对应的 XxxHandlerMapping

alt

RequestMappingHandlerMapping:保存了所有@RequestMapping 和 handler的映射规则,所有的请求映射都在HandlerMapping中。

alt

自定义HandlerMapping(以后学)

常见参数注解
  • @PathVariable :获取路径变量,RestFul风格 /user/{name}
  • @RequestParam :获取请求参数,/user?name=zhangsan&...
  • @RequestHeader :获取请求头
  • @RequestBody :获取请求体(必须Post方式)
  • @RequestAttribute :获取request域属性
  • @ModelAttribute :获取Model设置参数值
  • @MatrixVariable :获取矩阵变量
  • @CookieValue :获取cookie值
  • @MatrixVariable(pathVar="路径变量名",value="属性名")

@RestController
public class HelloController {

@GetMapping("/car/{id}/owner/{username}")
public Map<String,Object> getCar(@PathVariable("id") String id,         // /car/{id}
                                 @PathVariable("username") String name ,// /car/{username}
                                 //获取所有的路径变量,存放进map<String,String>,map的key、value都得是String
                                 @PathVariable Map<String,String> pvMap,

                                 @RequestParam("age") Integer age,      // /car?age=18

                                 @RequestParam("hobbies") List<String> inters,// /car?hobbies=zq,lq
                                    //获取所有的请求参数,存放进map<String,String>,map的key、value都得是String
                                 @RequestParam Map<String,String> params,

                                 @RequestAttribute("str") String str,  //request.setAttribute("str","str1111");

                                 @RequestHeader("User-Agent") String userAgent,
                                 @RequestHeader() Map<String,String> headMap,
                                 @CookieValue("_ga") String _ga,
                                 @CookieValue("_ga") Cookie cookie,
                                 HttpServletRequest request){


    Map<String,Object> map = new HashMap<>();
//    request.setAttribute("str","str1111");
//    map.put("id",id);
//    map.put("name",name);
//    map.put("pvMap",pvMap);
//    map.put("userAgent",userAgent);
//    map.put("headMap",headMap);

//    map.put("hobbies",inters);
    return map;
}



}

矩阵变量:绑定在路径变量中

alt

@MatrixVariable使用之前要在springboot中开启 1.要有一个配置类 2.手动开启

@Configuration(proxyBeanMethods = false)
public class WebConfig {

    @Bean
    public WebMvcConfigurer webMvcConfigurer(){
        return new WebMvcConfigurer() {
            @Override
            public void configurePathMatch(PathMatchConfigurer configurer) {
                UrlPathHelper urlPathHelper = new UrlPathHelper();
                //不移除;后面内容,这样矩阵变量才能生效
                urlPathHelper.setRemoveSemicolonContent(false);
                configurer.setUrlPathHelper(urlPathHelper);
            }
        };
    }
}
  • 示例
@RestController
public class HelloController {

    //http://localhost:8080/car/1;name=lisi;age=18/10;name=2000;age=20
@GetMapping("/car/{boss1}/{boss2}")
public Map<String,Object> getCar(@MatrixVariable(pathVar="boss1",value="name") String boss1name,
                                 @MatrixVariable(pathVar="boss1",value="age") Integer boss1age,
                                 @PathVariable("boss1") String boos1,
                                 @MatrixVariable(pathVar="boss2",value="name") String boss2name,
                                 @MatrixVariable(pathVar="boss1",value="age") Integer boss2age,
                                 @PathVariable("boss2") String boos2

){
    Map<String,Object> map = new HashMap<>();
    map.put("boss1name",boss1name);
    map.put("boss1age",boss1age);
    map.put("boos1",boos1);
    map.put("boss2name",boss2name);
    map.put("boss2age",boss2age);
    map.put("boos2",boos2);
    return map;
}
}

面试题:cookies被禁用,请问session里的内容怎么获取
用矩阵变量
url重写:/abc;jsesssionid=xxxx 把cookie的值使用矩阵变量的方式进行传递
  • Map、Model(map、model里面的数据会被放在request的请求域 request.setAttribute)、Errors/BindingResult、RedirectAttributes( 重定向携带数据)、ServletResponse(response)、SessionStatus、UriComponentsBuilder、ServletUriComponentsBuilder

  • @ResponseBody 加在方法上,代表返回jason

内容协商

根据客户端接收能力不同,返回不同媒体类型的数据。

<!--        内容协商,引入xml依赖-->
        <dependency>
            <groupId>com.fasterxml.jackson.dataformat</groupId>
            <artifactId>jackson-dataformat-xml</artifactId>
        </dependency>

alt alt

3、开启浏览器参数方式内容协商功能 为了方便内容协商,开启基于请求参数的内容协商功能。

spring:
    contentnegotiation:
      favor-parameter: true  #开启请求参数内容协商模式

发请求: format=json代表返回json类型

http://localhost:8080/test/person?format=json

http://localhost:8080/test/person?format=xml

登录检查用拦截器

拦截器

/**
 * 登录检查
 * 1.配置好拦截器要拦截哪些请求
 * 2.把这些配置放在容器中
 */
public class LoginInterceptor implements HandlerInterceptor {
    /**
     *目标方法执行前
     **/
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //登录逻辑检查
        HttpSession session = request.getSession();
        //获取LoginUser,因为在Controller中user是存放在session中,所以要用session获取
        User user = (User) session.getAttribute("loginUser");

        if(user!=null){
            //放行
            return true;
        }
        //拦截,提示信息并重定向回登录页面
        request.setAttribute("msg","请 先 登 录 !");
        request.getRequestDispatcher("/").forward(request,response);
        return false;
    }
}

在WebMvcConfigurer总,添加拦截器

@Controller
public class AdminWebConfig implements WebMvcConfigurer {
    /**
     * 编写一个拦截器实现 HandlerInterceptor接口
     * 拦截器注册进容器中(实现WebMvcConfiguer的addInterceptors)
     * 指定拦截器规则,/**拦截所有
     * */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        WebMvcConfigurer.super.addInterceptors(registry);
        registry.addInterceptor(new LoginInterceptor())
                .addPathPatterns("/**")     //所有请求都被拦截,包括静态资源
                .excludePathPatterns("/","/login","/css/**","/fonts/**","/images/**","/js/**"); //放行登录请求和静态资源
    }
}

文件上传

html

<!--文件上传固定写法-->
<form role="form" th:action="@{/upload}" method="post" enctype="multipart/form-data">
    <div class="form-group">
        <label for="exampleInputEmail1"> 邮 箱 </label>
    <input type="email" name="email" class="form-control" id="exampleInputEmail1" placeholder="Enter email">
    </div>
    
    <div class="form-group">
         <label for="exampleInputPassword1"> 名 字 </label>
         <input type="text" name="username" class="form-control" id="exampleInputPassword1" placeholder="Password">
    </div>
    
    <div class="form-group">
         <label for="exampleInputFile"> 头 像 </label>
         <input type="file" name="headerImg" id="exampleInputFile">
    </div>
    
    <div class="form-group">
         <label for="exampleInputFile"> 生 活 照 </label>
         <input type="file" name="photos" multiple>
    </div>
    
    <div class="checkbox">
         <label>
             <input type="checkbox"> Check me out
         </label>
    </div>
    <button type="submit" class="btn btn-primary"> 提 交 </button>
</form>

Controller

/**
     * MultipartFile 自动封装上传过来的文件
* */
@PostMapping("/upload")		//点击表单提交请求到这
    public String upload(@RequestParam("email") String email,
                         @RequestParam("username") String username,
                         @RequestPart("headerImg") MultipartFile headerImg,
                         @RequestPart("photos") MultipartFile[] photos) throws IOException {

        //把照片写入磁盘
        if(!headerImg.isEmpty()){
            String originalFilename = headerImg.getOriginalFilename();
            headerImg.transferTo(new File("D://"+originalFilename));

        }

        if(photos.length > 0){
            for (MultipartFile photo : photos) {
                if(!photo.isEmpty()){
                    final String originalFilename = photo.getOriginalFilename();
                    photo.transferTo(new File("D://"+originalFilename));
                }
            }
        }
        return "index";	//返回首页面
    }

配置上传大小

#设置文件上传大小限制
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=100MB

错误处理

  • 默认404白页 alt alt

在templates引擎模板下面建立error,会被自动解析错误处理页面

alt

alt

自定义错误处理

  • @ControllerAdvice + @ExceptionHandler处理全局异常

alt

/**
 * 处理整个web controller 的异常
 * 异常解析器:
 *      ExceptionHandlerExceptionResolver(推荐):处理 @ExceptionHandler注解 、
 *      ResponseStatusExceptionResolver:处理 @ResponseStatus注解、
 *      DefaultHandlerExceptionResolver(默认异常解析器:出里框架自带异常)
 *
 */

@ControllerAdvice
public class GlobalExceptionHandler {

    //匹配 数学运算异常和空指针异常
    //@ExceptionHandler 注解 能被 ExceptionHandlerExceptionResolver 异常解析器处理
    @ExceptionHandler({ArithmeticException.class,NullPointerException.class})   //处理异常
    public String handleArithException(){


        return "login";  //视图地址
    }
}

Web组件

1、Web原生组件(Servlet、Filter、Listener)可以使用
  • 如果没有标注@WebServlet、@WebFilter、@WebListener就不是组件了,@ServletComponentScan(basePackages = "com.gwq.admin") 扫描不到 alt

主启动器,配置扫描原生Servlet三大组件

//主启动器,扫描原生Servlet三大组件
@ServletComponentScan(basePackages = "com.gwq.admin")   
@SpringBootApplication
public class Boot05WebAdminApplication {

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

}

Servlet类

@WebServlet(urlPatterns = "/my")
public class MyServlet  extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("666");
    }
}

alt

Filter类

@Slf4j
@WebFilter(urlPatterns = {"/css/*"})//拦截/css下所有,单*是Servlet写法,双**是Spring写法
public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        log.info("嘿嘿,抓到你啦");
        filterChain.doFilter(servletRequest,servletResponse);//放行
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}

alt alt

Listener类

@Slf4j
@WebListener
public class MyServletContextListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        log.info("监听到MyServletContextListener ==> 初始化完成");
    }
}

alt

2、使用RegistrationBean (非常方便)

(0)写未标注@WebXXX的 MyServlet、 MyFilter 和 MyListener

  • MyServlet
public class MyServlet  extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("666");
    }
}
  • MyFilter
@Slf4j
public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        log.info("嘿嘿,抓到你啦");
        filterChain.doFilter(servletRequest,servletResponse);//放行
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}
  • MyServletContextListener
@Slf4j
public class MyServletContextListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        log.info("监听到MyServletContextListener ==> 初始化完成");
    }
}

(1)写配置类

@Configuration(proxyBeanMethods = true) //细节1 :始终保证依赖的组件是单实例的
public class MyRegistConfig {

    @Bean
    public ServletRegistrationBean myServlet(){
        //创建一个自定义MyServlet
        MyServlet servlet = new MyServlet();
        return new ServletRegistrationBean(servlet,"/my","/my02");
    }

    @Bean
    public FilterRegistrationBean myFilter(){
        //创建一个自定义MyFilter
        MyFilter filter = new MyFilter();

        //方式一 return new FilterRegistrationBean(filter,myServlet());

        //方式二
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(filter);
        //设置过滤路径
        filterRegistrationBean.setUrlPatterns(Arrays.asList("/my","/css/*"));
        return filterRegistrationBean;
    }

    @Bean
    public ServletListenerRegistrationBean myListener(){
        //创建一个自定义Listener
        MyServletContextListener listener = new MyServletContextListener();
        return new ServletListenerRegistrationBean(listener);
    }

}

更改web服务器(Tomcat够用了)

alt

alt

alt

数据访问

导入jdbc场景,如果引入mabatis场景,就把这删了

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>

使用Druid数据源

自定义方式

引入druid-starter

<dependency>
     <groupId>com.alibaba</groupId>
     <artifactId>druid-spring-boot-starter</artifactId>
     <version>1.1.17</version>
</dependency>

自动配置

● 扩展配置项 spring.datasource.druid
● DruidSpringAopConfiguration.class,   
	监控SpringBean的;配置项:spring.datasource.druid.aop-patterns
● DruidStatViewServletConfiguration.class, 
	监控页的配置:spring.datasource.druid.stat-view-servlet;默认开启
●  DruidWebStatFilterConfiguration.class, 
	web监控配置;spring.datasource.druid.web-stat-filter;默认开启
● DruidFilterConfiguration.class}) 所有Druid自己filter的配置

yml配置

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/db_account
    username: root
    password: 123456
    driver-class-name: com.mysql.jdbc.Driver

    druid:
      aop-patterns: com.atguigu.admin.*  #监控SpringBean
      filters: stat,wall     # 底层开启功能,stat(sql监控),wall(防火墙)

      stat-view-servlet:   # 配置监控页功能
        enabled: true
        login-username: admin
        login-password: admin
        resetEnable: false

      web-stat-filter:  # 监控web
        enabled: true
        urlPattern: /*
        exclusions: '*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*'


      filter:
        stat:    # 对上面filters里面的stat的详细配置
          slow-sql-millis: 1000
          logSlowSql: true
          enabled: true
        wall:
          enabled: true
          config:
            drop-table-allow: false		#不允许删表跑路

springboot整合Mybatis

GitHub地址,选择最新版 https://github.com/mybatis/spring-boot-starter alt

选择mybatis-spring-boot-starter,然后选pom文件格式

alt

<!--引入最新版mybatis-spring-boot-starter-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.2</version>
        </dependency>

alt

提示信息用Model存,

用戶用HttpSession存

全部评论

相关推荐

评论
点赞
收藏
分享
牛客网
牛客企业服务