SpringMVC(4)的异常处理器,拦截器,图片上传的实现(Tomcat的虚拟目录的设置)

本文深入探讨SpringMVC框架的高级功能,包括异常处理器、拦截器、图片上传及JSON交互等,旨在帮助开发者掌握更复杂的业务场景处理技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在三次学习已经简单介绍了springmvc工程的搭建,springmvc的三大组件,参数绑定,@Controller返回值,下面介绍springmvc的功能配置,后续添加…

1.异常处理器

使用场景:在程序运行的时候,可能会出现异常,此时直接返回用户异常页面是及其不友好的,做一个全局异常处理器,处理所有没有处理过的运行时异常用于更友好地提示用户。

处理思路:系统中的异常包括两类:预期异常和运行时异常 RuntimeException,前者通过捕获异从而获取异常信息,或者通过测试减少运行时异常的发生。
其中dao,service,Controller都用throws Exception向上抛出,最后有sringmvc前端控制器交由异常处理器去处理。HandlerExceptionResolver(异常处理器)

具体实现:

  1. 创建全局异常处理器
public class CustomerExceptionResolve implements HandlerExceptionResolver {
	@Override
	public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handle,
			Exception e) {
		// TODO Auto-generated method stub
    //响应用户错误提示
		ModelAndView modelAndView = new ModelAndView();
		String message="页面错误";    
		//自定义异常,显示自定义信息
		if(e instanceof MyException){
			 message = ((MyException)e).getMessage();
		}
    //返回错误消息
		modelAndView.addObject("msg", message);
    //响应错误提示页面
		modelAndView.setViewName("error");
		return modelAndView;
	}
}
  1. 配置异常处理器(springmvc.xml)
<!-- 配置全局异常处理器 -->
<bean class="ctgu.utils.CustomerExceptionResolve"/>
  1. 测试
/**
	 * 全局异常处理
	 * 包括自定义异常信息
	 * @throws MyException
	 */
	@RequestMapping("/error")
	public void MyError() throws MyException{
//		int a=1/0;
		/**
		 * 模拟商品查询不到的场景
		 * 这样的话,错误页面无需定义多个,而直接抛出exception,然后全局异常处理器接收后处理
		 */
		if(true){
			throw new MyException("你查找的商品不存在");
		}
	}

2.拦截器

应用:springmvc的处理器拦截器类似于servlet中的过滤器Filter,用于处理器进行预处理和后处理

  • 就是一个普通的类去继承HandlerInterceptor接口;
  • afterCompletion():只要放行了都会执行
    • 用于:处理异常,记录日志
  • postHandle():在控制器COntroller执行之后,返回ModelAndView视图,之前被执行
    • 作用:设置或清理页面共用参数,比如标题栏共用
  • preHandle():在执行Controller方法之前时执行
    • 作用:登录拦截,用户认证
public class UserIntercepter implements HandlerInterceptor {
	/**
	 * 只要放行了都会执行
	 * 用于:处理异常,记录日志
	 */
	@Override
	public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
			throws Exception {
		// TODO Auto-generated method stub
		//System.out.println("afterCompletion执行...");
	}
	/**
	 * 在控制器COntroller执行之后,返回ModelAndView视图,之前被执行
	 * 作用:设置或清理页面共用参数,比如标题栏共用
	 */
	@Override
	public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
			throws Exception {
		// TODO Auto-generated method stub
		//System.out.println("postHandle执行...");
	}
	/**
	 * 在执行Controller方法之前时执行
	 * 作用:登录拦截,用户认证
	 */
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception {
		// TODO Auto-generated method stub
		//System.out.println("preHandle执行...");
		String name = (String) request.getSession().getAttribute("username");
		if(name!=null){
			//放行
			//当我们输入其他URL的时候,必须判断用户是否完成登录,如果没有,必须返回登录页面
			return true;
		}else{
			response.sendRedirect(request.getContextPath()+"/user/toLogin.action");
			return false;
		}
	}
}

springmvc.xml的配置:

<!-- 配置拦截器 -->
	<mvc:interceptors>
		<mvc:interceptor>
			<!-- 配置拦截地址 -->
			<mvc:mapping path="/**/"/>
			<!-- 配置不拦截地址 -->
			<mvc:exclude-mapping path="/user/*"/>
			<bean class="ctgu.intercepter.UserIntercepter"/>
		</mvc:interceptor>
	</mvc:interceptors>

说明:拦截器可以配置多个,即配置多个 mvc:interceptor,但是如果第一个拦截器preHandler没有放行(返回的是false),那其他的两个方法也不会执行,第二个拦截器的所有方法都不会执行,Controller也不执行了。
问:当有两个即两个以上的拦截器存在时,afterCompletion()、postHandle()、preHandle()的执行顺序是如何的?

  • preHandle()按照拦截器定义的顺序调用
  • postHandle()按照拦截器定义逆序调用
  • afterCompletion()按照拦截器定义逆序调用
  • postHandle()在拦截器链内所有拦截器返回成功调用
  • afterCompletion()只有在preHandle返回true才调用

3.图片上传

  1. 配置虚拟目录

相当于配置了一个tomcat与本地磁盘的路径映射。

springmvc配置虚拟目录

相当于在tomcat的server.xml中添加了一行
<Context docBase=“springmvc03-mybatis” path="/"reloadable=“true” source=“org.eclipse.jst.jee.server:springmvc03-mybatis”/>

  1. 导jar包
    commons-fileupload-1.2.2.jar
    commons-io-2.4.jar

  2. jsp页面

注意method一定要为"post"
enctype=“multipart/form-data”

<form id="itemForm"	action="${pageContext.request.contextPath }/updateItem.action" method="post" enctype="multipart/form-data">
<tr>
	<td>商品图片</td>
		<td>
			<c:if test="${item.pic !=null}">
				<img src="/pic/${item.pic}" width=100 height=100/><br/>
			</c:if>
			<input type="file"  name="pictureFile"/>
		</td>
</tr>

4.springmvc.xml配置

<!-- 配置多媒体处理器 -->
	<!-- 注意:这里id必须填写:multipartResolver -->
	<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<!-- 最大上传文件大小 -->
		<property name="maxUploadSize" value="8388608" />
	</bean>
  1. 图片上传处理代码Controller

思路:

  • 拿到图片的名字,根据托图片名拿到其后缀名,再拼接一个图片的新的名字
  • 将其写入磁盘,把图片的路径+名字(虚拟目录)写入数据库
  • 在tomcat建立一个虚拟目录,因为前端页面<img src="/pic/${item.pic}">标签显示
  • 我们上传上去的图片,需要controller层对其做出处理:
    • 1.将其保存在虚拟目录对应的目录,否则前端页面找不到;
    • 2.给其一个新的名字(设计到获取其后缀,给一个唯一标识)并赋值给item.pic

说明:相当于将上传的图片保存在tomcat能找的到的目录 (前面映射的虚拟目录),但是我们将其保存的时候给其一个新名字(防止重复),保存在数据库里面的是图片的名字

@RequestMapping(value="/updateItem.action")
	public String updateItem(Model model,MultipartFile pictureFile,Item item) throws Exception{
		//生成唯一标识作为图片id,uuid
		String name=UUID.randomUUID().toString();
		//获取上传图片的名字
		String originalFilename = pictureFile.getOriginalFilename();
		//得到图片名后缀
		String newname = originalFilename.substring(originalFilename.lastIndexOf("."));
		//保存在磁盘
		File file = new File("C:\\Users\\DELL\\Pictures\\java\\"+name+newname);
		pictureFile.transferTo(file);
		//把图片名保存到数据库
		item.setPic(name+newname);
		itemService.update(item);
		model.addAttribute("item", item);
		model.addAttribute("msg", "修改商品成功");
		return "itemEdit";
	}

4.json交互

5.Restful

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值