zoukankan      html  css  js  c++  java
  • SpringBoot-02-SpringMVC


    导入静态资源

    直接找到WebMvcAutoConfiguration配置类(对应web开发)

    @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/**")) {
            customizeResourceHandlerRegistration(registry.addResourceHandler("/webjars/**")
                    .addResourceLocations("classpath:/META-INF/resources/webjars/")
                    .setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
        }
        String staticPathPattern = this.mvcProperties.getStaticPathPattern();
        if (!registry.hasMappingForPattern(staticPathPattern)) {
            customizeResourceHandlerRegistration(registry.addResourceHandler(staticPathPattern)
                    .addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations()))
                    .setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
        }
    }

    发现项目路径resources/webjars/映射到了http://localhost:8080/webjars/

    另外去https://www.webjars.org/得到jquery

    <dependency>
        <groupId>org.webjars</groupId>
        <artifactId>jquery</artifactId>
        <version>3.5.1</version>
    </dependency>

    添加到pom.xml,左边会发现

    (表示jQuery资源被放到了classpath:/META-INF/resources/)

    http://localhost:8080/webjars/jquery/3.5.1/jquery.js

    (除了classpath:/META-INF/resources/)其他存放静态资源的位置

     

    http://localhost:8080/1.js


    首页定制

    还是在WebMvcAutoConfiguration配置类中

    @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() {
        String[] locations = getResourceLocations(this.resourceProperties.getStaticLocations());
        return Arrays.stream(locations).map(this::getIndexHtml).filter(this::isReadable).findFirst();
    }
    
    private Resource getIndexHtml(String location) {
        return this.resourceLoader.getResource(location + "index.html");
    }
    
    private boolean isReadable(Resource resource) {
        try {
            return resource.exists() && (resource.getURL() != null);
        }
        catch (Exception ex) {
            return false;
        }
    }

    通常并不是将index.html放到到上述目录进行访问,而是放到templates下,通过controller进行跳转

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h1>首页</h1>
    </body>
    </html>
    /**
     * templates目录下的资源只能通过controller进行跳转而访问
     * 这种访问方式需要导入依赖
     */
    @Controller
    public class IndexController {
    
        @GetMapping("/index")
        public String index(){
            return "index";
        }
    }

    http://localhost:8080/

    ico图标显示暂时没搞定(不同版本不一样https://docs.spring.io/spring-boot/docs/2.3.2.RELEASE/reference/htmlsingle/#boot-features-spring-mvc-pathmatch)


    Thymeleaf模板引擎

    上文已经导入了依赖

    这个东西就类似于freemarker(电商网站拿来生成静态页面用的)

    它的自动配置类ThymeleafAutoConfiguration(叫这个名字跑不了了),对应的ThymeleafProperties

    (视图解析)

    在html的<html lang="en">标签中加入xmlns:th="http://www.thymeleaf.org"属性(导入命名空间/约束/头文件)

    (用法:链接使用@  文本使用#)

    @Controller
    public class TestController {
    
        @RequestMapping("/test")
        public String test(Model model){
            //存入数据
            model.addAttribute("msg","Hello,Thymeleaf");
            //classpath:/templates/test.html
            return "test";
        }
    
        @RequestMapping("/test2")
        public String test2(Map<String,Object> map){
            //存入数据
            map.put("msg","<h1>Hello</h1>");
            map.put("users", Arrays.asList("xiaoming","xiaohong"));
            //classpath:/templates/test.html
            return "test";
        }
    }
    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <!--th:text就是将div中的内容设置为它指定的值-->
    <div th:text="${msg}"></div>
    
    <!--不转义-->
    <div th:utext="${msg}"></div>
    <!--遍历数据-->
    <!--th:each每次遍历都会生成当前这个标签:官网#9-->
    <h4 th:each="user :${users}" th:text="${user}"></h4>
    <h4>
        <!--行内写法:官网#12-->
        <span th:each="user:${users}">[[${user}]]</span>
    </h4>
    
    </body>
    </html>

    MVC配置原理

    官网学习https://docs.spring.io/spring-boot/docs/2.3.2.RELEASE/reference/htmlsingle/#boot-features-spring-mvc-auto-configuration

    If you want to keep those Spring Boot MVC customizations and make more MVC customizations 
    (interceptors, formatters, view controllers, and other features)
    , you can add your own @Configuration class of type WebMvcConfigurer but without @EnableWebMvc.

    (通常自定义的配置类写在config包里边) 

    //应为类型要求为WebMvcConfigurer,这是一个接口
    // (一个人当过兵,我们说他是一个兵;一个人会下象棋,我们说他是一个棋手;接口丶)
    //使用自定义类扩展视图解析器的功能
    @Configuration
    public class MyMvcConfig implements WebMvcConfigurer {
    
        @Bean //放到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;
            }
        }
    }

    给 DispatcherServlet 类的 doDispatch 方法加断点,随便访问一个页面

    发现自定义的视图解析器已经在容器中了(当然上面是为了说明原理,官方推荐的是如下做法实现视图跳转)

    重写WebMvcConfigurer的方法  Alt+Insert

    @Configuration
    public class MyMvcConfig implements WebMvcConfigurer {
    
        @Override
        public void addViewControllers(ViewControllerRegistry registry) {
            // 浏览器发送/test , 就会跳转到test页面;
            registry.addViewController("/test4").setViewName("test");
        }
    }

    http://localhost:8080/test4就轻松的跳转成功了

    上面说自定义配置类不能加@EnableWebMvc这个注解,是因为这个注解会向容器中导入DelegatingWebMvcConfiguration这个类(WebMvcConfigurationSupport的子类),有了这个类之后,WebMvcAutoConfiguration就不满足@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)了,所以不能加丶

    @EnableWebMvc全面接管SpringMVC的操作,据说是大厂写自己的starter才会用到,后面再继续了解

    总之,看到了别人代码自定义的配置类(@Configuration修饰的XxxConfig),立马就要去看看他扩展了什么功能,因为这表示他动了springboot原有的东西丶


    击石乃有火,不击元无烟!!
  • 相关阅读:
    html基本标签练习
    实践1-qq邮箱主页
    html加强
    Date日期操作
    日期类的加减及java中所以日期类的操作算法大全
    讲解java异常
    关于Java并发编程的总结和思考
    删除map、list集合元素总结
    Jedis使用总结【pipeline】【分布式的id生成器】【分布式锁【watch】【multi】】【redis分布式】
    Java中的时间日期处理
  • 原文地址:https://www.cnblogs.com/rain2020/p/12757605.html
Copyright © 2011-2022 走看看