什么是SpringMVC?
SpringMVC:是一个模型-试图-控制器(MVC)的Web框架,他提供了MVC架构和用于开发灵活和松散耦合的Web应用程序的组件,MVC模式导致应用程序的不同方面(输入逻辑,业务逻辑和UI逻辑)分离。
- 模型(Model):封装了应用程序数据,一般由POJO类组成
- 视图(View):负责渲染模型数据,一般来说它生产客户端浏览器可以解释HTML输出
- 控制器(Controller):负责处理用户请求并构建适当的模型,并将其传递给视图进行渲染
SpringMVC的简单开发步骤
我们依然使用maven来创建一个web项目,然后进行配置。
首先,我们需要在pom.xml的dependency坐标导入SpringMVC相关的依赖,这里导入的比较多,有备无患,开发中可以按照需要导入:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
然后我们去配置web.xml:
<!--配置生成启动时需要构建IOC容器的Servlet,需要springmvc的配置文件,Servlet的对象默认构造时间是,第一个访问该servlet时才构建该Servlet的对象-->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--设置当前Servlet的初始化参数,如果不设置,默认名称为servlet-name-servlet.xml,且该文件必须在WEB-INF目录下-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<!--设置当前Servlet的初始化参数,一般为1-->
<load-on-startup>1</load-on-startup>
</servlet>
<!--在Web工厂中注册的dispatcherServlet需要拦截所有的请求资源-->
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
解释一下,SpringMVC就相当于做了Servlet做的事情,它给我们提供了一个DispatcherServlet类来构建Spring IOC容器
然后在自带的index.jsp下配置一个超链接:
<a href="/helloWorld">Test Hello World</a>
在java目录下创建一个HelloWorld类,来处理index.jsp下的超链接
@Controller //用来指示该类充当控制器的角色
public class HelloWorld {
@RequestMapping("/hello")
public String helloWorld(ModelMap modelMap) {
//ModelMap用来设置一个key-value对,key用于jsp来读取后面的value。
modelMap.addAttribute("message", "hello");
return "hello";
}
}
接下来,由于我们return的是hello,所以在WEB-INF下创建一个views,用来放我们的jsp页面,我们在该目录下创建一个hello.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Hello</title>
</head>
<body>
利用EL表达式来读取Controller方法的信息
<h1>${message}</h1>
</body>
</html>
可以看到我们用的EL表达式去读取controller里的message,读取到的其实就是"hello"。
最后,我们去配置springmvc.xml里的视图解析器:
<bean id="resolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
完整的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: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/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<!--配置请求的默认处理的Servlet,它是web容器提供的。
default-servlet-name属性:是指默认处理请求的servlet注册到web容器中定义的名称
使用了此标签就必须添加<mvc:annotation-driven />这个标签
从默认的请求里面找,如果有就不经过SpringMVC了-->
<mvc:default-servlet-handler />
<!--有一点要说的是,比如使用context,这个傻屌xml不会自己写schemaLocation,只能自己补上,如果写不全则会导致无法运行-->
<!--配置视图解析器
概念解释:
1.该xml将用于创建定义的bean,它会覆盖在全局范围中使用相同名称定义的任何bean的定义
2.<context:component-scan base-package="com.hty" /> 用于激活SpringMVC注释扫描功能,就能扫描到例如@Controller和@ResultMapping等注解
3.InternalResourceViewResolver类则用于定义用于解析视图名称的规则。例如根据上面定义的规则,hello的逻辑视图将委托给位于
/WEB-INF/views/hello.jsp这个视图来实现
-->
<context:component-scan base-package="com.hty" />
<context:annotation-config />
<mvc:annotation-driven />
<bean id="resolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
<!--使用该标记来映射静态页面。映射的属性值必须是指定http请求的URL模式的Ant模式。location属性必须指定一个或多个有效地资源目录配置,
其中包含静态页面,包括图片,样式表,JS和其他静态内容。可以用逗号分隔的值列表来指定多个资源位置
-->
<!--<mvc:resources mapping="WEB-INF/views/**" location="/views/" />-->
<!--文件上传所用的bean-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" />
<!--处理错误所用的bean-->
<bean class="org.springframework.context.support.ResourceBundleMessageSource" id="messageSource">
<property name="basename" value="messages" />
</bean>
</beans>
至此,前期准备工作算是ojbk了,我们来请求一下,跑一下试试:
最后讲一下,SpringMVC是围绕着DispatcherServlet设计的,DispatcherServlet传入HTTP请求来发生事件的顺序为:
- 在接受到HTTP请求后,DispatcherServlet会查询HandlerMapping以调用响应的Controller
- Controller接受请求并根据使用的GET或POST方法调用相应的服务方法。服务方法将基于定义的业务逻辑设置模型数据,并将视图名称返回给DispatcherServlet
- DispatcherServlet将从ViewResolver获取请求的定义视图
- 当视图完成,DispatcherServlet将模型数据传递到最终的视图,并在浏览器上呈现
转发与重定向?
一般Controller里面的@RequestMapping方法返回值都为一个页面,我们可以在里面利用此来进行转发与重定向。
我们写一个类Redirect
package com.hty.jingtaiyemian;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
/**
* @program: springmvc
* @author: Semineces
* @create: 2020-02-09 15:33
*/
@Controller
public class Redirect {
@RequestMapping(value = "/index", method = RequestMethod.GET)
public String index() {
return "index";
}
@RequestMapping(value = "/redirect", method = RequestMethod.GET)
public String redirect() {
//重定向到下面的finalPage
return "redirect:finalPage";
}
@RequestMapping(value = "/finalPage", method = RequestMethod.GET)
public String finalPage() {
return "final";
}
@RequestMapping(value = "/forward", method = RequestMethod.GET)
private String staticPage() {
return "forward:/WEB-INF/views/forward.jsp";
}
}
然后我们在view下创建三个jsp文件,index.jsp、final.jsp、forward.jsp:
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ page contentType="text/html;charset=UTF-8" %>
<html>
<head>
<title>Spring Landing Page</title>
</head>
<body>
<h2>Spring页面重定向与页面转发</h2>
<!--访问redirect,而却要跳到finalPage,这就是我们的目标-->
<form:form method="GET" action="${pageContext.request.contextPath}/redirect" >
<table>
<tr>
<td><input type="submit" value="页面重定向" /></td>
</tr>
</table>
</form:form>
<form:form method="GET" action="${pageContext.request.contextPath}/forward">
<table>
<tr>
<td>
<input type="submit" value="页面转发" />
</td>
</tr>
</table>
</form:form>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>SpringMVC重定向页面</title>
</head>
<body>
<h2>重定向页面。。。</h2>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>SpringMVC转发页面</title>
</head>
<body>
<h2>转发的页面</h2>
</body>
</html>
我们启动服务器,访问index:
我们试试重定向,可以看出,我们原本是要访问/redirect,可最后的url后面是/finalPage:
在试试转发,还是forward,内容也设forward.jsp里的内容: