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)页面中。
其中ModelMap和Model都是用来存储模型数据的,只不过前者是用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)。
我们依然通过实例来演示
- 将上述表单的action改为doLogin3
- 控制器中标注doLogin3的方法
- 再次执行测试:
-
注意一点如果我们使用重定向该怎么转发
- 登录界面的action改为doLogin4
- 控制器中标注doLogin4的方法
- 主界面index.jsp
- 执行过程:
Spring MVC系列初识Spring MVCSpring MVC系列Spring MVC中请求转发中出现异常如何处理