springboot 基本操作

web框架的一些基础功能

0web工程更换主机需要的工作

1修改maven配置

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A4jNn8uy-1648877198499)(springboot应用.assets/Snipaste_2022-03-05_14-01-11.png)]

F:/yang/software/Maven/apache-maven-3.8.3

F:\yang\software\Maven\apache-maven-3.8.3\conf\settings.xml

F:\yang\software\Maven\maven_repository

修改java版本

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9VkKYbkh-1648876653711)(springboot应用.assets/Snipaste_2022-03-05_14-01-33.png)]

1请求数据

数据的传输格式一般为json格式

客户端发送请求(可以包含数据,或者不包含数据)服务端响应请求(可以包含数据,或者不包含数据)

服务端发送请求()

2请求转发 ,重定向 跳转页面

一、请求转发与重定向区别

重定向:

1.可以理解为是客户端行为,客户端发起一次请求,服务器端给出一次响应,但这个响应包含下一次客户端需要 访问的服务器端处理程序的地址,客户端再次发起请求,将会得到处理结果,也就意味着重定向客户端至少发起两次请求
[外链图片转存失败,源站可能有防盗
链机制,建议将图片保失败,源站可能有防盗链机制,建议将图片保存下来直接上传存上传(imPZyiduODLd-1648876653712)(springboot应用.assets/v-888898a708dca21247770152ca86c58_720w.jpg73)(springboot应用.assets/v2-9888178a708dca21247770352ca86c58_720w.jpg)]

请求转发:

1.可以理解是服务器端行为,客户端发起一次请求,这个请求在整个服务器端可以被多次传递,但都是由服务器端的处理程序传递给另一个处理程序,客户端不需要发起二次请求,无论这个请求经历过多少个处理程序,始终都是同一个请求,也就意味着,这个请求中的数据经历过的每一个处理程序都可以使用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7vXyhjS6-1648876653712)(springboot应用.assets/v2-9be47256786691ba3fa13ee3ca817b14_720w.jpg)]

二、使用

当前后两个页面有数据传递时,例如查询了数据需要在页面显示时,用请求转发

当没有数据传递,例如做了更新操作跳转到其他页面,就用重定向。

3文件的上传下载

package com.xianjingshang.admin.controller;

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;

/**
 * 文件上传测试
 */
@Slf4j
@Controller
public class FormTestController {
    @GetMapping("/form_layouts")
    public String form_layouts(){
        return "form/form_layouts";
    }

    /**
     * MultipartFile  自动封装上传过来的文件
     * @param email
     * @param username
     * @param headerImg
     * @param photos
     * @return
     */
    @SneakyThrows
    @PostMapping("/upload")
    public String upload(@RequestParam("email") String email,//从请求参数中获取email的值
                         @RequestParam("username") String username,
                         @RequestPart("headerImg") MultipartFile headerImg,  //MultiparFile 文件格式
                         @RequestPart("photos") MultipartFile[] photos){

        log.info("上传的信息:email={},username={},headerImg{},photos={}",
                email,username,headerImg.getSize(),photos.length);

        if(!headerImg.isEmpty()){
            //保存到文件服务器,oss服务器
            String originalFilename = headerImg.getOriginalFilename();//拿到原始文件名
            //保存文件到这个地方
            headerImg.transferTo(new File("F:\\yang\\study\\学习\\记忆宫殿3.0\\自然科学\\计算机\\Java\\Spring boot2\\resource\\"+originalFilename));
        }

        if(photos.length>0){
            for (MultipartFile photo:photos){
                if(!photo.isEmpty()){
                    //保存到文件服务器,oss服务器
                    String originalFilename = photo.getOriginalFilename();//拿到原始文件名
                    //保存文件到这个地方
                    photo.transferTo(new File("F:\\yang\\study\\学习\\记忆宫殿3.0\\自然科学\\计算机\\Java\\Spring boot2\\resource\\"+originalFilename));
                }
            }
        }
        return "main";
    }
}

4往请求域中存取数据

方法一

public String dynamic_table(Model model){
    //表格内容的遍历
    List<User> users = Arrays.asList(new User("zhangsan", "123456"),
            new User("Lisi", "aaaa"),
            new User("haha", "aadd"));
    model.addAttribute("user",users);  //addAttribute把model数据放在请求域中session
    return "table/dynamic_table";
}

方法二

(HttpServletRequest request){
HttpSession session = request.getSession();
    //取数据
Object loginUser=session.getAttribute("loginUser");
    //存数据
    session.setAttribute("msg","请先登录");
}

spring boot应用

00

结构

第三方库AutoConfiguration

注解的运用

@Configuration@Bean一起使用
    @Configuration//放在类的上面作为配置类的标识
    @Bean //放在方法上作为配置属性的修改
    

xml配置与配置类之间的转换

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NkY8IP1E-1648876653713)(springboot应用.assets/Snipaste_2022-03-04_14-09-46.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-egeEsagC-1648876653714)(springboot应用.assets/Snipaste_2022-03-04_14-43-20.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uxEHlfMR-1648876653714)(springboot应用.assets/Snipaste_2022-03-04_14-36-25.png)]

0创建一个简单的springboot后台管理系统

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rdMyf4Ne-1648876653715)(springboot应用.assets/Snipaste_2022-02-21_15-43-27.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t7GFx4yI-1648876653715)(springboot应用.assets/Snipaste_2022-02-21_15-43-19.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ch2GwEjP-1648876653716)(springboot应用.assets/Snipaste_2022-02-21_15-43-10.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4AhhGGeO-1648876653716)(springboot应用.assets/Snipaste_2022-02-21_15-44-09.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-we80Nc60-1648876653716)(springboot应用.assets/Snipaste_2022-02-21_15-44-15.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-b1cMX3w6-1648876653717)(springboot应用.assets/Snipaste_2022-02-21_15-47-31.png)]

1浏览器接收和发送的数据类型

基于请求头(header)来判断数据类型

1、开启浏览器参数方式内容协商功能

为了方便内容协商,开启基于请求参数的内容协商功能。

在请求后带上一个format的参数,在参数后面跟上返回的数据类型,就能得到参数类型

yaml 配置类中写

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

发请求:

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

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

2、自定义 MessageConverter

实现多协议数据兼容。json、xml、x-guigu

0、@ResponseBody 响应数据出去 调用 RequestResponseBodyMethodProcessor 处理

1、Processor 处理方法返回值。通过 MessageConverter 处理

2、所有 MessageConverter 合起来可以支持各种媒体类型数据的操作(读、写)

3、内容协商找到最终的 messageConverter

SpringMVC的什么功能。一个入口给容器中添加一个 WebMvcConfigurer

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AMVVm9m9-1648876653717)(springboot应用.assets/Snipaste_2022-02-21_11-51-27.png)]

 @Bean
    public WebMvcConfigurer webMvcConfigurer(){
        return new WebMvcConfigurer() {

            @Override
            public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {

            }
        }
    }

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ac8EwraX-1648876653718)(springboot应用.assets/1605260623995-8b1f7cec-9713-4f94-9cf1-8dbc496bd245-163937286206561.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4XH6Fbvm-1648876653718)(springboot应用.assets/1605261062877-0a27cc41-51cb-4018-a9af-4e0338a247cd-163937286206563.png)]

有可能我们添加的自定义的功能会覆盖默认很多功能,导致一些默认的功能失效。

大家考虑,上述功能除了我们完全自定义外?SpringBoot有没有为我们提供基于配置文件的快速修改媒体类型功能?怎么配置呢?【提示:参照SpringBoot官方文档web开发内容协商章节】

/**
 * 自定义类的converter
 */
public class GuiguMessageConverter implements HttpMessageConverter<Person> {


    @Override
    /**
     * 得到读取自己定义的数据
     */
    public boolean canRead(Class<?> clazz, MediaType mediaType) {
        return false;
    }

    /**
     *
     *返回 类型 是person类就可以
     * @return
     */
    @Override
    public boolean canWrite(Class<?> clazz, MediaType mediaType) {
        return clazz.isAssignableFrom(Person.class);
    }

    /**
     * 服务器要统计所有MessageConverter都能写出哪些内容类型
     *
     * application/x-guigu
     * @return
     */
    @Override
    public List<MediaType> getSupportedMediaTypes() {
        return MediaType.parseMediaTypes("application/x-guigu");
    }

    @Override
    public Person read(Class<? extends Person> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
        return null;
    }

    @Override
    public void write(Person person, MediaType contentType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {

        //自定义协议数据的写出
        String data=person.getUserName()+";"+person.getAge()+";"+person.getBirth()+";"+
                person.getPet();

        //写出去
        OutputStream body = outputMessage.getBody();
        body.write(data.getBytes());
    }
}

3、基于参数的内容协商

在webconfig中的WebMvcConfigurer(){}进行配置

/**
             * 设置内容协商策略  参数,请求头
             * @param configurer
             */
            @Override
            public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
//                Map<String, MediaType> mediaTypes
                Map<String, MediaType> mediaTypes=new HashMap<>();
                mediaTypes.put("json",MediaType.APPLICATION_JSON);
                mediaTypes.put("xml",MediaType.APPLICATION_XML);
                mediaTypes.put("gg",MediaType.parseMediaType("application/x-guigu"));
                //指定支持解析哪些参数对应的哪些媒体类型
                ParameterContentNegotiationStrategy parameterStrategy = new ParameterContentNegotiationStrategy(mediaTypes);
                //把format换成ff
                parameterStrategy.setParameterName("ff");
                //支持请求头的参数
                HeaderContentNegotiationStrategy headerStrategy = new HeaderContentNegotiationStrategy();
                //把头和参数全放进去了
                configurer.strategies(Arrays.asList(parameterStrategy,headerStrategy));
            }

            /**
             * 拓展自定义的converter
             * @param converters
             */
            @Override
            public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
                //添加自定义的converter
                converters.add(new GuiguMessageConverter());

            }

2图形解析器thymeleaf

1、引入Starter
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
2、自动配置好了thymeleaf
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(ThymeleafProperties.class)
@ConditionalOnClass({ TemplateMode.class, SpringTemplateEngine.class })
@AutoConfigureAfter({ WebMvcAutoConfiguration.class, WebFluxAutoConfiguration.class })
public class ThymeleafAutoConfiguration { }

自动配好的策略

  • 1、所有thymeleaf的配置值都在 ThymeleafProperties

  • 2、配置好了 SpringTemplateEngine

  • 3、配好了 ThymeleafViewResolver

  • 4、我们只需要直接开发页面

	public static final String DEFAULT_PREFIX = "classpath:/templates/";
//资源路径下的resources/templates放页面

	public static final String DEFAULT_SUFFIX = ".html";  //xxx.html
<!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>
<h2>
<!--    超链接  是<a>-->
<!--    替换超链接,替换什么,在th后面加什么-->
    <a href="www.atguigu.com" th:href="${link}">去百度</a> <br/>
    <a href="www.atguigu.com" th:href="@{link}">去百度2</a>
</h2>
</body>
</html>
没有放到后端进行模板引擎的刷新

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HRLjqJek-1648876653719)(springboot应用.assets/Snipaste_2022-02-21_15-17-51-16454279122343.png)]

在后端进行了引擎的刷新

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kKxzpEZ8-1648876653719)(springboot应用.assets/Snipaste_2022-02-21_15-16-15-16454279122344.png)]

3跳转页面

@Controller
public class IndexController {

    /**
     * 来登录页
     * @return
     */
    @GetMapping(value = {"/","/login"})
    public String loginPage(){
        return "login";
    }

    @PostMapping("/login")
    public String main(String username,String password){

        //登录成功重定向到main.html;重定向防止表单重复提交
        return "redirect:/main.html";
    }

    /**
     * 去main页面
     * @return
     */
    @GetMapping("/main.html")
    public String mainPage(){
        return "main";
    }
}

4,bean的建立

@Data  get,set方法
@AllArgsConstructor  有参构造器
@NoArgsConstructor	 无参构造器

@SneakyThrows
Exception异常有两个分支,一个是运行时异常RuntimeException,一个是编译时异常,在Exception下的所有非RuntimeException异常,比如IOException、SQLException等;所有的运行时异常不捕获,编译时异常是一定要捕获,否则编译会报错。@SneakyThrows就是利用了这一机制,将当前方法抛出的异常,包装成RuntimeException,骗过编译器,使得调用点可以不用显示处理异常信息

5,拦截器

  • 1,编写一个拦截器实现HandlerInterceptor接口
  • 2,拦截器注册到容器中(实现WebMvcConfigurer的addInterceptors)
  • 3,指定拦截规则【如果是拦截所有,静态资源也会被拦截】

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MK8WUwfN-1648876653720)(springboot应用.assets/Snipaste_2022-02-28_14-56-35.png)]

接口功能
preHandle在执行前处理
postHandle在执行后处理
afterCompletion在请求完成后处理

拦截类

向浏览器中发送一个session

@Controller
public class IndexController {
@PostMapping("/login")
    public String main(User user, HttpSession session, Model model){ //RedirectAttributes

        if(StringUtils.hasLength(user.getUserName()) && "123456".equals(user.getPassword())){
            //把登陆成功的用户保存起来
            session.setAttribute("loginUser",user);
            //登录成功重定向到main.html;  重定向防止表单重复提交
            return "redirect:/main.html";
        }else {
            model.addAttribute("msg","账号密码错误");
            //回到登录页面
            return "login";
        }

    }
}
package com.xianjingshang.admin.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * 登录检查
 * 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;
        }else {
        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 {

    }
}

配置拦截器

@Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor())
//                添加路径
                .addPathPatterns("/**")
//                放行路径
                .excludePathPatterns("/","/login");
    }

拦截器的执行顺序

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BFDr4Mco-1648876653720)(springboot应用.assets/Snipaste_2022-02-28_16-01-13.png)]

6,配置类

spring的容器的注册都在配置类中写

加上==@Configuration===

继承WebMvcConfigurer接口

就完成了配置类的基础搭建

package com.xianjingshang.admin.config;

import com.xianjingshang.admin.interceptor.LoginInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class AdminWebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor())
//                添加路径
                .addPathPatterns("/**")
//                放行路径
                .excludePathPatterns("/","/login");
    }
}

7,日志

@Slf4j  引入注释,是lombok插件里的

使用

log.info("当前的日志内容");
log.info("拦截的请求路径是{}",requestURI);
//{}类似c语言中的pringtf("%d",a);中的%d

8,加载更新

实际上是重启,不是更新。更新的插件收费

ctrl+F9

9、异常处理

1、错误处理(自动配置)

  • 默认情况下,Spring Boot提供/error处理所有错误的映射
  • 对于机器客户端,它将生成JSON响应,其中包含错误,HTTP状态和异常消息的详细信息。对于浏览器客户端,响应一个“ whitelabel”错误视图,以HTML格式呈现相同的数据
  • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v8RyEjcy-1648876653721)(springboot应用.assets/1606024421363-77083c34-0b0e-4698-bb72-42da351d3944-163937286206583.png)]
  • 要对其进行自定义,添加**View**解析为**error**``** **
  • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ahIW8Tfq-1648876653721)(springboot应用.assets/1606024616835-bc491bf0-c3b1-4ac3-b886-d4ff3c9874ce.png)]
  • 要完全替换默认行为,可以实现 ErrorController并注册该类型的Bean定义,或添加ErrorAttributes类型的组件以使用现有机制但替换其内容。
  • error/下的4xx,5xx页面会被自动解析;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bq2G5dyb-1648876653721)(springboot应用.assets/1606024592756-d4ab8a6b-ec37-426b-8b39-010463603d57-163937286206587.png)]

2,应用

1自定义错误页

error/404.html error/5xx.html;有精确的错误状态码页面就匹配精确,没有就找 4xx.html;如果都没有就触发白页

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zKRQ6B3d-1648876653722)(springboot应用.assets/1606024592756-d4ab8a6b-ec37-426b-8b39-010463603d57-163937286206587.png)]

2处理全局异常

@ControllerAdvice+@ExceptionHandler处理全局异常;底层是 ExceptionHandlerExceptionResolver 支持的

package com.xianjingshang.admin.exception;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

/**
 * 处理整个web controller
 */
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler({ArithmeticException.class,NullPointerException.class}) //处理异常
    public String handleArithException(Exception e//抓住异常
                                                    ){
        log.error("异常是:{}",e);
        return "login"; //视图地址
    }
}
3处理自定义异常

@ResponseStatus+自定义异常 ;底层是 ResponseStatusExceptionResolver ,把responsestatus注解的信息底层调用 response.sendError(statusCode, resolvedReason);tomcat发送的/error

package com.xianjingshang.admin.exception;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;

@ResponseStatus(value = HttpStatus.FORBIDDEN,reason = "用户数量太多")
public class UserTooManyException extends RuntimeException{
    public UserTooManyException(){

    }
   public UserTooManyException(String message){
        super(message);  //把信息传到异常里
    }
}
//引出异常
@GetMapping("/dynamic_table")
public String dynamic_table(Model model){
    //表格内容的遍历
    List<User> users = Arrays.asList(new User("zhangsan", "123456"),
            new User("Lisi", "aaaa"),
            new User("haha", "aadd"));
    model.addAttribute("user",users);  //addAttribute把model数据放在请求域中session

    if(users.size()>3){
        throw new UserTooManyException();
    }

    return "table/dynamic_table";
}
4,Spring底层的异常

Spring底层的异常,如 参数类型转换异常;DefaultHandlerExceptionResolver 处理框架底层的异常。

5,可以作为默认的全局异常处理规则

自定义实现 HandlerExceptionResolver 处理异常;可以作为默认的全局异常处理规则

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tz69fN20-1648876653722)(springboot应用.assets/Snipaste_2022-03-01_16-49-29.png)]

6 ,tomcat处理

ErrorViewResolver 实现自定义处理异常;

  • response.sendError 。error请求就会转给controller

  • 你的异常没有任何人能处理。tomcat底层

  • response.sendError。error请求就会转给controller

  • basicErrorController 要去的页面地址是 ErrorViewResolver

10原生组件注入

1注释类型

1在spring配置文件中添加注释
@ServletComponentScan(basePackages = "com.xianjingshang.admin") //默认是配置类下的所有包及其子包,也就是当前目录
@SpringBootApplication
public class Boot05WebAdminApplication {

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

}
2创建Servlet,Filter,ServlerContextList的方法中添加注释
1监听器
@WebListener
public class MyServletContextListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        log.info("MyServletContextListener监听到项目初始化完成");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        log.info("MyServletContextListener监听到项目销毁");
    }
}
2方法
//必须在配置类中添加一个包扫描器
//直接响应没有经过spring拦截器的拦截
@WebServlet(urlPatterns = "/my")
public class MyServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("6666");
    }
}

3拦截器
//web自带的拦截器
//*是servlet的写法,**是spring的写法
@WebFilter(urlPatterns = {"/css/*","/images/*"})//没有拦截my
public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        log.info("MyFilter初始化完成");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        log.info("MyFilter工作");
        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {
        log.info("MyFilter销毁");
    }
}
3,@Configuration+@Bean 的MyRegistConfig实现组件的注册
1MyRegistConfig
@Configuration
public class MyRegistConfig {
//    当没有在Servlet中写@WebServlet(urlPatterns = "/my")时可以用这个注册
    @Bean//用来注册的标记注释
    public ServletRegistrationBean myServlet(){
        MyServlet myServlet = new MyServlet();
        return new ServletRegistrationBean(myServlet,"/my","/my02");

    }
//    当没有写@WebFilter(urlPatterns = {"/css/*","/images/*"})时可以用这个注册
    @Bean
    public FilterRegistrationBean myFilter(){

        MyFilter myFilter=new MyFilter();
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(myFilter);
        filterRegistrationBean.setUrlPatterns(Arrays.asList("/my","/css/*"));//配置拦截路径

        return filterRegistrationBean;
    }
    @Bean
    public ServletListenerRegistrationBean myListener(){
        MyServletContextListener myServletContextListener = new MyServletContextListener();
        return new ServletListenerRegistrationBean(myServletContextListener);
    }

}
2,Servlet
public class MyServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("6666");
    }
}
3,Filter
public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        log.info("MyFilter初始化完成");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        log.info("MyFilter工作");
        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {
        log.info("MyFilter销毁");
    }
}
4,ServletContextListener
public class MyServletContextListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        log.info("MyServletContextListener监听到项目初始化完成");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        log.info("MyServletContextListener监听到项目销毁");
    }
}

11、嵌入式Servlet容器

1、切换嵌入式Servlet容器

  • 默认支持的webServer
    • Tomcat, Jetty, or Undertow
    • ServletWebServerApplicationContext 容器启动寻找ServletWebServerFactory 并引导创建服务器
  • 切换服务器
  • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tkXedyca-1648876653722)(springboot应用.assets/1606280937533-504d0889-b893-4a01-af68-2fc31ffce9fc-1639372862067109.png)]
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>

12.定制化常见方式

1,全面接管springMvc

/**
 * 1,编写一个拦截器实现HandlerInterceptor接口
 * 2,拦截器注册到容器中(实现WebMvcConfigurer的addInterceptors)
 * 3,指定拦截规则【如果是拦截所有,静态资源也会被拦截】
 * @EnableWebMvc:全面接管
 *              1,静态资源?视图解析器?欢迎页。。。全部失效
 */
//@EnableWebMvc//一定要慎用
@Configuration
public class AdminWebConfig implements WebMvcConfigurer {

    /**
     * 定义静态资源行为
     * @param registry
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        /**
         * 访问/aa/** 所有请求都去classpath:/static/ 下面进行匹配
         */
        registry.addResourceHandler("/aa/**")
                .addResourceLocations("classpath:/static/");
    }


    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor())
//                添加路径
                .addPathPatterns("/**")//所有请求都被拦截,包括静态请求
//                放行路径
                .excludePathPatterns("/","/login","/css/**","/fonts/**","/js/**","/images/**","/aa/**");
    }

    /**
     * 可以修改底层的内容
     * @return
     */
//    @Bean
//    public WebMvcRegistrations webMvcRegistrations(){
//        return new WebMvcRegistrations() {
//            @Override
//            public RequestMappingHandlerMapping getRequestMappingHandlerMapping() {
//                return null;
//            }
//        };
//    }
}

2,==Web应用 编写一个配置类实现 WebMvcConfigurer 即可定制化web功能;+ @Bean给容器中再扩展一些组件==常用

@Configuration
public class AdminWebConfig implements WebMvcConfigurer

3、原理分析套路重点

场景starter - xxxxAutoConfiguration - 导入xxx组件 - 绑定xxxProperties – 绑定配置文件项

13.引入数据库

1配置数据库

1,基本配置
1、导入JDBC场景
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jdbc</artifactId>
        </dependency>
        

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0jCY3GZ8-1648876653723)(springboot应用.assets/1606366100317-5e0199fa-6709-4d32-bce3-bb262e2e5e6a.png)]

2.导入数据库驱动

数据库版本和驱动版本对应

默认版本:<mysql.version>8.0.22</mysql.version>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
<!--            <version>5.1.49</version>-->
        </dependency>
想要修改版本
1、直接依赖引入具体版本(maven的就近依赖原则)
2、重新声明版本(maven的属性的就近优先原则)
    <properties>
        <java.version>1.8</java.version>
        <mysql.version>5.1.49</mysql.version>
    </properties>
navicat如何查看当前mysql的版本

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0n2VbW9g-1648876653723)(springboot应用.assets/Snipaste_2022-03-04_08-44-13.png)]

3、修改配置项
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/db_account
    username: root
    password: 123456
    driver-class-name: com.mysql.jdbc.Driver
2配置druid数据库连接池(过时了)

maven


<!--        引入阿里德鲁伊数据库-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.17</version>
        </dependency>


@Configuration
public class MyDataSourceConfig {

    /**
     * 默认的自动配置是判断容器中没有才会配@ConditionalOnMissingBean(DataSource.class)
     */
    //把public DataSource dataSource中
    // DataSource里边的属性跟配置文件进行绑定 绑定之后不能再用配置类配置了
    @ConfigurationProperties("spring.datasource")
    @Bean
    public DataSource dataSource() throws SQLException {
        DruidDataSource druidDataSource = new DruidDataSource();
//        druidDataSource.setUrl();
//        druidDataSource.setUsername();
//        druidDataSource.setPassword();

//        //加入监控功能
//        druidDataSource.setFilters("stat");


        return new DruidDataSource();
    }


    /**
     * 配置druid的监控页功能
     * @return
     */

    @Bean
    public ServletRegistrationBean statViewServlet(){
        StatViewServlet statViewServlet = new StatViewServlet();
        ServletRegistrationBean<StatViewServlet> registrationBean = new ServletRegistrationBean<>(statViewServlet, "/druid/*" );
        return registrationBean;
    }
}
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/occupy
    username: root
    password: 123456

#    加入监控功能
    filters: stat
    driver-class-name: com.mysql.jdbc.Driver
#    type: com.zaxxer.hikari.HikariDataSource

#  查询超时默认是s
  jdbc:
    template:
      query-timeout: 3
1,开启sql监控

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VS9IqmKJ-1648876653723)(springboot应用.assets/Snipaste_2022-03-04_13-05-53.png)]

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/occupy
    username: root
    password: 123456

#    加入监控功能
    filters: stat
2,开启web监控

MyDataSourceConfig类中

 /**
     * webStatFilter 用于采集web—jdbc关联监听的数据。
     * @return
     */
    @Bean
    public FilterRegistrationBean webStatFilter(){
        WebStatFilter webStatFilter=new WebStatFilter();
        FilterRegistrationBean<WebStatFilter> filterFilterRegistrationBean=
                new FilterRegistrationBean<WebStatFilter>(webStatFilter);
        filterFilterRegistrationBean.setUrlPatterns(Arrays.asList("/*"));
        filterFilterRegistrationBean.addInitParameter("exclusions","*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");

        return filterFilterRegistrationBean;
    }
3配置druid数据库连接池(官方配置)
3、使用官方starter方式
1、引入druid-starter
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.17</version>
        </dependency>

2,写sql语句

@SpringBootTest
class Boot05WebAdminApplicationTests {

    @Autowired//自动注入 这个类的参数和方法
            //类似静态变量,已经放到容器中了,随着请求而改变
    JdbcTemplate jdbcTemplate;

    @Autowired
    DataSource dataSource;//sql类中的
    @Test
    void contextLoads() {
//          查询单条记录
//        jdbcTemplate.queryForObject("select * from seats ");
        jdbcTemplate.queryForList("select * from seats");

        Long aLong = jdbcTemplate.queryForObject("select count(*) from seats", long.class);
        for(int i=0;i<10;i++) {
            log.info("msg   记录总数:{}", aLong);
            log.info("msg 数据源类型:{}",dataSource.getClass());
        }
    }

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

仙境觞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值