Spring MVC是基于 Servlet 的一个 MVC 框架,主要解决 WEB 开发的问题。
2.2.2 用途介绍
Spring MVC是Spring的一部分,主要用于开发WEB应用和网络接口,它是Spring的一个模块,通过Dispatcher Servlet, ModelAndView 和 View Resolver,让应用开发变得很容易。
一个典型的Spring MVC应用开发分为下面几步:
首先通过配置文件声明Dispatcher Servlet:
通过配置文件声明servlet详情,如MVC resource,data source,bean等
若需添加其它功能,如security,则需添加对应配置:
增加业务代码,如controller,service,model等,最后生成war包,通过容器进行启动
2.2.3 SpringMVC常用注解
@Controller
负责注册一个bean 到spring 上下文中
@RequestMapping
注解为控制器指定可以处理哪些 URL 请求
@RequestBody
该注解用于读取Request请求的body部分数据,使用系统默认配置的HttpMessageConverter进行解析,然后把相应的数据绑定到要返回的对象上 ,再把HttpMessageConverter返回的对象数据绑定到 controller中方法的参数上
@ResponseBody
该注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区
@ModelAttribute
在方法定义上使用 @ModelAttribute 注解:Spring MVC 在调用目标处理方法前,会先逐个调用在方法级上标注了@ModelAttribute 的方法
在方法的入参前使用 @ModelAttribute 注解:可以从隐含对象中获取隐含的模型数据中获取对象,再将请求参数 –绑定到对象中,再传入入参将方法入参对象添加到模型中
@RequestParam
在处理方法入参处使用 @RequestParam 可以把请求参 数传递给请求方法
@PathVariable
绑定 URL 占位符到入参
@ExceptionHandler
注解到方法上,出现异常时会执行该方法
@ControllerAdvice
使一个Contoller成为全局的异常处理类,类中用@ExceptionHandler方法注解的方法可以处理所有Controller发生的异常
一、@RequestMapping 简介
在Spring MVC 中使用 @RequestMapping 来映射请求,也就是通过它来指定控制器可以处理哪些URL请求,相当于Servlet中在web.xml中配置
1 | <servlet> |
的映射作用一致。让我们先看一下RequestMapping注解类的源码:
1 | @Target({ElementType.METHOD, ElementType.TYPE}) |
produces:指定返回值类型,不但可以设置返回值类型还可以设定返回值的字符编码
consumes:指定处理请求的提交内容类型(Content-Type),例如application/json, text/html;
例子:
1.produces第一种使用,返回json数据,下边的代码可以省略produces属性,因为我们已经使用了注解@responseBody就是返回值是json数据:
1 | @Controller |
produces第二种使用,返回json数据的字符编码为utf-8:
1 | @Controller |
2.consumes的例子( 方法仅处理request Content-Type为“application/json”类型的请求。)
1 | @Controller |
1)在@Target中有两个属性,分别为 ElementType.METHOD 和 ElementType.TYPE ,也就是说 @RequestMapping 可以在方法和类的声明中使用
2)可以看到注解中的属性除了 name() 返回的字符串,其它的方法均返回数组,也就是可以定义多个属性值,例如 value() 和 path() 都可以同时定义多个字符串值来接收多个URL请求
二、准备工作
1)新建一个 Web 工程,取名为 SpringMVC
略
2)新建一个的控制器类:UserController
1 | package cn.kolbe.spring.mvc.controller; |
3)新建和配置 web.xml 以及 spring-mvc.xml 文件
4)新建一个测试的 JSP 页面 index.jsp
1 | <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> |
5)新建一个成功跳转的页面 JSP 页面 welcome.jsp
1 | <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> |
三、测试 @RequestMapping 中的 value 和 path 属性
(这两个属性作用相同,可以互换,如果仅有这一个属性,则可以省略,下面两个例子均采用省略的方式)
1)将 @RequestMapping 注解在 login 方法上,而UserController上不添加 @RequestMapping 注解,这时的请求 URL 是相对于 Web 根目录
1 | @Controller |
这时的方法 login() 能处理的 URL 请求路径是基于 Web 应用的,也就是 http://localhost/SpringMVC/login,也就是 index.jsp 页面中的 User Login 链接地址应该是:
1 | <a href="login">User Login</a> |
2)将 @RequestMapping 注解在 UserController 类上,这时类的注解是相对于 Web 根目录,而方法上的是相对于类上的路径
1 | @Controller |
这时的方法login()能处理的 URL 请求路径则是 http://localhost/SpringMVC/user/login,也就是 index.jsp 页面中的 User Login 链接地址应该是:
1 | <a href="user/login">User Login</a> |
四、测试 @RequestMapping 的 method 属性
1)简介:@RequestMapping 中的 method 主要用来定义接收浏览器发来的何种请求。在Spring中,使用枚举类
org.springframework.web.bind.annotation.RequestMethod来定义浏览器请求的方式。
Http规范定义了多种请求资源的方式,最基本的有四种,分别为:GET(查)、POST(增)、PUT(改)、DELETE(删),而URL则用于定位网络上的资源相当于地址的作用,配合四种请求方式,可以实现对URL对应的资源的增删改查操作。
在实际应用中,很多人并没有按照这个规范做,因为使用GET/POST同样可以完成PUT和DELETE操作,甚至GET也可以完成POST操作,因为GET不需要用到表单,而POST却需要通过表单来发送。
2)通过 @RequestMapping(value=”/login”,method=RequestMethod.GET) 来指定 login()方法 仅处理通过 GET 方式发来的请求
1 | @Controller |
这时,如果浏览器发来的请求不是GET的话,将收到浏览器返回的错误提示,也就是得通过链接的方式而不是表单的方式:
1 | <a href="user/login>User Login</a> |
3)通过 @RequestMapping(value=”/login”,method=RequestMethod.POST) 来指定 login()方法 仅处理通过 POST 方式发来的请求
1 | @Controller |
这时,必须通过表单的方式发送请求,否则将收到浏览器返回的错误提示
1 | <form action="user/login" method="post"> |
4)由于在 RequestMapping 注解类中 method() 方法返回的是 RequestMethod 数组,所以可以给 method 同时指定多个请求方式,例如:
1 | @Controller |
五、测试 @RequestMapping 的 params 属性,该属性表示请求参数,也就是追加在URL上的键值对,多个请求参数以&隔开,例如:
1 | http://localhost/SpringMVC/user/login?username=kolbe&password=123456 |
则这个请求的参数为username=kolbe以及password=123456,@RequestMapping 中可以使用 params 来限制请求参数,来实现进一步的过滤请求,举个例子:
1 | @Controller |
该例中则表示 UserController 中的 login() 方法仅处理 /user/login 发来的请求,且必须带有 username=kolbe&password=123456 的请求参数,否则浏览器将返回HTTP 404的错误, 对应 index.jsp 中的键接地址为:
1 | <a href="user/login?username=kolbe&password=123456">User Login</a> |
六、测试 @RequestMapping 的 headers 属性,该属性表示请求头
用于HTTP协义交互的信息被称为HTTP报文,客户端发送的HTTP报文被称为请求报文,服务器发回给客户端的HTTP报文称为响应报文,报文由报文头部和报文体组成。
请求头部(Request Headers):请求头包含许多有关客户端环境和请求正文的信息,例如浏览器支持的语言、请求的服务器地址、客户端的操作系统等。
响应头部(Rsponse Headers):响应头也包含许多有用的信息,包括服务器类型、日期、响应内容的类型及编码,响应内容的长度等等。
如果你安装的是Chrome浏览器,可以通过在网页中 右击鼠标—->审查元素—->Network—->Name中点击网页—->右侧查看Headers即可,如果Name中没有出现网页,可以刷新一下即可,下边是我电脑中的一个请求头部示例:
1 | Request Headers |
回规正题,通过 @RequestMapping 中的 headers 属性,可以限制客户端发来的请求
1 | @Controller |
七、带占位符的URL
(一)带占位符的URL是Spring 3.0 新增的功能,可以通过 @PathVariable 将 URL 中的占位符绑定到控制器的处理方法的参数中,占位符使用{}括起来
(二)使用方法:
1)带占位符的URL示例:
1 | @Controller |
在这个控制器中 show() 方法将可以接收 user/1、user/2、user/3等等的路径请求,请求的方法必须为GET,使用 @PathVariable 为应用实现 REST 规范提供了具大的便利条件。
八、采用 REST 风格的 URL 请求
1)简介:REST(Representational State Transfer):(资源)表现层状态转化,它是目前最流行的一种软件架构,其结构清晰、易于理解、扩展方便且符合标准,正在越来越多的被实践到应用中。
2)REST 风格的 URL 请求
1 | 请求路径 请求方法 作用 |
3)由于浏览器表单只支持 GET 和 POST 请求,为了实现 DELETE 和 PUT 请求,Spring 为我们提供了一个过滤器org.springframework.web.filter.HiddenHttpMethodFilter,可以为我们将 GET 和 POST 请求通过过滤器转化成 DELETE 和 PUT 请求。
4)在 web.xml 中配置过滤器
1 | <!-- 配置 org.springframework.web.filter.HiddenHttpMethodFilter 过滤器 --> |
5)由于浏览器表单无法发送 DELETE 和 PUT 请求,所以为了让 HiddenHttpMethodFilter 识别请求的方法,需要在表单中添加一个隐藏域,名字为 _method 值为 DELETE 或 POST 或PUT,修改后 index.jsp 页面代码如下:
1 | <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> |
6)修改后的UserController代码
1 | package cn.kolbe.spring.mvc.controller; |
1、使用Maven的方式
1 | <dependency> |
2、在web.xml文件中配置Spring的DispatcherServlet用来拦截请求
1 | <?xml version="1.0" encoding="UTF-8"?> |
3、添加Spring MVC的配置文件取名为 spring-mvc.xml,用来加载web应用中的Spring Bean
1 | <?xml version="1.0" encoding="UTF-8"?> |
4、编写类HelloWorld,并通过添加注解 @Controller 将其标识为控制器,这里可以看出HelloWorld仅仅是一个普通的Java类,通过简单的注解,就可以将其解析为Servlet类来响应用户的请求
1 | package cn.kolbe.spring.mvc.controller; |
5、编写视图层的页面,这里就两个简单的页面,一个是index.jsp页面,一个是success.jsp页面
(一)index.jsp页面,路径是 /index.jsp
1 | %@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> |
6、success.jsp页面,路径是 /WEB-INF/views/success.jsp
1 | <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> |
注解
@ControllerAdvice
增强的 Controller:
- 全局异常处理
- 全局数据绑定
- 全局数据预处理