五SpringMVC——处理器方法的返回值

Posted 上善若水

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了五SpringMVC——处理器方法的返回值相关的知识,希望对你有一定的参考价值。

一、处理器方法的返回值

使用@Controller注解的处理器的处理器方法,其返回值常用的有四种类型:

  • 第一种:ModeAndView。有数据和视图,对视图执行forward。
  • 第二种:String。表示视图,可以逻辑名称,也可以是完整视图路径。
  • 第三种:无返回值void。不能表示数据,也不能表示视图。
    在处理Ajax的时候,可以使用void返回值。通过HttpServletResponse输出数据,响应Ajax请求。Ajax请求服务器端返回的就是数据,和视图无关。
  • 第四种:返回自定义类型对象。例如:String,Integer,Map,List,Student等等都是对象,对象有属性,属性就是数据。所以返回object表示数据,和视图无关。可以使用对象表示的数据,响应Ajax请求。

根据不同的情况,使用不同的返回值。

1.1、返回ModelAndView

若处理器方法处理完后,需要跳转到其它资源,且又要在跳转的资源间传递数据,此时处理器方法返回ModelAndView比较好。当然,若要返回ModelAndView,则处理器方法中需要定义ModelAndView对象。
在使用时,若该处理器方法只是进行跳转而不是传递数据,或只是传递数据而并不向任何资源跳转(如对页面的Ajax异步响应),此时若返回ModelAndView,则将总是有一部分多余:要么Model多余,要么View多余。即此时返回ModelAndView将不合适。

1.2、返回String

处理器方法返回的字符串可以指定逻辑视图名,通过视图解析器解析,可以将其转换为物理视图地址。
返回内部资源逻辑视图名
若要跳转的资源为内部资源,则视图解析器可以使用InternalResourceViewResolver内部资源视图解析器。此时处理器方法返回的字符串就是要跳转页面的文件名去掉文件扩展名后的部分。这个字符串与视图的prefix、suffix相结合,即可形成要访问的URI。

src/main/resources/springmvc.xml

<!--  注册视图解析器  -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
	<property name="prefix" value="/WEB-INF/view/" />
	<property name="suffix" value=".jsp" />
</bean>

MyController.java

package com.xbmu.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;

/**
 * @RequestMapping :
 *      value:所有请求地址的公共部分,叫做模块名称
 *      位置:放在类的上面
 */
@Controller
public class MyController {
    /**
     * 处理器方法返回string -- 表示逻辑视图名称,需要配置视图解析器
     */
    @RequestMapping(value = "/returnString-view.do")
    public String doReturnView(HttpServletRequest request,String name,Integer age)
    {
        System.out.println("doReturnView,name="+name+"  age="+age);
        // 可以自己手工添加数据到request作用域
        request.setAttribute("myname",name);
        request.setAttribute("myage",age);
        // show : 逻辑视图名称,项目中配置了视图解析器
        // 框架对视图执行forward转发操作
        return "show";
    }
}

当然,也可以直接返回资源的物理视图名。不过,此时就不需要再在视图解析器中配置前缀与后缀了

package com.xbmu.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;

/**
 * @RequestMapping :
 *      value:所有请求地址的公共部分,叫做模块名称
 *      位置:放在类的上面
 */
@Controller
public class MyController {
    // 处理器方法返回String,表示完整视图路径,此时不能配置视图解析器
    @RequestMapping(value = "/returnString-view2.do")
    public String doReturnView2(HttpServletRequest request,String name,Integer age)
    {
        System.out.println("doReturnView2,name="+name+"  age="+age);
        // 可以自己手工添加数据到request作用域
        request.setAttribute("myname",name);
        request.setAttribute("myage",age);
        // show : 逻辑视图名称,项目中配置了视图解析器
        // 框架对视图执行forward转发操作
        // /WEB-INF/view//WEB-INF/view/show.jsp.jsp
        // /WEB-INF/view/WEB-INF/view/show.jsp.jsp
        return "/WEB-INF/view/show.jsp";
    }
}

1.3、返回void(了解)

对于处理器方法返回void的应用场景,Ajax响应。
若处理器对请求处理后,无需跳转到其它任何资源,此时可以让处理器方法返回void。

例如,对于Ajax的异步请求的响应。

现在做Ajax,主要使用json的数据格式。实现步骤:
1.加入处理json的工具库的依赖,SpringMVC默认使用的Jackson。
2.在SpringMVC配置文件之间加入 <mvc:annotation-driven>注解驱动。

json  = om.writeValueAsString(student);

3.在处理器方法的上面加入@ResponseBody注解

response.setContentType("application/json;charset=utf-8");
PrintWriter pw  = response.getWriter();
pw.println(json);
  1. maven加入Jackson依赖
    由于本项目中服务端向浏览器传回的是json数据,需要使用一个工具类将字符串包装为json格式,所以需要导入json的依赖。
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-core</artifactId>
  <version>2.9.8</version>
</dependency>
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>2.9.8</version>
</dependency>
  1. 引入jQuery库
    由于本项目要使用jQuery的ajax()方法提交Ajax请求,所以项目中需要引入jQuery的库。在webapp下新建一个folder(文件夹),命名为js,并将jquery-3.4.1.js文件放入其中。
    在这里插入图片描述当然,该jQuery库文件,需要在使用ajax()方法的index页面中引入。
<script type="text/javascript" src="js/jquery-3.4.1.js"></script>
  1. 定义index页面
    index页面由两部分内容构成:一个是<button />,用于提交Ajax请求;一个是<script/>,用于处理Ajax请求。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <script type="text/javascript" src="js/jquery-3.4.1.js"></script>
    <script type="text/javascript">
        $(function () {
            $("button").click(function () {
                // alert("btn click");
                $.ajax({
                    url:"returnVoid-ajax.do",
                    data:{
                        name:"刘关张",
                        age:18
                    },
                    type:"post",
                    dataType:"json",
                    success:function (resp) {
                        //resp从服务器端返回的是json格式的字符串 {"name":"刘关张","age":18}
                        //jquery会把字符串转为json对象, 赋值给resp形参。

                        // [{"name":"李四同学","age":20},{"name":"张三","age":28}]
                        alert(resp.name + "    "+resp.age);
                    }
                })
            })
        })
    </script>
</head>
<body>
<%--点击按钮发起Ajax请求--%>
<button id="btn">发起ajax请求</button>
</body>
</html>
  1. 定义对象student
package com.xbmu.vo;

/**
 * 保存请求参数值的一个普通类
 */
public class Student {
    // 属性名和请求中参数名一样
    private String name;
    private Integer age;

    // get / set
}

  1. 修改处理器类MyController
    处理器对于Ajax请求中所提交的参数,可以使用逐个接收的方式,也可以以对象的方式整体接收。只要保证Ajax请求参数与接收的对象类型属性同名。
    以逐个方式接收参数:
package com.xbmu.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.xbmu.vo.Student;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * @RequestMapping :
 *      value:所有请求地址的公共部分,叫做模块名称
 *      位置:放在类的上面
 */
@Controller
public class MyController {
    /**
     * 处理器方法返回值void,不能表示数据,也没有视图。
     * 可以通过使用HttpServletResponse的输出对象,把数据输出到浏览器
     */
    @RequestMapping(value = "/returnVoid-ajax.do")
    public void doReturnVoidAjax(HttpServletResponse response, String name, Integer age) throws IOException {
        System.out.println("===doReturnVoidAjax===,name="+name+"    age="+age);
        // 处理Ajax,使用json做数据的格式
        // service 调用完成了,使用student表示处理结果
        Student student = new Student();
        student.setName(name);
        student.setAge(age);

        String json = "";
        // 把结果的对象转为json格式的数据
        if (null != student)
        {
            // 使用Jackson工具库,把student转为json
            ObjectMapper om = new ObjectMapper();
            json = om.writeValueAsString(student);
            System.out.println("student转换的json===="+json);
        }

        // 输出数据,响应ajax的请求
        // 使用HttpServletResponse输出数据到浏览器
        response.setContentType("application/json;charset=utf-8");
        PrintWriter pw  = response.getWriter();
        pw.println(json);
        pw.flush();
        pw.close();
    }
}

  1. 删除视图页面
    由于是服务端直接向浏览器发回数据,所以也就无需视图页面了,所以需要删除WEB-INF中的jsp目录及其中的show页面。
  2. 测试
    在这里插入图片描述

以上是关于五SpringMVC——处理器方法的返回值的主要内容,如果未能解决你的问题,请参考以下文章

SpringMVC_[3]处理器方法的返回值

SpringMVC_[3]处理器方法的返回值

Java--SpringMVC之处理器方法返回值

SpringMVC处理器方法返回值void ajax方式

Springday05 SpringMVC访问静态资源操作请求域控制器方法返回值JSON数据交互RESTful风格文件上传异常处理拦截器

springMVC处理器相关内容