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.core</ groupId>
< artifactId> jackson-core</ artifactId>
< version> 2.9.6</ version>
</ dependency>
< dependency>
< groupId> com.fasterxml.jackson.core</ groupId>
< artifactId> jackson-databind</ artifactId>
< version> 2.9.6</ version>
</ dependency>
< dependency>
< groupId> com.fasterxml.jackson.core</ groupId>
< artifactId> jackson-annotations</ artifactId>
< version> 2.9.6</ version>
</ 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 ( 1 L) ;
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<String,Object> 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> encodingFilter</ 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>
</ filter>
< filter-mapping>
< filter-name> encodingFilter</ filter-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.springframework</ groupId>
< artifactId> spring-webmvc</ artifactId>
< version> 5.0.11.RELEASE</ version>
</ dependency>
② 在src/main目录下新建java文件夹和resources文件夹并且右键Mark为相对应的文件类型。 ③ 配置 webapp/WEB-INF下的web.xml文件。
<?xml version="1.0" encoding="UTF-8"?>
< 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.html</ welcome-file>
< welcome-file> index.jsp</ welcome-file>
< welcome-file> /WEB-INF/jsp/index.jsp</ welcome-file>
</ welcome-file-list>
< servlet>
< servlet-name> dispatcherServlet</ servlet-name>
< servlet-class> org.springframework.web.servlet.DispatcherServlet</ servlet-class>
< init-param>
< param-name> contextConfigLocation</ param-name>
< param-value> classpath:spring-mvc.xml</ param-value>
</ init-param>
< load-on-startup> 1</ load-on-startup>
</ servlet>
< servlet-mapping>
< servlet-name> dispatcherServlet</ servlet-name>
< url-pattern> /</ url-pattern>
</ servlet-mapping>
</ web-app>
④ 在src/main/resources目录下新建spring-mvc.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"
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通用多媒体文件解析器。
<?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: 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.projectlombok</ groupId>
< artifactId> lombok</ artifactId>
< version> 1.16.22</ version>
</ dependency>
3.在实体类中使用Lombok相关注解
@Data
@Setter
@Getter
@AllArgsConstructor
@NoArgsConstructor
@RequiredArgsConstructor
@Log4j
@Slf4j
@EqualsAndHashCode
@ToString
16.Thymeleaf是什么?怎么使用?
概念: 是一种静态页面模板,可以实现在html页面中动态加载数据,使html成为动态网页。使用步骤
< dependency>
< groupId> org.thymeleaf</ groupId>
< artifactId> thymeleaf</ artifactId>
< version> 3.0.11.RELEASE</ version>
</ dependency>
< dependency>
< groupId> org.thymeleaf</ groupId>
< artifactId> thymeleaf-spring5</ artifactId>
< version> 3.0.11.RELEASE</ version>
</ dependency>
② spring-mvc.xml文件中配置thymeleaf的解析器。
<?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: 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里面做前缀,得以区分两种视图解析器。
<?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: 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文件中进行错误页面的配置
<?xml version="1.0" encoding="UTF-8"?>
< 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> SpringMVC</ servlet-name>
< servlet-class> org.springframework.web.servlet.DispatcherServlet</ servlet-class>
< init-param>
< param-name> contextConfigLocation</ param-name>
< param-value> classpath:spring_mvc.xml</ param-value>
</ init-param>
< init-param>
< param-name> throwExceptionIfNoHandlerFound</ param-name>
< param-value> true</ param-value>
</ init-param>
< load-on-startup> 1</ load-on-startup>
</ servlet>
< servlet-mapping>
< servlet-name> SpringMVC</ servlet-name>
< url-pattern> /</ url-pattern>
</ servlet-mapping>
< error-page>
< error-code> 404</ error-code>
< location> /WEB-INF/jsp/404.jsp</ location>
</ error-page>
< error-page>
< error-code> 500</ error-code>
< location> /WEB-INF/jsp/500.jsp</ location>
</ 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文件中注册拦截器。
<?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: 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.hibernate</ groupId>
< artifactId> hibernate-validator</ artifactId>
< version> 5.3.6.Final</ version>
</ dependency>
< dependency>
< groupId> javax.validation</ groupId>
< artifactId> validation-api</ artifactId>
< version> 2.0.1.Final</ version>
</ dependency>
< dependency>
< groupId> org.jboss.logging</ groupId>
< artifactId> jboss-logging</ artifactId>
< version> 3.3.2.Final</ version>
</ 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(限字符串)
22.springmvc请求参数转自动换成枚举