JSON工具類的構建(後端版本)

前言

在先後端交互的選擇上,以前一直採用的是模板引擎(由於我只負責後端)。
而此次的一個算是做業吧,先後端都是我,因此就研究了一下JSON交互在java web的應用(主要是前端)。html

優缺點

  • 先後端耦合前端

    • 模板引擎加載只是將jsp的交互方式移植到html上,前端文件格式改變了,可是jsp中先後端耦合的缺點沒有改變。
    • json交互中,數據經過js/jquery動態加載在頁面上,數據與頁面進行分離,頁面只是單純用於展現。
  • 數據加載邏輯複用java

    • 模板引擎的方式中,若是有不少類似的頁面元素以及同樣的數據返回格式,那只是複製粘貼大法了。
    • 在模板引擎的例子中,只須要定義一套數據加載模型,傳入不一樣的頁面元素id以及數據則能實現邏輯複用
  • 後端接口的複用
    由於個人學習路線的問題,因此我開發過安卓原生一段時間。jquery

    • 模板引擎式的加載必須使用webView組件加載,且需另進行原生構建時接口也要另外構建。
    • json交互,谷歌爸爸鼓勵使用json進行交互(一年多前的事,如今不清楚了),且安卓原生內置GJSON進行json解析與構建,因此能夠在原生以及跨平臺的構建有很好的平衡。

對比

既然選擇了json交互的方式,而java官方據我所知是沒有內置對json的支持,Spring在Controller的層面使用RestContrller註解實現對json的支持。
可是我我的強迫症很強,我對Contrller(或者說是Presenter)的定義是git

  • 對用戶訪問的url做頁面的映射
  • 對用戶觸發的事件進行數據的傳遞與返回

正是這兩點的定義,我須要在Service層組合統一格式的結果返回到上層,因此須要第三方json支持。
可選擇的JSON庫有不少,GSON,FastJson,Jackson,根據對比,我選擇爲馬老師充值一波。github

需求拆分

我初步定義的需求主要有三個web

  • Service傳遞統一處理結果到上層
  • 不管是單一數據實體或者List型數據處理的結果是同樣的
  • 處理過程是獨立的,不依賴於實體類的支持

格式設計

在網上看過不少後端返回數據的格式,不少都是返回一個處理的status以及具體的數據,而這個status是根據http狀態碼進行設定的,由於此次時間比較緊,因此我就採用了這個方案。json

{
    "status": "status",
    "object": {
        
    }
}

代碼設計

由於我但願Controller能直接拿到結果,因此構建結果的過程全放在Result類中。
而結果構建我主要分爲兩種:只有狀態碼(通知處理結果)以及具備返回結果(數據顯示),而根據結果的我的也分爲兩種:單個數據以及List型數據。後端

實際代碼

@Getter
@Slf4j
public class ResultSet {

    private JSONObject result;

    public ResultSet(){
        result=new JSONObject();
    }

    /**
     * 初始化狀態碼
     * @param status
     */
    public void initStatus(String status){
        result.put("status", status);
    }

    /**
     * 初始化狀態碼以及返回數據
     * @param status
     * @param obj
     */
    public void initData(String status,Object obj){
        initStatus(status);
        if(obj instanceof List){
            List list=(List)obj;
            JSONArray array=new JSONArray();
            for(Object object:list){
                array.add(putObjectToJSON(object));
            }
            result.put("object",array);
        }
        else {
            result.put("object",putObjectToJSON(obj));
        }
    }

    /**
     * 將單個Object放入json文件中
     * @param obj
     * @return
     */
    private JSONObject putObjectToJSON(Object obj){
        JSONObject result=new JSONObject();
        Field[] fields=obj.getClass().getDeclaredFields();
        for(Field field:fields){
            field.setAccessible(true);
            String fieldName=field.getType().getSimpleName();
            if(fieldName.equals("Department")||fieldName.equals("Job")){
                JSONObject tempJson=new JSONObject();
                try {
                    Object tempObject = field.get(obj);
                    Field[] tempFields=tempObject.getClass().getDeclaredFields();
                    for(Field tempField:tempFields){
                        tempField.setAccessible(true);
                        tempJson.put(tempField.getName(),tempField.get(tempObject));
                        tempField.setAccessible(false);
                    }
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
                if(fieldName.equals("Department")){
                    result.put("depart",tempJson);
                }
                else {
                    result.put("job",tempJson);
                }
            }
            else {
                try {
                    result.put(field.getName(),field.get(obj));
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
            field.setAccessible(false);
        }
        return result;
    }
}

代碼思路

  1. Service經過initStatus/initData傳入數據/狀態碼進行對象的生成
  2. Controller經過result的getter方法獲取處理結果
  3. 單個數據以及List數據的處理jsp

    1. 單個對象直接經過putObjectToJSON進行處理
    2. List數據經過對象類型判斷,向下轉型,遍歷元素造成JSONArray進行處理,對元素處理的方法也是採用putObjectToJSON
  4. 嵌套對象的處理

    public class Employee {
    
       private int id;
    
       private Department depart;
    
       private Job job;
    
       private String name;
    
        ..................
    }
    1. 經過反射獲取對象的全部成員變量類型以及對應的值
    2. 遇到上述bean類含有嵌套自定義對象時,遞歸生成json文件加入到結果json中

結果演示

​ (左爲單object型,右爲List型)

不足之處

  1. 狀態碼的設置應該採用枚舉類的賦值,能更好的約束返回的狀態碼
  2. 在對象轉換方面,應該採用配置掃描的方式。在配置文件中寫入bean的包所在,在嵌套對象轉換時經過掃描配置文件的信息判斷
  3. 在嵌套對象的轉換方面,只是作了一層的嵌套轉換,更多層的沒有考慮到,以後會再重構的
  4. 對異常處理方面,只是簡單的輸出錯誤信息。應該對錯誤信息進行進一步的處理

後記

由於此次時間比較趕,從項目的立項到成品的創建花了5天時間,因此注意到不少細節,可是沒有去處理。
有想過以後有時間的話將這個工具類的細節完善起來,造成jar包供本身或者供開源。

相關鏈接

這只是後臺對結果的統一處理,我另外寫了一篇文章:JSON工具類的構建(前端版本)),配合使用效果更佳哦~

本文首發於cartoon的博客
轉載請註明出處:https://cartoonyu.github.io/cartoon-blog/post/json/json工具類的構建後端版本/

相關文章
相關標籤/搜索