6. 方法返回值
控制器的目标最终要给浏览器客户端进行响应(内容:html、json-js、ajax)
6.1. void
返回值是void以为着需要编程进行相应,方法入参需要显示的声明request、response.
6.1.1. 使用request转向页面,
如下:
request.getRequestDispatcher("页面路径").forward(request, response);
6.1.2. 可以通过response页面重定向:
response.sendRedirect("url")
6.1.3. 可以通过response指定响应结果,
例如响应json数据如下:
response.setCharacterEncoding("utf-8");
response.setContentType("application/json;charset=utf-8");
response.getWriter().write("json串");
java
@RequestMapping("/req1")
public void req1(HttpServletRequest request, HttpServletResponse response) throws IOException {
System.out.println("测试在方法中定义@RequestMapping注解");
PrintWriter out = response.getWriter();
out.println("req1:"+new Date().getTime());
out.flush();
out.close();
}
6.1.4 整合jdbc
- 添加依赖
- spring-jdbc
- JDBCTemplate
- spring-context
- mysql驱动
- spring-test
- junit4
- 数据源
- DBCP、C3P0、DRUID-CP、HikariCP Connection Pool
- spring-jdbc
- 在容器中声明声明数据源、JDBCTemplate
- 使用JDBCTemplate封装Dao UserDao
- insert
- delete
- update
- selectList
- selectById
- Service
- Controller使用service
- MVC使用 ModelAndView
xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.neuedu.mvc</groupId>
<artifactId>p17-springmvc-url-mappging</artifactId>
<version>1.0-SNAPSHOT</version>
<name>p17-springmvc-url-mappging</name>
<packaging>war</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.target>11</maven.compiler.target>
<maven.compiler.source>11</maven.compiler.source>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
</dependency>
<!-- 数据库的驱动 com.mysql.cj.jdbc.Driver-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.21</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.2</version>
</plugin>
</plugins>
</build>
</project>
xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.neuedu.mvc"></context:component-scan>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="username" value="root"/>
<property name="password" value="root"/>
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/jdbctemp"/>
</bean>
<bean class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
</beans>
java
package com.neuedu.mvc.entity;
import java.util.Date;
/**
* 用户的实体对象
*/
public class User {
private Integer userId;
private String userName;
private String gender;
private Date birthday;
private Integer status;
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
@Override
public String toString() {
return "User{" +
"userId='" + userId + '\'' +
", userName='" + userName + '\'' +
", gender='" + gender + '\'' +
", birthday=" + birthday +
", status=" + status +
'}';
}
}
java
package com.neuedu.mvc.dao;
import com.neuedu.mvc.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* 项目: spring-framework
* 类名: UserDao
* 创建时间: 2024/3/14 08:49
* 描述 :
* 作者 : 张金山
* QQ : 314649444
* Site: https://jshand.gitee.io
*/
@Repository
public class UserDao {
@Autowired
JdbcTemplate jdbcTemplate;
/**
* 查询集合
* @return
*/
public List<Map<String ,Object>> selectListMap(){
String sql = "select * from t_user ";
List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
return maps;
}
/**
* 查询集合
* @return
*/
public List<User> selectListEntity(){
String sql = "select * from t_user ";
List<User> userList = jdbcTemplate.query(sql, new BeanPropertyRowMapper<User>(User.class));
return userList;
}
public User selectByIdEntiry(int id) {
String sql = "select * from t_user where user_id = ? ";
User user = jdbcTemplate.queryForObject(sql, new Object[]{id}, new BeanPropertyRowMapper<User>(User.class));
return user;
}
/**
* 根据主键查询单条结果
* @return
*/
public User selectById(int id){
String sql = "select * from t_user where user_id = ? ";
// Map<String, Object> row = jdbcTemplate.queryForMap(sql, id);
// System.out.println("row = " + row);
User user = jdbcTemplate.queryForObject(sql, new Object[]{id}, new RowMapper<User>() {
@Override
public User mapRow(ResultSet resultSet, int i) throws SQLException {
int userId = resultSet.getInt("user_id");
String userName = resultSet.getString("user_name");
String gender = resultSet.getString("gender");
Date birthday = resultSet.getTimestamp("birthday");
int status = resultSet.getInt("status");
User user = new User();
user.setUserId(userId);
user.setUserName(userName);
user.setGender(gender);
user.setBirthday(birthday);
user.setStatus(status);
return user;
}
});
return user;
}
/**
* 根据主键查询单条结果
* @return
*/
public int selectCount(){
String sql = "select count(*) from t_user ";
Integer count = jdbcTemplate.queryForObject(sql, Integer.class);
return count;
}
public int insert(User user){
String sql = "insert into t_user(user_id,user_name,gender,birthday,status) values(?,?,?,?,?)";
return jdbcTemplate.update(sql,
user.getUserId(),
user.getUserName(),
user.getGender(),
user.getBirthday(),
user.getStatus()
);
}
public int updateById(User user){
StringBuffer sql = new StringBuffer();
sql.append(" update ");
sql.append(" `t_user` set ");
sql.append(" `user_name` = ?, ");
sql.append(" `gender` = ?, ");
sql.append(" `birthday` = ?, ");
sql.append(" `status` = ? where `user_id` = ? ");
return jdbcTemplate.update(sql.toString(), user.getUserName(),user.getGender(),user.getBirthday(),user.getStatus(),user.getUserId() );
}
public int deleteById(int id){
String sql = "delete from t_user where user_id = ?";
return jdbcTemplate.update(sql, id );
}
}
java
package com.neuedu.mvc.dao;
import com.neuedu.mvc.entity.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.List;
import static org.junit.Assert.*;
/**
* 项目: spring-framework
* 类名: UserDaoTest
* 创建时间: 2024/3/19 09:21
* 描述 :
* 作者 : 张金山
* QQ : 314649444
* Site: https://jshand.gitee.io
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring-mvc.xml")
public class UserDaoTest {
@Autowired
private UserDao userDao;
@Test
public void selectListEntity() {
List<User> users = userDao.selectListEntity();
for (User user : users) {
System.out.println("user = " + user);
}
}
}
java
package com.neuedu.mvc.service;
import com.neuedu.mvc.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import javax.servlet.http.HttpServletRequest;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* 项目: spring-framework
* 类名: IUserService
* 创建时间: 2024/3/19 09:24
* 描述 :
* 作者 : 张金山
* QQ : 314649444
* Site: https://jshand.gitee.io
*/
public interface IUserService {
/**
* 查询集合
* @return
*/
public List<Map<String ,Object>> selectListMap();
/**
* 查询集合
* @return
*/
public List<User> selectListEntity();
public User selectByIdEntiry(int id);
/**
* 根据主键查询单条结果
* @return
*/
public User selectById(int id);
/**
* 根据主键查询单条结果
* @return
*/
public int selectCount();
public boolean insert(User user);
public boolean updateById(User user);
public boolean deleteById(int id);
}
java
package com.neuedu.mvc.service.impl;
import com.neuedu.mvc.dao.UserDao;
import com.neuedu.mvc.entity.User;
import com.neuedu.mvc.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
/**
* 项目: spring-framework
* 类名: UserServiceImpl
* 创建时间: 2024/3/19 09:28
* 描述 :
* 作者 : 张金山
* QQ : 314649444
* Site: https://jshand.gitee.io
*/
@Service
public class UserServiceImpl implements IUserService {
@Autowired
private UserDao userDao;
@Override
public List<Map<String, Object>> selectListMap() {
return userDao.selectListMap();
}
@Override
public List<User> selectListEntity() {
return userDao.selectListEntity();
}
@Override
public User selectByIdEntiry(int id) {
return userDao.selectByIdEntiry(id);
}
@Override
public User selectById(int id) {
return userDao.selectByIdEntiry(id);
}
@Override
public int selectCount() {
return userDao.selectCount();
}
@Override
public boolean insert(User user) {
return userDao.insert(user)>0;
}
@Override
public boolean updateById(User user) {
return userDao.updateById(user)>0;
}
@Override
public boolean deleteById(int id) {
return userDao.deleteById(id)>0;
}
}
java
package com.neuedu.mvc.service.impl;
import com.neuedu.mvc.entity.User;
import com.neuedu.mvc.service.IUserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static org.junit.Assert.*;
/**
* 项目: spring-framework
* 类名: UserServiceImplTest
* 创建时间: 2024/3/19 09:30
* 描述 :
* 作者 : 张金山
* QQ : 314649444
* Site: https://jshand.gitee.io
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring-mvc.xml")
public class UserServiceImplTest {
@Autowired
IUserService userService;
@Test
public void insert() {
User user = new User();//模拟从页面接收的参数表单
user.setUserId(101);
user.setUserName("MVC");
boolean success = userService.insert(user);
System.out.println("success = " + success);
}
}
6.2. ModelAndView
自己设置model 和视图,由【视图解析器】进行渲染响应(html)
6.2.1. 添加jstl依赖
xml
<!-- https://mvnrepository.com/artifact/jstl/jstl -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
6.2.2. 使用servlet-3.0的版本
6.2.3. 映射的方法
java
package com.neuedu.mvc.controller;
import com.neuedu.mvc.entity.User;
import com.neuedu.mvc.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
/**
* 项目: spring-framework
* 类名: UserController
* 创建时间: 2024/3/18 16:23
* 描述 :
* 作者 : 张金山
* QQ : 314649444
* Site: https://jshand.gitee.io
*/
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
IUserService userService;
/**
* http://localhost:8080/web/user/list
* @param request
* @param response
* @return
* @throws ServletException
* @throws IOException
*/
@RequestMapping("/list")
public ModelAndView list(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ModelAndView mv = new ModelAndView();
mv.addObject("userList",userService.selectListEntity());
mv.setViewName("/WEB-INF/jsp/user/user_list.jsp");
return mv;
}
@RequestMapping("toAdd")
public ModelAndView toAdd(){
ModelAndView mv = new ModelAndView();
mv.setViewName("/WEB-INF/jsp/user/user_add.jsp");
return mv;
}
@RequestMapping("add")
public ModelAndView add(HttpServletRequest request) throws ParseException {
// 获取参数
String userId = request.getParameter("userId");
String userName = request.getParameter("userName");
String birthday = request.getParameter("birthday");// "2024-03-19" "asdfasfasdfas"
String gender = request.getParameter("gender");
String status = request.getParameter("status");
//调用service保存
User user = new User();
user.setUserId(Integer.parseInt(userId));
user.setUserName(userName);
user.setBirthday(new SimpleDateFormat("yyyy-MM-dd").parse(birthday));
user.setGender(gender);
user.setStatus(Integer.parseInt(status));
boolean success = userService.insert(user);
ModelAndView mv = new ModelAndView();
if(success) {
mv.setViewName("/user/list");
}else{
mv.setViewName("/WEB-INF/jsp/user/user_add.jsp");
}
return mv;
}
}
6.2.4. 跳转的jsp
页面放置在 WEB-INF/jsp/user/user_list.jsp
和 /WEB-INF/jsp/user/user_add.jsp
html
<%@ page import="java.util.List" %>
<%@ page import="com.neuedu.mvc.entity.User" %><%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2024/3/18
Time: 16:26
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--<%--%>
<%-- List<User> userList = (List<User>) request.getAttribute("userList");--%>
<%--%>--%>
<h3>用户列表: </h3>
<a href="${pageContext.request.contextPath}/user/toAdd">添加</a>
<table cellspacing="0" cellpadding="0" width="100%" border="1">
<tr>
<td>序号</td>
<td>用户id</td>
<td>用户名</td>
<td>性别</td>
<td>出生日期</td>
<td>状态</td>
</tr>
<c:forEach items="${userList}" var="user" varStatus="status">
<tr>
<td>${status.count}</td>
<td>${user.userId}</td>
<td>${user.userName}</td>
<td>${user.gender}</td>
<td>${user.birthday}</td>
<td>${user.status}</td>
</tr>
</c:forEach>
</table>
</body>
</html>
html
<%@ page import="java.util.List" %>
<%@ page import="com.neuedu.mvc.entity.User" %><%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2024/3/18
Time: 16:26
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--<%--%>
<%-- List<User> userList = (List<User>) request.getAttribute("userList");--%>
<%--%>--%>
<h3>用户列表: </h3>
<form action="${pageContext.request.contextPath}/user/add" method="post">
<table>
<tr>
<td>用户ID</td>
<td> <input type="text" name="userId" value=""> </td>
</tr>
<tr>
<td>用户名</td>
<td> <input type="text" name="userName" value=""> </td>
</tr>
<tr>
<td>出生日期("2024-03-19")</td>
<td> <input type="text" name="birthday" value=""> </td>
</tr>
<tr>
<td>性别</td>
<td> <input type="text" name="gender" value=""> </td>
</tr>
<tr>
<td>状态</td>
<td> <input type="text" name="status" value=""> </td>
</tr>
<tr>
<td>
<button type="submit">提交</button>
<button type="reset">重置</button>
</td>
</tr>
</table>
</form>
</body>
</html>
6.2.5. 测试
6.3. 视图解析器
6.4. String
6.4.1. 代表视图名称
根据视图解析器配置的前缀、后缀,自动的匹配完整的路径
xml
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp"></property>
<property name="suffix" value=".jsp"></property>
</bean>
6.4.1.1. 映射方法
默认的是内部跳转,可以使用request共享数据,视图名称会受视图解析器的前后缀影响
- 重定向和内部跳转
内部跳转 不会受视图解析器的前后缀影响,路径需要写完整,WEB-INF目录中的资源不能被浏览器直接访问,可以通过内部跳转的形式进行访问,目录是安全。可以在Controller和JSP中共享requst对象(下面代码90和100行)
重定向不能共享request(如下88行)
java
package com.neuedu.mvc.controller;
import com.neuedu.mvc.entity.User;
import com.neuedu.mvc.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
/**
* 项目: spring-framework
* 类名: UserController
* 创建时间: 2024/3/18 16:23
* 描述 :
* 作者 : 张金山
* QQ : 314649444
* Site: https://jshand.gitee.io
*/
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
IUserService userService;
/**
* http://localhost:8080/web/user/list
* @param request
* @param response
* @return
* @throws ServletException
* @throws IOException
*/
@RequestMapping("/list")
public ModelAndView list(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ModelAndView mv = new ModelAndView();
mv.addObject("userList",userService.selectListEntity());
mv.setViewName("/user/user_list");
return mv;
}
// @RequestMapping("toAdd")
// public ModelAndView toAdd(){
// ModelAndView mv = new ModelAndView();
// mv.setViewName("/user/user_add");
// return mv;
// }
@RequestMapping("toAdd")
public String toAdd(){
return "/user/user_add";
}
@RequestMapping("add")
public String add(HttpServletRequest request) throws ParseException {
// 获取参数
String userId = request.getParameter("userId");
String userName = request.getParameter("userName");
String birthday = request.getParameter("birthday");// "2024-03-19" "asdfasfasdfas"
String gender = request.getParameter("gender");
String status = request.getParameter("status");
//调用service保存
User user = new User();
user.setUserId(Integer.parseInt(userId));
user.setUserName(userName);
user.setBirthday(new SimpleDateFormat("yyyy-MM-dd").parse(birthday));
user.setGender(gender);
user.setStatus(Integer.parseInt(status));
boolean success = userService.insert(user);
String path = "";
if(success) {
// 重定向
// redirect 和 forward 使用的不带前缀和后缀的视图层处理
path = "redirect:/user/list";
}else{
path = "/user/user_add";
}
return path;
}
@RequestMapping("forward")
public ModelAndView forward(HttpServletRequest request) throws ParseException {
ModelAndView mv = new ModelAndView();
// mv.setViewName("/dept/dept_add.jsp");
mv.setViewName("forward:/dept/dept_add.jsp");
return mv;
}
}
下表描述了支持的控制器方法返回值
Controller method return value | Description |
---|---|
@ResponseBody | The return value is converted through HttpMessageConverter implementations and written to the response. See @ResponseBody . |
HttpEntity<B> , ResponseEntity<B> | The return value that specifies the full response (including HTTP headers and body) is to be converted through HttpMessageConverter implementations and written to the response. See ResponseEntity. |
HttpHeaders | For returning a response with headers and no body. |
String | A view name to be resolved with ViewResolver implementations and used together with the implicit model — determined through command objects and @ModelAttribute methods. The handler method can also programmatically enrich the model by declaring a Model argument (see Explicit Registrations). |
View | A View instance to use for rendering together with the implicit model — determined through command objects and @ModelAttribute methods. The handler method can also programmatically enrich the model by declaring a Model argument (see Explicit Registrations). |
java.util.Map , org.springframework.ui.Model | Attributes to be added to the implicit model, with the view name implicitly determined through a RequestToViewNameTranslator . |
@ModelAttribute | An attribute to be added to the model, with the view name implicitly determined through a RequestToViewNameTranslator .Note that @ModelAttribute is optional. See "Any other return value" at the end of this table. |
ModelAndView object | The view and model attributes to use and, optionally, a response status. |
void | A method with a void return type (or null return value) is considered to have fully handled the response if it also has a ServletResponse , an OutputStream argument, or an @ResponseStatus annotation. The same is also true if the controller has made a positive ETag or lastModified timestamp check (see Controllers for details).If none of the above is true, a void return type can also indicate “no response body” for REST controllers or a default view name selection for HTML controllers. |
DeferredResult<V> | Produce any of the preceding return values asynchronously from any thread — for example, as a result of some event or callback. See Asynchronous Requests and DeferredResult . |
Callable<V> | Produce any of the above return values asynchronously in a Spring MVC-managed thread. See Asynchronous Requests and Callable . |
ListenableFuture<V> , java.util.concurrent.CompletionStage<V> , java.util.concurrent.CompletableFuture<V> | Alternative to DeferredResult , as a convenience (for example, when an underlying service returns one of those). |
ResponseBodyEmitter , SseEmitter | Emit a stream of objects asynchronously to be written to the response with HttpMessageConverter implementations. Also supported as the body of a ResponseEntity . See Asynchronous Requests and HTTP Streaming. |
StreamingResponseBody | Write to the response OutputStream asynchronously. Also supported as the body of a ResponseEntity . See Asynchronous Requests and HTTP Streaming. |
Reactor and other reactive types registered via ReactiveAdapterRegistry | A single value type, e.g. Mono , is comparable to returning DeferredResult . A multi-value type, e.g. Flux , may be treated as a stream depending on the requested media type, e.g. "text/event-stream", "application/json+stream", or otherwise is collected to a List and rendered as a single value. See Asynchronous Requests and Reactive Types. |
Other return values | If a return value remains unresolved in any other way, it is treated as a model attribute, unless it is a simple type as determined by BeanUtils#isSimpleProperty, in which case it remains unresolved. |
