Spring MVC基本操作

Spring MVC

一、Spring MVC概述

1.1 Spring MVC 简介

  1. MVC是一种常见的用户界面设计模式(设计套路),其实现方案有很多:Struts2、SpringMVC等等。MVC=Model(数据模型)+View(视图)+Controller(控制器),SpringMVC框架主要解决了VC之间的交互问题,在SpringMVC框架中,并不关心M的问题。

1.2 SpringMVC核心组件和执行流程

  1. 核心组件

    (1)DispatcherServlet:前端控制器,用于接收所有请求。

    (2)HandlerMapping:用于配置请求路径与Controller组件的对应关系。

    (3)Controller:控制器,具体处理请求的组件。

    (4)ModelAndView:Controller组件处理完请求后得到的结果,由数据与视图名称组件。

    (5)ViewResolver:视图解析器,可根据视图名称确定需要使用的视图组件。

  2. 执行流程图
    在这里插入图片描述

1.3 搭建SpringMVC项目

  1. 使用SpringMVC强大功能的第一步就是创建SpringMVC项目,SpringMVC项目就是一个标准的Java EE Web项目,在JavaEE项目中配置Spring MVC。

    (1)新建Maven Project,并且选择webapp原型,然后next
    在这里插入图片描述

    (2)这里的GroupId和ArtifactID随意填写,但是ArtifactID最好和你的项目一名一致,然后next
    在这里插入图片描述

    (3)这里我们添加一个参数archetypeCatalog=internal,可以帮助我们快速搭建骨架,然后点击Finish
    在这里插入图片描述
    (4)在pom.xml文件中添加SpringMVC和Servlet的依赖
    在这里插入图片描述

    (5)将项目部署到Tomcat服务器上(这里就不做演示了)

    (6)创建SpringMVC配置类
    在这里插入图片描述
    (7)启动Tomcat,启动成功之后检索信息,如果检索到下面两行信息表示配置成功

    06-Nov-2020 22:40:50.383 信息 [RMI TCP Connection(3)-127.0.0.1] org.springframework.web.servlet.FrameworkServlet.initServletBean Initializing Servlet 'dispatcher'
    06-Nov-2020 22:40:50.959 信息 [RMI TCP Connection(3)-127.0.0.1] org.springframework.web.servlet.FrameworkServlet.initServletBean Completed initialization in 576 ms
    

1.4SpringMVC初体验

  1. 编写配置类SpringMvcConfig,开启组件扫描功能,目的是扫码创建控制器对象

    package com.yuanle.config;
    
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    @ComponentScan("com.yuanle.controller")
    public class SpringMvcConfig {
    }
    
  2. 在WebApp类中注册SpringMvcConfig,目的是启动SpringMvc时候加载SpringMvcConfig类并将请求映射交给DispatcherServlet处理

    package com.yuanle.config;
    
    import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
    
    public class WebApp extends AbstractAnnotationConfigDispatcherServletInitializer {
    
        @Override
        protected Class<?>[] getRootConfigClasses() {
            return new Class[0];
        }
    
        @Override
        protected Class<?>[] getServletConfigClasses() {
            //注册配置类SpringMvcConfig
            return new Class[]{SpringMvcConfig.class};
        }
    
        @Override
        protected String[] getServletMappings() {
            //将*.do请求交给DispatcherServlet处理
            return new String[]{"*.do"};
        }
    }
    
  3. 编写控制器类,再累上标注@RestController,这样组件扫描功能扫描到@RestController就会创建对象,@GetMapping(“/hello.do”)注解可以将用户的get请求映射到demo()方法,这样在浏览器请求时就会执行该方法,而demo()方法的结果会返回显示在浏览器上。

    package com.yuanle.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    @Controller
    public class DemoController {
    
        @GetMapping("/hello.do")
        public String demo(){
            System.out.println("demo()");
            return "HelloWorld!";
        }
    }
    

二、视图View

​ 视图就是给用户呈现数据的界面。在SpringMVC中,响应给客户端的View可以是多种,例如JSP、Thymeleaf中的HTML模板页面等。

2.1 Thymeleaf 视图解析器

  1. Thymeleaf是Spring MVC推荐的试图模板,其最大的优势是所见即所得。其官方网站是:https://www.thymeleaf.org/。

  2. 使用Thymeleaf的步骤:

    (1)首先导入thymeleaf和thymeleaf整合Spring5的坐标

    <dependency>
      <groupId>org.thymeleaf</groupId>
      <artifactId>thymeleaf</artifactId>
      <version>3.0.11.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.thymeleaf</groupId>
      <artifactId>thymeleaf-spring5</artifactId>
      <version>3.0.11.RELEASE</version>
    </dependency>
    

    (2)将Thymeleaf模板引擎当做Bean组件配置到Spring的配置文件中

    @Bean
        public ThymeleafViewResolver viewResolver(){
            //配置ClassLoaderTemplateResolver去/templates/文件夹中读取*.html的模板
            ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
            templateResolver.setPrefix("/templates/");
            templateResolver.setSuffix(".html");
            templateResolver.setCharacterEncoding("UTF-8");
            templateResolver.setTemplateMode(TemplateMode.HTML);
            templateResolver.setCacheable(true);
            //创建模板引擎
            SpringTemplateEngine templateEngine = new SpringTemplateEngine();
            templateEngine.setTemplateResolver(templateResolver);
            templateEngine.setEnableSpringELCompiler(true);
            //创建模板解析器
            ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
            viewResolver.setTemplateEngine(templateEngine);
            viewResolver.setCharacterEncoding("UTF-8");
            return viewResolver;
        }
    

    (3)配置的时候,模板存储有两种常见的方式:

    a. 使用ClassLoaderTemplateResolver时候,模板存储位置在src/main.resources/下

    b. 使用ServletContextTemplateResolver时候,模板存储位置在/webapp/WEB-INF/下

2.2 将视图显示到浏览器

  1. SpringMVC控制器方法可以返回ModelAndView对象,当前端控制器收到控制器返回的ModelAndView对象,前端控制器会利用视图解析器查找视图模板,并且进一步解析视图模板为html页面然后响应给浏览器。

  2. 实现步骤:

    (1)在DemoController中声明控制器方法

    @GetMapping("/test.do")
    public ModelAndView test(){
        System.out.println("test()");
        return new ModelAndView("helloworld");
    }
    

    (2)在templates文件夹下新建一个模板页面,然后打开浏览器访问即可。

三、接收客户端提交的请求参数

3.1 使用控制器方法参数接收表单数据

  1. SpringMVC提供了很多封装好的功能,这样可以大大简化编程,其中就包括自动解析接收表单参数。SpringMVC对接收表单数据做了封装,只需要在输入元素的name属性与控制器方法参数名字对应上,SpringMVC就会将数据注入到方法中。

  2. 处理表单中的中文数据

    (1)我们自己的程序是UTF-8,但浏览器传送到服务器的编码是ISO8859-1不支持中文,所以服务器接收表单参数时会乱码。

    (2)解决办法:SpringMVC提供了一个编码过滤器,CharacterEncodingFilter,只需要在SpringMVC的配置类中添加上,就可以自动的设置接收时的编码,解决中文编码问题。

3.2 使用JavaBean作为参数接收表单数据

  1. SpringMVC提供利用JavaBean打包传递参数功能,这样可以简化控制器参数。

  2. 注意:

    各属性的名称需要与请求参数的名称保持一致,并且,每个属性都要有规范名称的SET/GET方法。

3.3 使用request对象接收数据

  1. 控制器可以注入request对象,这样就可以获取任何请求参数包含请求头信息,ip等信息,由于request包含getPramater方法,也可以获取请求表示数据。

3.4 特殊参数名处理

  1. 当参数名与Java关键字冲突的时候,就无法利用默认规则接收参数了,例如:String while需要写成@RequestParam(“while”)String whiles,就可以解决参数名冲突的问题。

四、控制器向页面传递数据

​ 控制器负责处理业务规则,为业务规则处理结束以后需要将处理结果反馈给客户。

4.1 利用request向View传递数据

  1. 在Servlet中,可以利用request对象的Attribute向页面模板传递数据,在SpringMVC中同样有效。只要在控制器中将需要传递当数据存储到request中,就可以在视图模板中利用表达式显示出来。

4.2 利用ModelAndView向View传递数据

  1. 上述案例中request对象可以将数据传递到View中。但是在控制器中注入HttpServletRequest类行对象,会造成控制器强依赖于HttpServletRequest API,不能脱离Servlet容器进行测试。
  2. SpringMVC提供了替代解决方案:ModelAndView,ModelAndView不仅可以封装视图(View)名称,更能封装向视图传递的数据(Model)。其中Model是一个Map类型的数据结构。

4.3 利用ModelMap向View传递数据

  1. 在控制器方法中添加ModelMap类型的参数,SpringMVC会将传递参数的model对象创建好,注入到控制器,在控制器中将需要传递到数据存储的model中即可。

五、转发、重定向和Session

5.1 什么是转发

  1. 转发是服务器内部的控制器和视图协作完成同一项任务处理的过程,例如登陆业务中,控制器处理登陆业务过程,处理结束以后将结果发送到视图,这就是转发。
  2. 使用转发的目的是将控制器处理的结果送给视图去显示,转发是一个请求处理过程两个连续接力处理步骤。

5.2 什么是重定向

  1. 重定向是Http协议提供的功能,在客户端请求服务器,服务器在响应中反馈状态码“302”,并且提供目标的URL地址,浏览器收到302和URL地址以后,立即向新的URL发起请求,这个重定向的本质是浏览器根据第一次请求结果向新的URL发起第二次请求。

  2. SpringMVC对重定向进行了封装,可以很轻松的从控制器发起重定向,具体方式是在控制器中返回以redirect前缀的视图就可以了,例如:

    return new ModelAndView("redirect:http://doc.canglaoshi.org");
    

5.3 重定向的使用

  1. 当控制器将业务处理完成以后,希望跳转到其它HTTP请求时候,就可以利用重定向功能。例如:一个网站登录成功之后一般都会跳转到网站首页。

    (1)登录页面

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>登录页面</title>
    </head>
    <body>
        <h1>欢迎登陆</h1>
        <form method="post" action="handle_login.do">
            <div>
                <label>用户名:</label>
                <input type="text" name="username" />
            </div>
            <div>
                <label>密码:</label>
                <input type="password" name="password" />
            </div>
            <div>
                <input type="submit" value="登陆" />
            </div>
        </form>
    </body>
    </html>
    

    (2)显示错误消息页面

    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
    <head>
        <meta charset="UTF-8">
        <title>显示消息</title>
    </head>
    <body>
        <h1>消息</h1>
        <p th:text="${message}"></p>
    </body>
    </html>
    

    (3)首页

    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
    <head>
        <meta charset="UTF-8">
        <title>首页</title>
    </head>
    <body>
        <h1>首页</h1>
        <p th:text="${date}"></p>
    </body>
    </html>
    

    (4)处理登陆页面的控制器,重定向操作就在其中,在登陆成功之后重定向到首页

    @PostMapping("/handle_login.do")
    public ModelAndView handleLogin(String username, String password, ModelMap model){
        if ("王源".equals(username)){
             if ("123".equals(password)){
                 model.put("message","登陆成功!");
                 return new ModelAndView("redirect:../home/index.do");
             }else {
                 model.put("message","密码错误!");
                 return new ModelAndView("message");
             }
        }else {
            model.put("message","用户名不存在!");
            return new ModelAndView("message");
        }
    }
    

    (5)显示首页控制器

    @GetMapping("/index.do")
        public ModelAndView index(ModelMap model){
            String date = LocalDate.now().toString();
            model.put("date",date);
            return new ModelAndView("index");
        }
    

5.4 转发和重定向的区别

  1. 请求次数上:转发是一次请求,重定向是两次请求

    (1)转发是一次请求的两个环节进行协作,控制器转发到视图。

    (2)重定向是两次请求,第一次请求结束告诉浏览器可以赚到另外一个请求了。

  2. 使用目的不同

    (1)转发的目的是协作,控制器先处理业务功能,然后利用转发将处理结果转发到视图显示业务结果。

    (2)重定向的目的是URL跳转,一个URL处理完成以后,跳转到另外一个URL。

  3. 作用域有差别

    (1)转发是一次请求,在一次请求处理期间可以利用同一个request数据共享。

    (2)重定向是两次请求,两次请求各自创建request,这时不能利用request共享数据。

5.5使用Session

  1. 在开发中经常需要利用Session存储共享信息,SpringMVC中对Session提供了封装,在控制器方法上定义HttpSession类型参数,SpringMVC就会把Session对象注入到控制器中,在控制器中就可以访问这个Session对象了。

六、拦截器

6.1 什么是拦截器

  1. 拦截器(Interceptor)是SpringMVC中的组件,可以使得若干个请求路径在被处理时,都会执行拦截器中的代码,并且,拦截器可以选择阻止程序继续向后执行,或选择放行。

  2. 在SpringMVC中可以自定义类,实现HandlerInteceptor拦截器接口,这个类就会是一个拦截器类,实现接口后需要重写三个方法,分别是:

    (1)preHandle():利用拦截器编程的核心就在于用控制器preHandle方法的返回值,返回true表示拦截器放过请求继续处理,返回false就表示进行拦截处理,不在之心后续控制器,所以这个方法会在控制器方法执行之前执行。

    (2)postHandle():当preHandle方法的返回值为true时,控制器执行完之后,postHandle方法会执行

    (3)afterCompletion():会在整个框架处理流程结束之前那一刻被执行。

  3. 自定义类之后,SpringMVC拦截器还必须在SpringMVC的配置类中进行配置才能使用,配置步骤:

    (1)将配置类实现SpringMVC提供的配置接口WebMvcConfigurer,这个配置接口中声明了包含注册拦截器的方法,并且必须在配置类上标注@EnableWebMvc

    (2)重写配置接口中的addInterceptors()方法,在方法中注册拦截器对象,以及拦截位置配置拦截器

6.2 拦截器的配置

  1. 利用.addPathPatterns()设置拦截规则,多个参数可以设置多个拦截规则。

  2. 利用通配符可以拦截一组规则

    (1)*表示一级目录

    (2)**表示多级目录,一级和二级都可以拦截

  3. 利用excludePathPatterns方法可以设置排除规则,用于添加例外清单。

6.3 拦截器与过滤器的区别

  1. 拦截器和过滤器都可以作用于HTTP请求,并且使得这些路径的请求在被处理时,都会经过相关检查,最终决定组织或放行。
  2. 过滤器,也称为Servlet过滤器,过滤器是Servlet标注的一部分,可以拦截任意的HTTP请求。
    (2)重写配置接口中的addInterceptors()方法,在方法中注册拦截器对象,以及拦截位置配置拦截器
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值