Spring MVC系列Spring MVC应用及ModelAndView(模型视图)

Posted 一宿君

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring MVC系列Spring MVC应用及ModelAndView(模型视图)相关的知识,希望对你有一定的参考价值。

二、Spring MVC实际应用

2.1 使用maven创建springmvc的web项目

需要导入两个Web相关的jar包依赖,分别为spring-web和spring-webmvc
,这两个jar包就是Spring MVC框架所需的jar包,同时因为我们创建的时web项目,必然会用到servlet,所以还需要导入setvlet-api的jar包,如下图:
在这里插入图片描述

2.2 引入相关jar依赖

  • pom.xml文件
    <!--serlvet-api-->
        <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>javax.servlet-api</artifactId>
          <version>3.1.0</version>
        </dependency>
    
        <!--spring-webmvc依赖jar包-->
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-webmvc</artifactId>
          <version>5.3.0</version>
        </dependency>
    
        <!--log4j日志文件-->
        <dependency>
          <groupId>log4j</groupId>
          <artifactId>log4j</artifactId>
          <version>1.2.17</version>
        </dependency>
        <dependency>
          <groupId>org.slf4j</groupId>
          <artifactId>slf4j-api</artifactId>
          <version>1.7.21</version>
        </dependency>
        <dependency>
          <groupId>org.slf4j</groupId>
          <artifactId>slf4j-log4j12</artifactId>
          <version>1.7.21</version>
        </dependency>
    
        <!--单元测试-->
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.11</version>
          <scope>test</scope>
        </dependency>
    

其中log4j日志文件,在spring5之后,只引入log4j依赖是不够的,还需要引入slf4j-api和slf4j-log4j12等两个依赖文件才可以使用。

2.3 导入log4j.properties文件

  • log4j.properties
    log4j.rootLogger=DEBUG,CONSOLE
    #log4j.rootLogger=ERROR,ROLLING_FILE
    log4j.logger.com.dao=debug
    log4j.logger.com.ibatis=debug 
    log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=debug 
    log4j.logger.com.ibatis.common.jdbc.ScriptRunner=debug 
    log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=debug 
    log4j.logger.java.sql.Connection=debug 
    log4j.logger.java.sql.Statement=debug 
    log4j.logger.java.sql.PreparedStatement=debug 
    log4j.logger.java.sql.ResultSet=debug 
    ######################################################################################
    # Console Appender  \\u65e5\\u5fd7\\u5728\\u63a7\\u5236\\u8f93\\u51fa\\u914d\\u7f6e
    ######################################################################################
    log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
    log4j.appender.Threshold=error
    log4j.appender.CONSOLE.Target=System.out
    log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
    log4j.appender.CONSOLE.layout.ConversionPattern=[%p] %d %c - %m%n
    

2.4 springmvc核心配置文件(Spring MVC第一步)

  • applicationContext-springmvc.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"
           xmlns:bean="http://www.springframework.org/schema/aop"
           xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
           xmlns:mvc="http://www.springframework.org/schema/mvc"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/aop
           https://www.springframework.org/schema/aop/spring-aop.xsd
           http://www.springframework.org/schema/context
           https://www.springframework.org/schema/context/spring-context.xsd
           http://www.springframework.org/schema/tx
           http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
           http://www.springframework.org/schema/mvc
           https://www.springframework.org/schema/mvc/spring-mvc.xsd">
    
        <!--指定springmvc扫描哪个包-->
        <context:component-scan base-package="com.controller"/>
        <!--开启springmvc注解驱动-->
        <mvc:annotation-driven/>
    
        <!--内部资源视图解析器-->
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <!--扫描以.jsp为后缀的jsp页面-->
            <property name="suffix" value=".jsp"/>
            <!--扫描/WEB-INF下的所有jsp-->
            <property name="prefix" value="/WEB-INF/jsp/"/>
        </bean>
    
    </beans>
    
    在这里插入图片描述

2.5 在web.xml文件中配置前端过滤器DispatcherServlet(Spring MVC第二步)

  • web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                          http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
             version="3.1">
    
      <display-name>Archetype Created Web Application</display-name>
    
      <!--配置servlet调度程序-->
      <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--启动tomcat服务器时,默认加载applicationContext-springmvc.xml配置文件-->
        <init-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>classpath*:applicationContext-springmvc.xml</param-value>
        </init-param>
        <!--表示容器在启动时立即加载Servlet(此处值越小,加载优先级越高)-->
        <load-on-startup>1</load-on-startup>
      </servlet>
      <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
      </servlet-mapping>
      
    </web-app>
    

    在这里插入图片描述
    在这里插入图片描述

  • “/”与“/*”的区别

    //*
    会匹配到像/login这样的前端请求url会匹配到像/login这样的前端请求url
    不会匹配*.jsp后缀文件,不会再次进入springmvc的Dispatcher类中会匹配.jsp后缀文件,会出现在转发某个*.jsp视图时,会再次进入springmvc的Dispatcher类中,导致循环拦截,找不到对应的controller,所以会报404错
    会匹配*.html后缀文件会匹配*.html后缀文件
    会拦截所有的静态资源(js、css、jpg、png、gif等)会拦截所有的静态资源(js、css、jpg、png、gif等)

2.6 创建com.controller.HelloController控制类(控制器Controller)

  • HelloController.java
    package com.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    
    /**
     * @author 一宿君(CSDN : qq_52596258)
     * @date 2021-07-20 20:44:21
     */
    @Controller
    public class HelloController {
    
        @RequestMapping(method = RequestMethod.GET,value = {"/showHello1","showHello2"})
        public String hello(){
            /**
             * 此处返回值无需加.jsp后缀,
             * 因为在applicationContext-springmvc.xml配置文件中配置了
             * 以.jsp为后缀的所有视图
             */
            return "hello";
        }
    }
    
    在这里插入图片描述

2.7 我们在WEB-INF(该目录是受保护的)录下创建一个jsp目录,同时在jsp目录下创建一个hello.jsp页面(视图View)

  • hello.jsp
    <%--
      Created by IntelliJ IDEA.
      User: wang'bo'shi
      Date: 2021/7/20
      Time: 20:36
      To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Title</title>
    </head>
    <body>
    这是hello.jsp页面
    </body>
    </html>
    

2.8 将该springmvc的Web项目部署到tomcat服务器上,启动tomcat

  • 部署项目
    在这里插入图片描述
  • 启动运行结果,默认加载index.jsp页面:
    在这里插入图片描述
  • 我们在地址栏输入访问showHello1请求:
    在这里插入图片描述
  • 我们在地址栏输入访问showHello2请求:
    在这里插入图片描述

2.9 模拟登录控制

  • 在WEB-INF/jsp目录下创建一个login.jsp登录界面

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Title</title>
    </head>
    <body>
    <form method="post" action="doLogin1">
        用户名:<input type="text" name="loginId"/><br/>
        密码:<input type="password" name="loginPwd"/><br/>
        <input type="submit" value="登录"/>
    </form>
    
    </body>
    </html>
    
  • 在WEB-INF/jsp目录下创建一个index.jsp主界面

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Title</title>
    </head>
    <body>
    这是主界面----${requestScope.loginId}
    </body>
    </html>
    
  • 编写控制器类SystemUserController

    package com.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.servlet.ModelAndView;
    import com.pojo.SystemUser;
    
    import javax.servlet.http.HttpServletRequest;
    
    /**
     * @author 一宿君(CSDN : qq_52596258)
     * @date 2021-07-21 09:56:24
     */
    @Controller
    public class SystemUserController {
        HttpServletRequest request;
    
        /**
         * 跳转登录界面
         * @return
         */
        @RequestMapping(method = RequestMethod.GET,value = {"/toLogin"})
        public String toLogin(){
            return "login";
        }
    
        /**
         * 通过参数绑定
         * @param loginId
         * @param loginPwd
         * @return
         */
        @RequestMapping(method = RequestMethod.POST,value = {"/doLogin1"})
        public String doLogin(String loginId,String loginPwd){
            System.out.println("loginId:" + loginId);
            System.out.println("loginPwd:" + loginPwd);
            request.setAttribute("loginId",loginId);
            return "index";
        }
    
    
        /**
         * 通过对象匹配属性字段,自动绑定参数
         * @param systemUser
         * @return
         */
        @RequestMapping(method = RequestMethod.POST,value = {"/doLogin2"})
        public String doLogin2(SystemUser systemUser){
            System.out.println("loginId:" + systemUser.getLoginId());
            System.out.println("loginPwd:" + systemUser.getLoginPwd());
            request.setAttribute("loginId",systemUser.getLoginId());
            return "index";
        }
    
        /**
         * 通过对象匹配属性,自动绑定参数
         * @param systemUser
         * @return
         */
        @RequestMapping(method = RequestMethod.POST,value = {"/doLogin3"})
    public ModelAndView doLogin3(SystemUser systemUser, HttpServletRequest request, HttpSession session){
            System.out.println("loginId:" + systemUser.getLoginId());
            System.out.println("loginPwd:" + systemUser.getLoginPwd());
            ModelAndView mav = new ModelAndView();
            mav.addObject("loginId",systemUser.getLoginId());
            /*request.setAttribu    te("loginId",systemUser.getLoginId());*/
            /*session.setAttribute("loginId",systemUser.getLoginId());*/
            mav.setViewName("index");
            return mav;
    }
    
    	@RequestMapping(method= RequestMethod.GET, value={"/myindex"})
    	public String myindex()
    	{
    	    return "index";
    	 }
    
    
    
        @ExceptionHandler(value = RuntimeException.class)
        public String exception(RuntimeException re,HttpServletRequest req){
            req.setAttribute("MSG",re.getMessage());
            return "error";
        }
    
    }
    

    在这里插入图片描述

  • 执行过程:
    在这里插入图片描述

  • 提交登录(通过doLogin1控制器,请求转发到index.jsp主界面):
    在这里插入图片描述
    在这里插入图片描述

  • 修改login.jsp页面
    在这里插入图片描述

  • 创建一个实体类com.pojo.SystemUser,让其字段名和登录表单界面的name参数保持一致

    package com.pojo;
    
    import java.io.Serializable;
    
    /**
     * @author 一宿君(CSDN : qq_52596258)
     * @date 2021-07-21 09:53:55
     */
    public class SystemUser implements Serializable {
        private String loginId;
        private String loginPwd;
    
        @Override
        public String toString() {
            return "SystemUser{" +
                    "loginId='" + loginId + '\\'' +
                    ", loginPwd='" + loginPwd + '\\'' +
                    '}';
        }
    
        public String getLoginId() {
            return loginId;
        }
    
        public void setLoginId(String loginId) {
            this.loginId = loginId;
        }
    
        public String getLoginPwd() {
            return loginPwd;
        }
    
        public void setLoginPwd(String loginPwd) {
            this.loginPwd = loginPwd;
        }
    }
    
  • 再次测试
    在这里插入图片描述

  • 控制台:
    在这里插入图片描述

  • 提交登录(通过doLogin1控制器,请求转发到index.jsp主界面):
    在这里插入图片描述
    在这里插入图片描述

2.10 ModelAndView(模型和视图的集合)

Spring MVC提供了几种途径输出模型数据,模型数据主要输出到视图(View)页面中。

其中ModelMapModel都是用来存储模型数据的,只不过前者是用map集合存储,后者单纯存储模型数据。

Spring MVC在内部使用了一个org.springframework.ui.Model接口存储模型数据,Spring MVC在调用方法(@RequestMapping注解标注的方法)前会创建一个隐含的模型对象作为模型数据的存储容器。如果方法的参数为Map或者Model类型,Spring MVC会将隐含模型对象的引用传递给这些参数(这就是Spring MVC利用HandlerMapping处理器映射器自动绑定参数的原理)。在方法体内,可以通过这些参数对象访问到模型中的所有数据,也可以向模型中添加新的属性数据。

Model是每次请求中都存在的默认参数存储容器。

  • 返回模型数据

    利用model中的addAttribute()方法或者ModelMap的put()方法即可将服务器的值传递到页面中,用到mode模型存储数据时,该方法体必须return返回视图,在视图(View)中获取model模型中的数据可以用EL表达式直接获取 ${key}

ModelAndView(模型和视图)

  • 使用ModelAndView来存储处理后的结果数据,以及存储显示该数据的视图;
  • 单从名字上就可以看出是模型和视图的结合体;
  • 添加模型数据:

    ModelAndView addObject(String attributeName, Object attributeValue)
    ModelAndView addAllObject(Map<String, ?> modelMap)

  • 设置视图:

    void setView(View view)(自定义视图)
    void setViewName(String viewName)。

我们依然通过实例来演示