SpringMVC总结
Posted poixao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringMVC总结相关的知识,希望对你有一定的参考价值。
SpringMVC总结
- 什么是MVC
- @RequestMapping注解
- SpringMVC获取请求参数
- SpringMVC域对象共享数据
- 视图
- HiddenHttpMethodFilter
- 拦截器
- 异常处理器
- 模板SpringMVC配置文件
- SpringMVC所需依赖
什么是MVC
@RequestMapping注解
@RequestMapping注解的功能
将请求和处理请求的控制器方法关联起来,建立映射关系。
@RequestMapping注解的位置
- @RequestMapping标识一个类:设置映射请求的请求路径的初始信息
- @RequestMapping标识一个方法:设置映射请求请求路径的具体信息
@RequestMapping注解的四个属性
属性 | 解释 |
---|---|
value | 设置匹配地址 字符串类型的数组(或关系) |
method | 设置请求方式 RequestMethod类型的数组(或关系) 满足匹配地址,不满足请求方式,报错405 如果不加method,那么默认是接收所有请求 |
params | 通过请求的请求参数匹配请求映射 字符串类型的数组(与关系) 不满足params数组中任何一个表达式,返回400 |
headers | 通过请求的请求头信息匹配请求映射 字符串类型的数组(与关系) 不满足headers属性,此时页面显示404错误 |
@RequestMapping(
value = "/test1","test2",
method = RequestMethod.GET,RequestMethod.POST,
params = "username","password=123",
headers = "host=localhost:8081"
)
public String test()
SpringMVC支持ant风格的路径(模糊匹配)
?
:表示任意的单个字符:
:表示任意的0个或多个字符**
:表示任意的一层或多层目录
注意:在使用**
时,只能使用/**/xxx
的方式
@RequestMapping(
value = ("/a?a/testAnt")
value = ("/a*a/testAnt")
value = ("/**/testAnt")
)
SpringMVC支持路径中的占位符
- SpringMVC路径中的占位符常用于RESTful风格中,当请求路径中将某些数据通过路径的方式传输到服务器中,就可以在相应的
@RequestMapping
注解的value属性中通过占位符xxx表示传输的数据 - 在通过
@PathVariable
注解,将占位符所表示的数据赋值给控制器方法的形参
@RequestMapping("/testRest/id/username")
public String testRest(@PathVariable("id") String id, @PathVariable("username") String username)
SpringMVC获取请求参数
通过控制器方法的形参获取请求参数
- 若请求所传输的请求参数中有多个同名的请求参数,此时可以在控制器方法的形参中设置字符串数组或者字符串类型的形参接收此请求参数
- 若使用字符串数组类型的形参,此参数的数组中包含了每一个数据
- 若使用字符串类型的形参,此参数的值为每个数据中间使用逗号拼接的结果
@RequestMapping("testParam")
//如果是单个数据,形参与请求参数保持一致就可以获取
public String testParam(String username,String password,String hobby)
@RequestParam
- value:指定为形参赋值的请求参数的参数名
- required:设置是否必须传输此请求参数,默认值为true
- 若设置为true时,则当前请求必须传输value所指定的请求参数,若没有传输该请求参数,且没有设置defaultValue属性,则页面报错400;
- 若设置为false,则当前请求不是必须传输value所指定的请求参数,若没有传输,则注解所标识的形参的值为null
- defaultValue:不管required属性值为true或false,当value所指定的请求参数没有传输或传输的值为""时,则使用默认值为形参赋值
@RequestMapping("testParam")
public String testParam(
@RequestParam(value = "user_name", required = false, defaultValue = "poixao") String username)
@RequestHeader
- @RequestHeader是将请求头信息和控制器方法的形参创建映射关系
- @RequestHeader注解一共有三个属性:value、required、defaultValue,用法同@RequestParam
public String testParam(
@RequestHeader(value = "host", required = false, defaultValue = "192.168.0.1") String host)
@CookieValue
- @CookieValue是将cookie数据和控制器方法的形参创建映射关系
- @CookieValue注解一共有三个属性:value、required、defaultValue,用法同@RequestParam
@RequestMapping("test1")
public String testParam(
@CookieValue(value = "JSESSIONID") String JSESSIONID)
通过POJO获取请求参数
可以在控制器方法的形参位置设置一个实体类类型的形参,此时若浏览器传输的请求参数的参数名和实体类中的属性名一致,那么请求参数就会为此属性赋值
@RequestMapping("/test1")
public String testBean(User user)
解决获取请求参数的乱码问题
解决获取请求参数的乱码问题,可以使用SpringMVC提供的编码过滤器CharacterEncodingFilter,但是必须在web.xml中进行注册
<filter>
<!--设置request的编码为utf-8-->
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>Encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<!--设置response的编码为utf-8-->
<init-param>
<param-name>ForceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
SpringMVC域对象共享数据
-
使用ServletAPI向request域对象共享数据
-
使用ModelAndView向request域对象共享数据
-
使用Model向request域对象共享数据
-
使用map向request域对象共享数据
-
使用ModelMap向request域对象共享数据
使用Model向request域对象共享数据
@RequestMapping("/testModel")
public String testModel(Model model)
model.addAttribute("testScope", "hello,Model");
return "success";
使用ModelMap向request域对象共享数据
@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView()
/**
* ModelAndView有Model和View的功能
* Model主要用于向请求域共享数据
* View主要用于设置视图,实现页面跳转
*/
ModelAndView mav = new ModelAndView();
//向请求域共享数据
mav.addObject("testScope", "hello,ModelAndView");
//设置视图,实现页面跳转
mav.setViewName("success");
return mav;
向session域共享数据
@RequestMapping("/testSession")
public String testSession(HttpSession session)
session.setAttribute("testSessionScope", "hello,session");
return "success";
向application域共享数据
@RequestMapping("/testApplication")
public String testApplication(HttpSession session)
ServletContext application = session.getServletContext();
application.setAttribute("testApplicationScope", "hello,application");
return "success";
视图
1、ThymeleafView
当控制器方法中所设置的视图名称没有任何前缀时,此时的视图名称会被SpringMVC配置文件中所配置的视图解析器解析,视图名称拼接视图前缀和视图后缀所得到的最终路径,会通过转发的方式实现跳转
2、转发视图
SpringMVC中默认的转发视图是InternalResourceView
SpringMVC中创建转发视图的情况:
当控制器方法中所设置的视图名称以"forward:"为前缀时,创建InternalResourceView视图,此时的视图名称不会被SpringMVC配置文件中所配置的视图解析器解析,而是会将前缀"forward:"去掉,剩余部分作为最终路径通过转发的方式实现跳转
转到一个请求
@RequestMapping("/testThymeleafView")
public String testThymeleafView()
return "success";
@RequestMapping("/testForward")
public String testForward()
return "forward:/testThymeleafView";
3、重定向视图
pringMVC中默认的重定向视图是RedirectView
当控制器方法中所设置的视图名称以"redirect:"为前缀时,创建RedirectView视图,此时的视图名称不会被SpringMVC配置文件中所配置的视图解析器解析,而是会将前缀"redirect:"去掉,剩余部分作为最终路径通过重定向的方式实现跳转
Controller
public class ViewController
@RequestMapping("/testThymeleafView")
public String testThymeleafView()
return "success";
@RequestMapping("/testRedirect")
public String testRedirect()
return "redirect:/testThymeleafView";
4、视图控制器view-controller
当控制器方法中,仅仅用来实现页面跳转,即只需要设置视图名称时,可以将处理器方法使用view-controller标签进行表示
<!--
path:设置处理的请求地址
view-name:设置请求地址所对应的视图名称
-->
<mvc:view-controller path="/testView" view-name="success"></mvc:view-controller>
注:
当SpringMVC中设置任何一个view-controller时,其他控制器中的请求映射将全部失效(如:超链接失效),此时需要在SpringMVC的核心配置文件中设置开启mvc注解驱动的标签:
<mvc:annotation-driven />
HiddenHttpMethodFilter
由于浏览器只支持发送get和post方式的请求,那么该如何发送put和delete请求呢?
SpringMVC 提供了 HiddenHttpMethodFilter 帮助我们将 POST 请求转换为 DELETE 或 PUT 请求
HiddenHttpMethodFilter 处理put和delete请求的条件:
a>当前请求的请求方式必须为post
b>当前请求必须传输请求参数_method
满足以上条件,HiddenHttpMethodFilter 过滤器就会将当前请求的请求方式转换为请求参数_method的值,因此请求参数_method的值才是最终的请求方式
在web.xml中注册HiddenHttpMethodFilter
<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
注:
目前为止,SpringMVC中提供了两个过滤器:CharacterEncodingFilter和HiddenHttpMethodFilter
在web.xml中注册时,必须先注册CharacterEncodingFilter,再注册HiddenHttpMethodFilter
原因:
在 CharacterEncodingFilter 中通过 request.setCharacterEncoding(encoding) 方法设置字符集的
request.setCharacterEncoding(encoding) 方法要求前面不能有任何获取请求参数的操作
而 HiddenHttpMethodFilter 恰恰有一个获取请求方式的操作:
String paramValue = request.getParameter(this.methodParam);
使用过滤器将http请求转换成其他请求方法:
将http请求设置成post
设置隐藏域,name=_method,value=请求方法
拦截器
SpringMVC中的拦截器用于拦截控制器方法的执行
SpringMVC中的拦截器需要实现HandlerInterceptor
Component
public class FirstInterceptor implements HandlerInterceptor
//控制器方法之前执行
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
//是否放行
return true; //false拦截 true放行
//控制器方法之后执行
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception
//处理完视图和模型数据,渲染视图完毕之后执行
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception
SpringMVC的拦截器必须在SpringMVC的配置文件中进行配置:
<!--配置拦截器-->
<mvc:interceptors>
<!--对所有请求进行拦截-->
<!--<bean class="com.study.mvc.interceptors.FirstInterceptor"></bean>-->
<!--<ref bean="firstInterceptor"></ref>-->
<mvc:interceptor>
<!--
"/*" 只能对一级目录进行拦截
"/**" 对多级目录进行拦截
-->
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/"/>
<ref bean="firstInterceptor"></ref>
</mvc:interceptor>
</mvc:interceptors>
以上配置方式可以通过ref或bean标签设置拦截器,通过mvc:mapping设置需要拦截的请求,通过mvc:exclude-mapping设置需要排除的请求,即不需要拦截的请求
拦截器三个抽象方法执行顺序
preHandle -->
控制器方法 -->
postHandle -->
this.render(输出视图) -->
afterComplation
多个拦截器的执行顺序
- 当每个拦截器的preHandle()都返回true:preHandle()会按照配置的顺序执行,而postHandle()和afterComplation()会按照配置的反序执行
- 若某个拦截器的preHandle()返回了false:当前拦截器(false)和之前的拦截器的preHandle()都会执行,postHandle()都不执行,当前拦截器(false)之前的拦截器的afterComplation()会执行
异常处理器
如果发生的异常与我们配置的异常类型相同,那么我们可以将其转发到指定的页面,如404、400、400…
SpringMVC提供了一个处理控制器方法执行过程中所出现的异常的接口:HandlerExceptionResolver
HandlerExceptionResolver接口的实现类有:DefaultHandlerExceptionResolver和SimpleMappingExceptionResolver
- DefaultHandlerExceptionResolver:SpringMVC默认异常处理器
- SimpleMappingExceptionResolver:自定义的异常处理器
//@ControllerAdvice将当前类标识为异常处理的组件
@ControllerAdvice
public class ExceptionController
//@ExceptionHandler用于设置所标识方法处理的异常
@ExceptionHandler(value = ArithmeticException.class, NullPointerException.class)
//ex表示当前请求处理中出现的异常对象
public String testException(Exception ex, Model model)
model.addAttribute("ex", ex);
return "error";
模板SpringMVC配置文件
<?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.xsd">
<!--配置默认servlet-->
<mvc:default-servlet-handler/>
<!-- 开启mvc注解驱动 -->
<mvc:annotation-driven/>
<!--自动扫描包-->
<context:component-scan base-package="com.study.mvc"></context:component-scan>
<!--必须通过文件解析器的解析才能将文件转换为MultipartFile对象-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean>
<!--视图控制器view-controller-->
<mvc:view-controller path="/" view-name="index"></mvc:view-controller>
<!--配置拦截器-->
<mvc:interceptors>
<!--对所有请求进行拦截-->
<!--<ref bean="firstInterceptor"></ref>-->
<!--<ref bean="secondInterceptor"></ref>-->
<!--<bean class="com.study.mvc.interceptors.FirstInterceptor"></bean>-->
<!--<ref bean="firstInterceptor"></ref>-->
<mvc:interceptor>
<!--
"/*" 只能对一级目录进行拦截
"/**" 对多级目录进行拦截
-->
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/"/>
<ref bean="firstInterceptor"></ref>
</mvc:interceptor>
</mvc:interceptors>
<!--配置异常信息-->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="java.lang.ArithmeticException">error</prop>
</props>
</property>
<!--
设置了exceptionAttribute后,可以存储错误信息,默认存储在请求域中
value设置的就是存储错误信息的 键
这样就可以在页面中,通过 键 取出错误信息,展示
-->
<property name="exceptionAttribute" value="ex"></property>
</bean>
<!-- 配置Thymeleaf视图解析器 -->
<bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
<property name="order" value="1"/>
<property name="characterEncoding" value="UTF-8"/>
<property name="templateEngine">
<bean class="org.thymeleaf.spring5.SpringTemplateEngine">
<property name="templateResolver">
<bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
<!-- 视图前缀 -->
<property name="prefix" value="/WEB-INF/templates/"/>
<!-- 视图后缀 -->
<property name="suffix" value=".html"/>
<property name="templateMode" value="HTML5"/>
<property name="characterEncoding" value="UTF-8"/>
</bean>
</property>
</bean>
</property>
</bean>
</beans>
SpringMVC所需依赖
<packaging>war</packaging>
<dependencies>
<!-- SpringMVC -->
<dependency>
<groupId>org.springframeworkSpringMVC 源码总结篇