SpringMVC详解五、@ResponseBody、@RequestBody、HttpEntity、ResponseEntity、文件上传、HandlerInterceptor拦截器及异常处理


1MultipartFile :文件上传

2、使用@ResponseBody返回的数据转成json

        @JsonFormat修改时间在json中的格式

3、使用@RequestBody接收请求体数据

4、使用HttpEntity参数获取请求头请求体

5、使用ResponseEntity返回值操作响应头和响应体:下载文件

6HandlerInterceptor拦截器

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.2Controller中的代码:

@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、打开浏览器测试如下:




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;
	}

6HandlerInterceptor拦截器

6.1HandlerInterceptor拦截器的介绍

拦截器,可以拦截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包下载


  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值