为什么不用实现Serializable
现在流行前后端分离开发,数据通信采用json格式,记得在哪看到过一个对象如果需要通过网络传输需要实现Serializable接口,但我们在开发后端的时候都是这样的
@ResponseBody
public User getCrossingInfo(String crossingIndexCode) {
User user= new User("xiaoming", 18);
return user;
}
我们的User并没有实现Serializable接口,但照样可以行得通,为什么呢。实际上这是Spring框架帮我们做了一些事情,Spring并不是直接把User对象进行网络传输,而是先把User对象转换成json格式的字符串,然后再进行传输的,而String类实现了Serializable接口
RestEasy
接口定义(服务提供方发布接口,并实现接口,需要将服务注册到服务中心,比如consul,假设注册的服务名为myService,路径为/myService/service/rs)
@Path("web/userService")
@Consumes({"application/json"})
@Produces({"application/json"})
public interface UserWebService {
@POST
@Path("/saveOrUpdate")
Result saveOrUpdateUser(UserVO var1, @QueryParam("language") String var2)
}
Result需要实现Serializable
public class Result<T> implements Serializable{
//结果类型,0成功,-1失败,默认-1
private Integer type = -1;
//错误码,type为0时,code也为0,其他情况为具体的错误码
private String code;
//消息描述
private String msg;
//数据内容
private T data;
//Getter and Setter...
}
调用方(同样需要引入consul)引入提供方提供的接口jar包,通过@FeignClient继承接口,然后就可以像调用本地方法一样调用提供方的方法
@FeignClient(
value = "myService",
path = "/myService/service/rs"
)
public interface UserWebServiceClient extends UserWebService {
}
@Autowired
UserWebServiceClient userWebServiceClient
public void test(){
UserVo user = ...;
String language = ...;
Result result = userWebServiceClient.saveOrUpdateUser(user, language)
}
容易出错的地方
使用fastjson解析json
User user = new User("xiaoming", 18);
Result<User> result = new Result(0, "0", "success", user);
String jsonStr = JSON.toJSONString(result);//{\"type\":0,\"code\":\"0\",\"msg\":\"success\",\"data\":{"\name\":\"xiaoming\",\"age\":18}}";
Result<User> result1 = JSON.parseObject(jsonStr, Result.class);
User user1 = result1.getData();//ClassCastException
问题就出在这里,JSON.parseObject是把jsonStr转换为Result对象了,但是debug你会发现Result的data字段实际上是JSONObject类型,也就是说result.getData()返回的是JSONObject类型,并不是想我们以为的User类型,所以会出现类型转换异常。到了这里,我们可能会想到调用JSON.toJavaObject(JSON, Class)方法来进行转换,但是你会发现根本用不了,因为JSON.toJavaObject的第一个参数是JSON类型的,尽管result.getData()的运行时类型是JSONObject,但是当你把result.getData()
敲出来的时后,它又是User类型的,无法转成JSON类型,真是拿它没办法。同理如果jsonStr中data是[]
,那result.getData()返回的是JSONArray类型。
我们可以使用下面的办法来解决,只是麻烦一点点
User user = new User("xiaoming", 18);
Result<User> result = new Result(0, "0", "success", user);
String jsonStr = toJSONString(result);//{\"type\":0,\"code\":\"0\",\"msg\":\"success\",\"data\":{"\name\":\"xiaoming\",\"age\":18}}";
Result result1 = JSON.parseObject(jsonStr, Result.class);//不要带上类型参数User,这样一来getData()返回的就是Object类型,就可以进行下面的转换
JSONObject obj = (JSONObject)result1.getData();
User user1 = JSON.toJavaObject(obj, User.class);
如果是JSONArray,我们就遍历JSONArray,依次取出JSONObject,再转成User