SpringMVC 响应返回值类型笔记

对应代码:com.qcby.controller.BackValueController 类上一级映射 @RequestMapping("/hello") 视图解析器配置:prefix = /WEB-INF/pages/ suffix = .jsp 即 return "suc" 最终跳转 /WEB-INF/pages/suc.jsp

总览

序号 返回值类型 关键点 访问路径
1 String(视图名) 走视图解析器拼接前后缀 /hello/test
2 void 使用 request response 原生 API 自行完成响应 /hello/test1
3 ModelAndView 视图名和数据一次性返回 /hello/test2
4 Model + String Model 存放数据 String 返回视图名 /hello/test3
5 String + forward: 请求转发 可以访问 WEB-INF 资源 /hello/test4
6 String + redirect: 重定向 浏览器地址发生改变 /hello/test5
7 @ResponseBody + Java 对象 对象转为 JSON 写入响应体 多用于 ajax 请求 /hello/test6

1 返回 String 走视图解析器

这是最基础的返回方式 返回字符串会被识别为逻辑视图名 交由视图解析器拼接前缀后缀 完成页面跳转

复制代码
@RequestMapping("/test")
public String sayhello() {
    System.out.println("返回String走视图解析器");
    return "suc";
}

注意事项

1 最终访问地址为类注解地址拼接方法注解地址 /hello/test

2 拼接规则 prefix + 返回值 + suffix 返回值不需要书写路径和后缀.jsp

3 底层本质是请求转发 浏览器地址栏不会变化 属于一次请求

2 返回 void 使用 Servlet 原生 API 响应

方法返回值为 void 时 SpringMVC 认为由开发者手动处理响应逻辑 有三种常用实现方式

复制代码
@RequestMapping("/test1")
public void sayhello01(HttpServletRequest request, HttpServletResponse response) {
    System.out.println("返回void第二种响应请求形式");
    // 方式一 直接向页面输出文本数据
    response.getWriter().write("asda");
    // 方式二 请求转发 可以访问WEB-INF下资源
    // request.getRequestDispatcher("/WEB-INF/pages/suc.jsp").forward(request, response);
    // 方式三 重定向跳转
    // response.sendRedirect("https://www.baidu.com");
}

注意事项

1 void 方法内如果已经执行 write 输出数据 不能再返回视图名 否则框架继续执行视图转发会清空缓冲区 页面内容丢失甚至抛出异常

2 请求转发和重定向只能选择一种 并且要在输出内容之前执行

3 该方式不会使用视图解析器的前后缀配置 资源路径必须写完整

3 返回 ModelAndView 视图和数据一起返回

复制代码
@RequestMapping("/test2")
public ModelAndView sayhello02() {
    ModelAndView mv = new ModelAndView();
    mv.setViewName("suc");
    mv.addObject("msg", "返回modelAndView对象成功");
    return mv;
}

suc.jsp 页面使用 EL 表达式取值 ${msg}

注意事项

1 setViewName 填写逻辑视图名 会自动走视图解析器

2 addObject 等价于 request.setAttribute 数据存入 request 域

3 适合同时需要页面跳转和携带数据的场景 是早期比较常用写法

4 返回 String 搭配 Model 参数 数据视图分离

复制代码
@RequestMapping("/test3")
public String sayhello03(Model model) {
    System.out.println("返回String第四种响应请求形式");
    model.addAttribute("msg", "返回model+String形式");
    return "suc";
}

注意事项

1 Model 对象由 SpringMVC 自动注入 不需要手动 new 创建

2 和 ModelAndView 最终效果完全一致 写法更加简洁

3 Model Map 都可以用来向 request 域存放数据

5 返回 forward: 请求转发

复制代码
@RequestMapping("/test4")
public String sayhello04() {
    System.out.println("返回字符串第五种响应请求形式,是请求转发");
    return "forward:/WEB-INF/pages/suc.jsp";
}

注意事项

1 返回字符串携带 forward 前缀时 不再经过视图解析器 路径必须写完整

2 WEB-INF 目录资源无法直接通过浏览器访问 只能依靠请求转发访问

3 浏览器地址栏不变 一次请求 request 域中的数据可以共享

4 不能转发到当前项目以外的外部地址

6 返回 redirect: 重定向

复制代码
@RequestMapping("/test5")
public String sayhello05() {
    System.out.println("返回字符串第六种响应请求形式,是重定向");
    return "redirect:https://www.baidu.com";
}

注意事项

1 跳转到外部网址时 redirect 后不能添加前置 / 如果写 redirect:/百度一下,你就知道 Spring 会识别为项目内路径 出现 404

2 项目内部重定向路径开头加 / 代表从项目根路径匹配 例如 redirect:/hello/test

3 浏览器地址栏会更新 属于两次请求 request 域的数据会丢失

4 重定向不能访问 WEB-INF 内部资源

forward 与 redirect 对比

对比项 forward 请求转发 redirect 重定向
请求次数 1 次 2 次
地址栏状态 不变 改变
request 域数据 可以共享 数据丢失
访问 WEB-INF 支持 不支持
跳转外部地址 不支持 支持
书写格式 return "forward:/ 路径" return "redirect:/ 路径"

7 @ResponseBody Java 对象转为 JSON 返回

多用于前后端分离或者 ajax 异步请求 返回值不再当做视图名称 直接写入响应体给到前端

复制代码
@ResponseBody
@RequestMapping("/test6")
public User sayhello06(String username, Integer age) {
    System.out.println("返回java对象转变为json数据第七种响应请求形式");
    System.out.println(username);
    System.out.println(age);
    User user1 = new User();
    user1.setUsername("小萌");
    user1.setSex("女");
    return user1;
}

前端 ajax 代码 index.jsp

复制代码
$("#btn").click(function () {
    $.ajax({
        type: "post",
        url: "/hello/test6",
        data: {"username": "haha", "age": "20"},
        dataType: "json",
        success: function (d) {
            alert(d.username + " - " + d.sex);
        }
    });
});

注意事项

1 需要引入 jackson 相关依赖 jackson-databind jackson-core jackson-annotations 缺少依赖会抛出 No converter found for return value of type 异常

2 实体类必须提供无参构造方法和 getter 方法 没有 getter 的字段不会序列化到 JSON

3 当前后端传递普通键值对 后端直接用普通形参接收 如果前端传递 application/json 格式 JSON 字符串 后端需要搭配 @RequestBody 接收 两种接收方式不能混用 混用会出现参数 null

4 方法添加 @ResponseBody 后 不会进入视图解析器 就算返回普通字符串 也会直接把文本输出到页面

5 在 Controller 类上添加 @ResponseBody 等价于 @RestController 该类全部方法都会直接返回数据 不再跳转视图

易错点速查

1 void 方法内执行 response.getWriter ().write 之后 不要再返回视图名

2 redirect 跳转外部地址不要加前置 / 项目内重定向路径需要加 /

3 forward 需要写完整路径 支持访问 WEB-INF redirect 不支持访问 WEB-INF

4 @ResponseBody 需要 jackson 依赖 实体类要有无参构造和 getter

5 application/json 请求搭配 @RequestBody 普通键值对使用普通参数接收 不要混用

相关推荐
小羊没烦恼!3 天前
Ajax与JSON的一些总结
android·java·前端·数据库·mysql·算法·okhttp
脉动数据行情4 天前
Java OkHttp 对接国际期货批量行情 SpringBoot 定时落库实践
java·spring boot·okhttp
牧瀬クリスだ9 天前
Ajax入门:从原生XHR到axios实战
java·spring boot·ajax·okhttp
墨天梦13 天前
B15_HTTP解析与OkHttp拦截器
网络协议·http·okhttp
没差c1 个月前
RetrofitClient写接口、导包、配置、路径
java·spring boot·okhttp
事圆则缓1 个月前
OkHttp + Retrofit 协作原理
okhttp·retrofit
降临-max1 个月前
接口自动化(TestNG+OKHttp)
软件测试·okhttp·自动化·testng
吴声子夜歌1 个月前
Java扩展——OkHttp
java·开发语言·okhttp
额鹅恶饿呃2 个月前
Asynchronous JavaScript And XML(异步的JS和XML )
okhttp