ProtoUtils { @ExperimentalApi("https: public static <T extends Message> Marshaller<T> jsonMarshaller(final T defaultInstance) { final Printer printer = JsonFormat.printer(); final JsonFormat.Parser parser = JsonFormat.parser(); final Charset charset = Charset.forName("UTF-8"); return new Marshaller<T>() { @Override public InputStream stream(T value) { try { return new ByteArrayInputStream(printer.print(value).getBytes(charset)); } catch (InvalidProtocolBufferException e) { throw Status.INTERNAL .withCause(e) .withDescription("Unable to print json proto") .asRuntimeException(); } } @SuppressWarnings("unchecked") @Override public T parse(InputStream stream) { Builder builder = defaultInstance.newBuilderForType(); Reader reader = new InputStreamReader(stream, charset); T proto; try { parser.merge(reader, builder); proto = (T) builder.build(); reader.close(); } catch (InvalidProtocolBufferException e) { throw Status.INTERNAL.withDescription("Invalid protobuf byte sequence") .withCause(e).asRuntimeException(); } catch (IOException e) { throw Status.INTERNAL.withDescription("Invalid protobuf byte sequence") .withCause(e).asRuntimeException(); } return proto; } }; } private  ProtoUtils(); @Deprecated static Marshaller<T> marshaller(final T defaultInstance); static Marshaller<T> marshaller(final T defaultInstance); @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1786") static Marshaller<T> jsonMarshaller(final T defaultInstance); static Metadata.Key<T> keyForProto(T instance);  }
@Test public void testJsonRoundtrip() throws Exception { Marshaller<Type> marshaller = ProtoUtils.jsonMarshaller(Type.getDefaultInstance()); InputStream is = marshaller.stream(proto); is = new ByteArrayInputStream(ByteStreams.toByteArray(is)); assertEquals(proto, marshaller.parse(is)); }
@Test public void testJsonRepresentation() throws Exception { Marshaller<Type> marshaller = ProtoUtils.jsonMarshaller(Type.getDefaultInstance()); InputStream is = marshaller.stream(proto); String s = new String(ByteStreams.toByteArray(is), "UTF-8"); assertEquals("{\"name\":\"value\"}", s.replaceAll("\\s", "")); }
@Ignore("https: @Test public void testJsonInvalid() throws Exception { Marshaller<Type> marshaller = ProtoUtils.jsonMarshaller(Type.getDefaultInstance()); try { marshaller.parse(new ByteArrayInputStream("{]".getBytes("UTF-8"))); fail("Expected exception"); } catch (StatusRuntimeException ex) { assertEquals(Status.Code.INTERNAL, ex.getStatus().getCode()); assertNotNull(ex.getCause()); } }
@Test public void testJsonInvalidProto() throws Exception { Marshaller<Type> marshaller = ProtoUtils.jsonMarshaller(Type.getDefaultInstance()); try { marshaller.parse(new ByteArrayInputStream("{\"\":3}".getBytes("UTF-8"))); fail("Expected exception"); } catch (StatusRuntimeException ex) { assertEquals(Status.Code.INTERNAL, ex.getStatus().getCode()); assertNotNull(ex.getCause()); } }
@Test public void testJsonIoException() throws Exception { Marshaller<Type> marshaller = ProtoUtils.jsonMarshaller(Type.getDefaultInstance()); final IOException ioe = new IOException(); try { marshaller.parse(new ByteArrayInputStream("{}".getBytes("UTF-8")) { @Override public void close() throws IOException { throw ioe; } }); fail("Exception expected"); } catch (StatusRuntimeException ex) { assertEquals(Status.Code.INTERNAL, ex.getStatus().getCode()); assertEquals(ioe, ex.getCause()); } }