狗屎的Java規範

規範

標題真有點侮辱了狗。html

最近作Java,C#與Java對比筆記: http://www.cnblogs.com/newsea/p/4839540.html前端

其實Java語法弱點就弱點,關鍵是Java程序員思想太保守,先講溼猴定律: http://baike.baidu.com/link?url=loP9q4bz-T14pQ0y_sa9nZDDFyAjI_eySEHXtyBuB2mRgybuQLyLiKsc-1Tnkq0Vy0f-OYpaHpFMcN0C9XT3_a程序員

貼內容:面試

把五隻猴子關在一個籠子裏,上頭有一串香蕉實驗人員裝了一個自動裝置。
一旦偵測到有猴子要去拿香蕉,立刻就會有水噴向籠子,而這五隻猴子都會一身溼。
首先有隻猴子想去拿香蕉,固然,結果就是每隻猴子都淋溼了。
以後每隻猴子在幾回的嘗試後,發現莫不如此。
因而猴子們達到一個共識:不要去拿香蕉,以免被水噴到。
後來實驗人員把其中的一隻猴子釋放,換進去一隻新猴子A。
這隻猴子A看到香蕉,立刻想要去拿。
結果,被其餘四隻猴子海K了一頓。
由於其餘四隻猴子認爲猴子A會害他們被水淋到,因此制止他去拿香蕉,A嘗試了幾回,雖被打的滿頭包,依然沒有拿到香蕉。
固然,這五隻猴子就沒有被水噴到。
後來實驗人員再把一隻舊猴子釋放,換上另一隻新猴子B。
這猴子B看到香蕉,也是火燒眉毛要去拿。
固然,一如剛纔所發生的情形,其餘四隻猴子海K了B一頓。
特別的是,那隻A猴子打的特別用力(這叫老兵欺負新兵,或是媳婦熬成婆^O^)。
B猴子試了幾回老是被打的很慘,只好做罷。
後來慢慢的一隻一隻的,全部的舊猴子都換成新猴子了,你們都不敢去動那香蕉。
可是他們都不知道爲何,只知道去動香蕉會被猴扁。
這就是道德的起源。

寫這篇文章,主要是在接觸Java以後,有一些感想。但對我震撼最大的莫過於Java程序員的思想束縛。json

1. Java很老,不少規範是在N年前就由一幫外國的老學究定下的。如今的猴子一直在遵照,不多有人去打破,他們發現一旦打破,程序就跑不起來了。後端

2. Java 1.8比 Java 1.6好多了,但我面試的過程當中,不少人都在使用 1.6數組

3. Lambda對Java程序員來講,就像怪物。不少人僅據說過,沒有用過。 服務器

4. 在年紀大的Java程序員眼中, 新版本是給小白用的,本身不會主動去用。違了Java規範的東西,都是怪物。app

 

一種約定俗成的東西,造成了規範,可是當這個規範被大衆接受,再想溶入新東西,就很難了。svn

Java對象序列化

1. 字段大小寫

引出

Java定義對象有N多規範,get , set 方法,private 字段。一旦造成規範,才能讓映射,Json變的簡單一些,同時也意味着,也變的死板。

Javascript Post Json:

{ Id: 1 , Name:"abc" }

=>C# Json

public class Model{
    public int Id { get; set;}
    public String Name {get;set;}
}

=> Java Json

public class Model{
    public int Id;
    public String Name;
}

在 SpringMvc 裏是映射不到的。不少人會先說,要用 get set。

public class Model {
    private  String Name;  
    public String getName() {
        return Name;
    }
    public void setName(String name) {
        this.Name = name;
    } 

    private  String Id;
    public String getId() {
        return Id;
    }
    public void setId(String id) {
        this.Id = id;
    } 
}

仍是不行,按照Java規範,須要把客戶端Post Json 的Key 首字線變成小寫。

規範真是害死人啊。雞肋的ModelBinder,不少人在這裏妥協,要麼傳遞首字母小寫,要麼傳遞Json字符串, 萬能的字符串。

破解

本身實現序列化。

對枚舉進行規範化: 定義的枚舉能夠和數字相互轉換(和C#一致),存儲時,枚舉保存爲 Int,服務器傳遞到客戶端的枚舉,客戶端傳遞到服務器端的枚舉,都使用 Int。

若是客戶端Post的內容格式是  application/json ,還好說。 直接用 Json反序列化到 HasMap<String,Object> 上,再操做。

若是客戶端Post的內容格式是  url 格式的, 那就須要本身寫轉換函數。

接收:

    @RequestMapping(method = RequestMethod.POST, value = "/testModel" )
    @ResponseBody
    public String test() {
        Test test = MyObject.Get(new Test());
        String ret =  JsonMapper.toJsonString(test);
        System.out.println(ret);
        return ret ;
    }

 

關鍵是客戶端Post的Json數據格式可能會是如下格式:

PersonInfo[0].Id=1&PersonIndo[0].CityInfo.Name=北京

須要把Key變成更精準的層級對象。把Url加載到HashMap中。再進行深層次對象化。

 public static <T> T Get( T defValue) {
        Class cls = defValue.getClass();
        HttpServletRequest request = HttpContext.getRequest();
        MapModel map = new MapModel();
        String result = "";
        try {
            BufferedReader inputStream = new BufferedReader(new InputStreamReader(request.getInputStream()));

            String line;
            while ((line = inputStream.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        if (request.getContentType().indexOf("application/json") >= 0) {
            map.Add(JsonMapper.fromJsonString(result, MapModel.class));
        } else {
            map.Add(MapModel.LoadFromUrl(result));
        }

        map.Add(MapModel.LoadFromUrl(request.getQueryString()));

        for (Field f : cls.getDeclaredFields()) {
            Object val = map.get(f.getName());
            if (val == null) continue;

            Class type = f.getType();
            if (type.isEnum()) {
                val = MyEnum.ToEnum(type, MyObject.AsString(val));
            } else if (type.isAssignableFrom(Integer.class) || type.isAssignableFrom(int.class)) {
                val = MyObject.AsInt(val);
            }
            else if( HashMap.class.isAssignableFrom(type)){
                val = ToMap(val);
            }
            else if( IsSimpleType(type) == false){
                try {
                    val = FromMap(ToMap(val), f.get(defValue));
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }

            try {
                f.setAccessible(true);
                f.set(defValue, val);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return defValue;
    }

 

public class MapModel extends HashMap<String, Object> {

    public void Add(MapModel other) {
        if (other == null) return;

        for (String key : other.keySet()) {
            this.put(key, other.get(key));
        }
    }

    public static MapModel LoadFromUrl(String UrlQuery) {
        MapModel ret = new MapModel();

        List<String> list = MyString.MySplit(UrlQuery, '&');
        for (String item : list) {

            List<String> kv = MyString.MySplit(item, '=');
            ret.Tourch(kv.get(0), kv.get(1));
        }

        return ret;
    }

    public void Tourch(String KeyPath, String Value) {
        if (this.containsKey(KeyPath)) return;

        int sepIndex = GetNextCharIndex_SkipQuotes(KeyPath, 0, '.', '[');
        if (sepIndex >= KeyPath.length()) {
            this.put(KeyPath, Value);
            return;
        }

        char chr = KeyPath.charAt(sepIndex);

        String objKey = KeyPath.substring(0, sepIndex);

        if (chr == '.') {
            if (this.containsKey(objKey) == false) {
                this.put(objKey, new MapModel());
            }

            MapModel vv = (MapModel) this.get(objKey);
            vv.Tourch(KeyPath.substring(sepIndex + 1), Value);
        } else {
            if (this.containsKey(objKey) == false) {
                this.put(objKey, new ArrayList<Object>());
            }

            List<Object> list = (List<Object>) this.get(objKey);

            int nextDotIndex = KeyPath.indexOf('.', sepIndex + 1);
            if (nextDotIndex < 0) {
                nextDotIndex = KeyPath.length();
            }

            List<String> aryIndexs_Strings = MySplit(TrimWithPair(Slice(KeyPath, sepIndex, nextDotIndex).replace(" ", "").replace("][", ","), "[", "]"), ',');
            List<Integer> aryIndexs = new ArrayList<Integer>();
            for (String k : aryIndexs_Strings) {
                aryIndexs.add(MyObject.AsInt(k));
            }


            MapModel vv = (MapModel) PatchArrayLevels(list, aryIndexs, Value, KeyPath.indexOf('.', sepIndex + 1) > 0, 0);

            if (vv != null) {
                vv.Tourch(Slice(KeyPath, nextDotIndex + 1), Value);
                return;
            }
        }
    }

    /// <summary>
    /// a[0][0][0].Id = 1 , 則建立3級數組,返回 字典
    /// </summary>
    /// <param name="list"></param>
    /// <param name="indexs"></param>
    /// <param name="Value"></param>
    /// <param name="NextIsDict">下一個對象是不是字典。</param>
    /// <param name="level"></param>
    /// <returns></returns>
    private static Object PatchArrayLevels(List<Object> list, List<Integer> indexs, String Value, boolean NextIsDict, int level) {
        int index = indexs.get(level);
        if (level >= (indexs.size() - 1)) {
            if (NextIsDict) {
                for (int i = list.size(); i <= index; i++) {
                    list.add(new MapModel());
                }
                list.set(index, new MapModel());
                return list.get(index);
            } else {
                for (int i = list.size(); i <= index; i++) {
                    list.add(null);
                }
                list.set(index, Value);
                return null;
            }
        }


        for (int i = list.size(); i <= index; i++) {
            list.add(new ArrayList<Object>());
        }

        return PatchArrayLevels((List<Object>) list.get(index), indexs, Value, NextIsDict, level + 1);
    }
}

 

具體實現參考開源項目的實現,項目地址: http://code.taobao.org/svn/MyJavaMvc

 

2. 屬性名

1. 狗B的Java到底作了什麼 , 爲何實體屬性是 isAdmin : Boolean ,客戶端會返回 admin : Boolean

2. 爲何SB的 Mongo驅動,會把 集合裏的 id 變爲 _id

3. 最後一個SB的坑。 前端Post以下數據:

cartIds[0].id:596713322b3fe4306a3a60f7
cartIds[0].number:10000
cartIds[0].amount:30000

 

  後端來接收:(Kotlin語法,和Java執行原理同樣)

  data class abc(var cartIds: Array<CommitOrderDataItem> = arrayOf()){}

    @ApiOperation(value = "生成訂單")
    @JsonpMapping("/toOrder")
    fun toOrder(@ApiParam("購物車中的id,number,amount的集合") abc:abc ){


    //再取出來。
    var cartIds = abc.cartIds;      
}

 

3. 依賴

 

文件上傳,使用 CommonsMultipartResolver  不報錯, 編譯不報錯, 運行時報錯。 添加如下依賴解決了。 

 

<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>

 

 

 

 Java就是狗屎  !!!

 

4.   @WebFilter 和   @Configuration 衝突。

在 Get 請求時,會執行兩次 filter

相關文章
相關標籤/搜索