2 springboot web开发

1 JRebel

  1. 开发web项目的时候,需要频繁的修改web页面,频繁的重启变得很麻烦,可以在idea中集成热部署插件:JRebel,改动代码之后不需要重新启动应用程序
  2. 安装
    1. Preferences–Plugins–搜索JRebel
    2. 安装好后重启idea
  3. 激活JRebel
    1. 生成一个GUID:https://www.guidgen.com/
    2. 打开JRebel激活面板:Help–JRebel–Activation–Team URL–填写https://jrebel.qekang.com/{GUID}
    3. 激活即可

2 springboot整合servlet

  1. 一般不会用,但配置druid数据源的监控时,需要编写servlet,所以此处需要了解springboot如何整合的servlet

2.1 使用注解扫描的方式注册

  1. 编写servlet类

    //web3.0后提供的注解的方式编写servlet
    @WebServlet(name = "myServlet",urlPatterns = "/srv")
    public class MyServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("111");
            super.doGet(req, resp);
        }
    }
    
  2. 注册servlet

    package com.mashibing;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.web.servlet.ServletComponentScan;
    
    @SpringBootApplication
    //启动器启动时,扫描本目录以及子目录带有@WebServlet注解的类自动注册
    @ServletComponentScan
    public class SpringbootApplication {
        public static void main(String[] args) {
            SpringApplication.run(SpringbootApplication.class, args);
        }
    }
    

2.2 使用组件ServletRegistrationBean注册

  1. 编写servlet类

    package com.mashibing.controller;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    //此处不需要使用@WebServlet注解
    public class MyServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("111");
            super.doGet(req, resp);
        }
    }
    
  2. 注册servlet

    package com.mashibing;
    
    import com.mashibing.controller.MyServlet;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.web.servlet.ServletRegistrationBean;
    import org.springframework.context.annotation.Bean;
    
    @SpringBootApplication
    public class SpringbootApplication {
        public static void main(String[] args) {
            SpringApplication.run(SpringbootApplication.class, args);
        }
    
        //需要自己创建一个ServletRegistrationBean对象,并交给spring管理,这样就完成了servlet的注册
        @Bean
        public ServletRegistrationBean<MyServlet> getServletRegistrationBean() {
            //"/root","/home"可以为这个servlet指定多个访问url,即通过/root、/home都可以访问这个servlet
            ServletRegistrationBean<MyServlet> bean = new ServletRegistrationBean<>(new MyServlet(), "/root", "/home");
            bean.setLoadOnStartup(1);
            return bean;
        }
    }
    

3 springboot整合filter

  1. 同样有注解扫描和组件两种方式

3.1 使用注解扫描的方式注册

  1. 编写filter类

    @WebFilter(filterName = "MyFilter", urlPatterns = "/filter")
    public class MyFilter implements Filter {
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            System.out.println("init");
        }
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            System.out.println("filter");
            chain.doFilter(request,response);
        }
    
        @Override
        public void destroy() {
            System.out.println("destory");
        }
    }
    
  2. 注册filter

    @ServletComponentScan
    public class SpringbootApplication
      ...
    

3.2 使用组件FilterRegistrationBean注册

  1. 编写filter

    //不需要任何注释
    public class MyFilter implements Filter
      ...
    
  2. 注册filter

    @Bean
    public FilterRegistrationBean<MyFilter> getFilterRegistrationBean() {
      FilterRegistrationBean<MyFilter> bean = new FilterRegistrationBean<>(new MyFilter());
      bean.addUrlPatterns("/filter");
      return bean;
    }
    

4 springboot整合监听器

  1. 同样有注解扫描和组件两种方式

4.1 使用注解扫描的方式注册

  1. 编写监听器类

    package com.mashibing.controller;
    
    import javax.servlet.annotation.WebListener;
    import javax.servlet.http.HttpSessionEvent;
    import javax.servlet.http.HttpSessionListener;
    @WebListener
    public class MyHttpSessionListener implements HttpSessionListener {
    
        public static int online = 0;
    
        @Override
        public void sessionCreated(HttpSessionEvent se) {
            System.out.println("创建session");
            online++;
        }
    
        @Override
        public void sessionDestroyed(HttpSessionEvent se) {
            System.out.println("销毁session");
        }
    }
    
  2. 注册监听器

    @ServletComponentScan
    public class SpringbootApplication
      ...
    
  3. 控制层测试代码

    package com.mashibing.controller;
    
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpSession;
    
    //使用两个浏览器分别输入:http://localhost:8080/login
    //然后输入:http://localhost:8080/online,发现打印在线人数有2人
    @RestController
    public class ThymeleafController {
        @RequestMapping("/login")
        public String login(HttpServletRequest request) {
            HttpSession session = request.getSession(true);
            return "login";
        }
    
        @RequestMapping("online")
        public String online() {
            return "当前在线人数:" + MyHttpSessionListener.online + "人";
        }
    }
    

4.2 使用组件ServletListenerRegistrationBean注册

  1. 编写监听器类

    //不需要任何注释
    public class MyHttpSessionListener implements HttpSessionListener
      ...
    
  2. 注册监听器

    @Bean
    public ServletListenerRegistrationBean listenerRegist() {
      ServletListenerRegistrationBean srb = new ServletListenerRegistrationBean();
      srb.setListener(new MyHttpSessionListener());
      System.out.println("listener");
      return srb;
    }
    

5 @Configuration配置类

  1. 配置类

    package com.test.spring.support.configuration;
    //相当于定一个了一个xml配置文件,其内有一个bean,id为testBean。且@Configuration注释被@Component所注释,所以还会产生一个id为testConfiguration的bean对象由spring管理
    @Configuration
    public class TestConfiguration {
      public TestConfiguration(){
        System.out.println("spring容器启动初始化。。。");
      }
      //@Bean注解注册bean,同时可以指定初始化和销毁方法
      //@Bean(name="testNean",initMethod="start",destroyMethod="cleanUp")
      @Bean
      @Scope("prototype")
      public TestBean testBean() {
        return new TestBean();
      }
    }
    
  2. 可以通过如下方式启动spring容器

    package com.test.spring.support.configuration;
    
    public class TestMain {
      public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(TestConfiguration.class);
        //获取bean
        TestBean tb = context.getBean("testBean");
        tb.sayHello();
        // 如果加载spring-context.xml文件
        // ApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml");
      }
    }
    

6 springboot中静态资源配置

  1. springboot默认使用WebMvcAutoConfiguration中的WebMvcAutoConfigurationAdapter内部类的addResourceHandlers方法来提供静态资源的映射方式。内部类WebMvcAutoConfigurationAdapter实现了WebMvcConfigurer接口,addResourceHandlers方法就来自该接口

  2. addResourceHandlers方法分析

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        if (!this.resourceProperties.isAddMappings()) {
            logger.debug("Default resource handling disabled");
            return;
        }
        Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
        CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
        if (!registry.hasMappingForPattern("/webjars/**")) {
            //此处代码表示,一旦发现格式为"/webjars/**"的请求,就映射到"classpath:/META-INF/resources/webjars/"下去查找是否有请求的静态资源
            customizeResourceHandlerRegistration(registry.addResourceHandler("/webjars/**")
                    .addResourceLocations("classpath:/META-INF/resources/webjars/")
                    .setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
        }
        String staticPathPattern = this.mvcProperties.getStaticPathPattern();
        if (!registry.hasMappingForPattern(staticPathPattern)) {
          	//1. staticPathPattern为/**
          	//2. getResourceLocations(this.resourceProperties.getStaticLocations())"classpath:/META-INF/resources/","classpath:/resources/", "classpath:/static/", "classpath:/public/"
          	//3. 这表示,一旦发现格式为"/**"的请求,就依次到上面的几个路径中查找是否有匹配的静态资源
            customizeResourceHandlerRegistration(registry.addResourceHandler(staticPathPattern)
                    .addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations()))
                    .setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
        }
    }
    
  3. 访问webjars

    1. webjars是将客户端(浏览器)资源(JavaScript,Css等)打成jar包文件,以对资源进行统一依赖管理。webjars的jar包在Maven中央仓库中

    2. 引入jquery的webjars

      <dependency>
          <groupId>org.webjarsgroupId>
          <artifactId>jqueryartifactId>
          <version>3.4.1version>
      dependency>
      
    3. 引入的jar包中,包含路径META-INF/resources/webjars/jquery/3.4.1,里面有jquery.js文件

    4. 此时我们可以直接通过http://localhost:8080/webjars/jquery/3.4.1/jquery.js访问该js文件

  4. 访问自定义的静态资源

    1. 由上面代码分析,在"classpath:/static/"下新建1.html
    2. 此时可以通过http://localhost:8080/1.html对此静态资源进行访问
  5. 自定义静态资源映射

    @Configuration
    //1. 这个注解会覆盖掉SpringBoot的默认的静态资源映射配置
    //@EnableWebMvc 
    //2. WebMvcConfigurerAdapter实际上已经过期,可以直接实现WebMvcConfigurer接口来自定义映射关系
    class WebMvcConfig extends WebMvcConfigurerAdapter {
        @Override
        void addResourceHandlers(ResourceHandlerRegistry registry) {
            //表示无论url中以什么方式访问"swagger-ui.html",都直接去"classpath:/META-INF/resources/"下查找对应文件
            registry.addResourceHandler("swagger-ui.html")
                    .addResourceLocations("classpath:/META-INF/resources/")
        }
    }
    

7 springboot中首页的配置

  1. springboot默认使用WebMvcAutoConfiguration中的EnableWebMvcConfiguration内部类的welcomePageHandlerMapping方法来提供首页路径和文件名

  2. welcomePageHandlerMapping方法分析

    @Bean
    public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext,
                                                               FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
        WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(
                new TemplateAvailabilityProviders(applicationContext), applicationContext, getWelcomePage(),
                this.mvcProperties.getStaticPathPattern());
        welcomePageHandlerMapping.setInterceptors(getInterceptors(mvcConversionService, mvcResourceUrlProvider));
        welcomePageHandlerMapping.setCorsConfigurations(getCorsConfigurations());
        return welcomePageHandlerMapping;
    }
    
    private Optional<Resource> getWelcomePage() {
      	//1. this.resourceProperties.getStaticLocations()对应路径为"classpath:/META-INF/resources/","classpath:/resources/", "classpath:/static/", "classpath:/public/" 
        String[] locations = getResourceLocations(this.resourceProperties.getStaticLocations());
      	//2. getIndexHtml方法会找到上面所有路径中的index.html文件
      	//3. 因此首页为上述路径下的index.html文件
        return Arrays.stream(locations).map(this::getIndexHtml).filter(this::isReadable).findFirst();
    }
    
    private Resource getIndexHtml(String location) {
        return this.resourceLoader.getResource(location + "index.html");
    }
    
  3. 访问首页

    1. 在"classpath:/static/"下新建index.html
    2. 通过http://localhost:8080/访问首页

8 springboot对springmvc的扩展

  1. springboot提供了适用于大多数springmvc应用的自动配置

  2. springboot默认使用的视图解析器,是WebMvcAutoConfiguration中的viewResolver方法所返回的ContentNegotiatingViewResolver类型的视图解析器。该方法上有@Bean,因此会作为bean交给spring管理,这样spring就会使用该视图解析器来解析视图

  3. 由于springboot使用的视图解析器是从bean中获取的,因此可以使用如下方式新增自定义视图解析器

    //将返回的视图解析器对象放入bean中,交给spring管理
    @Bean
    public ViewResolver myViewResolver(){
      return new MyViewResolver();
    }
    
    //自定义视图解析器需要实现ViewResolver接口
    private static class MyViewResolver implements ViewResolver{
      @Override
      public View resolveViewName(String s, Locale locale) throws Exception {
        return null;
      }
    }
    
  4. 如果想保留springboot mvc的功能的前提下,增加其他mvc相关配置(资源映射、拦截器、格式化器、视图控制器等),可以添加自己的WebMvcConfigurer类型的@Configuration类,注意自定义的类上不要带@EnableWebMvc注解,这样会令springboot mvc默认的mvc功能失效。上面自定义静态资源映射就是使用这种方式实现的

  5. 如果想自定义RequestMappingHandlerMapping、RequestMappingHandlerAdapter、ExceptionHandlerExceptionResolver 实例,可以声明一个WebMvcRegistrationsAdapter实例来提供这些组件

  6. 自定义视图控制器:视图控制器不是视图解析器,视图控制器用于实现页面跳转

    1. 需要在resources/templates下建立success.html

    2. 由于要访问templates文件夹下内容,因此必须导入模版引擎的依赖包

      <dependency>
        <groupId>org.thymeleafgroupId>
        <artifactId>thymeleaf-spring5artifactId>
      dependency>
      <dependency>
        <groupId>org.thymeleaf.extrasgroupId>
        <artifactId>thymeleaf-extras-java8timeartifactId>
      dependency>
      
    3. 通过实现WebMvcConfigurer,并重写addViewControllers来提供视图控制器

      package com.mashibing.controller;
      
      import org.springframework.context.annotation.Configuration;
      import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
      import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
      
      @Configuration
      public class MyMvcConfig implements WebMvcConfigurer {
        	//过去要访问一个页面需要先创建个Controller控制类,再写方法跳转到页面,在这里配置后就不需要那么麻烦了,直接访问http://localhost:8080/msb就跳转到success.html页面了
          @Override
          public void addViewControllers(ViewControllerRegistry registry) {
              registry.addViewController("/msb").setViewName("success");
          }
      }
      

你可能感兴趣的:(2 springboot web开发)