目录
2.使用ModelAndView向request域对象共享数据
2.创建WebConfig配置类,代替SpringMVC的配置文件
一、SpringMVC简介
1.什么是MVC
MVC是一种软件架构思想,将软件按照模型、视图、控制器来划分。
M
:Model
,模型层,指工程中的JavaBean
,作用是处理数据。
JavaBean分为两类:
- 一类称为实体类Bean:专门存储业务数据的,如 Student、User 等。
- 一类称为业务处理 Bean:指
Service
或Dao
对象,专门用于处理业务逻辑和数据访问。
V
:View
,视图层,指工程中的html
或jsp
等页面,作用是与用户进行交互,展示数据。
C
:Controller
,控制层,指工程中的servlet
,作用是接收请求和响应浏览器。
MVC的工作流程:
用户通过视图层发送请求到服务器,在服务器中请求被Controller
接收,Controller
调用相应的Model
层处理请求,处理完毕将结果返回到Controller
,Controller
再根据请求处理的结果找到相应的View
视图,渲染数据后最终响应给浏览器。
2.springmvc特点
- Spring 家族原生产品,与 IOC 容器等基础设施无缝对接。
- 基于原生的Servlet,通过了功能强大的前端控制器DispatcherServlet,对请求和响应进行统一处理。
- 表述层各细分领域需要解决的问题全方位覆盖,提供全面解决方案。
- 代码清新简洁,大幅度提升开发效率。
- 内部组件化程度高,可插拔式组件即插即用,想要什么功能配置相应组件即可。
- 性能卓著,尤其适合现代大型、超大型互联网项目要求
二、环境搭建
导入依赖
<!-- SpringMVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.1</version>
</dependency>
<!-- 日志 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<!-- ServletAPI -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- Spring5和Thymeleaf整合包 -->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
<version>3.0.12.RELEASE</version>
</dependency>
<!--文件上传-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
1.配置web.xml
a>默认配置方式
此配置作用下,SpringMVC的配置文件默认位于web-inf下,默认名称为<servlet-name>-servlet.xml
<!--配置springMVC的前端控制器,对浏览器发送的请求进行统一的处理-->
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
b>扩展配置方式
<!--配置springMVC的前端控制器,对浏览器发送的请求进行统一的处理-->
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--配置springMVC配置文件的位置和名称-->
<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>SpringMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
2.创建请求控制器
用@Controller注解标识一个普通的java类
/*用@Controller注解标识为控制层组件
将其交由IoC容器管理 */
@Controller
public class TestController {
}
3.创建SpringMVC配置文件
<!-- 自动扫描包 -->
<context:component-scan base-package="com.atguigu.mvc.controller"/>
<!-- 配置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>
<!--
处理静态资源,例如html、js、css、jpg
若只设置该标签,则只能访问静态资源,其他请求则无法访问
此时必须设置<mvc:annotation-driven/>解决问题
-->
<mvc:default-servlet-handler/>
<!-- 开启mvc注解驱动 -->
<mvc:annotation-driven>
<mvc:message-converters>
<!-- 处理响应中文内容乱码 -->
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="defaultCharset" value="UTF-8" />
<property name="supportedMediaTypes">
<list>
<value>text/html</value>
<value>application/json</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
测试
@Controller
public class TestController {
//@RequestMapping处理请求和控制器方法之间的映射关系
//localhost:8080/springMVC/index
@RequestMapping("/index")
public String index() {
//设置视图名称,会被视图解析器解析
return "index";
}
}
浏览器发送请求,如果请求符合前端控制器的url-pattern,请求就会被DiapatcherServlet处理。将请求地址和控制器中@RequestMapping
注解的value
属性值进行匹配,若匹配成功,该注解所标识的控制器方法就是处理请求的方法。处理请求的方法需要返回一个字符串类型的视图名称,该视图名称会被视图解析器解析,加上前缀和后缀组成视图的路径,通过Thymeleaf
对视图进行渲染,最终转发到视图所对应页面
三、@RequestMapping注解
1.@RequestMapping注解的功能
将请求和处理请求的控制器方法关联起来,建立映射关系
2.@RequestMapping注解的位置
标识一个类:设置映射请求的请求路径的初始信息
标识一个方法:设置映射请求请求路径的具体信息
如:
@Controller
@RequestMapping("/test")
public class TestController {
@RequestMapping("/index")
public String index() {
return "index";
}
}
此时请求路径为/test/index
3.@RequestMapping注解的属性
(a)value属性
是一个字符串数组,可以匹配多个请求地址所对应的请求
@RequestMapping(value = {"/index", "/hello"})
public String index() {
return "index";
}
(b)method属性:根据get或post匹配请求映射(不设置则任何请求都能匹配)
@RequestMapping(value = {"/a","/b"},method = {RequestMethod.GET,RequestMethod.POST})
可以@GetMapping @PostMapping等注解指定请求方式
@GetMapping("/test")
public String testGet() {
return "target";
}
(c)params属性
"param":要求请求映射所匹配的请求必须携带param请求参数
"!param":要求请求映射所匹配的请求必须不能携带param请求参数
"param=value":要求请求映射所匹配的请求必须携带param请求参数且param=value
"param!=value":要求请求映射所匹配的请求必须携带param请求参数但是param!=value
@RequestMapping(
value = "/index"
,params = {"username","password!=123456"})
//请求参数要有username password不能等于123456
public String index() {
return "index";
}
(d)headers属性
"header":要求请求映射所匹配的请求必须携带header请求头信息
"!header":要求请求映射所匹配的请求必须不能携带header请求头信息
"header=value":要求请求映射所匹配的请求必须携带header请求头信息且header=value
"header!=value":要求请求映射所匹配的请求必须携带header请求头信息且header!=value
4.SpringMVC支持ant风路径
针对@RequestMapping的value属性进行模糊匹配
?: 标识任意的单个字符
* :表示任意的0个或多个字符
/** : 表示任意的一层或多层目录
注意:在使用/**时,只能使用/**/xxx的方式,若写成/a**/,**会被当成两个单独的*被解析
@RequestMapping("/a?a/testAnt")
public String testAnt() {
return "target";
}
5.SpringMVC支持路径中的占位符
原始方式:/deleteUser?id=1
rest方式:/deleteUser/1
//将占位符{id} 中的值自动赋值给形参
@RequestMapping("/testPath/{id}")
public String testPath(@PathVariable("id")Integer id) {
return "target";
}
@RequestMapping("/testPath/{id}/{username}")
public String testPath(@PathVariable("id")Integer id, @PathVariable("username")String username) {
return "target";
}
四、SpringMVC获取请求参数
1.通过servletAPI获取
(不推荐使用)
@RequestMapping("/testServletAPI")
//根据形参类型自动赋值
public String testServletApi(HttpServletRequest request) {
String str = request.getParameter("a");
return "target";
}
2.通过控制器方法的形参获取请求参数
@RequestMapping("testParam")
//只要保证形参中的参数名和请求参数的名字保持一致,就可以自动进行赋值
public String testParam(String username,String password) {
System.out.println(username + " " + password);
return "target";
}
//如果有多个同名的请求参数,可以直接用字符串进行获取,参数会用逗号拼接起来
//也可以用字符串数组进行获取
3.@RequestParam
前端请求的名字如果和后端不一样,可以用@RequestParam注解配置前端请求参数与形参的映射
@RequestMapping("testParam")
//只要保证形参中的参数名和请求参数的名字保持一致,就可以自动进行赋值
public String testParam(@RequestParam("name") String username, String password) {
System.out.println(username + " " + password);
return "target";
}
有value required defaultValue三个属性
value:指定为形参赋值的请求参数的参数名
required 设置为true表示需要有这个请求参数,默认值为true
defaultValue 当请求参数没有传输时,使用默认值为形参(不管required为true还是false)
4.@RequestHeader
将请求头信息与形参创建映射关系
public void testHeader(@RequestHeader(value = "Host",required = true,defaultValue = "Host") String host) {
System.out.println(host);
}
5.@CookieValue
将cookie数据和控制器的形参创建映射关系
也有value required deaultValue三个属性
6.通过POJO获取请求参数
@RequestMapping("/testBean")
//User内部要提供set方法
//如果浏览器请求参数名与User属性名一致,就会自动为属性赋值
public String testBean(User user) {
System.out.println(user);
return "target";
}
7.解决获取请求参数的乱码问题
在web.xml中
<!--配置解决乱码的过滤器-->
<filter>
<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>
<!--设置相应的编码-->
<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>
五、域对象共享数据
1.使用servletAPI向request域对象共享数据
@RequestMapping("/testServletAPI")
public String testServletAPI(HttpServletRequest request) {
request.setAttribute("name","Jack");
return "target";
}
2.使用ModelAndView向request域对象共享数据
@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView() {
ModelAndView modelAndView = new ModelAndView();
//向请求与request共享数据
modelAndView.addObject("name","Jack");
//设置视图
modelAndView.setViewName("success");
return modelAndView;
}
3.使用Model向request域对象共享数据
@RequestMapping("/testModel")
public String testModel(Model model) {
model.addAttribute("name", "Jack");
return "success";
}
4.使用map向request域对象共享数据
@RequestMapping("/testMap")
public String testMap(Map<String,Object> map) {
map.put("name","Mike");
return "success";
}
5.使用ModelMap向request域对象共享数据
@RequestMapping("/testModelMap")
public String testModelMap(ModelMap modelMap) {
modelMap.addAttribute("name","Jack");
return "success";
}
Model、ModelMap、Map类型的参数本质上都是BindingAwareModelMap类型的
6.向session域共享数据
(建议使用servletAPI)
@RequestMapping("/testSession")
public String testSession(HttpSession session) {
session.setAttribute("name","Jack");
return "success";
}
<!--thymeleaf获取session域数据-->
<p th:text="${session.name}"></p>
7.向Application域共享数据
@RequestMapping("/testApplication")
public String testApplication(HttpSession session) {
ServletContext application = session.getServletContext();
application.setAttribute("name","Jack");
return "success";
}
<!--thymeleaf获取application域数据-->
<p th:text="${application.name}"></p>
六、SpringMVC的视图
SpringMVC中的视图是View
接口,视图的作用渲染数据,将模型Model
中的数据展示给用户
SpringMVC视图的种类很多,默认有转发视图InternalResourceView
和重定向视图RedirectView
当工程引入jstl
的依赖(解决jsp中嵌入java代码的繁琐),转发视图会自动转换为JstlView
。
若使用的视图技术为Thymeleaf
,在SpringMVC的配置文件中配置了Thymeleaf的视图解析器,由此视图解析器解析之后所得到的是ThymeleafView。
1.ThymeleafView
当控制器方法返回的视图名称没有任何前缀时,此时视图名称会被spirngMVC配置的(thymeleaf)视图解析器解析,视图名称拼接视图前缀和视图后缀,并通过转发进行跳转
2.转发视图
当控制器方法中所设置的视图名称以“forward: ”为前缀时,创建InternalResourceView视图,此时视图名称不会被springMVC配置文件中所配置的thymeleaf视图解析器解析,而是会将前缀去掉,剩余部分作为最终路径通过转发的方式实现跳转
@RequestMapping("/index")
public String index() {
return "success";
}
@RequestMapping("/testForward")
public String testForward() {
//将index作为最终路径,通过转发进行跳转
//这里会转发到上面那个index中
return "forward:index";
}
3.重定向视图
@RequestMapping("/testRedirect")
public String testRedirect() {
//重定向
return "redirect:index";
}
4.视图控制器view-controller
在控制器方法中没有任何处理过程,仅仅用来跳转,只需要设置一个视图名称,可以将处理器方法使用view-controller标签进行表示
<!--
在springMVC配置文件中
path:请求路径 view-name:视图名称
-->
<mvc:view-controller path="/testView" view-name="success"></mvc:view-controller>
view-name中的视图名称会被thymeleaf视图解析器解析
当SpringMVC中设置任何一个view-controller时,其他控制器中的请求映射将全部失效,此时需要在SpringMVC的核心配置文件中设置开启mvc注解驱动的标签
<!--开启mvc的注解驱动-->
<mvc:annotation-driven/>
七、HttpServletConverter
报文信息转换器,将请求报文转换为java对象,或将java对象转换为相应报文
提供了两个注解和两个类型@RequestBody,@ResponseBody,RequestEntity,
ResponseEntity
1.@RequestBody
可以获取请求体,需要在控制器方法设置一个形参,使用@RequestBody进行标识,当前请求的请求体就会为标识的形参进行赋值
@RequestMapping("/testRequestBody")
public String testRequestBody(@RequestBody String requestBody) {
System.out.println(requestBody);
return "success";
}
2.RequestEntity
是封装请求报文的一种类型,需要在控制器方法的形参中设置该类型的形参
@RequestMapping("/testRequestEntity")
public String testRequestEntity(RequestEntity<String>requestEntity) {
System.out.println(requestEntity.getHeaders());
System.out.println(requestEntity.getBody());
return "success";
}
3.ResponseBody
用于标识一个控制器方法,可以将该方法的返回值直接作为响应报文的响应体响应到浏览器
@RequestMapping("/testResponseBody")
@ResponseBody
public String testResponseBody() {
return "I'm Jack";
}
结果
4.springmvc处理json
a>导入jackson依赖
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.2</version>
</dependency>
b>在springmvc的核心配置文件中开启mvc注解驱动
<mvc:annotation-driven />
此时在HanlderAdaptor中会自动装配一个消息转器:MappingJackson2HttpMessageConverter, 可以将相应到浏览器的java对象转换为Json格式的字符串
c>在处理器方法上使用@ResponseBody注解进行标识
d>将Java对象直接作为控制器的返回值返回,就会自动转换为Json格式的字符串
@RequestMapping("/testResponseUser")
@ResponseBody
public User testResponseUser() {
return new User("1","男",12,"Jack","1234");
}
结果
5.@RestController注解
是SpringMVC提供的一个复合注解,标识在控制器的类上,就相当于为类添加了@Controller注解,并为其中的每个方法添加了@ResponseBody注解
6.ResponseEntity
用于控制器方法的返回值类型,该控制器方法的返回值就是响应到浏览器的响应报文
例:下面的文件下载
八、文件上传和下载
1.文件下载
利用ResponseEntity实现文件的下载
@RequestMapping("/testDown")
public ResponseEntity<byte[]> testResponseEntity(HttpSession session) throws IOException {
//获取ServletContext对象
ServletContext servletContext = session.getServletContext();
//获取服务器中文件的真实路径
String realPath = servletContext.getRealPath("/static/img/1.jpg");
//创建输入流
InputStream is = new FileInputStream(realPath);
//创建字节数组
byte[] bytes = new byte[is.available()];
//将流读到字节数组中
is.read(bytes);
//创建HttpHeaders对象设置响应头信息
MultiValueMap<String, String> headers = new HttpHeaders();
//设置要下载方式以及下载文件的名字
headers.add("Content-Disposition", "attachment;filename=1.jpg");
//设置响应状态码
HttpStatus statusCode = HttpStatus.OK;
//创建ResponseEntity对象
ResponseEntity<byte[]> responseEntity = new ResponseEntity(bytes, headers, statusCode);
//关闭输入流
is.close();
return responseEntity;
}
2.文件上传
添加依赖
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
配置SpringMVC文件上传解析器
<!--配置文件上传解析器,将上传文件封装为MultipartFile-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean>
以post方式提交,并添加属性enctype="multipart/form-data"
<!--测试上传-->
<form th:action="@{/testUp}" method="post" enctype="multipart/form-data">
头像:<input type="file" name="photo">
<input type="submit" value="上传">
</form>
SpringMVC将form表单上传的文件封装到MultipartFile对象中,通过此对象可以获取文件相关信息
@RequestMapping("/testUp")
public String testUp(MultipartFile photo, HttpSession session) throws IOException {
//获取文件名
String filename = photo.getOriginalFilename();
//防止文件名重复
//获取文件后缀名
String suffixName = filename.substring(filename.lastIndexOf("."));
//将UUID作为文件名
String uuid = UUID.randomUUID().toString();
filename = uuid + suffixName;
//获取服务器中photo目录的路径
ServletContext servletContext = session.getServletContext();
String photoPath = servletContext.getRealPath("photo");
File file = new File(photoPath);
if (!file.exists()){
//如果文件夹不存在,创建文件夹
file.mkdir();
}
String finalPath = photoPath + File.separator + filename;
photo.transferTo(new File(finalPath));
return "success";
}
九、拦截器
拦截器属于SpringMVC框架,只有使用了SpringMVC框架的工程才能使用
1.拦截器的配置
SpringMVC中的拦截器用于拦截控制器方法的执行
SpringMVC中的拦截器需要实现HandlerInterceptor
SpringMVC的拦截器必须在SpringMVC的配置文件中进行配置:
<!--在SpringMVC配置文件中配置拦截器-->
<mvc:interceptors>
<!--用这种方式配置会拦截所有的请求-->
<bean class="com.cc.mvc.interceptors.FirstInterceptor"></bean>
</mvc:interceptors>
另一种配置拦截器的方式(这种方式也会拦截所有请求)
<mvc:interceptors>
<!--拦截器要用@Component标识-->
<ref bean="firstInterceptor"></ref>
</mvc:interceptors>
通过下面这种方式可以指定拦截哪些请求
<mvc:interceptors>
<mvc:interceptor>
<!--拦截指定路径的请求-->
<mvc:mapping path="/*"/>
<!--设置需要排除的请求,指定请求不经过拦截器-->
<mvc:exclude-mapping path="/"/>
<!--设置拦截器,可以用ref或bean标签设置-->
<ref bean="firstInterceptor"></ref>
</mvc:interceptor>
</mvc:interceptors>
2.拦截器的三个抽象方法
preHandle()
:控制器方法执行之前执行,返回值表示是否拦截,返回true
放行,返回false
拦截
postHandle()
:控制器方法执行之后执行postHandle()
。
afterComplation()
:处理完视图和模型数据,渲染视图完毕之后执行afterComplation()
//实现HandlerInterceptor接口
public class FirstInterceptor implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle");
//返回false拦截请求,返回true放行
return false;
}
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
3.多个拦截器执行顺序
a>若每个拦截器的proHandle()都返回true,此时多个拦截器的执行顺序和拦截器在SpringMVC的配置文件的配置顺序有关:preHanlde()按照配置顺序执行,postHandle()和afterCompletion()会按照配置的反序执行
b>若某个拦截器的proHandle()返回了false,preHandle()返回false和它之前的拦截器的preHandle()都会执行,postHandle()都不执行,返回false的拦截器之前的拦截器的afterCompletion()会执行
十、SpringMVC的异常处理
1.基于配置的异常处理
SpringMVC提供了一个处理控制器方法执行过程中所出现的异常的接口:HandlerExceptionResolver
HandlerExceptionResolver接口的实现类有:DefaultHandlerExceptionResolver和SimpleMappingExceptionResolver
SpringMVC提供了自定义的异常处理器SimpleMappingExceptionResolver
基于配置的异常处理
<!--基于配置的异常处理-->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<!--key放全类名 这里的error会被视图解析器解析,然后跳转到对应的页面-->
<prop key="java.lang.ArithmeticException">error</prop>
</props>
</property>
<!--exceptionAttribute属性设置一个属性名,将出现的异常信息在请求域中共享-->
<property name="exceptionAttribute" value="ex"></property>
</bean>
2.基于注解的异常处理
@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
使用配置类和注解代替web.xml和SpringMVC配置文件的功能
1.创建初始化类,代替web.xml
在Servlet3.0环境中,容器会在类路径中查找实现javax.servlet.ServletContainerInitializer接口的类,如果找到的话就用它来配置Servlet容器。 Spring提供了这个接口的实现,名为SpringServletContainerInitializer,这个类反过来又会查找实现WebApplicationInitializer的类并将配置的任务交给它们来完成。Spring3.2引入了一个便利的WebApplicationInitializer基础实现,名为AbstractAnnotationConfigDispatcherServletInitializer,当我们的类扩展了AbstractAnnotationConfigDispatcherServletInitializer并将其部署到Servlet3.0容器的时候,容器会自动发现它,并用它来配置Servlet上下文。
//web工程的初始化类,用来代替web.xml
//需要继承AbstractAnnotationConfigDispatcherServletInitializer
public class WebInit extends AbstractAnnotationConfigDispatcherServletInitializer {
//指定spring的配置类
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
//指定SpringMVC的配置类
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{WebConfig.class};
}
//指定DispatcherServlet的映射规则 即url-pattern
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
//添加过滤器
@Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
characterEncodingFilter.setEncoding("UTF-8");
characterEncodingFilter.setForceEncoding(true);
HiddenHttpMethodFilter hiddenHttpMethodFilter = new HiddenHttpMethodFilter();
return new Filter[]{characterEncodingFilter,hiddenHttpMethodFilter};
}
}
2.创建WebConfig配置类,代替SpringMVC的配置文件
/* 代替SpringMVC的配置文件
1、扫描组件 2、视图解析器 3、view-controller
4、default-servlet-handler 5、mvc注解驱动
6、文件上传解析器 7、异常处理 8、拦截器 */
//将当前类表示为一个配置类
@Configuration
//扫描组件
@ComponentScan("com.cc.mvc.controller")
//mvc注解驱动
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
//default-servlet-handler
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
//添加拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
//创建一个拦截器
TestInterceptor testInterceptor = new TestInterceptor();
//添加拦截器 设置要拦截的请求路径
registry.addInterceptor(testInterceptor).addPathPatterns("/**").excludePathPatterns("/");
}
//配置视图控制
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
}
//文件上传解析器
public MultipartResolver multipartResolver() {
CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver();
return commonsMultipartResolver;
}
//异常处理
@Override
public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
SimpleMappingExceptionResolver exceptionResolver = new SimpleMappingExceptionResolver();
Properties prop = new Properties();
prop.setProperty("java.lang.ArithmeticException", "error");
exceptionResolver.setExceptionMappings(prop);
//设置在请求域中共享数据的键值,通过键获取异常信息
exceptionResolver.setExceptionAttribute("exception");
resolvers.add(exceptionResolver);
}
//--thymeleaf视图解析器(下面三个)
//配置生成模板解析器
@Bean
public ITemplateResolver templateResolver() {
WebApplicationContext webApplicationContext = ContextLoader.getCurrentWebApplicationContext();
// ServletContextTemplateResolver需要一个ServletContext作为构造参数,可通过WebApplicationContext 的方法获得
ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver(
webApplicationContext.getServletContext());
templateResolver.setPrefix("/WEB-INF/templates/");
templateResolver.setSuffix(".html");
templateResolver.setCharacterEncoding("UTF-8");
templateResolver.setTemplateMode(TemplateMode.HTML);
return templateResolver;
}
//生成模板引擎并为模板引擎注入模板解析器
@Bean
public SpringTemplateEngine templateEngine(ITemplateResolver templateResolver) {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver);
return templateEngine;
}
//生成视图解析器并未解析器注入模板引擎
@Bean
public ViewResolver viewResolver(SpringTemplateEngine templateEngine) {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setCharacterEncoding("UTF-8");
viewResolver.setTemplateEngine(templateEngine);
return viewResolver;
}
}