Spring MVC
- 1.说一下Spring MVC的执行流程?
- 2.Spring MVC的核心组件有哪些?
- 3.什么是Spring MVC?什么是MVC设计模式?
- 4.Spring MVC的注解有哪些?分别表示什么含义?
- 5.Spring MVC往页面传值(添加模型数据)的方式有几种?
- 6.Spring MVC请求转发的写法有几种?
- 7.Spring MVC 重定向的写法有几种?
- 8.Spring MVC 常用的JSON解析器有哪些?
- 9.Spring MVC中怎么解决Http POST请求中文乱码问题?
- 10.Spring MVC怎么解决响应到页面出现中文乱码?
- 11.@DateTimeFormat 和 @JsonFormat 注解的区别?
- 12.Spring MVC如何使用?
- 13.Spring MVC里的静态资源访问怎么设置?
- 14.Spring MVC实现文件上传?
- 15.什么是Lombok?怎么使用?
- 16.Thymeleaf是什么?怎么使用?
- 17.Spring MVC中同时存在动态html和jsp,怎么解决视图解析器问题?
- 18.Spring MVC全局异常处理页面怎么配置?
- 19.Spring MVC中拦截器的实现过程和拦截顺序?
- 20.ant风格资源地址支持的3种匹配符分别代表什么意思?
- 21.Spring MVC怎么实现数据校验?
1.说一下Spring MVC的执行流程?
- ① 流程图

- ② 流程分析
- 1.客户端请求被 DisptacherServlet 接收。
- 2.根据 HandlerMapping 映射到 Handler。
- 3.生成 Handler 和 HandlerInterceptor。
- 4.Handler 和 HandlerInterceptor 以 HandlerExecutionChain 的形式一并返回给 DisptacherServlet。
- 5.DispatcherServlet 通过 HandlerAdapter 调用 Handler 的方法完成业务逻辑处理。
- 6.Handler 返回一个 ModelAndView 给 DispatcherServlet。
- 7.DispatcherServlet 将获取的 ModelAndView 对象传给 ViewResolver 视图解析器,将逻辑视图解析为物理视图 View。
- 8.ViewResovler 返回一个 View 给 DispatcherServlet。
- 9.DispatcherServlet 根据 View 进行视图渲染(将模型数据 Model 填充到视图 View 中)。
- 10.DispatcherServlet 将渲染后的结果响应给客户端。
2.Spring MVC的核心组件有哪些?
- ① DispatcherServlet:中央调度器,是整个流程控制的核心,控制其他组件的执行,进行统一调度,降低组件之间的耦合性,相当于总指挥。
- ② Handler:处理器,完成具体的业务逻辑,相当于 Servlet 或 Action。
- ③ HandlerMapping:处理器映射器,DispatcherServlet 接收到请求之后,通过 HandlerMapping 将不同的请求映射到不同的 Handler。
- ④ HandlerInterceptor:处理器拦截器,是一个接口,如果需要完成一些拦截处理,可以实现该接口。
- ⑤ HandlerExecutionChain:处理器执行链,包括两部分内容:Handler 和 HandlerInterceptor(系统会有一个默认的 HandlerInterceptor,如果需要额外设置拦截,可以添加拦截器)。
- ⑥ HandlerAdapter:处理器适配器,Handler 执行业务方法之前,需要进行一系列的操作,包括表单数据的验证、数据类型的转换、将表单数据封装到 JavaBean 等,这些操作都是由 HandlerApater 来完成,开发者只需将注意力集中业务逻辑的处理上,DispatcherServlet 通过 HandlerAdapter 执行不同的 Handler。
- ⑦ ModelAndView:装载了模型数据和视图信息,作为 Handler 的处理结果,返回给 DispatcherServlet。
- ⑧ ViewResolver:视图解析器,DispatcheServlet 通过它将逻辑视图解析为物理视图,最终将渲染结果响应给客户端。
3.什么是Spring MVC?什么是MVC设计模式?
- Spring MVC: 是目前主流的实现 MVC 设计模式的企业级开发框架,Spring 框架的一个子模块,无需整合,开发起来更加便捷。
- MVC设计模式: 将应用程序分为 Controller、Model、View 三层,Controller 接收客户端请求,调用 Model 生成业务数据,传递给 View。Spring MVC 就是对这套流程的封装,屏蔽了很多底层代码,开放出接口,让开发者可以更加轻松、便捷地完成基于 MVC 模式的 Web 开发。
4.Spring MVC的注解有哪些?分别表示什么含义?
- @Controller : 定义在类上,表示将该类交给IOC容器来管理,同时使其成为一个控制器,可以接收客户端请求。
- @RequestMapping : 该注解将URL请求与业务方法进行映射(一般用来定义请求接口名和请求方式),定义在类上表示父路径名,定义在方法上表示子路径。它有以下六个属性:
- value: 指定请求的实际地址。
- method: 指定请求的方式( GET、POST、PUT、DELETE)。
- consumes: 指定处理请求的提交内容类型(Content-Type),例如application/json, text/html。
- produces: 指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回。(如 produces=“application/json” 表示只处理request请求中Accept头中包含了"application/json"的请求)
- params: 指定request请求中必须包含某些参数值,才让该方法处理请求。(如 params = {"!username",“id=10”} 表示只接收不包含名为username的参数且拥有名为id的参数且参数id值是10的request请求)
- headers: 指定request请求中必须包含某些指定的header值,才让该方法处理请求。(如headers = “Accept=application/json” 表示请求头中必须有“Accept =application/json”参数才让处理)
- @RequestParam(value=“paramName”) : 用来获取request请求中名为paramName的参数值,并赋给形参。它有以下三个参数:
- value: 设置请求参数的名称。
- required: 默认为true,设置请求中是否必带该参数。
- defaultValue: 设置默认值,如果请求中没有同名参数时就使用该默认值。
- @RequestBody: 将前端发来的JSON数据,进行自动解析,并把JSON数据自动封装到形参(形参必须为对象类型)中,且形参对象要与JSON对象的属性一致。
- @RequestHeader: 获取请求头中的值,并赋值给形参。
@RequestMapping("/request")
public void query(@RequestHeader("Accept-Encoding") String encoding, @RequestHeader("Keep-Alive") long keepAlive) { }
- @ResponseBody: 响应体注解,响应信息到前端页面。
- 注意 :当使用该注解并且方法返回值是对象类型的时候,需要添加jackSON依赖包,将java对象转换为JSON信息再响应到前端。
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-coreartifactId>
<version>2.9.6version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>2.9.6version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-annotationsartifactId>
<version>2.9.6version>
dependency>
- @PathVariable: 用来获取URL请求中的一个动态变量值。一般配合RESTful 风格的URL使用。
@RequestMapping("/rest/{name}/{id}")
public String rest(@PathVariable("name") String name, @PathVariable("id") int id){
System.out.println("name = "+ name + ",id =" + id);
return "index";
}
- @CookieValue(“cookieName”): 获取名为cookieName的cookie的值,并赋值给形参。
@Controller
@RequestMapping("/cookie")
public class HelloController {
@RequestMapping("/show")
public String test( @CookieValue("JSESSIONID") String jsessionid){
System.out.println(jsessionid);
return "hello";
}
}
- @ModelAttribute: 用在方法上,使该方法专门用来返回要填充到模型数据中对象,并把模型数据绑定到request域中。这样其它业务方法中无需再处理模型数据,只需要返回视图即可。
@ModelAttribute
public void getUser(Model model){
User user = new User();
user.setId(1L);
user.setName("李四");
model.addAttribute("user",user);
}
@RequestMapping("/modelAttribute")
public String modelAttribute(){
return "view";
}
对于ViewHandler类中所有的业务方法,
只要向request中添加了key="user"、key="address"的对象时,
Spring MVC会自动将该数据添加到session域中,保存的key不变。
@SessionAttributes(value = {"user","address"})
public class ViewHandler { }
对于ViewHandler2类中的所有业务方法,
只要向request中添加了数据类型是User和Address对象时,
Spring MVC会自动将该数据添加到session域中,保存的key不变。
@SessionAttributes(types = {User.class,Address.class})
public class ViewHandler2 { }
5.Spring MVC往页面传值(添加模型数据)的方式有几种?
- ① 将模型数据绑定request域
- HttpServletRequest
- Map
- Model
- ModelMap
- ModelAndView
- @ModelAttribute
- ② 将模型数据绑定到session域
- HttpSession
- @SessionAttributes
6.Spring MVC请求转发的写法有几种?
1.不带forward关键字
默认写法: return "index"; index是逻辑视图名,跳转之前会根据视图解析器的配置进行前缀和后缀的拼接,
最后跳才转到拼接后的页面.
2.带forward关键字
①物理视图 return "forward:/WEB-INF/jsp/index.jsp";
②相对路径 return "forward:second"; forward后面写 接口名(RequestMapping括号里面的Value值)
③绝对路径 return "forward:/index/second" :index为类上的接口名,second为类中业务方法的接口名
7.Spring MVC 重定向的写法有几种?
1.相对路径 :return "redirect:second"; second为业务方法中的接口名
2.绝对路径 :return "redirect:/index/second"; index为类上的接口名,second为类中业务方法的接口名
3.特别注意:使用重定向,是不能直接跳转到/WEB-INF/内部的资源的,
因为浏览器中不能通过URL地址直接访问/WEB-INF/内部的资源
例: return "redirect:/WEB-INF/jsp/first.jsp"; 这是错误的写法
8.Spring MVC 常用的JSON解析器有哪些?
- ① jackSON
- ② fastJSON (阿里巴巴)
- ③ gSON (谷歌)
9.Spring MVC中怎么解决Http POST请求中文乱码问题?
<filter>
<filter-name>encodingFilterfilter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
<init-param>
<param-name>encodingparam-name>
<param-value>UTF-8param-value>
init-param>
filter>
<filter-mapping>
<filter-name>encodingFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
10.Spring MVC怎么解决响应到页面出现中文乱码?
- 1.在springmvc.xml文件中配置StringHttpMessageConverter消息转换器
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg value="UTF-8" />
bean>
mvc:message-converters>
mvc:annotation-driven>
- 2.在类或方法上的@RequestMapping注解中添加produces属性:设置返回的JSON数据的字符编码格式为UTF8
@RequestMapping(value = "/rest/{name}", produces = MediaType.APPLICATION_JSON_UTF8_VALUE )
@ResponseBody
public User test(@PathVariable("name") String name) {
User user = new User();
user.setName("中文乱码")
return user;
}
11.@DateTimeFormat 和 @JsonFormat 注解的区别?
- @DateTimeFormat (spring的注解): 入参格式化,把前端提交的时间字符串转换为java.util.Date类型(如果格式匹配的话),不加此注解会抛异常。
- @JsonFormat(jackson的注解) : 出参格式化,把后端对象的Date类型属性按照指定格式响应到前端。(需要添加jackson依赖)
1.实体类
package com.wpq.domain;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
@Data
public class DatePojo {
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date date;
}
2.地址栏访问时携带date参数,模拟form表单GET方式提交数据
http://localhost:8080/date?date=2019-10-12 12:22:22
3.web层接口
@GetMapping("/date")
@ResponseBody
public DatePojo dateTest(DatePojo datePojo){
System.out.println("datePojo = " + datePojo);
return datePojo;
}
4.响应到前端页面的结果
@JsonFormat注解中加timezone = "GMT+8"显示: {"date":"2019-10-12 12:22:22"}
@JsonFormat注解中不加timezone = "GMT+8"显示:{"date":"2019-10-12 04:22:22"}
原因:jackson在序列化时间时是按照国际标准时间GMT进行格式化的,而在国内默认时区使用的是CST时区,两者相差8小时。
12.Spring MVC如何使用?
- ① 新建Maven工程(选择webapp骨架创建),在项目pom.xml添加Spring-webmvc依赖。
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>5.0.11.RELEASEversion>
dependency>
- ② 在src/main目录下新建java文件夹和resources文件夹并且右键Mark为相对应的文件类型。
- ③ 配置 webapp/WEB-INF下的web.xml文件。
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<welcome-file-list>
<welcome-file>index.htmlwelcome-file>
<welcome-file>index.jspwelcome-file>
<welcome-file>/WEB-INF/jsp/index.jspwelcome-file>
welcome-file-list>
<servlet>
<servlet-name>dispatcherServletservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<init-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:spring-mvc.xmlparam-value>
init-param>
<load-on-startup>1load-on-startup>
servlet>
<servlet-mapping>
<servlet-name>dispatcherServletservlet-name>
<url-pattern>/url-pattern>
servlet-mapping>
web-app>
- ④ 在src/main/resources目录下新建spring-mvc.xml文件,并配置。
<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.2.xsd">
<context:component-scan base-package="com.wpq"/>
<mvc:annotation-driven />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/">property>
<property name="suffix" value=".jsp">property>
bean>
beans>
@Controller
public class Hello {
@GetMapping("/hello")
public String test(){
return "index";
}
}
13.Spring MVC里的静态资源访问怎么设置?
- 方式一:在spring-mvc.xml文件中配置静态文件的存放位置
<mvc:resources mapping="/static/**" location="/static/"/>
1.location元素:表示webapp目录下的static包下的所有文件;
2.mapping元素:表示以/static开头的所有请求路径,如/static/a 或者/static/a/b;
3.作用:DispatcherServlet不会拦截以/static开头的所有请求路径,并当作静态资源交由Servlet处理。
比如设置之后DispatcherServlet就不会拦截src的请求了,这样就可以拿到jquery-3.2.1.min.js这个包了
<script src="/static/js/jquery-3.2.1.min.js" type="text/javascript">script>
- 方式二:在spring-mvc.xml中配置default-servlet-handler处理静态资源的访问,配合mvc注解驱动使用,注意要放在mvc注解驱动的下面。
<mvc:annotation-driven />
<mvc:default-servlet-handler/>
14.Spring MVC实现文件上传?
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>文件上传title>
head>
<body>
<%--注意:文件上传表单中,必须添加enctype="multipart/form-data"--%>
<form method="post" action="upload" enctype="multipart/form-data">
<input type="file" name="file"/><br/>
<input type="submit" value="上传"/>
form>
body>
html>
- ② 在spring-mvc.xml文件中配置CommonsMultipartResolver通用多媒体文件解析器。
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
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/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.wpq.mvc.web,com.wpq.mvc.exception"/>
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
bean>
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="UTF-8"/>
<property name="maxUploadSize" value="5242880"/>
<property name="uploadTempDir" value="file:d:/upload/"/>
bean>
beans>
- ③ 新建UploadController,里面写个方法专门处理上传过来的文件,使用MultipartFile类型接收上传过来的文件。
package com.wpq.mvc.web;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
@Controller
public class UploadController {
@ResponseBody
@PostMapping("/upload")
public String upload(@RequestParam("file") MultipartFile file) throws IOException {
if (!file.isEmpty()) {
String filename = file.getOriginalFilename();
File destFile = new File("d:/upload/" + filename);
if (!destFile.exists()) {
destFile.mkdirs();
}
file.transferTo(destFile);
}
return "ok";
}
}
15.什么是Lombok?怎么使用?
- 概念: Lombok能通过注解的方式,在编译时自动为类生成构造器、getter/setter、equals、hashcode、toString方法。出现的神奇就是在源码中没有getter和setter方法,但是在编译生成的字节码文件中有getter和setter方法。这样就省去了手动重建这些代码的麻烦,使代码看起来更简洁些。
- 使用过程
1.在idea中下载lombok插件
2.在项目pom.xml中添加lombok依赖
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>1.16.22version>
dependency>
3.在实体类中使用Lombok相关注解
@Data
@Setter
@Getter
@AllArgsConstructor
@NoArgsConstructor
@RequiredArgsConstructor
@Log4j
@Slf4j
@EqualsAndHashCode
@ToString
16.Thymeleaf是什么?怎么使用?
- 概念: 是一种静态页面模板,可以实现在html页面中动态加载数据,使html成为动态网页。
- 使用步骤
<dependency>
<groupId>org.thymeleafgroupId>
<artifactId>thymeleafartifactId>
<version>3.0.11.RELEASEversion>
dependency>
<dependency>
<groupId>org.thymeleafgroupId>
<artifactId>thymeleaf-spring5artifactId>
<version>3.0.11.RELEASEversion>
dependency>
- ② spring-mvc.xml文件中配置thymeleaf的解析器。
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
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/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.wpq.web"/>
<mvc:annotation-driven/>
<bean id="templateResolver" class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
<property name="prefix" value="/html/"/>
<property name="suffix" value=".html"/>
<property name="characterEncoding" value="UTF-8"/>
<property name="templateMode" value="HTML5"/>
<property name="cacheable" value="false"/>
bean>
<bean id="templateEngine" class="org.thymeleaf.spring5.SpringTemplateEngine">
<property name="templateResolver" ref="templateResolver"/>
bean>
<bean class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
<property name="characterEncoding" value="UTF-8"/>
<property name="templateEngine" ref="templateEngine"/>
bean>
beans>
- ③ 新建html,添加Thymeleaf的命名空间。
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<table>
<thead>
<td>用户名td>
<td>年龄td>
thead>
<tr th:each="user:${users}" >
<td th:text="${user.id}">td>
<td th:text="${user.name}">td>
tr>
table>
html>
- ④ 后端编写对应接口,带着数据跳转到Thymeleaf页面,html就能拿到数据。
17.Spring MVC中同时存在动态html和jsp,怎么解决视图解析器问题?
- ① 在spring-mvc.xml文件中添加 ContentNegotiatingViewResolver内容协调视图解析器,把SpringMVC默认视图解析器和Thymeleaf的视图解析器内嵌进去。
- ② 在两种视图解析器中分别设置viewNames属性:把jsp(文件夹名)或者html(文件夹名)抽取出来放在Value里面做前缀,得以区分两种视图解析器。
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
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/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.wpq.web"/>
<mvc:annotation-driven/>
<bean id="templateResolver" class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
<property name="prefix" value="/html/"/>
<property name="suffix" value=".html"/>
<property name="characterEncoding" value="UTF-8"/>
<property name="templateMode" value="HTML5"/>
<property name="cacheable" value="false"/>
bean>
<bean id="templateEngine" class="org.thymeleaf.spring5.SpringTemplateEngine">
<property name="templateResolver" ref="templateResolver"/>
bean>
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="viewResolvers">
<list>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/"/>
<property name="viewNames" value="jsp/*"/>
<property name="suffix" value=".jsp"/>
<property name="order" value="1"/>
bean>
<bean class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
<property name="characterEncoding" value="UTF-8"/>
<property name="templateEngine" ref="templateEngine"/>
<property name="viewNames" value="html/*"/>
<property name="order" value="2"/>
bean>
list>
property>
bean>
beans>
- ③ 最后在接口代码中,明确指明使用的是哪种视图解析器 如 return “jsp/1” 或者 return “html/2” ,这样就解决了两种视图解析器不能共存的问题。
18.Spring MVC全局异常处理页面怎么配置?
- 方式一: 在web.xml文件中进行错误页面的配置
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<servlet>
<servlet-name>SpringMVCservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<init-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:spring_mvc.xmlparam-value>
init-param>
<init-param>
<param-name>throwExceptionIfNoHandlerFoundparam-name>
<param-value>trueparam-value>
init-param>
<load-on-startup>1load-on-startup>
servlet>
<servlet-mapping>
<servlet-name>SpringMVCservlet-name>
<url-pattern>/url-pattern>
servlet-mapping>
<error-page>
<error-code>404error-code>
<location>/WEB-INF/jsp/404.jsplocation>
error-page>
<error-page>
<error-code>500error-code>
<location>/WEB-INF/jsp/500.jsplocation>
error-page>
web-app>
- 方式二: 新建一个全局异常处理类,在类上加上@ControllerAdvice注解,保证spring-mvc.xml中的组件扫描器可以扫描到此包。
package com.wpq.mvc.exception;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.NoHandlerFoundException;
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(value = Exception.class)
public ModelAndView handleException(Exception ex) {
ModelAndView mv = new ModelAndView();
mv.addObject("msg", ex.getMessage());
mv.setViewName("500");
return mv;
}
@ExceptionHandler(NoHandlerFoundException.class)
public String handle404Exception(NoHandlerFoundException ex, Model model) {
model.addAttribute("msg", ex.getMessage());
return "404";
}
}
19.Spring MVC中拦截器的实现过程和拦截顺序?
- ① 新建拦截器类MyInterceptor01和MyInterceptor02,让它们都实现HandlerInterceptor接口,重写preHandle,postHandle和afterCompletion方法(也可以只创建一个拦截器类),打印语句中数字代表了拦截器的执行顺序。
package com.wpq.mvc.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyInterceptor01 implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
System.out.println("1.MyInterceptor01--->preHandle()方法执行了...");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
System.out.println("5.MyInterceptor01--->postHandle()方法执行了...");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
System.out.println("7.MyInterceptor01--->afterCompletion()方法执行了...");
}
}
package com.wpq.mvc.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyInterceptor02 implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
System.out.println("2.MyInterceptor02--->preHandle()方法执行了...");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
System.out.println("4.MyInterceptor02--->postHandle()方法执行了...");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
System.out.println("6.MyInterceptor02--->afterCompletion()方法执行了...");
}
}
package com.wpq.mvc.web;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
public class IndexController {
@RequestMapping(value = "/index", method = RequestMethod.GET)
public String show() {
System.out.println("3.Controller被执行了...");
return "index";
}
}
- ② spring-mvc.xml文件中注册拦截器。
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
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/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.wpq.mvc.web"/>
<mvc:annotation-driven/>
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.wpq.mvc.interceptor.MyInterceptor01"/>
mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.wpq.mvc.interceptor.MyInterceptor02"/>
mvc:interceptor>
mvc:interceptors>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
bean>
beans>

20.ant风格资源地址支持的3种匹配符分别代表什么意思?
1 ? :匹配文件名中的一个字符
2 * :匹配文件名中的任意多个字符
3 ** :匹配多层路径
@RequestMapping("/ant/**/test")
public String ant(){
return "success";
}
21.Spring MVC怎么实现数据校验?
- Spring MVC 提供了两种数据校验的方式:1、基于 Validator 接口。2、使用 Annotation JSR - 303 标准进行校验,实际开发选择第二种方式。
- ① 使用 Annotation JSR - 303 标准进行验证,需要导入支持这种标准的依赖 jar 文件,这里我们使用 Hibernate Validator。
<dependency>
<groupId>org.hibernategroupId>
<artifactId>hibernate-validatorartifactId>
<version>5.3.6.Finalversion>
dependency>
<dependency>
<groupId>javax.validationgroupId>
<artifactId>validation-apiartifactId>
<version>2.0.1.Finalversion>
dependency>
<dependency>
<groupId>org.jboss.logginggroupId>
<artifactId>jboss-loggingartifactId>
<version>3.3.2.Finalversion>
dependency>
- ② 通过注解的方式直接在实体类中添加相关的验证规则。
package com.boot.pojo;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import javax.persistence.*;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.Date;
@Data
@Table(name = "tb_spu")
@ApiModel(value = "Spu实体对象")
public class Spu {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@ApiModelProperty(value = "Spu的id")
private Integer id;
@ApiModelProperty(value = "主题")
@NotEmpty(message = "title不能为null或长度为0")
private String title;
@ApiModelProperty(value = "sub主题")
@Length(min = 1,
max = 255,message = "标题长度不能大于255且不能小于1")
@NotNull(message = "标题不能为空")
private String subTitle;
@NotNull(message = "cid不能为空")
private Integer cid1;
private Integer cid2;
private Integer cid3;
private Integer brandId;
@ApiModelProperty(value = "上下架")
private Boolean saleable;
private Integer valid;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(hidden = true)
private Date createTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(hidden = true)
private Date lastUpdateTime;
@Transient
private String bname;
@Transient
private String cname;
}
- ③ Controller层接口形参中使用@Valid注解开启验证,配合BindingResult 使用,BindingResult用于获取验证结果。
@ResponseBody
@PostMapping("/date")
@ApiOperation(value = "测试接口",response = Spu.class,httpMethod = "POST")
public Object date(@Valid @RequestBody Spu spu , BindingResult br){
Map<String,Object> errorMap = new HashMap<>();
StringBuffer sb = new StringBuffer();
if (br.hasErrors()){
List<FieldError> errors = br.getFieldErrors();
for (FieldError error : errors) {
sb.append(error.getDefaultMessage()+";");
}
errorMap.put("error",sb);
return errorMap;
}
System.out.println("spu = " + spu);
return spu;
}
- ④ spring-mvc.xml中开启mvc注解驱动。
<mvc:annotation-driven />
- ⑤ POSTMAN中发送JSON数据到接口进行测试。

- Hibernate Validate 常用注解
注解 |
描述 |
@Null |
必须为null |
@NotNull |
不能为null |
@AssertTrue |
必须为true |
@AssertFalse |
必须为false |
@Min |
必须为数字,其值大于或等于指定的最小值 |
@Max |
必须为数字,其值小于或等于指定的最大值 |
@DecimalMin |
必须为数字,其值大于或等于指定的最小值 |
@DecimalMax |
必须为数字,其值小于或等于指定的最大值 |
@Size |
集合的长度 |
@Digits |
必须为数字,其值必须再可接受的范围内 |
@Past |
必须是过去的日期 |
@Future |
必须是将来的日期 |
@Pattern |
必须符合正则表达式 |
@Email |
必须是邮箱格式 |
@Length |
长度范围 |
@NotEmpty |
不能为null,长度大于0 |
@Range |
元素的大小范围 |
@NotBlank |
不能为null,字符串长度大于0(限字符串) |