美文网首页
21.SpringMVC

21.SpringMVC

作者: 星野君 | 来源:发表于2022-05-04 14:44 被阅读0次

    一、快速入门

    • xml方式:
    1. 导入坐标
        <dependencies>
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>3.0.1</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>5.2.7.RELEASE</version>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.tomcat.maven</groupId>
                    <artifactId>tomcat7-maven-plugin</artifactId>
                    <version>2.2</version>
                    <configuration>
                        <port>80</port>
                        <path>/</path>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    
    1. 在web.xml里配置前端控制器
        <!--SpringMVC的前端控制器-->
        <servlet>
            <servlet-name>DispatcherServlet</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <!--加载第四步的spring-mvc.xml文件-->
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:spring-mvc.xml</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>DispatcherServlet</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>
    
    1. 创建controller
    package com.ylf.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller // 把UserController放在spring容器
    public class UserController {
      @RequestMapping("/index") // 请求映射
      public String save() {
        System.out.println("save running...");
        return "index.jsp"; // 跳转的jsp地址
      }
    }
    
    

    4.创建spring-mvc.xml文件

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
        <!--controller包扫描-->
        <context:component-scan base-package="com.ylf.controller"></context:component-scan>
    </beans>
    
    • 注解方式(推荐):
    1. 导入坐标同上
    2. 创建SpringMvcConfig配置类
    package com.ylf.config;
    
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    @ComponentScan("com.ylf.controller")
    public class SpringMvcConfig {}
    
    
    1. 创建ServletContainersIntiConfig配置类
    package com.ylf.config;
    
    import org.springframework.web.context.WebApplicationContext;
    import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
    import org.springframework.web.servlet.support.AbstractDispatcherServletInitializer;
    
    public class ServletContainersIntiConfig
        extends AbstractAnnotationConfigDispatcherServletInitializer {
      //加载Spring容器
      @Override
      protected Class<?>[] getRootConfigClasses() {
        return new Class[] {SpringConfig.class};
      }
      // 加载SpringMvc容器
      @Override
      protected Class<?>[] getServletConfigClasses() {
        return new Class[] {SpringMvcConfig.class};
      }
      // 所有请求都归SpringMvc处理
      @Override
      protected String[] getServletMappings() {
        return new String[] {"/"};
      }
    }
    
    
    1. 创建controller
    package com.ylf.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    public class UserController {
      @RequestMapping("/save")
      @ResponseBody
      public String save() {
        return "{'info':'xxx'}";
      }
    }
    

    二、SpringMVC执行流程

    1. 工作原理图


      image.png
    2. springmvc工作流程
      1、 用户向服务端发送一次请求,这个请求会先到前端控制器DispatcherServlet(也叫中央控制器)。
      2、DispatcherServlet接收到请求后会调用HandlerMapping处理器映射器。由此得知,该请求该由哪个Controller来处理(并未调用Controller,只是得知)
      3、DispatcherServlet调用HandlerAdapter处理器适配器,告诉处理器适配器应该要去执行哪个Controller
      4、HandlerAdapter处理器适配器去执行Controller并得到ModelAndView(数据和视图),并层层返回给DispatcherServlet
      5、DispatcherServlet将ModelAndView交给ViewReslover视图解析器解析,然后返回真正的视图。
      6、DispatcherServlet将模型数据填充到视图中
      7、DispatcherServlet将结果响应给用户

    3. 组件说明

    • DispatcherServlet:前端控制器,也称为中央控制器,它是整个请求响应的控制中心,组件的调用由它统一调度。
    • HandlerMapping:处理器映射器,它根据用户访问的 URL 映射到对应的后端处理器 Handler。也就是说它知道处理用户请求的后端处理器,但是它并不执行后端处理器,而是将处理器告诉给中央处理器。
    • HandlerAdapter:处理器适配器,它调用后端处理器中的方法,返回逻辑视图 ModelAndView 对象。
    • ViewResolver:视图解析器,将 ModelAndView 逻辑视图解析为具体的视图(如 JSP)。
    • Handler:后端处理器,对用户具体请求进行处理,也就是我们编写的 Controller 类。

    三、注解解析

    1. @RequestMapping:
      作用:用于建立请求url和处理请求方法之间的对应关系
      位置:类上,请求访问url的第一级访问目录,此处不写就相当于应用的根目录。方法上,请求url的第二级访问目录,与类上使用@RequestMapping标注的一级目录组成访问目录如/user/xxx
      属性:
      value,用于指定请求的url,它和path的属性一样。
      mathod,用于指定请求的方式,比如:method=RequestMethod.POST。
      params,用于指定限制请求参数的条件,它支持简单的表达式,要求请求参数的key和value必须和配置的一样。

    四、bean加载控制
    为了避免spring加载到本应该由SpringMVC加载的内容
    SpringMVCConfig

    //根据注解排除,controller
    @ComponentScan(
        value = "com.ylf",
        excludeFilters =
            @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Controller.class))
    

    或者直接精确包扫描
    五、数据响应和数据请求

    1. 乱码处理:
      在ServletContainersIntiConfig配置类
      //乱码处理
      @Override
      protected Filter[] getServletFilters() {
        final CharacterEncodingFilter filter = new CharacterEncodingFilter();
        filter.setEncoding("utf-8");
        return new Filter[]{filter};
      }
    
    1. 参数传递
      // 普通参数
      @RequestMapping("/save")
      @ResponseBody
      public String save(String name) {
        System.out.println(name);
        return "{'info':'ok'}";
      }
      // pojo参数
      @RequestMapping("/add")
      @ResponseBody
      public String add(User user) {
        System.out.println(user);
        return "{'info':'ok'}";
      }
    
      // 数组参数
      @RequestMapping("/arrayParam")
      @ResponseBody
      public String arrayParam(String[] likes) {
        System.out.println(likes);
        return "{'info':'ok'}";
      }
    
      // 集合参数
      @RequestMapping("/listParam")
      @ResponseBody
      public String arrayParam(@RequestParam ArrayList<String> likes) {
        System.out.println(likes);
        return "{'info':'ok'}";
      }
    
    1. json参数传递
    • 第一步导入坐标
            <dependency>
              <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-databind</artifactId>
                <version>2.9.0</version>
            </dependency>
    
    • 在SpringMvcConfig加上
    @EnableWebMvc
    public class SpringMvcConfig {}
    
    • 获得参数
      // json参数
      @RequestMapping("/jsonParam")
      @ResponseBody
      public String jsonParam(@RequestBody User user) {
        System.out.println(user);
        return "{'info':'ok'}";
      }
    
      // json参数
      @RequestMapping("/jsonListParam")
      @ResponseBody
      public String jsonListParam(@RequestBody List<User> user) {
        System.out.println(user);
        return "{'info':'ok'}";
      }
    
      // 日期参数
      @RequestMapping("/dateParam")
      @ResponseBody
      public String dateParam(@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date date) {
        System.out.println(date);
        return "{'info':'ok'}";
      }
    
    1. 数据响应
      // 返回json对象
      @RequestMapping("/toJson")
      @ResponseBody
      public User toJson(){
        final User user = new User();
        user.setId(1);
        user.setName("张三");
        return user;
      }
    
      // 返回json集合对象
      @RequestMapping("/toListJson")
      @ResponseBody
      public List<User> toListJson(){
        final User user1 = new User();
        user1.setId(1);
        user1.setName("张三");
        final User user2 = new User();
        user2.setId(1);
        user2.setName("李四");
        final List<User> users = new ArrayList<User>();
        users.add(user1);
        users.add(user2);
        return users;
      }
    
    1. rest风格
    // @RestController等于@Controller和@ResponseBody
    @RestController
    @RequestMapping("/users")
    public class UserController {
      // 普通参数
      @RequestMapping(value = "/{id}",method = RequestMethod.POST)
      public String save(@PathVariable Integer id) {
        System.out.println(id);
        return "{'message':'ok'}";
      }
    }
    
      // @PostMapping 相当于@RequestMapping(method = RequestMethod.POST)
      @PostMapping
      public String save(){
        return "{'message':'ok'}";
      }
    
      // @DeleteMapping 相当于@RequestMapping(value = "/{id}",method = RequestMethod.Delete)
      @DeleteMapping("/{id}")
      public String delete(){
        return "{'message':'ok'}";
      }
    
    1. 拦截器
    • 创建controller.interceptor.ProjectInterceptor
    package com.ylf.controller.interceptor;
    
    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class ProjectInterceptor implements HandlerInterceptor {
      @Override
      public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
          throws Exception {
        return true;
      }
    
      @Override
      public void postHandle(
          HttpServletRequest request,
          HttpServletResponse response,
          Object handler,
          ModelAndView modelAndView)
          throws Exception {
        System.out.println("postHandle");
      }
    
      @Override
      public void afterCompletion(
          HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
          throws Exception {
        System.out.println("afterCompletion");
      }
    }
    
    
    • 创建config.SpringMvcSupport
    package com.ylf.config;
    
    import com.ylf.controller.interceptor.ProjectInterceptor;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
    
    @Configuration
    public class SpringMvcSupport extends WebMvcConfigurationSupport {
      @Autowired private ProjectInterceptor projectInterceptor;
    
      /**
       * SpringMVC不去拦截pages页面
       *
       * @param registry
       */
      @Override
      protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
      }
    
      /**
       * 拦截/students下的所有请求
       *
       * @param registry
       */
      @Override
      protected void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(projectInterceptor).addPathPatterns("/students");
      }
    }
    
    
    • 在SpringMvc下加载SpringMvcSupport
    @Configuration
    @ComponentScan({"com.ylf.controller", "com.ylf.config"})
    @EnableWebMvc
    public class SpringMvcConfig {}
    
    • 或者直接在SpringMvcConfig下实现WebMvcConfigurer接口,这样就不用去创建新的配置类
    package com.ylf.config;
    
    import com.ylf.controller.interceptor.ProjectInterceptor;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.EnableWebMvc;
    import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    
    @Configuration
    @ComponentScan({"com.ylf.controller"})
    @EnableWebMvc
    public class SpringMvcConfig implements WebMvcConfigurer {
      @Autowired private ProjectInterceptor projectInterceptor;
      /**
       * 拦截/students下的所有请求
       *
       * @param registry
       */
      @Override
      public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(projectInterceptor).addPathPatterns("/students/*");
      }
      /**
       * SpringMVC不去拦截pages页面
       *
       * @param registry
       */
      @Override
      public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
      }
    }
    
    

    相关文章

      网友评论

          本文标题:21.SpringMVC

          本文链接:https://www.haomeiwen.com/subject/ioagertx.html