SpringMVC处理json和HttpMessageConverter< T >

  |   0 评论   |   0 浏览

SpringMVC处理json和HttpMessageConverter< T >

1.处理JSON-@ResponseBody

将前台传过来的数据 以 json 的格式相应回浏览器

● 说明: 项目开发中,我们往往需要服务器返回的数据格式是按照 json 来返回的, 我们看一下 SpringMVC 是如何处理的, 功能示意图

image-20220619100534698

json.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>json提交</title>
    <!-- 引入jquery -->
    <script type="text/javascript" src="script/jquery-3.6.0.min.js"></script>

    <!-- 编写jquery代码和ajax请求 -->
    <script type="text/javascript">
        $(function () {
            //给id="getJson"绑定点击事件
            $("#getJson").click(function () {
                //console.log("ok ....")

                var url = this.href;
                var args = {"time": new Date};//这是要发送数据,为了防止页面缓存
                $.post(
                    url,
                    args,
                    function (data) {//data 就是返回的数据,是json格式=>如果是多个json数据,可以遍历
                        console.log("dataa= ", data);
                        console.log("dog.name=", data.name)
                        console.log("dog.addresss=", data.address)
                    },
                    "json"
                );
                return false;//这里我们返回false,就不使用href默认机制
            })
        })
    </script>

</head>
<body>
<h1>请求一个json数据</h1>
<%--
1.当用户点击超链接时,我们发出一个ajax请求
2. 接收到请求后,我们查看这个数据
--%>
<a href="<%=request.getContextPath()%>/json/dog" id="getJson">点击获取json数据</a>

</body>
</html>

Dog.java

public class Dog {
    private String name;
    private String address;

    public Dog(String name, String address) {
        this.name = name;
        this.address = address;
    }

    public Dog() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                ", address='" + address + '\'' +
                '}';
    }
}

JsonHandler.java

/**
 * 
 * 1. 目标方法 @ResponseBody,表返回的数据是json格式
 * 2. springmvc底层根据目标方法@ResponseBody, 返回指定格式, 根据的http请求来进行处理
 *
 * @return
 */
@RequestMapping(value = "/json/dog")
@ResponseBody
public Dog getJson() {

    //返回对象
    //springmvc会根据你的设置,转成json格式数据返回
    Dog dog = new Dog();
    dog.setName("大黄狗");
    dog.setAddress("小新的家");
    return dog;

}

2.处理JSNON-@RequestBody

接收前台传入的json数据,并封装到javaBean中。在springmvc执行目标方法之前,封装请求参数时根据@RequestBody对请求的json数据进行转换

image-20220619101048579

json.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>json提交</title>
    <!-- 引入jquery -->
    <script type="text/javascript" src="script/jquery-3.6.0.min.js"></script>

    <!-- 编写jquery代码和ajax请求 -->
    <script type="text/javascript">
        $(function () {
            //给id="getJson"绑定点击事件
            $("#getJson").click(function () {
                //console.log("ok ....")

                var url = this.href;
                var args = {"time": new Date};//这是要发送数据,为了防止页面缓存
                $.post(
                    url,
                    args,
                    function (data) {//data 就是返回的数据,是json格式=>如果是多个json数据,可以遍历
                        console.log("dataa= ", data);
                        console.log("dog.name=", data.name)
                        console.log("dog.addresss=", data.address)
                    },
                    "json"
                );
                return false;//这里我们返回false,就不使用href默认机制
            })

            //绑定按钮点击事件, 提交json数据
            //springmvc 可以在在台將json轉成對象
            $("button[name='butt1']").click(function () {
                //目标:将userName 和 age 封装成json字符串,发送给目标方法
                var url = "/springmvc/save2";
                var userName = $("#userName").val();
                var age = $("#age").val();
                //将json对象转成json字符串
                var args = JSON.stringify({"userName": userName, "age": age});
                $.ajax({
                    url: url,
                    data: args,
                    type: "POST",
                    success: function (data) {
                        console.log("返回的data= ", data);
                    },
                    //下面这个contentType参数,是指定发送数据的编码和格式
                    contentType: "application/json;charset=utf-8"
                })
            })
        })
    </script>

</head>
<body>
<h1>请求一个json数据</h1>
<%--
1.当用户点击超链接时,我们发出一个ajax请求
2. 接收到请求后,我们查看这个数据
--%>
<a href="<%=request.getContextPath()%>/json/dog" id="getJson">点击获取json数据</a>

<h1>发出一个json数据</h1>
u:<input id="userName" type="text"><br/>
a:<input id="age" type="text"><br/>
<button name="butt1">添加用户</button>

</body>
</html>

JsonHandler.java

/**
 * 
 * 1. @RequestBody User user 在形参指定了 @RequestBody
 * 2. springmvc就会将提交的json字符串数据填充给指定Javabean
 *
 * @param user
 * @return
 */
@RequestMapping(value = "/save2")
@ResponseBody
public User save2(@RequestBody User user) {
    //将前台传过来的数据 以json的格式相应回浏览器
    System.out.println("user~= " + user);
    return user;
}

image-20220619101410095

3.处理JSON-注意事项

  1. 目标方法正常返回 JSON 需要的数据, 可以是一个对象, 也可以是一个集合[举例]
  2. @ResponseBody + @Controller 可以直接写成 @RestController
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {

   /**
    * The value may indicate a suggestion for a logical component name,
    * to be turned into a Spring bean in case of an autodetected component.
    * @return the suggested component name, if any (or empty String otherwise)
    * @since 4.0.1
    */
   @AliasFor(annotation = Controller.class)
   String value() default "";

}

4.HttpMessageConverter< T >

● 基本说明

SpringMVC 处理 JSON-底层实现是依靠 HttpMessageConverter< T>来进行转换的

● 工作机制简图

image-20220619104623667

● 处理 JSON-底层实现(HttpMessageConverter< T>)

  1. 使用 HttpMessageConverter< T> 将请求信息转化并绑定到处理方法的入参中, 或将响应结果转为对应类型的响应信息,

    Spring 提供了两种途径:

    √ 使用 @RequestBody / @ResponseBody 对目标方法进行标注

    √ 使用 HttpEntity< T> / ResponseEntity< T> 作为目标方法的入参或返回值

​ 2.当 控 制 器 处 理 方 法 使 用 到 @RequestBody/@ResponseBody 或 HttpEntity< T>/ResponseEntity< T> 时, Spring 首先根据请求头或响应头的 Accept 属性选择 匹配 的 HttpMessageConverter, 进而 根据参 数类型 或泛型 类型的 过滤得 到匹配 的 HttpMessageConverter, 若找不到可用的 HttpMessageConverter 将报错

● Dubug 源码-梳理一下

image-20220619123722240

SpringMVC 底层有很多类型转换器,这里已json转换处理为例。

请求数据转换

AbstractJackson2HttpMessageConverter是HttpMessageConverter接口处理json数据的一个实现类,其中readJavaType方法将请求数据进行转换并封装到JavaType中

image-20220619124759232

image-20220619124839318

响应数据转换

writeInternal

image-20220619125206955

image-20220619125248350


标题:SpringMVC处理json和HttpMessageConverter< T >
作者:llp
地址:https://llinp.cn/articles/2022/06/19/1655614518740.html