springboot 系列之返回 json 数据格式

在 springboot 2.0 中对于 json 的解析已经做到相当简单而完善了,在 web 层仅仅只需要一个注解即可实现,就是 @RestController 注解。

下面来实例演示一下:

首先在 model 层建一个实体类 User:

public class User {
    private String userName;
    private String password;
    private int age;
    //setter,getter 省略
}

然后在 controller 层新建⼀一个类 WebController,对数据进行解析,返回 json 数据格式:

@RestController
public class WebController {

    @RequestMapping(value="/getUser", method= RequestMethod.GET)
    public User getUser() {
        User user=new User();
        user.setUserName("小明");
        user.setPassword("123456");
        user.setAge(20);
        return user;
    }
}

浏览器输入 http://127.0.0.1:8080/getUser ,返回结果为 {"userName":"小明","password":"123456","age":20}

在SSM项目中我们一般用 @Controller 和 @ResponseBody 来把数据表示成 json 格式返回,我们点进 @RestController 的源码可以看出,@RestController 注解包含了原来的 @Controller 和 @ResponseBody 注解,因此 springboot 中 @RestController 就相当于它们加一起的效果。

上面是单对象转 json 格式返回,那么多对象呢?

把多对象放到一个 list 或者 map 中,返回 List 对象或 Map 对象:

@RestController
public class WebController {

    @RequestMapping("/getUsers")
    public List<User> getUsers() {
        List<User> users=new ArrayList<User>();
        
        User user1=new User();
        user1.setUserName("小方");
        user1.setPassword("123456");
        user1.setAge(20);
        users.add(user1);
        
        User user2=new User();
        user2.setUserName("小明");
        user2.setPassword("123456");
        user2.setAge(22);
        users.add(user2);
        return users;
    }
}
@RestController
public class WebController {

    @RequestMapping("/getUsersByMap")
    public Map<String,Object> getUsers() {
        Map<String,Object> map = new HashMap<>(1);
        
        User user1=new User();
        user1.setUserName("小方");
        user1.setPassword("123456");
        user1.setAge(20);
        
        User user2=new User();
        user2.setUserName("小明");
        user2.setPassword("123456");
        user2.setAge(22);
        
        map.put("用户1的信息",user1);
        map.put("用户2的信息",user2);
           
        return map;
    }
}

浏览器输入 http://127.0.0.1:8080/getUsers ,返回结果为[{"userName":"小方","password":"123456","age":20},{"userName":"小明","password":"123456","age":22}]

浏览器输入 http://127.0.0.1:8080/getUsersByMap ,返回结果为{"用户2的信息":{"userName":"小明","age":22,"password":"123456"},"用户1的信息":{"userName":"小方","age":20,"password":"123456"}}

那么 springboot 默认使用的是哪个 json 解析框架呢?

点开 pom.xml 中的 spring-boot-starter-web 依 赖,可以看到一个 spring-boot-starter-json 依赖,再点进 spring-boot-starter-json 依赖可知 springboot 中默认使用的 JSON 解析框架是 Jackson。

Jackson 解析 null 值:

在实际项目中,难免出现 null 值,例如:

@RestController
public class WebController {

    @RequestMapping("/getUsersByMap")
    public Map<String,Object> getUsers() {
        Map<String,Object> map = new HashMap<>(1);
        
        User user1=new User();
        user1.setUserName("小方");
        user1.setPassword("123456");
        user1.setAge(20);
        
        User user2=new User();
        user2.setUserName("小明");
        user2.setPassword("123456");
        user2.setAge(22);
        
        map.put("用户1的信息",user1);
        map.put("用户2的信息",user2);
        map.put("用户3的信息",null);
        
           
        return map;
    }
}

我们把用户3的信息设为null,那么返回的 json 数据就是 {"用户2的信息":{"userName":"小明","age":22,"password":"123456"},"用户1的信息":{"userName":"小方","age":20,"password":"123456"},"用户3的信息":null}

我们在转 json 时,一般不希望这些 null 值出现,比如我们期望所有的 null 在转 JSON 时都变成 "" 这种空字符串,那怎么做呢?在 Spring Boot 中,我们做一下配置即可,新建一个 Jackson 的配置类 JacksonConfig:

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

import java.io.IOException;

/**
 * @auther willi
 * @create-time 2019-05-07-17:19
 */

@Configuration
public class JacksonConfig {
    @Bean
    @Primary
    @ConditionalOnMissingBean(ObjectMapper.class)
    public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
        ObjectMapper objectMapper = builder.createXmlMapper(false).build();
        objectMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {
            @Override
            public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
                jsonGenerator.writeString("");
            }
        });
        return objectMapper;
    }
}

现在重新运行,就会发现 json 数据变成了 {"用户2的信息":{"userName":"小明","age":22,"password":"123456"},"用户1的信息":{"userName":"小方","age":20,"password":"123456"},"用户3的信息":""}。

因此就完成对于 null 值的定制,当你想在数据为 null 时输出 "无数据" ,只需要修改成 jsonGenerator.writeString("无数据") 即可实现。