歡迎關注公衆號【IT徐胖子】獲取更多互聯網和技術乾貨,感謝各位支持
1 文章概述
在阿里巴巴開發手冊中有這樣一條強制規定值得大家關注:【強制】二方庫裏可以定義枚舉類型,參數可以使用枚舉類型,但是接口返回值不允許使用枚舉類型或者包含枚舉類型的POJO對象。
我們在日常開發中服務生產者會提供二方包給消費者引用,在返回對象中屬性不能包含枚舉類型,這是一個強制要求。我們通過一個實例分析:爲什麼阿里巴巴開發手冊中會有這樣一條強制要求。
2 生產者實例
服務生產者提供1.0版本二方包
public class StudentDTO implements Serializable {
private Long id;
private String name;
private HobbyEnum hobbyEum;
}
public enum HobbyEnum {
FOOTBALL(1),
BASKETBALL(2)
}
服務生產者發佈RPC服務
public class StudentServiceImpl implements StudentService {
public StudentDTO queryStudentById(Long id) {
StudentDTO student = new StudentDTO();
student.setId(100L);
student.setName("今日頭條號「IT徐胖子」");
student.setHobbyEnum(HobbyEnum.FOOTBALL);
return student;
}
}
3 消費者實例
服務消費者引入生產者1.0版本二方包
<dependency>
<groupId>com.test.xpz</groupId>
<artifactId>xpz-student-api</artifactId>
<version>1.0</version>
</dependency>
服務消費者以如下代碼調用可以得到正確結果,到目前爲止都沒有問題
public class StudentTest {
@Resource
private StudentService studentService;
public void getStudent() {
StudentDTO student = studentService.queryStudent(100L);
System.out.println(student);
}
}
4 發現問題
服務生產者枚舉類新增信息並且升級二方包至2.0版本
public enum HobbyEnum {
FOOTBALL(1),
BASKETBALL(2),
SWIMMING(3)
}
服務生產者修改提供服務代碼實現
public class StudentServiceImpl implements StudentService {
public StudentDTO queryStudentById(Long id) {
StudentDTO student = new StudentDTO();
student.setId(100L);
student.setName("今日頭條號「IT徐胖子」");
student.setHobbyEnum(HobbyEnum.SWIMMING);
return student;
}
}
服務消費者不做任何改動保持引用1.0版本二方包。現在生產者返回結果包含SWIMMING信息,但是1.0版本二方包根本沒有這個值,所以會引起序列化異常。這是一個非常嚴重的問題,消費者在沒有做任何改動的情況下依然出現異常。
hessian.io.HessianFieldException:
Caused by: java.lang.IllegalArgumentException: No enum constant com.xpz.student.HobbyEnum.SWIMMING
5 解決方案
StudentDTO屬性全部改爲基本類型或者基本類型包裝類就可以避免這類嚴重錯誤,消費者可以使用HobbyEnum枚舉類去翻譯hobby這個數值的含義。這個問題非常容易被忽略值得大家關注。
public class StudentDTO implements Serializable {
private Long id;
private String name;
private int hobby;
}
掃描二維碼關注公衆號【IT徐胖子】獲取更多互聯網和技術乾貨,感謝各位支持