import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
import com.google.protobuf.Descriptors.FieldDescriptor;
import com.google.protobuf.GeneratedMessage;
public class ProtoToJson(){
//msg is any protobuf object
public static String generateJsonFromMsg(GeneratedMessage msg) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, ClassNotFoundException, NoSuchMethodException, SecurityException{
Map<FieldDescriptor,Object> allFields = msg.getAllFields();
StringBuilder sb = new StringBuilder();
for(FieldDescriptor field: allFields.keySet()){
sb.append("\"" + field.getName() +"\"");
sb.append(":");
boolean isRepeated = field.isRepeated();
Class<?> c = Class.forName(msg.getClass().getName());
try{
String name = field.getName();
if(isRepeated){
name = name + "List";
}
Method method = c.getDeclaredMethod ("get"+ WordUtils.capitalize(name,new char [] {'_'}).replace("_", "") );
Object value = method.invoke(msg);
if(value instanceof GeneratedMessage){
if(!isRepeated)
sb.append("{");
sb.append(generateJsonFromMsg((GeneratedMessage)value));
if(!isRepeated)
sb.append("}");
}else {
if(isRepeated){
sb.append("[");
List list = (List)value;
int size = list.size();
for(int i=0;i<size;i++){
if(list.get(i) instanceof GeneratedMessage)
sb.append("{").append(generateJsonFromMsg((GeneratedMessage)(list.get(i)))).append("}");
else
sb.append(list.get(i));
if(i!=size-1){
sb.append(",");
}
}
sb.append("]");
//sb.append(value);
} else
sb.append("\"" + value + "\"");
}
}catch(Exception e){
System.out.println(e);
}
sb.append(",");
}
//System.out.println("************************************************ "+sb.toString());
return sb.deleteCharAt(sb.length() -1).toString();
}
}发布于 2014-09-26 11:31:36
这里有一些你忽略的最佳实践问题,当它们结合在一起,就会产生一些杂乱无章的功能。
首先,这段代码:
} else sb.append("\"" + value + "\""); } }catch(Exception e){ System.out.println(e); }
缩进是代码逻辑块的一个非常强的指示符,当缩进出错时,代码中的逻辑很难识别。
现在,那个特别的6行代码段,还有一些其他的问题.
}catch(Exception e){应该是} catch (Exception e) {{...}大括号括起来,即使它们有1行长。代码:} else sb.append(“\”+值+“\”);应该是:{sb.append(“\”+值+“\”);}SecurityException,那么继续下去真的可以吗?谈论例外..。我希望看到的是类的自定义异常,而不是.的列表。IllegalAccessException, IllegalArgumentException, InvocationTargetException, ClassNotFoundException, NoSuchMethodException, SecurityException。在执行反射时捕获这些异常,然后将它们包装在一个更具描述性的异常中,然后重新抛出,这将使您有一个更干净的接口,并为您的代码提供一个更简单、更有效的尝试/捕获机制。
在查看HashMaps时,您正在循环遍历keySet,然后使用该键调用map.get(键)。这是低效的,因为还有一个返回entrySet()对象的Map.Entry对象,该对象在一个地方包含两个值。这里写得很好:entrySet()与keySet()。
类似地,您有以下循环:
int size = list.size(); for(int i=0;i<size;i++){ if(list.get(i) instanceof GeneratedMessage) sb.append("{").append(generateJsonFromMsg((GeneratedMessage)(list.get(i)))).append("}"); else sb.append(list.get(i)); if(i!=size-1){ sb.append(","); } }
该循环可以与主循环中的想法相同,或者还有迭代器版本.请考虑以下代码:
for(Object val : list) {
if(val instanceof GeneratedMessage) {
sb.append("{").append(generateJsonFromMsg((GeneratedMessage)(list.get(i)))).append("}");
} else {
sb.append(val);
}
sb.append(", ");
}
// remove the last ', ' if needed.
if (!list.isEmpty()) {
sb.setLength(sb.length() - 2);
}或者,您也可以这样做:
for (Iterator<?> itr = list.iterator(); it.hasNext();) {
Object val = it.next();
if(val instanceof GeneratedMessage) {
sb.append("{").append(generateJsonFromMsg((GeneratedMessage)(list.get(i)))).append("}");
} else {
sb.append(val);
}
if (itr.hasNext()) {
sb.append(", ");
}
}https://codereview.stackexchange.com/questions/63928
复制相似问题