前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringMVC学习笔记(五) --- 异常处理、图片上传、Json数据交互、RESTful支持、拦截器

SpringMVC学习笔记(五) --- 异常处理、图片上传、Json数据交互、RESTful支持、拦截器

作者头像
挽风
发布2021-04-13 14:58:39
6650
发布2021-04-13 14:58:39
举报
文章被收录于专栏:小道小道

1、自定义异常处理器

springmvc在处理请求过程中出现异常信息交由异常处理器进行处理,自定义异常处理器可以实现一个系统的异常处理逻辑。

异常处理思路:系统中异常包括两类:预期异常和运行时异常RuntimeException,前者通过捕获异常从而获取异常信息,后者主要通过规范代码开发、测试通过手段减少运行时异常的发生。系统的dao、service、controller出现都通过throws Exception向上抛出,最后由springmvc前端控制器交由异常处理器进行异常处理。

步骤一:自定义异常类

为了区别不同的异常通常根据异常类型自定义异常类,这里我们创建一个自定义系统异常,如果controller、service、dao抛出此类异常说明是系统预期处理的异常信息。

代码语言:javascript
复制
public class CustomException extends Exception {

	/** serialVersionUID*/
	private static final long serialVersionUID = -5212079010855161498L;
	
	public CustomException(String message){
		super(message);
		this.message = message;
	}

	//异常信息
	private String message;

	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
	}
}

步骤二:自定义异常处理类

代码语言:javascript
复制
public class CustomExceptionResolver implements HandlerExceptionResolver {

	@Override
	public ModelAndView resolveException(HttpServletRequest request,
			HttpServletResponse response, Object handler, Exception ex) {

		ex.printStackTrace();

		CustomException customException = null;
		
		//如果抛出的是系统自定义异常则直接转换
		if(ex instanceof CustomException){
			customException = (CustomException)ex;
		}else{
			//如果抛出的不是系统自定义异常则重新构造一个系统错误异常。
			customException = new CustomException("系统错误,请与系统管理 员联系!");
		}
		
		ModelAndView modelAndView = new ModelAndView();
		modelAndView.addObject("message", customException.getMessage());
		modelAndView.setViewName("error");

		return modelAndView;
	}

}
代码语言:javascript
复制
//取异常堆栈
           try {
			
		} catch (Exception e) {
			StringWriter s = new StringWriter();
			PrintWriter printWriter = new PrintWriter(s);
			e.printStackTrace(printWriter);
			s.toString();
		}

步骤三:错误界面

代码语言:javascript
复制
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt"  prefix="fmt"%> 




错误页面



    您的操作出现错误如下:

    ${message }

步骤四:异常处理配置

在springmvc.xml中添加:

代码语言:javascript
复制

步骤五:异常测试

修改商品信息,id输入错误提示商品信息不存在。

修改controller方法“editItem”,调用service查询商品信息,如果商品信息为空则抛出异常:

代码语言:javascript
复制
// 调用service查询商品信息
		Items item = itemService.findItemById(id);
		
		if(item == null){
			throw new CustomException("商品信息不存在!");
		}

2、图片上传

步骤一:配置虚拟目录

在tomcat上配置图片虚拟目录,在tomcat下conf/server.xml中添加:

代码语言:javascript
复制

访问http://localhost:8080/pic即可访问F:\develop\upload\temp下的图片。

也可以通过eclipse配置:

步骤二:加入Jar包

CommonsMultipartResolver解析器依赖commons-fileupload和commons-io,加入如下jar包:

步骤三:配置解析器

代码语言:javascript
复制
			5242880

步骤四:上传图片

代码语言:javascript
复制
//Controller
//商品修改提交
	@RequestMapping("/editItemSubmit")
	public String editItemSubmit(Items items, MultipartFile pictureFile)throws Exception{
		
		//原始文件名称
		String pictureFile_name =  pictureFile.getOriginalFilename();
		//新文件名称
		String newFileName = UUID.randomUUID().toString()+pictureFile_name.substring(pictureFile_name.lastIndexOf("."));
		
		//上传图片
		File uploadPic = new java.io.File("F:/develop/upload/temp/"+newFileName);
		
		if(!uploadPic.exists()){
			uploadPic.mkdirs();
		}
		//向磁盘写文件
		pictureFile.transferTo(uploadPic);

        .....
}

页面:

form添加enctype="multipart/form-data":

代码语言:javascript
复制

file的name与controller形参一致:

代码语言:javascript
复制
	商品图片

3、Json数据交互

Ⅰ、@RequestBody

作用:

@RequestBody注解用于读取http请求的内容(字符串),通过springmvc提供的HttpMessageConverter接口将读到的内容转换为json、xml等格式的数据并绑定到controller方法的参数上。

代码语言:javascript
复制
        List.action?id=1&name=zhangsan&age=12

本例子应用:

@RequestBody注解实现接收http请求的json数据,将json数据转换为java对象

Ⅱ、@ResponseBody

作用:

该注解用于将Controller的方法返回的对象,通过HttpMessageConverter接口转换为指定格式的数据如:json,xml等,通过Response响应给客户端。

本例子应用:

@ResponseBody注解实现将controller方法返回对象转换为json响应给客户端。

Ⅲ、请求json,响应json实现

步骤一:环境准备

Springmvc默认用MappingJacksonHttpMessageConverter对json数据进行转换,需要加入jackson的包,如下:

步骤二:配置json转换器

在注解适配器中加入messageConverters

代码语言:javascript
复制

注意:如果使用 则不用定义上边的内容。

步骤三:Controller编写

代码语言:javascript
复制
// 商品修改提交json信息,响应json信息
	@RequestMapping("/editItemSubmit_RequestJson")
	public @ResponseBody Items editItemSubmit_RequestJson(@RequestBody Items items) throws Exception {
		System.out.println(items);
		//itemService.saveItem(items);
		return items;

	}

步骤四:页面JS方法编写

引入 js:

代码语言:javascript
复制
代码语言:javascript
复制
//请求json响应json
	function request_json(){
		$.ajax({
			type:"post",
			url:"${pageContext.request.contextPath }/item/editItemSubmit_RequestJson.action",
			contentType:"application/json;charset=utf-8",
			data:'{"name":"测试商品","price":99.9}',
			success:function(data){
				alert(data);
			}
		});
	}

步骤五:测试结果

从上图可以看出请求的数据是json格式。

4、RESTful支持

Ⅰ、什么是Restful?

Restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格,是对http协议的诠释。

资源定位:互联网所有的事物都是资源,要求url中没有动词,只有名词。没有参数

Url格式:https://mp.csdn.net/postedit/103854159

资源操作:使用put、delete、post、get,使用不同方法对资源进行操作。分别对应添加、删除、修改、查询。一般使用时还是post和get。Put和Delete几乎不使用。

Ⅱ、实现RESTful方式实现商品信息查询,返回json数据

步骤一:添加DispatcherServlet的rest配置

代码语言:javascript
复制
		springmvc-servlet-rest
		org.springframework.web.servlet.DispatcherServlet
		
			contextConfigLocation
			classpath:spring/springmvc.xml
		


	
		springmvc-servlet-rest
		/

步骤二:URL 模板模式映射

@RequestMapping(value="/ viewItems/{id}"):{×××}占位符,请求的URL可以是“/viewItems/1”或“/viewItems/2”,通过在方法中使用@PathVariable获取{×××}中的×××变量。

@PathVariable用于将请求URL中的模板变量映射到功能处理方法的参数上。

代码语言:javascript
复制
@RequestMapping("/viewItems/{id}") 
	public @ResponseBody viewItems(@PathVariable("id") String id,Model model) throws Exception{
		//方法中使用@PathVariable获取useried的值,使用model传回页面
		//调用 service查询商品信息
		ItemsCustom itemsCustom = itemsService.findItemsById(id);
		return itemsCustom;
}

如果RequestMapping中表示为"/viewItems/{id}",id和形参名称一致,@PathVariable不用指定名称。

商品查询的controller方法也改为rest实现:

代码语言:javascript
复制
// 查询商品列表
	@RequestMapping("/queryItem")
	public ModelAndView queryItem() throws Exception {
		// 商品列表
		List itemsList = itemService.findItemsList(null);

		// 创建modelAndView准备填充数据、设置视图
		ModelAndView modelAndView = new ModelAndView();

		// 填充数据
		modelAndView.addObject("itemsList", itemsList);
		// 视图
		modelAndView.setViewName("item/itemsList");

		return modelAndView;
	}

Ⅲ、静态资源访问

如果在DispatcherServlet中设置url-pattern为 /则必须对静态资源进行访问处理。

spring mvc 的实现对静态资源进行映射访问。

如下是对js文件访问配置:

代码语言:javascript
复制

5、自定义拦截器

Spring Web MVC 的处理器拦截器类似于Servlet 开发中的过滤器Filter,用于对处理器进行预处理和后处理。

步骤一:实现HandlerInterceptor接口

代码语言:javascript
复制
public class HandlerInterceptor1 implements HandlerInterceptor{

	/**
	 * controller执行前调用此方法
	 * 返回true表示继续执行,返回false中止执行
	 * 这里可以加入登录校验、权限拦截等
	 */
	@Override
	Public boolean preHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler) throws Exception {
		// TODO Auto-generated method stub
		Return false;
	}
	/**
	 * controller执行后但未返回视图前调用此方法
	 * 这里可在返回用户前对模型数据进行加工处理,比如这里加入公用信息以便页面显示
	 */
	@Override
	Public void postHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		// TODO Auto-generated method stub
		
	}
	/**
	 * controller执行后且视图返回后调用此方法
	 * 这里可得到执行controller时的异常信息
	 * 这里可记录操作日志,资源清理等
	 */
	@Override
	Public void afterCompletion(HttpServletRequest request,
			HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		// TODO Auto-generated method stub
		
	}

}

步骤二:配置拦截器

针对某种mapping配置拦截器:

代码语言:javascript
复制

针对所有mapping配置全局拦截器:

代码语言:javascript
复制

拦截器正常流程测试:

定义两个拦截器分别为:HandlerInterceptor1和HandlerInteptor2,每个拦截器的preHandler方法都返回true。

运行流程:

代码语言:javascript
复制
    HandlerInterceptor1..preHandle..
    HandlerInterceptor2..preHandle..

    HandlerInterceptor2..postHandle..
    HandlerInterceptor1..postHandle..

    HandlerInterceptor2..afterCompletion..
    HandlerInterceptor1..afterCompletion..

总结:

代码语言:javascript
复制
    preHandle按拦截器定义顺序调用
    
    postHandler按拦截器定义逆序调用

    afterCompletion按拦截器定义逆序调用

    postHandler在拦截器链内所有拦截器返成功调用

    afterCompletion只有preHandle返回true才调用

6、拦截器应用

代码语言:javascript
复制
1、有一个登录页面,需要写一个controller访问页面
2、登录页面有一提交表单的动作。需要在controller中处理。
    a)	判断用户名密码是否正确
    b)	如果正确 想session中写入用户信息
    c)	返回登录成功,或者跳转到商品列表
3、拦截器。
    a)	拦截用户请求,判断用户是否登录
    b)	如果用户已经登录。放行
    c)	如果用户未登录,跳转到登录页面。

1、有一个登录页面,需要写一个controller访问页面

2、登录页面有一提交表单的动作。需要在controller中处理。

a)    判断用户名密码是否正确

b)    如果正确 想session中写入用户信息

 c)    返回登录成功,或者跳转到商品列表

3、拦截器。

a)    拦截用户请求,判断用户是否登录     b)    如果用户已经登录。放行     c)    如果用户未登录,跳转到登录页面。

实现用户身份认证拦截器:

代码语言:javascript
复制
public class LoginInterceptor implements HandlerInterceptor{

	@Override
	Public boolean preHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler) throws Exception {

		//如果是登录页面则放行
		if(request.getRequestURI().indexOf("login.action")>=0){
			return true;
		}
		HttpSession session = request.getSession();
		//如果用户已登录也放行
		if(session.getAttribute("user")!=null){
			return true;
		}
		//用户没有登录挑战到登录页面
		request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
		
		return false;
	}
}

实现用户登录Controller:

代码语言:javascript
复制
    //登陆页面
	@RequestMapping("/login")
	public String login(Model model)throws Exception{
		
		return "login";
	}
	
	//登陆提交
	//userid:用户账号,pwd:密码
	@RequestMapping("/loginsubmit")
	public String loginsubmit(HttpSession session,String userid,String pwd)throws Exception{
		
		//向session记录用户身份信息
		session.setAttribute("activeUser", userid);
		
		return "redirect:item/queryItem.action";
	}
	
	//退出
	@RequestMapping("/logout")
	public String logout(HttpSession session)throws Exception{
		
		//session过期
		session.invalidate();
		
		return "redirect:item/queryItem.action";
	}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-01-06 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、自定义异常处理器
  • 2、图片上传
  • 3、Json数据交互
    • Ⅰ、@RequestBody
      • Ⅱ、@ResponseBody
        • Ⅲ、请求json,响应json实现
          • Ⅰ、什么是Restful?
          • Ⅱ、实现RESTful方式实现商品信息查询,返回json数据
          • Ⅲ、静态资源访问
      • 4、RESTful支持
      • 5、自定义拦截器
      • 6、拦截器应用
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档