SpringMVC 进阶版
请求限制
一些情况下我们可能需要对请求进行限制,比如仅允许POST,GET等...
RequestMapping注解中提供了多个参数用于添加请求的限制条件
- value 请求地址
- path 请求地址
- method 请求方法
- headers 请求头中必须包含指定字段
- params 必须包含某个请求参数
- consumes 接受的数据媒体类型 (与请求中的contentType匹配才处理)
- produce 返回的媒体类型 (与请求中的accept匹配才处理)
案例:
@RequestMapping(value = "/editCourse",method = RequestMethod.POST,headers = {"id"},params = {"name"},consumes = {"text/plain"},produces = {"text/html"})//含义:url为/editCourse 请求方法为POST hander必须包含id字段 参数必须包含name 只接受text/plain类型数据 返回数据类型为text/html
为了简化书写,MVC还提供了集合路径和方法限制的注解,包括常见的请求方法:
PostMappingGetMappingDeleteMappingPutMapping例:@PostMapping("/editCourse")
handler返回值
handler方法可以是三种类型的返回值,用于不同场景
ModelAndView
返回值为视图和数据的包装类型,用于返回逻辑视图名称和视图需要展示的数据
等同于在Request中添加了属性,然后进行了请求转发
例:
@RequestMapping("/test")public ModelAndView test() { ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName("index.jsp"); modelAndView.addObject("msg", "hello ssm!"); return modelAndView;}
void
表示handler不返回任何数据,用于当需要直接操作response完成响应的场景
例:
@RequestMapping("/test2")public void test2(String name,HttpServletResponse response) throws IOException { response.getWriter().println(name.toUpperCase());}
String
返回一个字符串类型的值,返回的内容可以是视图名称也可以是其他请求地址
其背后采用的是请求转发的方式
例:
@RequestMapping("/test3")public String test3(Model model) { model.addAttribute("msg","hello XXX"); return "index.jsp";}@RequestMapping("/test4")public String test4() { return "/test";}
转发和重定向:
也可指定对目标地址的请求是通过重定向或请求转发;
例:
@RequestMapping("/test5")public String test5() { return "forward:/index.jsp";}@RequestMapping("/test6")public String test6() { return "redirect:/index.jsp";}
当然了 默认就是forward所以可以省略;
json交互
当下,大多数公司都会有移动端App,当我们的后台服务需要为App提供接口时,就不得不使用到json数据了,当然还有前后端分离项目中前端和后台同样采用json来交换数据;
在开始前,需要导入jackson依赖,用于实现json的序列化与反序列化;
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.9</version></dependency>
返回json数据
@ResponseBody注解用于标注一个handler方法返回的是json数据,同时方法的返回值将作为返回给前台的数据;
例:
@RequestMapping("/getCourseList")@ResponseBodypublic List<Course> getCourseList() { //获取所有课程 return courseService.selectCourses();}@RequestMapping("/getCourse")@ResponseBodypublic Course getCourse(Integer id) {// 根据id获取一个课程 return courseService.selectByID(id);}
ResponseBody会将响应的ContentType设置为application/json, 然后调用jackson的toJsonString将返回值转为json字符串,最后返回给客户端;
@RestController
如果需要为每一个方法添加ResponseBody的话,就显得非常麻烦,SpringMVC提供了@RestController注解,表示这是一个所有handler返回值全都是json的Controller,相当于把Controller和ResponseBody两个注解合并在一起;
例:
@RestControllerpublic class CourseController {.....}
接受json数据
SpringMVC可以帮助我们将json参数反序列化到指定的实体类型,List或Map;
需要强调的是: 客户端必须指定ContenType为application/json
@RequestMapping("/addCourse")@ResponseBodypublic Course addCourse(@RequestBody Course course) {//接收json参数映射到实体 course.setName("接收json成功");//修改name再把数据发回去 以便查看效果 return course;}@RequestMapping("/addCourses")@ResponseBodypublic List<Course> addCourse(@RequestBody List<Course> courses) {//接收json数组参数映射到list return courses;}@RequestMapping("/addData")@ResponseBodypublic Map<String,String> addData(@RequestBody Map<String,String> data) {//接收json数据映射到map return data;}@RequestMapping("/addInfo")@ResponseBodypublic String addInfo(@RequestBody String data) {//接收json数据不做任何转换 return data;}
当客户端传递的json比较复杂时可能无法直接转换到某个实体类型,这是我们可以通过Map来接收,或直接获取原始的json字符串自己处理; 就像上面的 addData 和 addInfo 一样
Handler拦截器
顾名思义Handler拦截器可对Handler方法进行拦截,控制Handler方法是否执行,与Servlet的过滤器非常相似
但是要注意:
Servlet的filter的执行时机是在SpringMVC之前,过滤的目标对象是请求;
而Handler拦截器,拦截的目标对象是Handler方法
Handler拦截器可以方便的实现,登录状态验证,操作权限验证等操作;
使用案例:
1.编写拦截器
public class MyInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //在执行handler前调用 返回值将决定是否继续执行请求 System.out.println("preHandle"); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { //handler被真正执行了,已经拿到了handler的返回结果 但是DispatcherServlet还没有发送给前台 System.out.println("postHandle"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { //DispatcherServlet将视图发送给前台后的回调 (无论handler是否执行 一定有响应发给前台) System.out.println("afterCompletion"); //Handler中出现的任何异常也会传给该方法,可以在这里进行处理 if (ex != null){ System.out.println("handler中出现异常了...."); } }}
2.配置拦截器
<mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="com.kkb.interceptor.MyInterceptor"/> </mvc:interceptor></mvc:interceptors><!--* path用于指定拦截器拦截的url只有handler的url与之匹配才会被拦截 /** 表示拦截所有请求* interceptors中可配置多个interceptor -->
3.执行顺序
拦截器的执行顺序由配置顺序来决定,拦截器也和filter一样是一个链条的形式
在请求处理完成时,会按照相反的顺序通知interceptor(即执行afterComplation),前提是这个拦截器正常放行了请求(preHandler中返回了true),否则不会收到通知;
异常处理
一个完整的系统必然要考虑异常情况的处理,SpringMVC提供了一种非常方便的处理方法,只需要实现HandlerExceptionResolver接口,并注册Bean至容器中即可
1.编写异常处理器
@Componentpublic class MyExceptionHandler implements HandlerExceptionResolver { @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName("error.jsp"); modelAndView.addObject("exobj",ex); return modelAndView; }}
可以看到在处理方法的返回值为ModelAndView,我们需要在其中添加错误页面的名称和错误信息;
2.注册到容器中
可以直接添加Component注解或是,在配置文件中注册
<bean class="com.kkb.exceptionhandler.MyExceptionHandler"/>
强调:无论是拦截器还是异常处理器都是针对handler而不是所有请求,举个例子如果请求本身就是错误的如404,是无法被异常Handler异常处理器处理的,仍需要到web.xml来进行配置
SpringMVC 进阶版的更多相关文章
- zip伪加密文件分析(进阶版)
作者近日偶然获得一misc题,本来以为手到擒来,毕竟这是个大家都讨论烂了的题,详情访问链接http://blog.csdn.net/ETF6996/article/details/51946250.既 ...
- springMVC(注解版笔记)
springMVC(注解版) 较之于非注解版本,发生一下变化: 1.配置文件需要配置的标签有: <!-- 包的扫描,此包下面的所有包都启用注解 --> <context:compon ...
- python--代码统计(进阶版)
在上一篇的随笔中发表了代码统计小程序,但是发表后,我发现,以前写的代码怎么办 写了那么多,怎么就从0开始了呢,,,,我还是个孩子啊,不能这么残忍 于是,代码统计进阶版:统计当前目录下所有指定文件类型的 ...
- webpack4打包nodejs项目进阶版——多页应用模板
前段时间我写了个打包nodejs项目的文章,点击前往 但是,问题很多.因为之前的项目是个历史遗留项目,重构起来可能会爆炸,当时又比较急所以就写个的适用范围很小的webpack的打包方法. 最近稍微得空 ...
- 手机端页面自适应解决方案—rem布局进阶版
手机端页面自适应解决方案—rem布局进阶版 https://www.jianshu.com/p/985d26b40199 注:本文转载之处:https://www.cnblogs.com/anni ...
- MyBatis实操进阶版(一)
MyBatis实操进阶版(一) 目前而言,持久层框架中,在业务实现灵活性上,无可出MyBatis之右者.具体原因,后续将逐步展开 ResultMap元素的设置 配置文件中,ResultMap元素的作用 ...
- python三级菜单实例(傻瓜版和进阶版)
程序: python三级菜单 要求: : 1.打印省.市.县三级菜单 2.可返回上一级 3.可随时退出程序 方案一:傻瓜版(其实傻瓜版考察的主要是思路!思路清楚了,那才不是傻瓜!O(∩_∩)O哈哈~) ...
- BZOJ 2243 染色 | 树链剖分模板题进阶版
BZOJ 2243 染色 | 树链剖分模板题进阶版 这道题呢~就是个带区间修改的树链剖分~ 如何区间修改?跟树链剖分的区间询问一个道理,再加上线段树的区间修改就好了. 这道题要注意的是,无论是线段树上 ...
- 手机端页面自适应解决方案—rem布局(进阶版,附源码示例)
转自:https://segmentfault.com/a/1190000007350680 一年前笔者写了一篇 <手机端页面自适应解决方案—rem布局>,意外受到很多朋友的关注和喜欢.但 ...
随机推荐
- Power BI官方客户案例2021
微软商业应用峰会Power BI客户案例,今年的客户案例相比前2年不同,主要是大客户,基本都是行业Top公司. 选取零售,医药制造,教育,医疗IT等行业龙头.沃尔玛,拜耳,滑铁卢大学的分享内容非常棒, ...
- 依赖倒置原则(Dependence Inversion Principle)
目录 背景 说明 例子 "倒置"的解释 总结 参考资料 背景 这几天组内的人一起学习DDD,里面再次提到了依赖倒置原则,在这学习过程中,大家又讨论了一下依赖倒置原则. 说明 采用依 ...
- 手把手教你部署验证freeswitch(避免踩坑)
前言:请各大网友尊重本人原创知识分享,谨记本人博客:南国以南i 介绍:freeswitch可集成ASR(语音识别)和TTS(文本转语音)创建智能电话机器人和用户通话,可用于问卷调查,自动催缴等业务,电 ...
- 普里姆算法(Prim)
概览 普里姆算法(Prim算法),图论中的一种算法,可在加权连通图(带权图)里搜索最小生成树.即此算法搜索到的边(Edge)子集所构成的树中,不但包括了连通图里的所有顶点(Vertex)且其所有边的权 ...
- Mybatis-Plus的应用场景及注入SQL原理分析
一.背景 1.1 传统Mybatis的弊端 1.1.1 场景描述 假设有两张表:一张商品表.一张订单表,具体表的字段如下: 现有如下需求: 分别根据id查询商品表和订单表所有信息 根据支付状态和通知状 ...
- Msf--永恒之蓝 ms17_010
|>>>中华人民共和国网络安全法<<<|警告:请勿用于非法用途,后果自负! 简介 一.概述 永恒之蓝是指2017年4月14日晚,黑客团体Shadow Brokers ...
- k8s管理机密信息(12)
一.启动应用安全信息的保护 1.Secret介绍 应用启动过程中可能需要一些敏感信息,比如访问数据库的用户名密码或者秘钥.将这些信息直接保存在容器镜像中显然不妥,Kubernetes 提供的解决方案是 ...
- 「 刘一哥与GIS的故事 」专业技术博文专栏目录索引
刘一哥,多年研究地图学.地理信息系统.遥感.摄影测量和GPS等应用,精通ArcGIS.MapGIS.ENVI.Erdas.CASS.Pix4d.CC.PhotoScan.Inpho.EPS.Globa ...
- JavaSE-QuickStart
老话常说:基础不牢地动山摇,于是我在b站上看杨中科老师的课程脑补一下,便记录这岁月的点滴 1.什么是编程 ? 编程:编写能够控制计算机来执行特定任务的代码. 2.什么是编程语言 ? 编程语言:是指程序 ...
- springboot对mybatis的整合
1. 导入依赖 首先新建一个springboot项目,勾选组件时勾选Spring Web.JDBC API.MySQL Driver pom.xml配置文件导入依赖 <!--mybatis-sp ...