六SpringMVC——处理器方法的返回对象Object

Posted 上善若水

tags:

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

一、返回对象Object

处理器方法也可以返回Object对象。这个Object可是Integer、String,自定义对象,Map、List等。但返回的对象不是作为逻辑视图出现的,而是作为直接在页面显示的数据出现的。
返回对象,需要使用@ResponseBody注解,将转换后的JSON数据放入到响应体中。

1.1、环境搭建

A、maven pom.xml
由于返回object数据,一般都是将数据转化为了json对象后传递给浏览器页面的。而这个由object转换为json,是由Jackson工具完成的。所以需要导入Jackson的相关jar包。

依赖

<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>

B、声明注解驱动
将object数据转化为json数据,需要由消息转换器HttpMessageConverter完成。而转换器的开启,需要<mvc:annotation-driven/>来完成。
springmvc使用消息转换器实现请求数据和对象,处理器方法返回对象和响应输出之间的自动转换。
当spring容器进行初始化过程中,在<mvc:annotation-driven/>处创建注解驱动时,默认创建了8个HttpMessageConverter对象。也就是说,我们注册<mvc:annotation-driven/>,就是为了让容器为我们创建HttpMessageConverter对象。

<!--  mvc注解驱动  -->
<mvc:annotation-driven/>

HttpMessageConverter接口:HttpMessageConverter<T>是spring3.0新添加的一个接口,负责将请求信息转换为一个对象(类型为T),将对象(类型为T)输出为响应信息
HttpMessageConverter<T>接口定义的方法:


public interface HttpMessageConverter<T> {

	/**
	 * 指定转换器可以读取的对象类型,即转换器是否可将请求信息转换为clazz类型的对象,
	 * 同时指定支持MIME类型(text/html、application/json等)
	 */
	boolean canRead(Class<?> clazz, @Nullable MediaType mediaType);

	/**
	 * 指定转换器是否可将clazz类型的对象写到响应流中,响应流支持的媒体类型在MediaType中定义。
	 */
	boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType);

	/**
	 *
	 */
	List<MediaType> getSupportedMediaTypes();

	/**
	 * 将请求信息流转换为T类型的对象
	 */
	T read(Class<? extends T> clazz, HttpInputMessage inputMessage)
			throws IOException, HttpMessageNotReadableException;

	/**
	 * 将T类型的对象写到响应流中,同时指定相应的媒体类型为contentType
	 */
	void write(T t, @Nullable MediaType contentType, HttpOutputMessage outputMessage)
			throws IOException, HttpMessageNotWritableException;

}

未加入注解驱动<mvc:annotation-driven/>后适配器类messageConverters属性值
在这里插入图片描述
加入注解驱动<mvc:annotation-driven/>后适配器类messageConverters属性值
在这里插入图片描述

HttpMessageConverter接口实现类作用
ByteArrayHttpMessageConverter负责读取二进制格式的数据和写出二进制格式的数据
StringHttpMessageConverter负责读取字符串格式的数据和写出字符串格式的数据
ResourceHttpMessageConverter负责读取资源文件和写出资源文件数据
SourceHttpMessageConverter能够读/写来自HTTP的请求与响应的javax.xml.transform.Source,支持DOMSource、SAXSource和StreamSource的XML格式
AllEncompassingFormHttpMessageConverter负责读取表单(form)的数据
Jaxb2RootElementHttpMessageConverter使用jaxb负责读取和写入xml标签格式的数据
MappingJackson2HttpMessageConverter负责读取和写入json格式的数据。利用Jackson的ObjectMapper读写json数据,操作Object类型数据,可读取application/json,响应媒体类型为application/json

1.2、返回自定义类型对象

返回自定义类型对象时,不能以对象的形式直接返回客户端浏览器,而是将对象转换为JSON格式的数据发送给浏览器的。
由于转换器底层使用了Jackson转换方式将对象转换为JSON数据,所以需要导入Jackson的相关jar包。

  1. 定义数据类
package com.xbmu.vo;
public class Student {
    private String name;
    private Integer age;
    
    // getter and setter
    // toString()
}

  1. 修改处理器MyController
@Controller
public class MyController {
   /**
     * 处理器方法返回一个Student,通过框架转为json,响应ajax请求
     * @ResponseBody:
     *    作用:把处理器方法返回对象转为json后,通过HttpServletResponse输出给浏览器。
     *    位置:方法的定义上面。 和其它注解没有顺序的关系。
     * 返回对象框架的处理流程:
     *  1. 框架会把返回Student类型,调用框架的中ArrayList<HttpMessageConverter>中每个类的canWrite()方法
     *     检查那个HttpMessageConverter接口的实现类能处理Student类型的数据--MappingJackson2HttpMessageConverter
     *
     *  2.框架会调用实现类的write(), MappingJackson2HttpMessageConverter的write()方法
     *    把赵氏孤儿同学的student对象转为json, 调用Jackson的ObjectMapper实现转为json
     *    contentType: application/json;charset=utf-8
     *
     *  3.框架会调用@ResponseBody把2的结果数据输出到浏览器, ajax请求处理完成
     */
    @RequestMapping(value = "/returnStudentJson.do")
    @ResponseBody
    public Student doStudentJson()
    {
        // 创建java对象,转为json
        Student student = new Student();
        student.setName("赵氏孤儿");
        student.setAge(20);
        return student;
    }
}
  1. 修改index页面
<%@ 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 () {
                $.ajax({
                    url:"returnStudentJson.do",
                    success:function (resp) {
                        alert(resp.name + "    "+resp.age);
                    }
                })
            })
        })
    </script>
</head>
<body>
<%--点击按钮发起Ajax请求--%>
<button id="btn">发起ajax请求</button>
</body>
</html>

在这里插入图片描述

1.3、返回List集合

  1. 修改处理器MyController
@Controller
public class MyController {
    /**
     * 处理器方法返回List<Student>
     * 返回对象框架的处理流程:
     *  1. 框架会把返回List<Student>类型,调用框架的中ArrayList<HttpMessageConverter>中每个类的canWrite()方法
     *     检查那个HttpMessageConverter接口的实现类能处理Student类型的数据--MappingJackson2HttpMessageConverter
     *
     *  2.框架会调用实现类的write(), MappingJackson2HttpMessageConverter的write()方法
     *    把李四同学的student对象转为json, 调用Jackson的ObjectMapper实现转为json array
     *    contentType: application/json;charset=utf-8
     *
     *  3.框架会调用@ResponseBody把2的结果数据输出到浏览器, ajax请求处理完成
     */
    @RequestMapping(value = "/returnStudentJsonArray.do")
    @ResponseBody
    public List<Student> doStudentJsonObjectArray(String name,Integer age)
    {
        List<Student> list = new ArrayList<>();
        //调用service,获取请求结果数据 , Student对象表示结果数据
        Student student = new Student();
        student.setName("李四同学");
        student.setAge(20);
        list.add(student);

        student = new Student();
        student.setName("张三");
        student.setAge(28);
        list.add(student);

        return list;
    }
}
  1. 修改index页面
<%@ 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 () {
               $.ajax({
                   url:"returnStudentJsonArray.do",
                   success:function (resp) {
                       alert(resp);
                   }
               })
           })
       })
   </script>
</head>
<body>
<%--点击按钮发起Ajax请求--%>
<button id="btn">发起ajax请求</button>
</body>
</html>

在这里插入图片描述

1.4、返回字符串对象

若要返回非中文字符串,将前面返回数值型数据的返回值直接修改为字符串即可。但若返回的字符串中带有中文字符,则接收方页面将会出现乱码。此时需要使用@RequestMapping的produces属性指定字符集。

produces:产品,结果。即该属性用于设置输出结果类型。

  1. 修改处理器MyController
@Controller
public class MyController {
    /**
     * 处理器方法返回的是String , String表示数据的,不是视图。
     * 区分返回值String是数据,还是视图,看有没有@ResponseBody注解
     * 如果有@ResponseBody注解,返回String就是数据,反之就是视图
     *
     * 默认使用“text/plain;charset=ISO-8859-1”作为contentType,导致中文有乱码,
     * 解决方案:给RequestMapping增加一个属性 produces, 使用这个属性指定新的contentType.
     * 返回对象框架的处理流程:
     *  1. 框架会把返回String类型,调用框架的中ArrayList<HttpMessageConverter>中每个类的canWrite()方法
     *     检查那个HttpMessageConverter接口的实现类能处理String类型的数据--StringHttpMessageConverter
     *
     *  2.框架会调用实现类的write(), StringHttpMessageConverter的write()方法
     *    把字符按照指定的编码处理 text/plain;charset=ISO-8859-1
     *
     *  3.框架会调用@ResponseBody把2的结果数据输出到浏览器, ajax请求处理完成
     */
    @RequestMapping(value = "/returnStringData.do",produces = "text/plain;charset=utf-8")
    @ResponseBody
    public String doStringData(String name,Integer age){
        return "Hello SpringMVC 返回对象,表示数据";
    }
}
  1. 修改index
<%@ 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 () {
                $.ajax({
                    url:"returnStringData.do",
                    data:{
                        name:"zhangsan",
                        age:20
                    },
                    type:"post",
                    dataType:"text",
                    success:function(resp){
                        alert("返回的是文本数据:"+resp);
                    }
                })
            })
        })
    </script>
</head>
<body>
<%--点击按钮发起Ajax请求--%>
<button id="btn">发起ajax请求</button>
</body>
</html>

在这里插入图片描述
在这里插入图片描述

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

[Java面试六]SpringMVC总结以及在面试中的一些问题.

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

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

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

SpringMvc:视图和视图解析器

Java框架之SpringMVC 04-视图解析-Spring表单-JSON-上传下载