视图解析
1. 视图解析
- 视图是View接口,视图的作用渲染数据,将模型Model中的数据展示给用户
- 默认有转发视图(InternalResourceView)和重定向视图(RedirectView)
- 当工程引入jstl的依赖,转发视图会自动转换为JstlView
- 视图技术为Thymeleaf,视图解析器解析之后所得到的是ThymeleafView
2. 转发视图
- 视图名称以"forward:"为前缀时,创建InternalResourceView视图
- 将前缀"forward:"去掉,剩余部分作为最终路径通过转发的方式实现跳转
@RequestMapping("/testForward")
public String testForward(){
return "forward:/testHello";
}
3. 重定向视图
- 视图名称以"redirect:"为前缀时,创建RedirectView视图
- 将前缀"redirect:"去掉,剩余部分作为最终路径通过重定向的方式实现跳转
- 将redirect:前缀去掉后,会判断剩余部分是否以/开头,若是则会自动拼接上下文路径
@RequestMapping("/testRedirect")
public String testRedirect(){
return "redirect:/testHello";
}
4. 视图控制器view-controller
- 仅仅用来实现页面跳转,只需要设置视图名称
<!--
path:设置处理的请求地址
view-name:设置请求地址所对应的视图名称
-->
<mvc:view-controller path="/testView" view-name="success">
</mvc:view-controller>
- 设置任何一个view-controller时,其他控制器中的请求映射将全部失效,此时需要在SpringMVC的核心配置文件中设置开启mvc注解驱动
<mvc:annotation-driven />
5. JSTL
- 若项目中使用了JSTL,则SpringMVC会自动把视图由InternalResourceView 转为JstlView
- 若使用JSTL的fmt标签则需要在SpringMVC的配置文件中配置国际化资源文件
<!-- 配置国际化资源文件 -->
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="i18n"></property>
</bean>
文件下载
@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;
}
文件上传
1. 添加依赖
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
2. SpringMVC的配置文件中添加配置
<!--必须通过文件解析器的解析才能将文件转换为MultipartFile对象-->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
</bean>
3. form表单的请求方式必须为post,并且添加属性enctype="multipart/form-data"
4. 控制器方法
@RequestMapping("/testUp")
public String testUp(MultipartFile photo, HttpSession session)
throws IOException {
//获取上传的文件的文件名
String fileName = photo.getOriginalFilename();
//处理文件重名问题
String hzName = fileName.substring(fileName.lastIndexOf("."));
fileName = UUID.randomUUID().toString() + hzName;
//获取服务器中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";
}
拦截器
1. 拦截器的配置
- 自定义拦截器需要实现HandlerInterceptor
- SpringMVC的配置文件中进行配置
<bean class="com.atguigu.interceptor.FirstInterceptor"></bean>
<ref bean="firstInterceptor"></ref>
<!-- 以上两种配置方式都是对DispatcherServlet所处理的所有的请求进行拦截 -->
<mvc:interceptor>
<!--
通过mvc:mapping设置需要拦截的请求
通过mvc:exclude-mapping设置需要排除的请求,即不需要拦截的请求
-->
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/testRequestEntity"/>
<ref bean="firstInterceptor"></ref>
</mvc:interceptor>
2. 拦截器的三个抽象方法
- preHandle:控制器方法执行之前执行preHandle(),其boolean类型的返回值表示是否拦截或放行,返回true为放行,即调用控制器方法;返回false表示拦截,即不调用控制器方法
- postHandle:控制器方法执行之后执行postHandle()
- afterComplation:处理完视图和模型数据,渲染视图完毕之后执行afterComplation()
3. 多个拦截器的执行顺序
- 若每个拦截器的preHandle()都返回true,preHandle()会按照配置的顺序执行,而postHandle()和afterComplation()会按照配置的反序执行
- 若某个拦截器的preHandle()返回了false,preHandle()返回false和它之前的拦截器的preHandle()都会执行,postHandle()都不执行,返回false的拦截器之前的拦截器的afterComplation()会执行
异常处理器
1. 基于配置的异常处理
- SpringMVC提供了一个处理控制器方法执行过程中所出现的异常的接口:HandlerExceptionResolver
- 接口的实现类有:DefaultHandlerExceptionResolver和SimpleMappingExceptionResolver
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<!--
键key表示处理器方法执行过程中出现的异常
值表示若出现指定异常时,设置一个新的视图名称,跳转到指定页面
-->
<prop key="java.lang.ArithmeticException">error</prop>
</props>
</property>
<!--
exceptionAttribute属性设置一个属性名,将出现的异常信息在请求域中进行共享
-->
<property name="exceptionAttribute" value="ex"></property>
</bean>
2. 基于注解的异常处理
//@ControllerAdvice将当前类标识为异常处理的组件
@ControllerAdvice
public class ExceptionController {
//@ExceptionHandler用于设置所标识方法处理的异常
@ExceptionHandler(ArithmeticException.class)
//ex表示当前请求处理中出现的异常对象
public String handleArithmeticException(Exception ex, Model model){
model.addAttribute("ex", ex);
return "error";
}
}