Spring MVC笔记

Spring MVC

Spring MVC是模型-视图-控制器的web框架

  • 模型(Model):封装应用程序的数据,通常由POJO类组成
  • 视图(View):负责渲染模型数据,一般由客户端浏览器解释HTML输出
  • 控制器(Controller):负责处理用户请求并构建适当模型,并将其传递给视图进行渲染

资源下载

  • Spring MVC Libs
  • 项目所需jar包

    1. commons-logging-x.y.jar
    2. spring-aop-x.y.z.RELEASE.jar
    3. spirng-beans-x.y.z.RELEASE.jar
    4. spring-context-x.y.z.RELEASE.jar
    5. spring-core-x.y.z.RELEASE.jar
    6. spring-expression-x.y.z.RELEASE.jar
    7. spring-tx-x.y.z.RELEASE.jar
    8. spring-web-x.y.z.RELEASE.jar
    9. spring-webmvc-x.y.z.RELEASE.jar

DispatcherServlet

作为全局的中央分发中心,是所有的发现请求、映射、视图解析、异常处理等所需的委托组件

  • 处理流程:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
HTTP REQUEST HTTP RESPONSE
| ↑
| |
↓ |
===============================================================================
DpatcherServlet
===============================================================================
| ↑ | ↑ | ↑ | ↑
1| | 2| | 3| | 4 | |
↓ | ↓ | ↓ | ↓ |
================ ================ ================ =============
HandlerMapping Controller View Resolver View
================ ================ ================ =============
1. 接收到HTTP请求后,DispatcherServlet会查询HandlerMapping调用相应的Controller
2. Controller接收请求,并根据使用的GET|POST|DELETE|PUT方法调用相应的业务方法,将视图名称返回给DispatcherServlet
3. DispatcherServlet将从ViewResolver获取请求的定义物理视图
4. 当视图完成,DispatcherServlet将模型数据传递到最终的视图,并在浏览器上呈现
HandlerMapping、Controller、ViewResolver是WebApplicationContext的一部分,它是普通ApplicationContext的扩展,带有Web应用程序所需的一些额外功能。
  • 配置

    1.web.xml中通过STS插件配置DispatcherServlet

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <!-- The front controller of this Spring Web application, responsible for handling all application requests -->
    <servlet>
    <servlet-name>springDispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:springmvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
    <servlet-name>springDispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
    </servlet-mapping>

    2.classpath:springmvc.xml配置,项目/java/src目录下创建springmvc.xml配置文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    <?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-4.3.xsd">
    <!-- 配置Spring MVC注解扫描器 -->
    <context:component-scan
    base-package="cn.imeina.springmvc"></context:component-scan>
    <!-- 配置内部资源视图解析器-->
    <bean
    class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <!-- 通过配置前缀和后缀来映射匹配对应的物理视图 -->
    <property name="prefix" value="/"></property>
    <property name="suffix" value=".jsp"></property>
    </bean>
    <!-- JSTL解析器 -->
    <bean class="org.springframework.web.servlet.view.JstlView">
    <property name="url" value="/"></property>
    </bean>
    </beans>
  • 定义控制器

    1. @Controller注解:Spring MVC通过给任意类添加该注解来授权该类充当控制器的角色
    2. @RequestMapping注解:该注解修饰类,则代表请求URL中PATH的一部分;修饰方法,则代表对应的业务处理

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      package cn.imeina.springmvc.handler;
      import java.util.Map;
      import org.springframework.stereotype.Controller;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RequestMethod;
      @Controller
      @RequestMapping("test")
      public class BaseDotHandler {
      private static final String SUCCESS = "success";
      /**
      * 使用@RequestMapping注解来映射路径->方法
      * @return
      */
      @RequestMapping(value="/hello", method = RequestMethod.GET)
      public String hello() {
      System.out.println("hello method running...");
      return SUCCESS;
      }

      当用户从浏览器里访问:http://host:port/springmvc/test/hello 地址时则会收到一个success.jsp的结果页面

常用注解使用

  • @Controller:修饰类,该类将作为Spring MVC的一个控制器
  • @RequestMapping:修饰类和方法,修饰类即指定PATH,修饰方法指定业务
  • @PathVariable:修饰形参,用于代替http Request.getParamter()来映射参数赋值参数
  • @RequestHeade:修饰形参,用于获取Http Request报头的信息
  • @CookieValue:修饰形参,用户获取Http Request的CookieValue
  • @SessionAttribute:修饰控制器类,可通过value[]和types[Class]来指定控制器内哪些属性或对象将被存储到session中
  • @ModelAttribute:修饰无返回值的方法时,需要在方法内,开发者手动将数据存储到RequestScope;修饰有返回值的方法时,则自动将数据存储到RequestScope中;修饰方法形参时,则指定该方法调用前需要先从域中查询是否有对应数据。
Spring MVC获取使用Servlet原生API

Spring MVC支持9种原生Servlet API的获取和使用

  • HttpServletRequest
  • HttpServletResponse
  • HttpSession
  • Principal
  • Locale
  • InputStream
  • OutputStream
  • Reader
  • Writer

直接在控制器的方法中,将其作为形参即可自动映射获取到对象。

ModelAndView

Spring MVC提供了四种方式用于开发者对数据的返回处理

  • ModelAndView
  • ModelMap
  • Model
  • Map

视图解析流程及工作原理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
DispatcherServlet doDispatch(HttpServletRequest req, HttpServletResponse rsp):Http Request首先经过主控制器进行分发处理
|
|
HandlerAdapter.handler(HttpServletRequest req, HttpServletResponse rsp, Object handler):通过反射回调我们自定义控制器的方法生成一个ModelAndView(Model:ModelMap,View:逻辑视图名称)
|
|
DispatcherServlet.processDispatchResult(req, rsp, handler, mv, dispatchException):对上一步的ModelAndView进行处理(非空判断数据验证等操作)
|
|
DispatcherServlet.render(mv, req, rsp):从ModelAndView获取到View视图
|
|
DispatcherServlet.resolveViewName(mv.getViewName(), mv.getModelInternal(), locale, req):遍历视图解析器集合,通过视图解析器对逻辑视图解析转换成物理视图
|
|
View.render(Map<String, ?> model, HttpServletRequest req, HttpServletResponse rsp):视图接口:渲染
|
|
AbstractView.renderMergeOutputModel(Map<String, ?> model, HttpServletRequest req, HttpServletResponse rsp):实现了View接口的抽象类:渲染
|
|
InternalResourceView.renderMergeOutputModel(Map<String, ?> model, HttpServletRequest req, HttpServletResponse rsp):AbstractView的实现类:渲染(最终内部调用RequestDispatcher.forward(req,rsp)完成请求转发)

常用视图实现类

类别 实现类 说明
URL视图资源 InternalResourceView 将JSP或其他资源封装成视图,是InternalResourceViewResolver默认使用的视图实现类
URL视图资源 JstlView 如果JSP文件中使用了JSTL国际化标签功能,则需要使用该视图类
文档视图 AbstractExcelView Excel文档视图抽象类,该视图类基于POI构造Excel文档
文档视图 AbstractPdfView PDF文档视图抽象类,该视图基于iText构造PDF文档
报表视图 ConfigurableJsperReportsView 使用JasperReports报表技术的视图
报表视图 JasperReportsCsvView 使用JasperReports报表技术的视图
报表视图 JasperReportsMultiFormalView 使用JasperReports报表技术的视图
报表视图 JasperReportsHtmlView 使用JasperReports报表技术的视图
报表视图 JasperReportsPdfView 使用JasperReports报表技术的视图
报表视图 JasperReportsXlsView 使用JasperReports报表技术的视图
JSON视图 MappingJacksonJsonView 将模型数据通过Jackson开源框架的ObjectMapper以JSON方式输出

配置视图映射及注意事项

除了在控制器中使用注解配置视图的映射关系外,还可以在springmvc.xml文件中使用如下配置直接指定映射关系

1
<mvc:view-controller path="/abcdefg" view-name="a"/>

当访问http://host:port/project/abcdefg 则会看到a.jsp视图页面
注意:当使用标签配置了视图映射后,会导致所有控制器及映射失效,解决办法,同时添加如下配置:

1
<mvc:annotation-driven></mvc:annotation-driven>

自定义视图及解析器

1.定义类实现org.springframework.web.servlet.View接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package cn.imeina.springmvc.view;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.View;
/**
* 自定义视图类型
* 默认bean的id为首字母小写对应的类名
*/
@Component
public class CustomView implements View {
@Override
public String getContentType() {
return "text/html";
}
@Override
public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response)
throws Exception {
response.getWriter().println("<h1>This is a CustomView</h1>");
}
}

2.springmvc.xml添加自定义视图解析器

1
2
3
4
5
6
7
8
9
<!-- 自定义视图解析器 -->
<bean
class="org.springframework.web.servlet.view.BeanNameViewResolver">
<property name="order" value="100"></property>
</bean>
<!--
BeanNameViewResolver以及InternalResourceViewResolver等他们父类拥有ORDER全局变量该值为Interger.MAX_VALUE
而对应的自定义视图我们使用频率少,所以他应该先执行,配置order属性,值越小优先级越高。
-->

3.springmvc.xml配置添加视图映射

1
<mvc:view-controller path="/customView" view-name="customView" />

相关文档资料

如果帮到了你,想打赏支持,喏~