文章目录
一、Spring MVC响应视图
Spring MVC 支持多种视图响应方式,包括字符串类型、ModelAndView 类型、JSON 类型
1、以字符串的方式响应网页
在 Spring MVC 的业务控制器方法中,如果返回值为 String 类型,同时处理方式没有定义为 JSON 方式,那么 Spring MVC 将会将该字符串的值作为网页地址或者逻辑视图来处理。
例如:
@RequestMapping("test")
public String test() {
return "success.jsp";
}
在上述方法中最终返回值是 success.jsp,那么 Spring-mvc 将以相对路径的方式去查找 success.jsp 网页并响应。
为了便于响应网页文件,Spring-mvc 提供了视图解析器,只返回一个逻辑视图名称的时候,视图解析器会把该逻辑视图名称解析为真正的视图 View 对象,视图解析器的配置如下,在 Spring-mvc 的配置文件中,使用 bean 标签加载视图解析器:
<!--配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
这样在 Controller 层就可以直接返回 success
@RequestMapping("test")
public String test() {
return "success";
}
prefix 为网页所在逻辑视图追加的前缀,suffix 为逻辑视图追加的后缀。例如我们在方法中返回 success,那么视图解析器通过解析之后在 success 逻辑视图上添加上前缀和后缀,最后响应的网页地址为/success.jsp
。
在定义了视图解析器的情况下,依然可以在返回值中使用网页文件的完整路径进行响应。默认情况下视图解析器将会采用转发的方式响应网页信息,可以在逻辑视图名称进行修饰,进行转发或者重定向。
return "redirect:success.jsp"; //重定向
return "forward:success.jsp"; //转发
如果要手动定义转发或者重定向,那么返回值中就不能写逻辑视图必须写网页文件的路径
如果需要在响应的 jsp 中使用动态数据,我们可以将 request 对象绑定包方法的形参中,然后将数据保存在 request 作用域中进行响应。
2、响应 ModelAndView 对象
在 web 项目中如果要响应网页信息,那么网页中通常都包含了动态数据,Spring-mvc 专门提供了一种包含数据的视图解析方式,也就是 ModelAndView。
ModelAndView 是 Spring-mvc 中的一个类,该类可以同时指定视图地址和需要保存到 request 作用域中的数据
@RequestMapping("test")
public ModelAndView test() {
ModelAndView mav = new ModelAndView();
mav.setViewName("success.jsp");
mav.addObject("name", "张三");
return mav;
}
addObject(key,value)
方法用于指定要保存到 request 作用域中的数据,key 最终会作为 request 作用域中数据的键。
addObject(value)
方法用于指定要保存到 request 作用域中的数据,如果保存的是一个实体类对象,那么key=实体类对象类名首字母小写
,如果保存的是一个集合数据,那么key=集合的泛型首字母小写+List
。
3、响应 JSON 数据
Spring-mvc 也可以响应 json 类型的数据,步骤非常的简单。
(1)导入 jackson 相关包
(2)需要将什么数据使用 json 的方式响应给客户端,就将方法的返回值定义为该数据类型,例如:想将 Users 对象数据以 json 的形式响应给客户端,方法的返回值就定义为 Users 类型,如果想响应一个 Users 类型的集合数据,就将方法的返回值定义为集合类型。
public Users test() {
Users users = new Users();
users.setUserName("张三");
users.setUserPassword("zhangsan");
return users;
}
(3)在方法上添加注解,@ResponseBody
表示该方法的返回值将采用 json 的形式返回给客户端。
@RequestMapping(value="test")
@ResponseBody
public Users test() {
Users users = new Users();
users.setUserName("张三");
users.setUserPassword("zhangsan");
return users;
}
(4)如果一个业务控制器中的所有方法都采用 json 的方式响应数据,那么可以在类上使用全局的设置,将@Controller
注解替换为@RestController
,如此就不需要在每一个方法上都添加@ResponseBody
注解。
@RestController
public class UserController {
@RequestMapping(value="test")
public Users test() {
Users users = new Users();
users.setUserName("张三");
users.setUserPassword("zhangsan");
return users;
}
}
(4)响应 JSON 示例
① 前端 ajax 请求
<script type="text/javascript">
$.ajax({
url: "ajax.do",
type: "post",
data: {"id":1},
dataType: "json",
success:function(data){
for(var i = 0; i < data.list.length; i++){
console.log(data.list[i].userName);
}
}
});
</script>
② Controller 层
@Controller
public class UserController {
@RequestMapping("ajax")
@ResponseBody
public ResultModel ajax(int id) {
System.out.println(id);
Users users1 = new Users();
users1.setUserName("张三");
Users users2 = new Users();
users2.setUserName("李四");
Users users3 = new Users();
users3.setUserName("王五");
List<Users> list = new ArrayList<Users>();
list.add(users1);
list.add(users2);
list.add(users3);
return new ResultModel(list, null, "success", null);
}
}
③ ResultModel 实体类
public class ResultModel {
private List list; //集合封装
private Object object; //对象封装
private String code; //反馈信息
private String message; //显示错误信息
public ResultModel() {}
public ResultModel(List list, Object object, String code, String message) {
this.list = list;
this.object = object;
this.code = code;
this.message = message;
}
//省略set、get方法
}
二、Spring MVC 统一异常处理
在编程过程中异常处理往往是一件很麻烦的事情,Spring-mvc 提供了异常处理器,在设计程序时每一层的异常不需要自己处理,而是选择逐层的抛出,也就是dao->service->controller->异常处理器
,最终在异常处理器中对异常进行统一的处理。
1、普通请求方式异常处理
(1)自定义异常处理器类
public class ExceptionResolver implements HandlerExceptionResolver{
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object object, Exception ex) {
ModelAndView mav = new ModelAndView();
mav.setViewName("error.jsp");
mav.addObject("message", "服务器内部错误");
return mav;
}
}
(2)根据视图解析器的配置在项目中新建错误页面
<body>
错误界面
${message}
</body>
(3)加载异常处理器
① 第一种方式:
<!-- 配置异常处理加载器 -->
<bean class="com.springmvc.demo1.exception.ExceptionResolver"></bean>
② 第二种方式
在自定义异常处理器类上添加@Component
注解
@Component
public class ExceptionResolver implements HandlerExceptionResolver{
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object object, Exception ex) {
ModelAndView mav = new ModelAndView();
mav.setViewName("error");
return mav;
}
}
然后通过配置扫描实体类的地址的配置进行自定义异常处理类的加载
<context:component-scan base-package="com.springmvc.demo1.exception"></context:component-scan>
(4)在控制层中定义方法时,将异常抛出
@Controller
public class UserController throws Exception {
@RequestMapping("test")
public String test() throws Exception{
System.out.println("自定义异常处理器");
//触发异常
int i = 1/0;
return "success.jsp";
}
}
2、AJAX 请求方式异常处理
(1)导入 fastjson 的 jar 包
(2)自定义异常处理器类
public class ExceptionResolver implements HandlerExceptionResolver{
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object object, Exception ex) {
FastJsonJsonView view = new FastJsonJsonView()
Map<String, Object> map = new HashMap<String, Object>();
map.put("code", "error.jsp");
map.put("message", "服务器内部错误");
view.setAttributesMap(map);
ModelAndView mav = new ModelAndView();
mav.setView(view);
return mav;
}
}
(3)ajax 请求页面
<body>
<script type="text/javascript">
$.ajax({
url: "ajax.do",
type: "post",
data: {"id":1},
dataType: "json",
success:function(data){
console.log(data);
}
});
</script>
</body>
(4)加载异常处理器(与普通类请求一样)
① 第一种方式:
<!-- 配置异常处理加载器 -->
<bean class="com.springmvc.demo1.exception.ExceptionResolver"></bean>
② 第二种方式
在自定义异常处理器类上添加@Component
注解
@Component
public class ExceptionResolver implements HandlerExceptionResolver{
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object object, Exception ex) {
ModelAndView mav = new ModelAndView();
mav.setViewName("error");
return mav;
}
}
然后通过配置扫描实体类的地址的配置进行自定义异常处理类的加载
<context:component-scan base-package="com.springmvc.demo1.exception"></context:component-scan>
(5)在控制层中定义方法时,将异常抛出
@Controller
public class UserController {
@RequestMapping("ajax")
@ResponseBody
public String ajax(int id) {
int i = 1 / 0;
return "success.jsp";
}
}