Skip to content

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
  • 在容器中声明声明数据源、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 valueDescription
@ResponseBodyThe 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.
HttpHeadersFor returning a response with headers and no body.
StringA 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).
ViewA 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.ModelAttributes to be added to the implicit model, with the view name implicitly determined through a RequestToViewNameTranslator.
@ModelAttributeAn 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 objectThe view and model attributes to use and, optionally, a response status.
voidA 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, SseEmitterEmit 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.
StreamingResponseBodyWrite 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 ReactiveAdapterRegistryA 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 valuesIf 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.

Released under the MIT License.