Json에서 Protobuf로 변환하는 방법?
protobuf를 처음 사용하는데 자바에서 json stream/string을 protobuf stream/string으로 간단하게 변환할 수 있는 방법이 없을까요?
예를들면,
protoString = convertToProto(jsonString)
protobuf 메시지로 해석하는 json 문자열이 있습니다.그래서 먼저 json 문자열을 protobuf로 변환하고 나서Message.parseFrom()
그 위에 올려놔요.
proto3에서는 JsonFormat을 사용하여 이를 수행할 수 있습니다.JSON 표현에서 직접 해석되므로 별도로 호출할 필요가 없습니다.MyMessage.parseFrom(...)
. 다음과 같은 것이 작동해야 합니다.
JsonFormat.parser().merge(json_string, builder);
//You can use this for converting your input json to a Struct / any other Protobuf Class
import com.google.protobuf.Struct.Builder;
import com.google.protobuf.Struct;
import com.google.protobuf.util.JsonFormat;
import org.json.JSONObject;
JSONObject parameters = new JSONObject();
Builder structBuilder = Struct.newBuilder();
JsonFormat.parser().merge(parameters.toString(), structBuilder);
// Now use the structBuilder to pass below (I used it for Dialog Flow V2 Context Management)
어떤 사람이 "com.google.protobuf" 예외에 대해 물어봤기 때문에Adam의 조언을 따를 때 InvalidProtocolBufferException: JsonObject"와 같은 문제가 발생하였습니다.구글 프로토부프 타임스탬프 때문인 것으로 드러났습니다.seconds 와 nanos 의 2 개의 필드를 포함한 오브젝트로 시리얼화 됩니다.이것은 프로덕션 코드가 아니기 때문에, 잭슨을 사용해 JSON 를 해석해, JSON 오브젝트를 재귀적으로 조사해, 오브젝트의 모든 타임스탬프를 RFC 3339 에 따라서 포맷 된 문자열로 변경해, 그것을 시리얼화해, 프로토를 사용했습니다.Adam이 나타낸 바와 같이 buf JSON 파서.이것으로 문제가 해결되었습니다.이것은 제가 작성한 일회용 코드입니다(모든 타임스탬프 필드에 "timestamp"라는 단어가 포함되어 있습니다.이것이 더 강력할 수 있지만, 저는 상관없습니다).
public Map<String, Object> fixJsonTimestamps(Map<String, Object> inMap) {
Map<String, Object> outMap = new HashMap<>();
for(String key : inMap.keySet()) {
Object val = inMap.get(key);
if(val instanceof Map) {
Map<String, Object> valMap = (Map<String, Object>)val;
if(key.toLowerCase().contains("timestamp") &&
valMap.containsKey("seconds") && valMap.containsKey("nanos")) {
if(valMap.get("seconds") != null) {
ZonedDateTime d = ZonedDateTime.ofInstant(Instant.ofEpochSecond((int)valMap.get("seconds")).plusNanos((int)valMap.get("nanos")),
ZoneId.of("UTC"));
val = d.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"));
}
} else {
val = fixJsonTimestamps(valMap);
}
} else if(val instanceof List && ((List) val).size() > 0 &&
((List) val).get(0) instanceof Map) {
List<Map<String, Object>> outputList = new ArrayList<>();
for(Map item : (List<Map>)val) {
outputList.add(fixJsonTimestamps(item));
}
val = outputList;
}
outMap.put(key, val);
}
return outMap;
}
가장 이상적인 솔루션은 아니지만 현재 작업에는 효과가 있습니다. 누군가 다른 타임스탬프 클래스를 사용하도록 권장하는 것을 본 것 같습니다.
builder와 json String을 사용하여 json 문자열을 Proto로 변환할 수 있습니다.
예:
YourProto.Builder protoBuilder = YourProto.newBuilder();
JsonFormat.parser().merge(JsonString, protoBuilder);
알 수 없는 json 필드를 무시하려면
YourProto.Builder protoBuilder = YourProto.newBuilder();
JsonFormat.parser()..ignoringUnknownFields().merge(JsonString, protoBuilder);
또 다른 방법은 ProtocolBuffer에서 mergeFrom 메서드를 사용하는 것입니다.
예:
YourProto.Builder protoBuilder = YourProto.newBuilder();
protoBuilder.mergeFrom(JsonString.getBytes());
실행되면 protoBuilder의 모든 데이터를 json String에서 가져옵니다.
온라인 서비스: https://json-to-proto.github.io/
이 도구는 JSON을 즉시 Protobuf로 변환합니다.왼쪽에 JSON 구조를 붙여넣으면 오른쪽에 동등한 Protobuf가 생성되어 프로그램에 붙여넣을 수 있습니다.이 스크립트는 몇 가지 가정을 해야 하므로 출력을 다시 확인하십시오.
언급URL : https://stackoverflow.com/questions/38406211/how-to-convert-from-json-to-protobuf
'programing' 카테고리의 다른 글
Google Chrome은 JSON AJAX 응답을 일반 텍스트가 아닌 트리로 표시합니다. (0) | 2023.03.19 |
---|---|
jQuery.ajax 처리 계속 응답: "success:" vs.done? (0) | 2023.03.19 |
데이터 변경 시 $watch가 실행되지 않음 (0) | 2023.03.14 |
스프링 부트(JPA 포함): @Entity를 다른 패키지로 이동 (0) | 2023.03.14 |
JSON 문자열에서 반환된 Objective-C의 null 값 확인 (0) | 2023.03.14 |