SpringMVC框架--学习笔记(下)
接上篇:SpirngMVC框架--学习笔记(上):https://blog.csdn.net/a745233700/article/details/81038382
17、全局异常处理:
系统中异常包括两类,预期异常和运行时异常RuntimeException,前者通过捕获异常从而获得异常信息,后者主要通过规范代码开发、测试通过手段减少运行时异常的发生。
系统的dao、service、controller出现异常都通过throws Exception向上抛出,最后由springmvc前端控制器交由异常处理器进行异常处理,如下图:
springmvc提供全局异常处理器(一个系统只有一个异常处理器)进行统一异常处理。
(1)自定义异常类:
对不同的异常类型定义异常类,继承Exception
//自定义异常:
//针对预期的异常,需要在此类中抛出此类的异常
public class CustomException extends Exception{private String message;public CustomException(String message){super(message);this.message=message;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}
}
(2)全局异常处理器:实现HandlerExceptionResolver接口
思路:
系统遇到异常,在程序中手动抛出,dao抛给service、service给controller、controller抛给前端控制器,前端控制器调用全局异常处理器。
全局控制器处理思路:
①解析出异常类型;
②如果该异常类型是系统自定义的异常,直接取出异常信息,在错误页面展示。
③如果该异常不是系统自定义的异常,构造一个自定义的异常类型(信息为“未知错误”)
//自定义异常:
//针对预期的异常,需要在此类中抛出此类的异常
public class CustomException extends Exception{private String message;public CustomException(String message){super(message);this.message=message;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}
}
在springmvc文件中注册全局异常处理器:
<!-- 全局异常处理器 --><!-- 不用写id,系统根据是否实现HandlerExceptionResolver接口,只要实现,就是全局异常处理器,如果配置多个,只有一个起作用 --><bean class="com.zwp.ssm.exception.CustomExceptionResolver"></bean>
如果与业务功能相关的异常,建议在service中抛出异常。
与业务功能没有关系的异常,建议在controller中抛出。
18、上传图片:
(1)创建图片虚拟目录:
①第一种:
②第二种:
也可以直接修改tomcat的配置:在conf/server.xml文件,添加虚拟目录:
注意:在图片虚拟目录中,一定将图片目录分级创建(提高I/O性能),一般我们采用按日期进行分级创建。
(2)加入上传图片的jar包:
(3)在页面的form表单中加入enctype="multipart/form-data"
(4)在springmvc.xml文件中配置解析器:
<!-- 上传文件 --><bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><!-- 设置上传文件最大尺寸 --><property name="maxUploadSize"><value>5242880</value></property></bean>
(5)编写Controller:
//MultipartFile items_pic用于接收图片@RequestMapping(value="/editItemsSubmit",method={RequestMethod.POST,RequestMethod.GET})public String editItemsSubmit(Model model,HttpServletRequest request,Integer id,@ModelAttribute("itemsCustom") @Validated(value={ValidGroup1.class}) ItemsCustom itemsCustom,BindingResult bindingResult,MultipartFile items_pic) throws Exception{if(bindingResult.hasErrors()){List<ObjectError> allErrors=bindingResult.getAllErrors();//自定义一个list接受自己编码后的提示字符串,在把自己定义的list传到界面,//这样就解决了把乱码传到界面的问题了List<String> listErrors=new ArrayList<>();for(ObjectError objectError:allErrors){//System.out.println(objectError.getDefaultMessage());//把返回错误的提示再次编码String strError=new String(objectError.getDefaultMessage().getBytes("ISO-8859-1"),"UTF-8"); listErrors.add(strError);//把编码好的错误提示信息加自己定义好list集合里面去}model.addAttribute("allErrors", listErrors);return "Items/editItems";}//原始名称String originalFilename=items_pic.getOriginalFilename();System.out.println(originalFilename);//上传图片:if(items_pic!=null && originalFilename!=null && originalFilename.length()>0){//存储图片的物理路径:String pic_path="D:\\Tomcat 5.5\\pictures\\";//新的图片名称String newFileName=UUID.randomUUID()+originalFilename.substring(originalFilename.lastIndexOf("."));//新图片:File newFile=new File(pic_path+newFileName);//将内存中的数据写入磁盘items_pic.transferTo(newFile);//将新图片名称写到itemsCustom中itemsCustom.setPic(newFileName);}//调用service更新商品信息,页面需要将商品信息传到此方法中itemsService.updateItems(id, itemsCustom);//页面转发:return "forward:queryItems.action";}
(6)页面显示:
19、json交互:
@RequestBody:将json串转成java对象
@ResponseBody:将java对象转成json输出。
(1)请求是Json串,输出也是json串。
(2)请求是key/value,输出是json(常用)
最终结果都是输出json数据,为了在前端页面方便对请求结果进行解析。
步骤:
第一步:导入jar包依赖:
第二步:配置json转化器:
在注解适配器中加入messageConverters
注意:如果使用<mvc:annotation-driver />则不用定义上边的内容。
第三步:页面和控制器:
20、springmvc对RESTful的支持:
(1)对url进行规范,写RESTful格式的url
(2)http的方法规范 :
不管是删除、添加、更新。。使用的url是一致的,如果进行删除,需要设置http的方法为delete,同理添加。
后台controller方法:判断http方法,如果是delete执行删除,如果是post执行添加。
(3)对http的contentType规范:
请求是指定contentType,要json数据,设置成json格式的type..
需求:查询商品信息,返回json数据。
思路:定义方法,进行url映射使用RESTful风格的url,将查询商品的信息的id传入controller。输出json是,使用@ResponseBody将java对象输出json。
(1)Controller:
//根据id查找商品信息,使用RESTful风格,并返回json格式的数据//("/itemView/{id}")的id要和@PathVariable("id")的id一致,表示将("/itemView/{id}")的id绑定到@PathVariable后面的参数上面@RequestMapping("/itemView/{id}")public @ResponseBody ItemsCustom itemView(@PathVariable("id") Integer id) throws Exception{ItemsCustom itemsCustom=itemsService.findItemsById(id);return itemsCustom;}
(2)前端控制器配置:
<!-- RESTful规范要用第二种方式: --><servlet><servlet-name>springmvc_restful</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!-- contextConfigLocation:配置springmvc加载的配置文件(处理处映射器、处理器适配器等等) --><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:/spring/springmvc.xml</param-value></init-param> </servlet><servlet-mapping><servlet-name>springmvc_restful</servlet-name><!-- 第一种:*.action,访问以.action结尾由DispatcherServlet进行解析第二种:/,所有访问的地址都由DispatcherServlet进行解析,对于静态文件的解析需要配置不让DispatcherServlet进行解析,使用此种方法可以实现RESTful风格的url第三种:/*,这种配置不对,使用这种配置,最终要转发到一个jsp页面,仍然会由DispatcherServlet解析jsp,不能根据jsp页面找到Handle,会报错--><url-pattern>/</url-pattern></servlet-mapping>
(3)访问的url:
(4)json结果数据:
--对静态资源的解析:
在springmvc.xml中添加静态资源的解析:
<!-- 对静态资源的解析,如js,css,img... --><!-- <mvc:resources location="/js/" mapping="/js/**"></mvc:resources> --><!-- <mvc:resources location="/css/" mapping="/css/**"></mvc:resources> -->
对静态资源的访问:
21、springmvc拦截器:
(1)定义拦截器:实现HandlerInterceptor接口
public class HandlerInterceptor1 implements HandlerInterceptor{//进入Handler方法之前//用于身份认证,身份授权//比如身份认证,如果认证不通过表示当前用户没有登陆,需要此方法拦截不再向下执行@Overridepublic boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception { //return false:表示拦截,不向下执行//return ture:表示放行System.out.println("HandlerInterceptor1...preHandle");return true;}//进去Handler方法之后,返回modelAndView之前执行//应用场景:将公用的模型数据(比如菜单导航)传到视图,也可以在这里统一制定视图@Overridepublic void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception {System.out.println("HandlerInterceptor1...postHandle");}//执行Handler完成执行此方法//应用场景:统一异常处理,统一日志处理@Overridepublic void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)throws Exception {System.out.println("HandlerInterceptor1...afterCompletion");}
}
(2)配置拦截器:
①针对HandlerMapping进行拦截配置:(一般不用)
如果在某个HandlerMapping中配置,经过该HandlerMapping映射成功的Handler最终使用该拦截器。
②类似全局的拦截器:
springmvc配置类似全局的拦截器,springmvc框架将配置的类似全局的拦截器注入到每个HandlerMapping中。
<!-- 拦截器 --><mvc:interceptors><!-- 多个拦截器:顺序执行 --><mvc:interceptor><!-- /**:表示拦截所有url包括子url路径 --><mvc:mapping path="/**"/><!-- 拦截器路径 --><bean class="com.zwp.ssm.intercept.HandlerInterceptor1"></bean></mvc:interceptor><mvc:interceptor><mvc:mapping path="/**"/><bean class="com.zwp.ssm.intercept.HandlerInterceptor2"></bean></mvc:interceptor> </mvc:interceptors>
(3)测试:
①两个拦截器都放行:
总结:preHandle方法按顺序执行;postHandle和afterCompletion按拦截器配置的逆向顺序执行。
②拦截器1放行,拦截器2不放行:
总结:拦截器1放行,拦截器2的preHandle才会执行;
拦截器2的preHandle不放行,拦截器2的postHandle和afterCompletion不会执行;
只要有一个拦截器不放行,postHandle不会执行。
③拦截器1不放行,拦截器2不放行:
总结:拦截器1的preHandle不放行,postHandler和afterCompletion不会执行。
拦截器1的preHandle不放行,拦截器2不执行。
(4)拦截器小结:
根据测试结果,对拦截器应用。
比如:统一日志处理拦截器,需要该拦截器的preHandle一定要放行,且将它放在拦截器链中第一个位置。
比如:登陆认证拦截器,放在拦截器链中第一个位置;权限校验拦截器,放在登陆认证拦截器之后。(因为登陆通过之后才检验权限)
(5)拦截器应用:
需求:
①用户请求url
②拦截器进行拦截校验:
--如果请求的url是公开地址(无需登陆即可访问的url),让放行。
--如果用户session不存在,跳转到登陆页面
--如果用户session存在,放行,继续操作。
登陆页面:
<form action="${pageContext.request.contextPath }/login.action" method="post">
用户名:<input type="text" name="username"/><br/>
密码:<input type="password" name="password"/><br/>
<input type="submit" value="登陆"/>
</form>
拦截器:
public class LoginInterceptor implements HandlerInterceptor{@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception { //获取请求的urlString url=request.getRequestURI();//判断url是否是公开地址(实际使用时,将公开地址配置在配置文件中)//这里公开地址是登陆提交的地址if(url.indexOf("login.action")>=0){//如果进行登陆提交,放行return true;}//判断sessionHttpSession session=request.getSession();//从session中取出用户身份信息:String username=(String) session.getAttribute("username");if(username!=null){ //身份存在,放行return true;} //执行到这里,表示用户身份需要认证,跳转到登陆界面request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response); return false; }@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object arg2, ModelAndView arg3) throws Exception {}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object arg2, Exception arg3)throws Exception {}
}
注册拦截器:
<!-- 拦截器 --><mvc:interceptors><!-- 多个拦截器:顺序执行 --><mvc:interceptor><!-- /**:表示拦截所有url包括子url路径 --><mvc:mapping path="/**"/><!-- 拦截器路径 --><bean class="com.zwp.ssm.intercept.LoginInterceptor"></bean></mvc:interceptor></mvc:interceptors>
编写Controller:
@Controller
public class LoginController {@RequestMapping("/login")public String login(HttpSession sesison,String username,String password) throws Exception{//调用service进行身份验证//...//保存用户身份信息sesison.setAttribute("username", username);//重定向到商品列表return "redirect:items/queryItems.action"; }@RequestMapping("/logout")public String logout(HttpSession sesison) throws Exception{//清除sessionsesison.invalidate();//重定向商品列表return "redirect:items/queryItems.action"; }
}
登陆成功页面:
SpringMVC框架--学习笔记(下)相关推荐
- SpringMVC框架--学习笔记(上)
1.SpringMVC入门程序: (1)导入jar包:spring核心jar包.spring-webmvc整合Jar包 (2)配置前端控制器:web.xml文件中 <?xml version=& ...
- [Spring+SpringMVC+Mybatis]框架学习笔记(四):Spring实现AOP
上一章:[Spring+SpringMVC+Mybatis]框架学习笔记(三):Spring实现JDBC 下一章:[Spring+SpringMVC+Mybatis]框架学习笔记(五):SpringA ...
- mybatis框架--学习笔记(下)
上篇:mybatis框架--学习笔记(上):https://blog.csdn.net/a745233700/article/details/81034021 8.高级映射: (1)一对一查询: ①使 ...
- 27Vert.X框架学习笔记
vert.x框架学习笔记 文章目录 1 Vert.x简明介绍 1.1 Vert.x能干什么 1.2 Vert.x快速体验 1.3 Vert.x的简单介绍 1.4 Vert.x的一些优势 1.4.1 异 ...
- mybatis框架--学习笔记(上)
使用JDBC操作数据库的问题总结: (1)数据库连接,使用时创建,不使用时立即释放,对数据库进行频繁连接开启和关闭,造成数据库资源浪费,影响数据库性能. 设想:使用数据库连接池管理数据库连接. (2) ...
- JavaSE中Map框架学习笔记
前言:最近几天都在生病,退烧之后身体虚弱.头疼.在床上躺了几天,什么事情都干不了.接下来这段时间,要好好加快进度才好. 前面用了三篇文章的篇幅学习了Collection框架的相关内容,而Map框架相对 ...
- python表单提交的两种方式_Flask框架学习笔记之表单基础介绍与表单提交方式
本文实例讲述了Flask框架学习笔记之表单基础介绍与表单提交方式.分享给大家供大家参考,具体如下: 表单介绍 表单是HTML页面中负责数据采集功能的部件.由表单标签,表单域和表单按钮组成.通过表单,将 ...
- php框架费尔康,GitHub - majixian/study-phalcon: phalcon(费尔康)框架学习笔记
phalcon(费尔康)框架学习笔记 以实例程序invo为例(invo程序放在网站根目录下的invo文件夹里,推荐php版本>=5.4) 环境不支持伪静态网址时的配置 第一步: 在app\con ...
- Netty网络框架学习笔记-16(心跳(heartbeat)服务源码分析)
Netty网络框架学习笔记-16(心跳(heartbeat)服务源码分析_2020.06.25) 前言: Netty 作为一个网络框架,提供了诸多功能,比如编码解码等,Netty 还提供了非常重要的一 ...
最新文章
- jQuery 在 IE 上 clone checkbox 的問題。
- NR 5G 测量与寻呼
- 关系运算符、逻辑 运算符与三元运算符
- Apache FOP与Eclipse和OSGi的集成
- 超大规模集成电路_纳米级超大规模集成电路芯片低功耗物理设计分析(二)
- python降噪突出人声_KlipC带您探寻——华为全新智慧动态降噪耳机
- 二进位注册文件_注册表导入时提示导入文件不是注册脚本,只能导入二进位注册文件...
- 文字转语音播报,兼容多种浏览器
- PDMS软光刻加工过程
- iOS 相机开发总结
- php写的公告栏代码,可爱的公告栏代码
- 是时候适配 Swift 3 了吗——专访 LINE iOS 开发工程师王巍
- flex 布局,省略号失效
- 20170425めも
- python画饼图柱状图_荐【python数据分析(24)】Matplotlib库基本图形绘制(1)(线形图、柱状图、堆叠图、面积图、填图、饼图)...
- 2021-04-27 Android 理解frameworks services jni hardware kernel 整个控制过程实例包括回调
- Python工具箱系列(七)
- 使用python提取所有word文件中的所有图片
- 电脑小白 给 电脑大白 讲 电脑基础(软件推荐篇)
- CSS 之 Flex布局
热门文章
- 二十五、Node中的Buffer缓冲器和EventEmitter事件触发器
- 四、分析HelloWorld程序,开始学习Java运算符
- 杭州/北京/新加坡 | 蚂蚁集团数字身份团队招聘计算机视觉算法实习生
- 直播 | 同源共流:一个优化框架统一与解释图神经网络
- 中文数据集有奖公开征集
- 让预训练模型学习知识:使用多学习器增强知识建模能力
- 丑憨批的html实战
- Redis 远程字典服务及shell全部命令汇总【点击可查看高清原图】(附 xmind思维导图原文件 百度网盘)
- 1333和1600能双通道吗_80后童年神作《光环致远星》steam解锁 ?你的电脑还OK吗?...
- 【LeetCode】LeetCode之乘积最大子数组——枚举+动态规划+Kadane算法