package org.zbus.client.rpc; import org.zbus.client.ZbusException; import org.zbus.common.json.JSON; import org.zbus.common.json.JSONObject; import org.zbus.common.json.serializer.JSONSerializer; import org.zbus.common.json.serializer.SerializeWriter; import org.zbus.common.json.serializer.SerializerFeature; import org.zbus.common.remoting.Message; public class JsonCodec implements Codec { private static final String DEFAULT_ENCODING = "UTF-8"; @Override public Message encodeRequest(Request request) { Message msg = new Message(); String encoding = request.getEncoding(); if(encoding == null) encoding = DEFAULT_ENCODING; msg.setBody(toJSONBytes(request, encoding, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteClassName)); return msg; } @Override public Request decodeRequest(Message msg) { String encoding = msg.getEncoding(); if(encoding == null){ encoding = DEFAULT_ENCODING; } String jsonString = msg.getBodyString(encoding); Request req = JSON.parseObject(jsonString, Request.class); return req; } @Override public Object normalize(Object param, Class<?> targetType) throws ClassNotFoundException { if(param instanceof JSON){ //转换为目标类型 return JSON.toJavaObject((JSON)param, targetType); } if(targetType.getName().equals("java.lang.Class")){ ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); return classLoader.loadClass(param.toString()); } return param; } @Override public Message encodeResponse(Response response) { Message msg = new Message(); msg.setStatus("200"); if(response.getError() != null){ Throwable error = response.getError(); if(error instanceof IllegalArgumentException){ msg.setStatus("400"); } else { msg.setStatus("500"); } } String encoding = response.getEncoding(); if(encoding == null) encoding = DEFAULT_ENCODING; msg.setBody(toJSONBytes(response, encoding, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteClassName)); return msg; } public Response decodeResponse(Message msg){ String encoding = msg.getEncoding(); if(encoding == null){ encoding = DEFAULT_ENCODING; } String jsonString = msg.getBodyString(encoding); Response res = null; try{ res = JSON.parseObject(jsonString, Response.class); } catch (Exception e){ //probably error can not be instantiated res = new Response(); JSONObject json = null; try{ jsonString = jsonString.replace("@type", "unknown-class"); //禁止掉实例化 json = JSON.parseObject(jsonString); } catch(Exception ex){ throw new ZbusException("JSON format invalid: "+ jsonString); } if(json != null){ final String stackTrace = Response.KEY_STACK_TRACE; if(json.containsKey(stackTrace)){ throw new ZbusException(json.getString(stackTrace)); } res.setResult(json.get(Response.KEY_RESULT)); } } return res; } private static final byte[] toJSONBytes(Object object, String charsetName, SerializerFeature... features) { SerializeWriter out = new SerializeWriter(); try { JSONSerializer serializer = new JSONSerializer(out); for (SerializerFeature feature : features) { serializer.config(feature, true); } serializer.write(object); return out.toBytes(charsetName); } finally { out.close(); } } }