很多时候前端都需要调用后台服务实现交互功能,常见的数据交换格式多是JSON或XML,这里主要讲解Spring MVC为前端提供JSON格式的数据并实现与前台交互。

 

一、概要

  JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式。它基于 ECMAScript (w3c制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。

  在 JS 语言中,一切都是对象。因此,任何支持的类型都可以通过 JSON 来表示,例如字符串、数字、对象、数组等。但是对象和数组是比较特殊且常用的两种类型。

(1)要实现从对象转换为 JSON 字符串,使用 JSON.stringify() 方法:

    var json = JSON.stringify({a: 'Hello', b: 'World'}); //结果是 '{"a": "Hello", "b": "World"}'

  (2)要实现从 JSON 转换为对象,使用 JSON.parse() 方法:

    var obj = JSON.parse('{"a": "Hello", "b": "World"}'); //结果是 {a: 'Hello', b: 'World'}

  示例:

 




springmvc解析json_xml

springmvc解析json_JSON_02

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title></title>
<!--[if lte IE 8]>
    <script type="text/javascript" src="//res.wx.qq.com/a/wx_fed/webwx/res/json3.min.js"></script>
    <![endif]-->
    </head>

    <body>
        <script type="text/javascript">
            //js对象
            var user = {
                "name": "张学友",
                "address": "中国香港"
            };
            //将对象转换成字符
            var str = JSON.stringify(user);
            alert(str);
            //将字符串转换成json对象
            var zxy = JSON.parse(str);
            alert(zxy.name + "," + zxy.address);
        </script>
    </body>

</html>


View Code


  运行结果:

springmvc解析json_xml_03

 

 

二、使用ModelAndView

  pom.xml添加对jackson的依赖




springmvc解析json_xml

springmvc解析json_JSON_02

<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.2</version>
        </dependency>


View Code


  在user控制器中添加一个action




springmvc解析json_xml

springmvc解析json_JSON_02

@RequestMapping(value = "/users")
    public ModelAndView users(){
        ModelAndView mav=new ModelAndView(new MappingJackson2JsonView());
        mav.addObject(userService.queryAllUsers());
        return mav;
    }


View Code


 运行结果:

springmvc解析json_Code_08

 

三、使用@ResponseBody与Jackson

  修改pom.xml添加对jackson的依赖




springmvc解析json_xml

springmvc解析json_JSON_02

<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.2</version>
        </dependency>


View Code


  添加一个action,使用注解@ResponseBody,响应主体而不是路径




springmvc解析json_xml

springmvc解析json_JSON_02

@RequestMapping(value = "/userJson",produces = "application/json;charset=utf-8")
    @ResponseBody
    public String userJson(){
        ObjectMapper mapper=new ObjectMapper();
        try {
          return  mapper.writeValueAsString(userService.queryAllUsers());
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }


View Code


  运行结果:

springmvc解析json_Code_13

 

四、乱码问题

(1)方法一:在action上声明编码格式




springmvc解析json_xml

springmvc解析json_JSON_02

@RequestMapping(path="/json",produces = "application/json;charset=UTF-8")

View Code

(2)方法二:修改spring配置文件

  上一种方法比较麻烦,如果项目中有许多action则每一个都要添加,可以通过Spring配置统一指定

 


springmvc解析json_xml

springmvc解析json_JSON_02

<mvc:annotation-driven>
    <mvc:message-converters register-defaults="true">
        <bean class="org.springframework.http.converter.StringHttpMessageConverter">
            <constructor-arg value="UTF-8"/>
        </bean>
        <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
            <property name="objectMapper">
                <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
                    <property name="failOnEmptyBeans" value="false"/>
                </bean>
            </property>
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>

View Code

 

五、日期格式化问题

  默认日期格式会变成一个数字,是1970年1月1日到当前日期的毫秒数:

springmvc解析json_springmvc解析json_18

  Jackson 默认是转成timestamps形式

 (1)方法一:注解字段

  在实体字段上使用@JsonFormat注解格式化日期

  @JsonFormat(locale="zh", timezone="GMT+8", pattern="yyyy-MM-dd HH:mm:ss")

 代码:


springmvc解析json_xml

springmvc解析json_JSON_02

/**
     * 出生日期
     */
    @JsonFormat(locale="zh", timezone="GMT+8", pattern="yyyy-MM-dd HH:mm:ss")
    private Date birthday;

View Code

运行结果:

springmvc解析json_xml_21

(2)方法二:取消timestamps形式

  如果只取消则会得到一个默认的日期格式,效果如下:

springmvc解析json_Code_22

  当然自定义输出格式是允许的


springmvc解析json_xml

springmvc解析json_JSON_02

@RequestMapping(value = "/userJson",produces = "application/json;charset=utf-8")
    @ResponseBody
    public String userJson(){
        ObjectMapper mapper=new ObjectMapper();
        //不使用时间差的方式
        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);

        //自定义日期格式对象
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //指定日期格式
        mapper.setDateFormat(sdf);
        try {
          return  mapper.writeValueAsString(userService.queryAllUsers());
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }

View Code

  运行结果:

springmvc解析json_JSON_25

 

六、工具类

   工具类可以复用代码,提高开发效率,如上文中的序列化JSON:


springmvc解析json_xml

springmvc解析json_JSON_02

package com.zhangguo.springmvc08.utils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

import java.text.SimpleDateFormat;

/**
 * JSON工具类,辅助类
 * */
public class JsonUtil {
    public static String getJson(Object object) {
        return getJson(object,"yyyy-MM-dd HH:mm:ss");
    }

    public static String getJson(Object object,String dateFormat) {
        ObjectMapper mapper = new ObjectMapper();
        //不使用时间差的方式
        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        //自定义日期格式对象
        SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
        //指定日期格式
        mapper.setDateFormat(sdf);
        try {
            return mapper.writeValueAsString(object);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }
}

View Code

  调用:


springmvc解析json_xml

springmvc解析json_JSON_02

@RequestMapping(value = "/userJson",produces = "application/json;charset=utf-8")
    @ResponseBody
    public String userJson(){
        return JsonUtil.getJson(userService.queryAllUsers(),"yyyy-MM-dd");
    }

View Code