1、MultipartFile :文件上传
2、使用@ResponseBody将返回的数据转成json
@JsonFormat修改时间在json中的格式
3、使用@RequestBody接收请求体数据
4、使用HttpEntity参数获取请求头和请求体
5、使用ResponseEntity返回值操作响应头和响应体:下载文件
6、HandlerInterceptor拦截器
7、异常处理
1、文件上传
文件上传在SpringMVC中如何实现:
1、准备一个文件上传的表单
2、导入文件上传需要的jar包
commons-fileupload-1.2.1.jar、
commons-io-1.4.jar
3、配置文件上传解析器: CommonsMultipartResolver
4、配置Controller控制器的代码
1.1、准备一个文件上传的表单
<body>
<form action="${ pageContext.request.contextPath }/upload"
method="post" enctype="multipart/form-data">
用户名:<input type="text" name="username"/><br/>
头像:<input type="file" name="photo"/><br/>
<input type="submit" />
</form>
</body>
1.2、导入文件上传需要的jar包
commons-fileupload-1.2.1.jar
commons-io-1.4.jar
commons-logging-1.1.3.jar
log4j-1.2.17.jar
spring-aop-4.0.0.RELEASE.jar
spring-beans-4.0.0.RELEASE.jar
spring-context-4.0.0.RELEASE.jar
spring-core-4.0.0.RELEASE.jar
spring-expression-4.0.0.RELEASE.jar
spring-web-4.0.0.RELEASE.jar
spring-webmvc-4.0.0.RELEASE.jar
1.3、配置文件上传解析器
<!-- 配置在SpringMVC中解决文件上传的协议的解析器
id 必须是multipartResolver
-->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 配置字符集为UTF-8 -->
<property name="defaultEncoding" value="UTF-8" />
</bean>
1.4、编写文件上传的Controller控制器中的代码:
单个文件上传:
@RequestMapping("/upload")
public String upload(String username, MultipartFile photo) {
System.out.println("名字" + username);
try {
if (!photo.isEmpty() && photo != null) {
// 第二个\是转义第一个\
// photo.transferTo(new File("e:\\" +
// photo.getOriginalFilename()));
// 正常的是访问磁盘路径
photo.transferTo(new File("e://" + photo.getOriginalFilename()));
}
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "/index.jsp";
}
多个文件上传:
@RequestMapping(value = "/upload")
public String upload(String username,
@RequestParam(value = "photo") MultipartFile[] photo) {
System.out.println("用户名:" + username);
for (MultipartFile multipartFile : photo) {
// 说明有上传的内容
// isEmpty判断是否为空
if (multipartFile != null && !multipartFile.isEmpty()) {
try {
// transferTo 将文件写入到硬盘位置
// getOriginalFilenameaqb
multipartFile.transferTo(new File("e:\\"
+ multipartFile.getOriginalFilename()));
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return "forward:/index.jsp";
}
springmc的文件上传就两点:
参数:MultipartFile photo
方法:photo.transferTo(new File("e:\\" + photo.getOriginalFilename()));
2、使用@ResponseBody将返回的数据转成json(***重点***)
2.1、使用的步骤如下:
1、导入json相关的包到web工程中
jackson-annotations-2.1.5.jar
jackson-core-2.1.5.jar
jackson-databind-2.1.5.jar
2、编写一个请求的方式接收请求,并返回数据对象
3、在方法上添加注解@ResponseBody自动将返回值json化
2.2、Controller中的代码:
@ResponseBody
@RequestMapping(value = "/queryPersonById")
public Person queryPersonById() {
return new Person(19, "name10", new Date(), "wzg186@qq.com",
new BigDecimal(100));
}
@ResponseBody
@RequestMapping(value = "/personList")
public List<Person> personList() {
List<Person> list = new ArrayList<Person>();
for (int i = 0; i < 10; i++) {
list.add(new Person(i, "name" + i, new Date(), "wzg186@qq.com",
new BigDecimal(100)));
}
return list;
}
从上面可以看出:控制器也可以返回对象类型
2.3、打开浏览器测试如下:
![](https://i-blog.csdnimg.cn/blog_migrate/167cc5994a4ddb7157166af7102f5245.png)
2.4、使用@JsonFormat修改时间在json中的格式
(1)、可以直接用在属性上
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date birthDate;
或
(2)、也可以直接用在getter()方法上
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
public Date getBirthDate() {
return birthDate;
}
@JsonFormat表示设置json转换格式。
pattern="yyyy-MM-dd HH:mm:ss"表示日期类型返回以 yyyy-MM-dd HH:mm:ss 格式yyyy-MM-dd表示年月日,HH:mm:ss表示时分秒
timezone = "GMT+8"表示时间为格林时间+8小时
3、使用@RequestBody接收请求体数据
在HTTP协议中,我们知道,请求体只存在于POST请求中才有。所以我们需要有一个表单。而且请求必须是post请求。
3.1、准备一个post请求的表单
post请求,默认的请求参数都会以name=value&name=value的形式进行拼接,然后发送给服务器。
<form action="${pageContext.request.contextPath }/requestBody" method="post">
用户名:<input type="text" name="username" /><br/>
密码:<input type="password" name="password" /><br/>
<input type="submit" />
</form>
3.2、在Controller中添加一个方法接收请求体
/**
* GET请求
* 1、请求行
* 2、请求头
* POST请求
* 1、请求行
* 2、请求头
* 空行
* 3、请求体(请求的参数)
*/
// @RequestBody 它可以接收请求体的数据---请求体,只存在于post请求
@RequestMapping(value = "/requestBody")
public String requestBody(@RequestBody String body) {
System.out.println("请求体的全部内容:" + body);
return "forward:/index.jsp";
}
4、使用HttpEntity参数获取请求头和请求体
页面代码:
<!-- post请求,默认的请求参数都会以name=value&name=value的形式进行拼接,然后发送给服务器。 -->
<form action="${pageContext.request.contextPath }/httpEntity" method="post">
用户名:<input type="text" name="username" /><br/>
密码:<input type="password" name="password" /><br/>
<input type="submit" />
</form>
Controller代码:
@RequestMapping(value = "/httpEntity")
public String httpEntity(HttpEntity<String> httpEntity) {
System.out.println("请求头:" + httpEntity.getHeaders());
System.out.println("请求体:" + httpEntity.getBody());
return "forward:/index.jsp";
}
5、使用ResponseEntity返回值操作响应头和响应体:下载文件
@RequestMapping(value = "/download")
public ResponseEntity<byte[]> download(HttpSession session) {
try {
ServletContext ctx = session.getServletContext();
// 斜杠(斜线)表示到http://ip:port/工程名/ 映射到代码的WebContent目录
InputStream is = ctx.getResourceAsStream("/imgs/e.jpg");
byte[] buffer;
buffer = new byte[is.available()];
//读文件数据
is.read(buffer);
is.close();
//获取需要下载的文件的数据类型
String mimeType = ctx.getMimeType("/imgs/e.jpg");
// 响应头
HttpHeaders httpHeaders = new HttpHeaders();
// 添加响应头,告诉客户端我回去的数据类型是什么
httpHeaders.add("Content-Type", mimeType);
httpHeaders.add("Content-Disposition", "attachment; filename=e.jpg");
// 第一个参数是你要返回的数据--我们要实现文件下载,就需要把下载的文件字节内容都放body中
// 第二个参数是 响应头
// 第三个参数是你要返回的响应状态码和响应 状态描述 符
ResponseEntity<byte[]> responseEntity = new ResponseEntity<byte[]>(
buffer, httpHeaders, HttpStatus.OK);
return responseEntity;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
6、HandlerInterceptor拦截器
6.1、HandlerInterceptor拦截器的介绍
拦截器,可以拦截Controller控制方法
6.2、单个HandlerInterceptor拦截器的示例
1、编写一个类去实现HandlerInterceptor接口
2、到Spring的容器配置文件中去配置拦截器,让SpringMVC知道都拦截哪些目标方法
拦截器类实现代码:
public class FirstHandlerInterceptor implements HandlerInterceptor {
/**
* 在拦截到目标方法前调用
*/
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
System.out.println("FirstHandlerInterceptor -- >>> preHandle" );
//return false不放行
//return true放行
return true;
}
/**
* 在目标方法执行之后执行。
*/
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("FirstHandlerInterceptor -- >>> postHandle" );
}
/**
* 在目标方法执行完。跳转页面渲染完之后
*/
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("FirstHandlerInterceptor -- >>> afterCompletion" );
}
}
配置拦截的地址:
<!-- 配置多个拦截器标签mvc:interceptors -->
<mvc:interceptors>
<!-- 配置一个拦截器标签mvc:interceptor -->
<mvc:interceptor>
<!-- 拦截的地址 -->
<mvc:mapping path="/hello"/>
<!-- 拦截器具体实现类 -->
<bean class="com.tcent.controller.FirstHandlerInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
用FirstHandlerInterceptor类中去拦截hello方法
正常情况下,拦截器的执行顺序:
FirstHandlerInterceptor -- >>> preHandle
目标方法执行…………
FirstHandlerInterceptor -- >>> postHandle
页面渲染的代码
FirstHandlerInterceptor -- >>> afterCompletion
6.3、单个拦截器异常时的执行顺序
一:目标方法前返回false的情况:
1、目标方法前执行 返回false
2、这是目标方法不执行
3、目标方法之后不执行
4、这是渲染页面不执行
5、页面渲染完成!不执行
二:目标方法前返回true的情况,目标方法异常
1、目标方法前执行 返回true
2、这是目标方法异常
3、目标方法之后不执行
4、这是渲染页面渲染异常页面
5、页面渲染完成!执行
三:目标方法前返回true的情况,目标方法后异常
1、目标方法前执行 返回true
2、这是目标方法执行
3、目标方法之后异常
4、这是渲染页面渲染异常页面
5、页面渲染完成!执行
四:目标方法前返回true的情况,渲染页面异常
1、目标方法前执行 返回true
2、这是目标方法执行
3、目标方法之后执行
4、这是渲染页面异常
5、页面渲染完成!执行
7、异常处理
7.1、使用@ExceptionHandler注解处理异常
//@ExceptionHandler可以拦截到本Controller中的异常
@ExceptionHandler
public ModelAndView exceptionHandler(Exception e) {
System.out.println("exceptionHandler --- Exception");
ModelAndView modelAndView = new ModelAndView("forward:/error.jsp");
modelAndView.addObject("exception", e);
return modelAndView;
}
//@ExceptionHandler可以拦截到本Controller中的异常
@ExceptionHandler
public ModelAndView exceptionHandler(RuntimeException e) {
System.out.println("exceptionHandler --- RuntimeException");
ModelAndView modelAndView = new ModelAndView("forward:/error.jsp");
modelAndView.addObject("exception", e);
return modelAndView;
}
//@ExceptionHandler可以拦截到本Controller中的异常
@ExceptionHandler
public ModelAndView exceptionHandler(ArithmeticException e) {
System.out.println("exceptionHandler --- ArithmeticException");
ModelAndView modelAndView = new ModelAndView("forward:/error.jsp");
modelAndView.addObject("exception", e);
return modelAndView;
}
在同一个Controller中可以有多个@ExceptionHandler标注的异常处理方法。
SpringMVC会优先选择异常信息精确的方法执行异常处理操作。
区别:
@ExceptionHandler可以拦截到本Controller中的异常(注解在方法上)
@ControllerAdvice它可以处理所有Controller中产生的异常(注解在类上)
7.2、使用@ControllerAdvice注解处理异常
/**
* @ControllerAdvice它可以处理所有Controller中产生的异常
*
*/
@ControllerAdvice
public class ExceptionEHander2 {
@ExceptionHandler
public ModelAndView exceptionHandler(Exception e) {
System.out.println("@ControllerAdvice --- Exception");
ModelAndView modelAndView = new ModelAndView("forward:/error.jsp");
modelAndView.addObject("exception", e);
return modelAndView;
}
@ExceptionHandler
public ModelAndView exceptionHandler(RuntimeException e) {
System.out.println("@ControllerAdvice --- RuntimeException");
ModelAndView modelAndView = new ModelAndView("forward:/error.jsp");
modelAndView.addObject("exception", e);
return modelAndView;
}
@ExceptionHandler
public ModelAndView exceptionHandler(ArithmeticException e) {
System.out.println("@ControllerAdvice --- ArithmeticException");
ModelAndView modelAndView = new ModelAndView("forward:/error.jsp");
modelAndView.addObject("exception", e);
return modelAndView;
}
}
7.3、异常处理优先顺序
在局部异常处理和全局异常处理同时存在的时候,优先顺序是:
1、局部优先---->>>>2、精确优化
7.4、使用SimpleMappingExceptionResolver类、简单映射异常跳转
说明:配置SimpleMappingExceptionResolver文件可以取代上面两种注解方式
<!-- 配置SimpleMappingExceptionResolver简单异常映射解析器 -->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<!-- 异常映射属性 -->
<property name="exceptionMappings">
<props>
<!--
key写上异常全类名
在prop标签中填写指定的跳转地址
-->
<prop key="java.lang.Exception">forward:/error.jsp</prop>
<prop key="java.lang.RuntimeException">forward:/error.jsp</prop>
<prop key="java.lang.ArithmeticException">forward:/error.jsp</prop>
<prop key="java.lang.NullPointerException">forward:/null.jsp</prop>
</props>
</property>
</bean>
SpringMVC详解四、自带标签库及自定义参数转换器
jar包下载