1. 程式人生 > >SpringBoot入門系列(二)如何返回統一的資料格式

SpringBoot入門系列(二)如何返回統一的資料格式

前面介紹了Spring Boot的優點,然後介紹瞭如何快速建立Spring Boot 專案。不清楚的朋友可以看看之前的文章:https://www.cnblogs.com/zhangweizhong/category/1657780.html。

今天來說一說Spring的@Controller和@RestController控制器, 他們是如何響應客戶端請求,如何返回json資料。

 

一、@Controller和@RestController 兩種控制器

Spring中有Controller,RestController的兩種控制器,都是用來表示Spring某個類的是否可以接收HTTP請求。

但是不同的是:

1、Controller:標識一個Spring類是Spring MVC controller處理器。

2、RestController:  主要用於Restfull介面,返回客戶端資料請求。

所以RestController是@Controller和@ResponseBody的結合體,兩個標註合併起來的作用。

 

二、@Controller的用法

1、建立pojo 包,並建立User 物件

package com.weiz.pojo;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;

import java.util.Date;

public class User {
    private  String name;

    @JsonIgnore
    private  String password;

    private Integer age;

    @JsonFormat(pattern = "yyyy-MM-dd hh:mm:ss",locale = "zh",timezone = "GMT+8")
    private Date birthday;

    @JsonInclude(JsonInclude.Include.NON_NULL)
    private  String desc;


    public String getName() {
        return name;
    }

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

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
}

 

2、建立UserController 控制器

package com.weiz.controller;

import com.weiz.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.Date;

@Controller
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/getUser")
    @ResponseBody
    public User getUser(){
        User u = new User();
        u.setName("weiz");
        u.setAge(18);
        u.setBirthday(new Date());
        u.setPassword("weiz");

        return u;
    }
}

 

3、執行檢視資料返回,在瀏覽器中輸入:http://localhost:8080/user/getUser,返回資料可以看到控制器自動將user物件轉換為json資料格式。

三、@RestController的用法

其實 RestController是Controller和ResponseBody的結合體,兩個標註合併起來的作用。

所以,將上面的UserController 修改如下即可:

package com.weiz.controller;

import com.weiz.pojo.JSONResult;
import com.weiz.pojo.User;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;

//@Controller
@RestController   // RestController = Controller + ResponseBody
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/getUser")
    //@ResponseBody
    public JSONResult getUser(){
        User u = new User();
        u.setName("weiz222");
        u.setAge(20);
        u.setBirthday(new Date());
        u.setPassword("weiz222");

        return u;
    }
}

 

四、統一返回

其實 RestController 給客戶端返回資料時,一般會用jackson序列化返回。而不是直接返回整個pojo類物件。下面就簡單介紹下如何統一返回json資料格式:

1、pojo類相關增加序列化格式配置,如上面的User物件的定義

2、增加Json通用的封裝類JsonUtils ,下面這個就是比較常用的json資料封裝類。

package com.weiz.utils;

import java.util.List;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * 
 * @Title: JSONResult.java
 * @Package com.weiz.utils
 * @Description: 自定義響應資料結構
 *                 這個類是提供給門戶,ios,安卓,微信商城用的
 *                 門戶接受此類資料後需要使用本類的方法轉換成對於的資料型別格式(類,或者list)
 *                 其他自行處理
 *                 200:表示成功
 *                 500:表示錯誤,錯誤資訊在msg欄位中
 *                 501:bean驗證錯誤,不管多少個錯誤都以map形式返回
 *                 502:攔截器攔截到使用者token出錯
 *                 555:異常丟擲資訊
 * Copyright: Copyright (c) 2016
 * 
 * @author weiz
 * @date 2016年4月22日 下午8:33:36
 * @version V1.0
 */
public class JSONResult {

    // 定義jackson物件
    private static final ObjectMapper MAPPER = new ObjectMapper();

    // 響應業務狀態
    private Integer status;

    // 響應訊息
    private String msg;

    // 響應中的資料
    private Object data;
    
    private String ok;    // 不使用

    public static JSONResult build(Integer status, String msg, Object data) {
        return new JSONResult(status, msg, data);
    }

    public static JSONResult ok(Object data) {
        return new JSONResult(data);
    }

    public static JSONResult ok() {
        return new JSONResult(null);
    }
    
    public static JSONResult errorMsg(String msg) {
        return new JSONResult(500, msg, null);
    }
    
    public static JSONResult errorMap(Object data) {
        return new JSONResult(501, "error", data);
    }
    
    public static JSONResult errorTokenMsg(String msg) {
        return new JSONResult(502, msg, null);
    }
    
    public static JSONResult errorException(String msg) {
        return new JSONResult(555, msg, null);
    }

    public JSONResult() {

    }
    
    public JSONResult(Integer status, String msg, Object data) {
        this.status = status;
        this.msg = msg;
        this.data = data;
    }

    public JSONResult(Object data) {
        this.status = 200;
        this.msg = "OK";
        this.data = data;
    }

    public Boolean isOK() {
        return this.status == 200;
    }

    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }

    /**
     * 
     * @Description: 將json結果集轉化為LeeJSONResult物件
     *                 需要轉換的物件是一個類
     * @param jsonData
     * @param clazz
     * @return
     * 
     * @author weiz
     * @date 2016年4月22日 下午8:34:58
     */
    public static JSONResult formatToPojo(String jsonData, Class<?> clazz) {
        try {
            if (clazz == null) {
                return MAPPER.readValue(jsonData, JSONResult.class);
            }
            JsonNode jsonNode = MAPPER.readTree(jsonData);
            JsonNode data = jsonNode.get("data");
            Object obj = null;
            if (clazz != null) {
                if (data.isObject()) {
                    obj = MAPPER.readValue(data.traverse(), clazz);
                } else if (data.isTextual()) {
                    obj = MAPPER.readValue(data.asText(), clazz);
                }
            }
            return build(jsonNode.get("status").intValue(), jsonNode.get("msg").asText(), obj);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 
     * @Description: 沒有object物件的轉化
     * @param json
     * @return
     * 
     * @author weiz
     * @date 2016年4月22日 下午8:35:21
     */
    public static JSONResult format(String json) {
        try {
            return MAPPER.readValue(json, JSONResult.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 
     * @Description: Object是集合轉化
     *                 需要轉換的物件是一個list
     * @param jsonData
     * @param clazz
     * @return
     * 
     * @author weiz
     * @date 2016年4月22日 下午8:35:31
     */
    public static JSONResult formatToList(String jsonData, Class<?> clazz) {
        try {
            JsonNode jsonNode = MAPPER.readTree(jsonData);
            JsonNode data = jsonNode.get("data");
            Object obj = null;
            if (data.isArray() && data.size() > 0) {
                obj = MAPPER.readValue(data.traverse(),
                        MAPPER.getTypeFactory().constructCollectionType(List.class, clazz));
            }
            return build(jsonNode.get("status").intValue(), jsonNode.get("msg").asText(), obj);
        } catch (Exception e) {
            return null;
        }
    }

    public String getOk() {
        return ok;
    }

    public void setOk(String ok) {
        this.ok = ok;
    }

}

3、如何呼叫

 

最後

以上,就把Spring Boot中的Controller及如何返回json資料介紹完了。

這個系列課程的完整原始碼,也會提供給大家。大家關注我的微信公眾號(架構師精進),回覆:springboot原始碼 獲取這個系列課程的完整原始碼。

&n