首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Protobuf to Json变换器

Protobuf to Json变换器
EN

Code Review用户
提问于 2014-09-26 07:59:01
回答 1查看 4.3K关注 0票数 -5
代码语言:javascript
复制
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();
}
}
EN

回答 1

Code Review用户

发布于 2014-09-26 11:31:36

这里有一些你忽略的最佳实践问题,当它们结合在一起,就会产生一些杂乱无章的功能。

首先,这段代码:

} else sb.append("\"" + value + "\""); } }catch(Exception e){ System.out.println(e); }

缩进是代码逻辑块的一个非常强的指示符,当缩进出错时,代码中的逻辑很难识别。

现在,那个特别的6行代码段,还有一些其他的问题.

  • 空白是代码的重要组成部分。你剥去了很多地方通常都是空白的地方。例如,}catch(Exception e){应该是} catch (Exception e) {
  • 当您使用StringBuilder时,与标准字符串级联相比,您具有减少内存‘搅动’的优点……因此,如果您有一个StringBuilder,则根本不应该使用字符串连接!使用追加方法(对于双引号,使用单引号有助于防止转义序列.:sb.append(“\”+值+“\”);应该是:sb.append(‘).append(值).append(’);
  • 1- line语句块应该始终用{...}大括号括起来,即使它们有1行长。代码:} else sb.append(“\”+值+“\”);应该是:{sb.append(“\”+值+“\”);}
  • 异常处理不仅仅是打印异常,它是您诊断问题的一部分。您至少也应该发布由at引起的异常的数据。在循环内部尤其如此,因为您不知道是哪个循环的迭代导致了问题。你的异常不仅对诊断毫无用处,而且还能诱捕不该被困住的异常.如果异常是一个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(","); } }

该循环可以与主循环中的想法相同,或者还有迭代器版本.请考虑以下代码:

代码语言:javascript
复制
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);
}

或者,您也可以这样做:

代码语言:javascript
复制
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(", ");
    }
}
票数 5
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/63928

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档