文章目录
- 1 Spring MVC入门
- 1.1 Spring MVC概述
- 1.1.1 Spring MVC框架的特点
- 2 第一个Spring MVC应用
- 3 Spring MVC的工作流程
- 4 Spring MVC的核心类和注解
- 4.1 DispatcherServlet核心类
- 4.2 @Controller注解类型
- 4.3 @RequestMapping注解类型
- 4.3.1 标注在方法上
- 4.3.2 标注在类上
- 4.4 组合注解
- 4.5 请求处理方法的参数和返回类型
- 4.5.1 请求处理方法的参数
- 4.5.2 返回类型
- 4.6 如何将数据带入视图页面及转发和重定向
- 4.6.1 使用Model
- 4.6.2 redirect重定向
- 4.6.3 forward请求转发
- 5 ViewResolver(视图解析器)
1 Spring MVC入门
1.1 Spring MVC概述
Spring MVC是Spring提供的一个实现Web MVC设计模式的轻量级Web框架。它和Struts2框架一样,都属于MVC模式,但其使用和性能等方面比Struts2更加优异。
1.1.1 Spring MVC框架的特点
- 是Spring框架的一部分,可以方便的使用Spring所提供的其他功能
- 灵活性强,易于与其他框架集成
- 提供一个前端控制器DispatcherServlet,使得开发人员无需额外开发控制器对象
- 可自动绑定用户输入,并能够正确转换数据类型
- 内置了常见的校验器,可以校验用户输入。如果校验不能通过,那么就会重定向到输入表单
- 支持国际化,可以根据用户区域显示多国语言
- 支持多种视图技术,支持JSP、Velocity和FreeMarker等视图技术
- 使用基于XML的配置文件,在编辑后,不需要重新编译应用程序
2 第一个Spring MVC应用
- 使用Maven创建Web项目
- 选择maven-archetype-webapp
- 需要修改的属性有java Build Path、Targeted Runtimes、java Compiler和Project Facets,可参考
- pom.xml中需要添加spring-webmvc依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
- 在web.xml中配置SpringMVC的前端控制器DispatcherServlet
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<servlet>
<!-- 配置前端过滤器 -->
<servlet-name>springmvc</servlet-name>
<!-- 没有.class -->
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<!-- 初始化时加载配置文件 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<!-- 配置加载Spring MVC配置文件的位置-->
<param-value>classpath:springmvc-config.xml</param-value>
</init-param>
<!-- “1”表示容器在启动时立即加载Servlet -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!-- /表示拦截所有URL的请求 -->
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
- 在src目录下,创建一个cn.edu.ujn.ch11.controller包,在包中创建FirstController,并实现Controller接口:
package cn.edu.ujn.ch11.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
//需要实现Controller接口
public class FirstController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
// TODO Auto-generated method stub
String name = request.getParameter("name");
System.out.println("name+" + name);
//创建ModelAndView对象
ModelAndView mav = new ModelAndView();
//添加返回信息
mav.addObject("msg", "这是我的第一个SpringMVC程序!");
//设置逻辑视图名,跳转到的页面
mav.setViewName("/WEB-INF/jsp/first.jsp");
return mav;
}
}
- 在src目录下,创建配置文件springmvc-config.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">
<!-- 配置处理器 -->
<bean name="/firstController"
class="cn.edu.ujn.ch11.controller.FirstController"></bean>
<context:component-scan
base-package="cn.edu.ujn.ch11.controller"></context:component-scan>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
- 在WEB-INF目录下创建一个jsp文件夹,并在文件夹中创建一个first.jsp页面,使用EL表达式获取msg中的信息:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@page isELIgnored="false"%>
<!DOCTYPE html>
<html>
<head>
<title>Insert title here</title>
</head>
<body>
<!-- 获取并显示 -->
${msg}
</body>
</html>
- 发布项目,启动服务器
EL表达式全名Expression Language。主要作用:
- 获取数据:
${msg}
${user.address.city} - 执行运算
${user==null}
${user!=null?user.name:""} - 获取web开发常用对象
${隐式对象名称}
${pageContext.request.contextPath} - 调用java方法
EL表达式允许用户开发自定义EL函数,以在JSP页面中通过EL表达式调用Java类的方法
${prefix:method(params)}
3 Spring MVC的工作流程
- 用户通过浏览器像服务器发送请求,请求会被Spring MVC的前端控制器DispatcherServlet所拦截
- DispatcherServlet拦截到请求后,会调用HandlerMapping处理器映射器,找到由谁来响应用户的这个请求
- 处理器映射器根据请求URL找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet
- DispatcherServlet会通过返回信息选择合适的HandlerAdapter(处理器适配器)
- HandlerAdapter会调用并执行Handler(处理器),这里的处理器指的是程序中编写的Controller类,也被称之为后端控制器
- Controller执行完成后,会返回一个ModelAndView对象,该对象中会包含视图名或包含模型和视图名
- HandlerAdapter将ModelAndView对象返回给DispatcherServlet
- DispatcherServlet会根据ModelAndView对象选择一个合适的ViewReslover(视图解析器)
- ViewReslover解析后,会向DispatcherServlet中返回具体的View(视图)
- DispatcherServlet对View进行渲染(即将模型数据填充至视图中)
- 视图渲染结果会返回给客户端浏览器显示
4 Spring MVC的核心类和注解
4.1 DispatcherServlet核心类
DiapatcherServlet全名是org.springframework.web.servlet.DispatcherServlet
,在程序中充当控制器的角色。使用时在web.xml文件中配置如下:
<servlet-name>springmvc</servlet-name>
<!-- .class一定要删除 -->
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
4.2 @Controller注解类型
org.springframework.stereotype.Controller注解类型用于指示Spring类的实例是一个控制器,其注解形式为@Controller。该注解在使用时不需要再实现Controller接口, 只需要将@Controller注解加入到控制器类上,然后通过Spring的扫描机制找到标注了该注解的控制器即可@Controller注解在控制器类中的使用示例如下:
package cn.edu.ujn.ch13.controller;
import org.springframework.stereotype.Controller;
@Controller
public class HelloController {
//其他部分
}
Spring配置文件添加相应的扫描配置信息:
<context:component-scan base-package="cn.edu.ujn" />
这个一定要包含注解所在的类。
4.3 @RequestMapping注解类型
Spring通过@Controller注解找到相应的控制器类后,还需要知道控制器内部对每一个请求是如何处理的,使用@RequestMapping注解类型,它用于映射一个请求或一个方法。使用时可以标注在一个方法或一个类上。
4.3.1 标注在方法上
//first就是访问这个方法时URL中的值
//http://localhost:8080/ch12/first
@RequestMapping(value = "/first")
public String handleRequest(Model model) {
model.addAttribute("msg", "这是我的第一个基于注解的SpringMVC程序!---");
return "first";
}
4.3.2 标注在类上
标注在类上,该类中的所有方法都将映射为相对于类级别的请求,表示该控制器所处理的所有请求都被映射到value属性值所指定的路径下。
@Controller
@RequestMapping(value = "/hello")
public class HelloController {
@RequestMapping(value = "/first")
public String handleRequest(Model model) {
model.addAttribute("msg", "这是我的第一个基于注解的SpringMVC程序!---");
return "first";
}
}
该方法访问路径为:http://localhost:8080/ch12/hello/first
除了value属性外,还有其他属性:
这些属性都是可选的,其默认属性是value,当value是其唯一属性时,可以省略属性名:
@RequestMapping(value="/firstController")
@RequestMapping("/firstController")
4.4 组合注解
Spring框架4.3以后版本中,引入了新的组合注解,来帮助简化常用的HTTP方法的映射,并更好的表达被注解方法的语义。组合注解及其描述如下:
- @GetMapping:匹配GET方式的请求
- @PostMapping:匹配POST方式的请求
- @PutMapping:匹配PUT方式的请求
- @DeleteMapping:匹配DELETE方式的请求
- @PatchMapping:匹配PATCH方式的请求
这里我们以@GetMapping为例说明一下,它会将HTTP GET请求映射到特定的处理方法上:
- 传统使用方式:
@RequestMapping(value = "/user/{id}",method=RequestMethod.GET)
public String index() {
return "register";
}
- 使用@GetMapping注解:
@GetMapping(value = "/user/{id}")
public String index() {
return "register";
}
4.5 请求处理方法的参数和返回类型
4.5.1 请求处理方法的参数
在控制器类中,每一个请求处理方法都可以有多个不同类型的参数,以及一个多种类型的返回结果。请求处理方法中,可以出现的参数类型如下:
其中Model类型不是一个Servlet API类型,而是一个包含了Map对象的Spring MVC类型,如果方法中添加了Model参数,则每次调用该请求处理方法时,Spring MVC都会创建Model对象,并将其作为参数传递给方法。
4.5.2 返回类型
Spring MVC所支持的常见方法返回类型如下:
- ModelAndView
- Model
- Map
- View
- String:可以跳转视图,但不能携带数据
- void
- HttpEntity<?>或ResponseEntity<?>
- Callable<?>
- DeferredResult<?>
由于ModelAndView类型未能实现数据与视图之间的解耦,所以在企业开发时,方法的返回类型通常都会使用String。
4.6 如何将数据带入视图页面及转发和重定向
4.6.1 使用Model
String类型的返回值不可以携带数据,在方法中可以通过Model参数类型来解决,既可添加需要在视图中显示的属性,如下:
@RequestMapping(value = "/first")
public String handleRequest(Model model) {
model.addAttribute("msg", "这是我的第一个基于注解的SpringMVC程序!---");
return "first";
}
4.6.2 redirect重定向
例如,在修改用户信息操作之后,将请求重新定向到用户查询方法的实现代码如下:
4.6.3 forward请求转发
例如,用户执行修改操作时,转发到用户修改页面的实现代码如下:
5 ViewResolver(视图解析器)
Spring MVC中的视图解析器负责解析试图,在配置文件(springmvc-config.xml)中配置如下:
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 设置前缀 -->
<property name="prefix" value="/WEB-INF/jsp/" />
<!-- 设置后缀 -->
<property name="suffix" value=".jsp" />
</bean>
上述代码中,定义了一个视图解析器,并设置了视图的前缀和后缀属性。这样设置后,方法中所定义的view路径将可以简化。例如,入门案例中的逻辑视图名只需设置为“first”,相当于“/WEB-INF/jsp/first.jsp” ,视图解析器会自动的增加前缀和后缀。