• springboot学习(二)——springmvc配置使用


    以下内容,如有问题,烦请指出,谢谢

    上一篇讲解了springboot的helloworld部分,这一篇开始讲解如何使用springboot进行实际的应用开发,基本上寻着spring应用的路子来讲,从springmvc以及web开发讲起。
    官方文档中在helloworld和springmvc之间还有一部分内容,主要讲了spring应用的启动、通用配置以及日志配置相关的内容,其中关于通用配置的部分对于springboot来说是个很重要的内容,这部分等到后面在细说下,有了一定的应用能力,到时候理解起来轻松些。

    先来回顾下springmvc是怎么使用的。
    首先需要配置DispatcherServlet,一般是在web.xml中配置

    <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    

    这一点在springboot中就不需要手动写xml配置了,springboot的autoconfigure会默认配置成上面那样,servlet-name并不是一个特别需要注意的属性,因此可以不用太关心这个属性是否一致。
    具体的初始化是在 org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration中完成的,对应的一些配置在 org.springframework.boot.autoconfigure.web.ServerProperties 以及
    org.springframework.boot.autoconfigure.web.WebMvcProperties,后面讲一些常用的配置,不常用的就自己看源码了解吧,就不细说了。

    然后是ViewResolver,也就是视图处理的配置。在springmvc中,一般是在springmvc的xml配置中添加下列内容

    <!-- ViewResolver -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
    

    低版本的spring需要加上viewClass,高版本的spring会自动检测是否使用JstlView,因此这个属性通常并不需要手动配置,主要关心prefix和suffix。另外高版本的springmvc也不需要手动指定 HandlerMapping 以及
    HandlerAdapter ,这两个也不需要显式声明bean。

    如何在springboot中配置ViewResolver,主要有两种方法。
    一种是在application.properties中配置,这是springboot中标准的配置方法。

    spring.mvc.view.prefix=/WEB-INF/jsp/
    spring.mvc.view.suffix=.jsp
    

    另外一种是springmvc中的代码式配置,这种也是现在比较流行的配置方式,不显式指定配置文件,配置即代码的思想,脚本语言python js scala流行的配置方式。
    代码是配置的主要操作就是自己写代码来为mvc配置类中的某个方法注入bean或者直接覆盖方法,如下:

    package pr.study.springboot.configure.mvc;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
    import org.springframework.web.servlet.view.InternalResourceViewResolver;
    
    @Configuration
    public class SpringMvcConfigure extends WebMvcConfigurerAdapter {
    
        @Bean
        public InternalResourceViewResolver viewResolver(){
            InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
            viewResolver.setPrefix("/WEB-INF/jsp/");
            viewResolver.setSuffix(".jsp");
            // viewResolver.setViewClass(JstlView.class); // 这个属性通常并不需要手动配置,高版本的Spring会自动检测
            return viewResolver;
        }
    }
    

    上面的视图使用的是jsp,这时需要在pom.xml中添加新的依赖。

    <dependency>
        <groupId>org.apache.tomcat.embed</groupId>
        <artifactId>tomcat-embed-jasper</artifactId>
        <scope>provided</scope>
    </dependency>
    

    代码也相应的改写下,返回视图时,不能使用@ResponseBody,也就是不能使用@RestController

    package pr.study.springboot.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.servlet.ModelAndView;
    
    //@RestController
    @Controller
    public class HelloWorldController {
    
        @RequestMapping("/hello")
        public ModelAndView hello() {
            ModelAndView mv = new ModelAndView();
            mv.addObject("msg", "this a msg from HelloWorldController");
            mv.setViewName("helloworld");;
            return mv;
        }
    }
    

    还要新建jsp文件,路径和使用普通的tomcat部署一样,要在src/main/webapp目录下新建jsp的文件夹,这里路径不能写错。

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>helloworld</title>
    </head>
    <body>
      <p>${msg}</p>
    </body>
    </html>
    

    springboot使用嵌入式Servlet容器,对jsp支持有限,官方是推荐使用模板引擎来代替jsp。

    第三点讲下比较重要的springmvc拦截器(HandlerInterceptor)。
    拦截器在springmvc中有重要的作用,它比servlet的Filter功能更强大(拦截器中可以编程的地方更多)也更好使用,缺点就是它只能针对springmvc,也就是dispatcherServlet拦截的请求,不是所有servlet都能被它拦截。
    springmvc中添加拦截器配置如下:

    <mvc:interceptors>
        <bean class="pr.study.springboot.aop.web.interceptor.Interceptor1"/>  
        <mvc:interceptor>
            <mvc:mapping path="/users" />
            <mvc:mapping path="/users/**" />
            <bean class="pr.study.springboot.aop.web.interceptor.Interceptor2"/>
        </mvc:interceptor>
    </mvc:interceptors>
    

    Interceptor1拦截所有请求,也就是/**,Interceptor2只拦截/users开头的请求。
    在springboot中并没有提供配置文件的方式来配置拦截器(HandlerInterceptor),因此需要使用springmvc的代码式配置,配置如下:

    package pr.study.springboot.configure.mvc;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
    import org.springframework.web.servlet.view.InternalResourceViewResolver;
    
    import pr.study.springboot.aop.web.interceptor.Interceptor1;
    import pr.study.springboot.aop.web.interceptor.Interceptor2;
    
    @Configuration
    public class SpringMvcConfigure extends WebMvcConfigurerAdapter {
    
        @Bean
        public InternalResourceViewResolver viewResolver(){
            InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
            viewResolver.setPrefix("/WEB-INF/jsp/");
            viewResolver.setSuffix(".jsp");
            // viewResolver.setViewClass(JstlView.class); // 这个属性通常并不需要手动配置,高版本的Spring会自动检测
            return viewResolver;
        }
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(new Interceptor1()).addPathPatterns("/**");
            registry.addInterceptor(new Interceptor2()).addPathPatterns("/users").addPathPatterns("/users/**");
            super.addInterceptors(registry);
        }
    }
    

    第四点讲下静态资源映射。
    一些简单的web应用中都是动静混合的,包含许多静态内容,这些静态内容并不需要由dispatcherServlet进行转发处理,不需要进行拦截器等等的处理,只需要直接返回内容就行。springmvc提供了静态资源映射这个功能,在xml中配置如下:

    <resources mapping="/**" location="/res/" />
    

    springboot中有两种配置,一种是通过配置文件application.properties指定

    # default is: /, "classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/"
    #spring.resources.static-locations=classpath:/res/
    # the 'staticLocations' is equal to 'static-locations'
    #spring.resources.staticLocations=classpath:/res/
    
    # default is /**
    #spring.mvc.staticPathPattern=/**
    

    另外一种是springmvc的代码式配置

    @Configuration
    public class SpringMvcConfigure extends WebMvcConfigurerAdapter {
    
        @Bean
        public InternalResourceViewResolver viewResolver() {
            InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
            viewResolver.setPrefix("/WEB-INF/jsp/");
            viewResolver.setSuffix(".jsp");
            // viewResolver.setViewClass(JstlView.class); // 这个属性通常并不需要手动配置,高版本的Spring会自动检测
            return viewResolver;
        }
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(new Interceptor1()).addPathPatterns("/**");
            registry.addInterceptor(new Interceptor2()).addPathPatterns("/users").addPathPatterns("/users/**");
            super.addInterceptors(registry);
        }
    
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            // addResourceHandler指的是访问路径,addResourceLocations指的是文件放置的目录  
            registry.addResourceHandler("/**").addResourceLocations("classpath:/res/");
        }
    }
    

    两种方式效果一样,配置后访问正确的静态文件都不会被拦截器拦截。
    当然,静态文件不被拦截的方法还有很多,比如使用其他的servlet来转发静态文件,拦截器(HandlerInterceptor)的exclude,dispatcherServlet拦截/*.do等等方式,这里就不细说了。

    今天就到此为止,springmvc以及Web的还有不少内容,下期在说
    因为Demo比较简单,这里就没有贴运行结果的图,相关代码如下:
    https://gitee.com/page12/study-springboot/tree/springboot-2/
    https://github.com/page12/study-springboot/tree/springboot-2

    一些有既可以通过application.properties配置,又可以使用代码式配置的,都注释掉了application.properties中的配置,试运行时可以切换下。

  • 相关阅读:
    [Swift]LeetCode843. 猜猜这个单词 | Guess the Word
    [Swift]LeetCode852. 山脉数组的峰顶索引 | Peak Index in a Mountain Array
    [Swift]LeetCode867. 转置矩阵 | Transpose Matrix
    [Swift]LeetCode859. 亲密字符串 | Buddy Strings
    [Swift]LeetCode844. 比较含退格的字符串 | Backspace String Compare
    [Swift]LeetCode824. 山羊拉丁文 | Goat Latin
    PHP 分析1
    php 分析
    停下库
    常用sql
  • 原文地址:https://www.cnblogs.com/page12/p/7967290.html
Copyright © 2020-2023  润新知