接上篇: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框架--学习笔记(下)相关推荐

  1. SpringMVC框架--学习笔记(上)

    1.SpringMVC入门程序: (1)导入jar包:spring核心jar包.spring-webmvc整合Jar包 (2)配置前端控制器:web.xml文件中 <?xml version=& ...

  2. [Spring+SpringMVC+Mybatis]框架学习笔记(四):Spring实现AOP

    上一章:[Spring+SpringMVC+Mybatis]框架学习笔记(三):Spring实现JDBC 下一章:[Spring+SpringMVC+Mybatis]框架学习笔记(五):SpringA ...

  3. mybatis框架--学习笔记(下)

    上篇:mybatis框架--学习笔记(上):https://blog.csdn.net/a745233700/article/details/81034021 8.高级映射: (1)一对一查询: ①使 ...

  4. 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 异 ...

  5. mybatis框架--学习笔记(上)

    使用JDBC操作数据库的问题总结: (1)数据库连接,使用时创建,不使用时立即释放,对数据库进行频繁连接开启和关闭,造成数据库资源浪费,影响数据库性能. 设想:使用数据库连接池管理数据库连接. (2) ...

  6. JavaSE中Map框架学习笔记

    前言:最近几天都在生病,退烧之后身体虚弱.头疼.在床上躺了几天,什么事情都干不了.接下来这段时间,要好好加快进度才好. 前面用了三篇文章的篇幅学习了Collection框架的相关内容,而Map框架相对 ...

  7. python表单提交的两种方式_Flask框架学习笔记之表单基础介绍与表单提交方式

    本文实例讲述了Flask框架学习笔记之表单基础介绍与表单提交方式.分享给大家供大家参考,具体如下: 表单介绍 表单是HTML页面中负责数据采集功能的部件.由表单标签,表单域和表单按钮组成.通过表单,将 ...

  8. php框架费尔康,GitHub - majixian/study-phalcon: phalcon(费尔康)框架学习笔记

    phalcon(费尔康)框架学习笔记 以实例程序invo为例(invo程序放在网站根目录下的invo文件夹里,推荐php版本>=5.4) 环境不支持伪静态网址时的配置 第一步: 在app\con ...

  9. Netty网络框架学习笔记-16(心跳(heartbeat)服务源码分析)

    Netty网络框架学习笔记-16(心跳(heartbeat)服务源码分析_2020.06.25) 前言: Netty 作为一个网络框架,提供了诸多功能,比如编码解码等,Netty 还提供了非常重要的一 ...

最新文章

  1. jQuery 在 IE 上 clone checkbox 的問題。
  2. NR 5G 测量与寻呼
  3. 关系运算符、逻辑 运算符与三元运算符
  4. Apache FOP与Eclipse和OSGi的集成
  5. 超大规模集成电路_纳米级超大规模集成电路芯片低功耗物理设计分析(二)
  6. python降噪突出人声_KlipC带您探寻——华为全新智慧动态降噪耳机
  7. 二进位注册文件_注册表导入时提示导入文件不是注册脚本,只能导入二进位注册文件...
  8. 文字转语音播报,兼容多种浏览器
  9. PDMS软光刻加工过程
  10. iOS 相机开发总结
  11. php写的公告栏代码,可爱的公告栏代码
  12. 是时候适配 Swift 3 了吗——专访 LINE iOS 开发工程师王巍
  13. flex 布局,省略号失效
  14. 20170425めも
  15. python画饼图柱状图_荐【python数据分析(24)】Matplotlib库基本图形绘制(1)(线形图、柱状图、堆叠图、面积图、填图、饼图)...
  16. 2021-04-27 Android 理解frameworks services jni hardware kernel 整个控制过程实例包括回调
  17. Python工具箱系列(七)
  18. 使用python提取所有word文件中的所有图片
  19. 电脑小白 给 电脑大白 讲 电脑基础(软件推荐篇)
  20. CSS 之 Flex布局

热门文章

  1. 二十五、Node中的Buffer缓冲器和EventEmitter事件触发器
  2. 四、分析HelloWorld程序,开始学习Java运算符
  3. 杭州/北京/新加坡 | 蚂蚁集团数字身份团队招聘计算机视觉算法实习生
  4. 直播 | 同源共流:一个优化框架统一与解释图神经网络
  5. 中文数据集有奖公开征集
  6. 让预训练模型学习知识:使用多学习器增强知识建模能力
  7. 丑憨批的html实战
  8. Redis 远程字典服务及shell全部命令汇总【点击可查看高清原图】(附 xmind思维导图原文件 百度网盘)
  9. 1333和1600能双通道吗_80后童年神作《光环致远星》steam解锁 ?你的电脑还OK吗?...
  10. 【LeetCode】LeetCode之乘积最大子数组——枚举+动态规划+Kadane算法