狗屎的Java规范
本文内容纲要:
-规范
-Java对象序列化
-引出
-破解
-2.属性名
-3.依赖
规范
标题真有点侮辱了狗。
最近做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程序员的思想束缚。
-
Java很老,很多规范是在N年前就由一帮外国的老学究定下的。现在的猴子一直在遵守,很少有人去打破,他们发现一旦打破,程序就跑不起来了。
-
Java1.8比Java1.6好多了,但我面试的过程中,很多人都在使用1.6
-
Lambda对Java程序员来说,就像怪物。很多人仅听说过,没有用过。
-
在年纪大的Java程序员眼中,新版本是给小白用的,自己不会主动去用。违了Java规范的东西,都是怪物。
一种约定俗成的东西,形成了规范,但是当这个规范被大众接受,再想溶入新东西,就很难了。
Java对象序列化
- 字段大小写
引出
Java定义对象有N多规范,get,set方法,private字段。一旦形成规范,才能让映射,Json变的简单一些,同时也意味着,也变的死板。
JavascriptPostJson:
{Id:1,Name:"abc"}
=>C#Json
publicclassModel{
publicintId{get;set;}
publicStringName{get;set;}
}
=>JavaJson
publicclassModel{
publicintId;
publicStringName;
}
在SpringMvc里是映射不到的。很多人会先说,要用getset。
publicclassModel{
privateStringName;
publicStringgetName(){
returnName;
}
publicvoidsetName(Stringname){
this.Name=name;
}
privateStringId;
publicStringgetId(){
returnId;
}
publicvoidsetId(Stringid){
this.Id=id;
}
}
还是不行,按照Java规范,需要把客户端PostJson的Key首字线变成小写。
规范真是害死人啊。鸡肋的ModelBinder,很多人在这里妥协,要么传递首字母小写,要么传递Json字符串,万能的字符串。
破解
自己实现序列化。
对枚举进行规范化:定义的枚举可以和数字相互转换(和C#一致),存储时,枚举保存为Int,服务器传递到客户端的枚举,客户端传递到服务器端的枚举,都使用Int。
如果客户端Post的内容格式是application/json,还好说。直接用Json反序列化到HasMap<String,Object>上,再操作。
如果客户端Post的内容格式是url格式的,那就需要自己写转换函数。
接收:
@RequestMapping(method=RequestMethod.POST,value="/testModel")
@ResponseBody
publicStringtest(){
Testtest=MyObject.Get(newTest());
Stringret=JsonMapper.toJsonString(test);
System.out.println(ret);
returnret;
}
关键是客户端Post的Json数据格式可能会是以下格式:
PersonInfo[0].Id=1&PersonIndo[0].CityInfo.Name=北京
需要把Key变成更精准的层级对象。把Url加载到HashMap中。再进行深层次对象化。
publicstatic<T>TGet(TdefValue){
Classcls=defValue.getClass();
HttpServletRequestrequest=HttpContext.getRequest();
MapModelmap=newMapModel();
Stringresult="";
try{
BufferedReaderinputStream=newBufferedReader(newInputStreamReader(request.getInputStream()));
Stringline;
while((line=inputStream.readLine())!=null){
result+=line;
}
}catch(Exceptione){
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(Fieldf:cls.getDeclaredFields()){
Objectval=map.get(f.getName());
if(val==null)continue;
Classtype=f.getType();
if(type.isEnum()){
val=MyEnum.ToEnum(type,MyObject.AsString(val));
}elseif(type.isAssignableFrom(Integer.class)||type.isAssignableFrom(int.class)){
val=MyObject.AsInt(val);
}
elseif(HashMap.class.isAssignableFrom(type)){
val=ToMap(val);
}
elseif(IsSimpleType(type)==false){
try{
val=FromMap(ToMap(val),f.get(defValue));
}catch(IllegalAccessExceptione){
e.printStackTrace();
}
}
try{
f.setAccessible(true);
f.set(defValue,val);
}catch(IllegalAccessExceptione){
e.printStackTrace();
}
}
returndefValue;
}
publicclassMapModelextendsHashMap<String,Object>{
publicvoidAdd(MapModelother){
if(other==null)return;
for(Stringkey:other.keySet()){
this.put(key,other.get(key));
}
}
publicstaticMapModelLoadFromUrl(StringUrlQuery){
MapModelret=newMapModel();
List<String>list=MyString.MySplit(UrlQuery,'&');
for(Stringitem:list){
List<String>kv=MyString.MySplit(item,'=');
ret.Tourch(kv.get(0),kv.get(1));
}
returnret;
}
publicvoidTourch(StringKeyPath,StringValue){
if(this.containsKey(KeyPath))return;
intsepIndex=GetNextCharIndex_SkipQuotes(KeyPath,0,'.','[');
if(sepIndex>=KeyPath.length()){
this.put(KeyPath,Value);
return;
}
charchr=KeyPath.charAt(sepIndex);
StringobjKey=KeyPath.substring(0,sepIndex);
if(chr=='.'){
if(this.containsKey(objKey)==false){
this.put(objKey,newMapModel());
}
MapModelvv=(MapModel)this.get(objKey);
vv.Tourch(KeyPath.substring(sepIndex+1),Value);
}else{
if(this.containsKey(objKey)==false){
this.put(objKey,newArrayList<Object>());
}
List<Object>list=(List<Object>)this.get(objKey);
intnextDotIndex=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=newArrayList<Integer>();
for(Stringk:aryIndexs_Strings){
aryIndexs.add(MyObject.AsInt(k));
}
MapModelvv=(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>
///<paramname="list"></param>
///<paramname="indexs"></param>
///<paramname="Value"></param>
///<paramname="NextIsDict">下一个对象是否是字典。</param>
///<paramname="level"></param>
///<returns></returns>
privatestaticObjectPatchArrayLevels(List<Object>list,List<Integer>indexs,StringValue,booleanNextIsDict,intlevel){
intindex=indexs.get(level);
if(level>=(indexs.size()-1)){
if(NextIsDict){
for(inti=list.size();i<=index;i++){
list.add(newMapModel());
}
list.set(index,newMapModel());
returnlist.get(index);
}else{
for(inti=list.size();i<=index;i++){
list.add(null);
}
list.set(index,Value);
returnnull;
}
}
for(inti=list.size();i<=index;i++){
list.add(newArrayList<Object>());
}
returnPatchArrayLevels((List<Object>)list.get(index),indexs,Value,NextIsDict,level+1);
}
}
具体实现参考开源项目的实现,项目地址:http://code.taobao.org/svn/MyJavaMvc
2.属性名
-
狗B的Java到底做了什么,为什么实体属性是isAdmin:Boolean,客户端会返回admin:Boolean
-
为什么SB的Mongo驱动,会把集合里的id变为_id
-
最后一个SB的坑。前端Post如下数据:
cartIds[0].id:596713322b3fe4306a3a60f7 cartIds[0].number:10000 cartIds[0].amount:30000
后端来接收:(Kotlin语法,和Java执行原理一样)
dataclassabc(varcartIds:Array<CommitOrderDataItem>=arrayOf()){}
@ApiOperation(value="生成订单")
@JsonpMapping("/toOrder")
funtoOrder(@ApiParam("购物车中的id,number,amount的集合")abc:abc){
//再取出来。
varcartIds=abc.cartIds;
}
3.依赖
文件上传,使用CommonsMultipartResolver不报错,编译不报错,运行时报错。添加以下依赖解决了。
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
Java就是狗屎!!!
在Get请求时,会执行两次filter
本文内容总结:规范,Java对象序列化,引出,破解,2.属性名,3.依赖,
原文链接:https://www.cnblogs.com/newsea/p/5010714.html