SpringMVC 进阶
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")
@ResponseBody
public List<Course> getCourseList() { //获取所有课程
return courseService.selectCourses();
}
@RequestMapping("/getCourse")
@ResponseBody
public 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两个注解合并在一起;
例:
@RestController
public class CourseController {.....}
接受json数据
SpringMVC可以帮助我们将json参数反序列化到指定的实体类型,List或Map;
需要强调的是:客户端必须指定ContenType为application/json
@RequestMapping("/addCourse")
@ResponseBody
public Course addCourse(@RequestBody Course course) {//接收json参数映射到实体
course.setName("接收json成功");//修改name再把数据发回去 以便查看效果
return course;
}
@RequestMapping("/addCourses")
@ResponseBody
public List<Course> addCourse(@RequestBody List<Course> courses) {//接收json数组参数映射到list
return courses;
}
@RequestMapping("/addData")
@ResponseBody
public Map<String,String> addData(@RequestBody Map<String,String> data) {//接收json数据映射到map
return data;
}
@RequestMapping("/addInfo")
@ResponseBody
public 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.编写异常处理器
@Component
public 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 进阶的更多相关文章
- SpringMVC进阶
1.springmvc(注解版本) 注解扫描 <?xml version="1.0" encoding="UTF-8"?> <beans xm ...
- SpringMVC进阶(二)
一.高级参数绑定 1.1. 绑定数组 Controller方法中可以用String[]接收,或者pojo的String[]属性接收.两种方式任选其一即可. /** * 包装类型 绑定数组类型,可以使用 ...
- SpringMVC 进阶版
请求限制 一些情况下我们可能需要对请求进行限制,比如仅允许POST,GET等... RequestMapping注解中提供了多个参数用于添加请求的限制条件 value 请求地址 path 请求地址 m ...
- springmvc进阶(5):mvc:default-servlet-handler详解
我们在配置dispatchServlet时配置<url-pattern>/</url-pattern>拦截所有请求,这时候dispatchServlet完全取代了default ...
- Spring注解开发系列VIII --- SpringMVC
SpringMVC是三层架构中的控制层部分,有过JavaWEB开发经验的同学一定很熟悉它的使用了.这边有我之前整理的SpringMVC相关的链接: 1.SpringMVC入门 2.SpringMVC进 ...
- JavaEE目录
第一章: Spring介绍 Spring项目搭建 Spring概念 第二章: Sprin配置详解 属性注入(构造方法注入,设值注入) 实例化(构造器(空参构造器),静态工厂,工厂方法) 装配(xml方 ...
- Spring+SpringMVC+MyBatis整合进阶篇(四)RESTful实战(前端代码修改)
前言 前文<RESTful API实战笔记(接口设计及Java后端实现)>中介绍了RESTful中后端开发的实现,主要是接口地址修改和返回数据的格式及规范的修改,本文则简单介绍一下,RES ...
- Spring+SpringMVC+MyBatis+easyUI整合进阶篇(十一)redis密码设置、安全设置
警惕 前一篇文章<Spring+SpringMVC+MyBatis+easyUI整合进阶篇(九)Linux下安装redis及redis的常用命令和操作>主要是一个简单的介绍,针对redis ...
- Spring+SpringMVC+MyBatis+easyUI整合进阶篇(十五)阶段总结
作者:13 GitHub:https://github.com/ZHENFENG13 版权声明:本文为原创文章,未经允许不得转载. 一 每个阶段在结尾时都会有一个阶段总结,在<SSM整合基础篇& ...
随机推荐
- js获取当前农历时间
<template> <div class="gaia-header"> <img alt="gaia_logo" src=&qu ...
- 《带你装B,带你飞》pytest成神之路2- 执行用例规则和pycharm运行的三种姿态
1. 简介 今天北京下的雪好大好美啊!!!哎呀,忘记拍照片了,自己想象一下吧.言归真传,今天还是开始pytest的学习和修炼,上一篇写完后群里反响各式各样的,几家欢乐几家愁,有的高兴说自己刚好要用到了 ...
- 1034 有理数四则运算 (20 分)C语言
题目描述 本题要求编写程序,计算2个有理数的和.差.积.商. 输入描述: 输入在一行中按照"a1/b1 a2/b2"的格式给出两个分数形式的有理数,其中分子和分母全是整型范围内的整 ...
- HTTP Strict Transport Security (HSTS) in ASP.NET Core
本文是<9012年了,还不会Https>的后篇,本文着重聊一聊 HTTP Strict Transport Security协议的概念和应用. 启用HTTPS还不够安全 站点通过HTTPS ...
- css部分概念
1.层叠 规则之间属性相同,值不同的时候就会发生声明冲突,这个时候层叠就会起作用了,层叠会将我们声明的不同的值进行保留,相同的值进行比较,选权重值更高的一个来运行.具体情境如下:假设我们定义了一个di ...
- SqlServer数据库知识点笔记
1.主键约束: 要对一个列加主键约束的话,这列就必须要满足的条件就是非空 因为主键约束:就是对一个列进行了约束,约束为(非空.不重复) 以下是代码 要对一个列加主键,列名为id,表名为emp 格式 ...
- 【转】ArcGIS Server 10.1 动态图层
ArcGISServer将GIS资源以服务的方式发布,能够让更多的人在Web上浏览.使用.不过,诸如气象.环保等方面的信息是实时变化的,按照之前常规的方法,我们先要将最新获得的信息组织成地图文档后再对 ...
- opencv利用svm训练
]]]]]])rand2 = np.array([[]]]]]])label = np.array([[]]]]]]]]]]])data = np.vstack((rand1]]])pt_data = ...
- JUnit 5和Selenium基础(三)
在这一部分教程中,将介绍JUnit 5的其他功能,这些功能将通过并行运行测试,配置测试顺序和创建参数化测试来帮助减少测试的执行时间.还将介绍如何利用Selenium Jupiter功能,例如通过系统属 ...
- cogs 1176. [郑州101中学] 月考 字典树
1176. [郑州101中学] 月考 ★★☆ 输入文件:mtest.in 输出文件:mtest.out 简单对比时间限制:1 s 内存限制:128 MB [题目描述] 在上次的月考中B ...