前面的話:
有關阿里的fastjson升級時遇到的問題,鏈接如下
https://github.com/alibaba/fastjson/wiki/enable_autotype
我要說的,是我碰到這個問題時的一些處理
1、問題描述:
我所在的項目組是使用的微服務架構,我們組只負責我們自有模塊,其他模塊由其他團隊負責,有一天,看到一條新聞說是fastjson修復了一些高危漏洞,然后我們就協定升版本,然后今天就踩到了這個坑,報錯如下:
com.alibaba.fastjson.JSONException: unclosed.str
問題是這樣的,我們原有代碼轉換的時候一個json字符串處理如下
String str = "{'@type':'com.dcf.platform.token.MessageHolder','forSend':'211554','generateTime':1490422777204,'id':'18701762172','lastCanSendTime':1490422777204,'message':'211554'}";
Object obj = JSON.parse(str);
當這個json字符串轉化為object的時候,autotype被fastjson禁用掉了,導致異常
2、問題處理:
按照fastjson官網(就是最上面那個鏈接里)的說法,有幾種處理方式,我們就臨時先做了一個簡單粗暴的處理,等到周一之后討論具體方案(因為今天是周六)
做法就是按照官網說法,在tomcat的catalina.sh里面的JAVA_OPTS參數后面添加了JVM啟動參數:-Dfastjson.parser.autoTypeSupport=true
這樣子就不會報錯了,不過這只是臨時做法,因為這個是fastjson的安全漏洞,如果按照這種方式的話,也還是存在這樣的漏洞的
3、另一種相對較好的解決方式:
添加配置項:fastjson.properties里面加入fastjson.parser.autoTypeAccept=com.serol.pojo
問題也可以解決,注意后面的包名是所要轉換對象的包名,測試如下:
Person person = new Person("明明", "aa", 21);
final String valueStr = JSON.toJSONString(person, SerializerFeature.WriteClassName);
System.out.println(valueStr);
Object obj = JSON.parse(valueStr);
System.out.println(((Person)obj).getUsername());
這個相對硬編碼方式ParserConfig.getGlobalInstance().addAccept("com.serol.pojo");的好處是不用去修改原有代碼,只需要添加這個配置,
相對於修改JVM啟動參數的好處是,這個解禁autotype只針對所設置的這個包下的對象,其他的還是不可以轉化
4、其他處理:
以上是針對已有代碼,不願意去大動干戈,那么如果新寫的話,以怎樣的方式更好一些呢?
我的做法是,轉化時,需要傳入所要轉化對象的class
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.serol.pojo.Person;
main: System.out.println(((Person)getJsonObject(Person.class)).getUsername());
public static Object getJsonObject(Class<?> clazz){
Person person = new Person("明明", "aa", 21);//轉化json,簡單化處理
String valueStr = JSON.toJSONString(person);//轉化json,簡單化處理
System.out.println(valueStr);
JSONObject obj = JSON.parseObject(valueStr);
return JSONObject.toJavaObject(obj, clazz);
}
這樣的話,就完全不用擔心那個安全問題了,避免autotype
有更好的方式請加評論,有問題,我們共同解決共同進步