Given a simple Protobuf message
message MessageWithUrl {
string url_params = 1;
}
I'm doing the following:
Msg.MessageWithUrl message = Msg.MessageWithUrl
.newBuilder()
.setUrlParams("?key=value")
.build();
String json = JsonFormat.printer()
.print(message);
System.out.println(json);
My expected outcome is:
{
"urlParams": "?key=value"
}
Instead I get:
{
"urlParams": "?key\u003dvalue"
}
I understand that the printer is using Gson under the hood, but I don't know how to have it accept the Gson option of disableHtmlEscaping
Related
I develop an Android app that communicates with a back-end developed with Spring. Sometimes, when I send a POST request with Retrofit, the back-end throw this error: ERROR RestExceptionHandler:29 - org.springframework.http.converter.HttpMessageNotReadableException: I/O error while reading input message; nested exception is java.io.CharConversionException: Invalid UTF-32 character 0x616d6765 (above 0x0010ffff) at char #4, byte #19).
Searching about this, I've logged the JSON sent in Retrofit onResponse callback and noticed it was not complete. It's something like that:
{
"key": "value"
"arrayKey": [
{
"objectKey": "objectValue"
}
]
"key2": "value2",
"key3": "
It just stop the JSON creation.
I don't know if this happens because of my convertion to JSON function when I log, or if the object creation has some error. And more strange, when users send multiple times, in one moment everything happens alright.
This is the function to convert object into JSON that I use to log the sent object in Retrofit:
public static <T> String ToJson(T obj) {
try{
GsonBuilder builder = new GsonBuilder();
Gson gson = builder.create();
return gson.toJson(obj);
}
catch(Exception ex) {
Log.v("convertion_error", ex.toString());
return null;
}
}
I don't think the problem is in the log function, because almost everytime the log is OK, with the complete JSON.
This is my object creation function:
private CreatedObject objectCreation(Parameter parameter) {
CreatedObject createdObject = new CreatedObject();
createdObject.setInformation1(parameter.getInformation1());
createdObject.setInformation2(parameter.getInformation2());
createdObject.setInformation3(parameter.getInformation3());
createdObject.setDate(DateFormatHelper.getGMTDate());
List<ObjectArray> objects = new ArrayList<>();
for (DataObject p : parameter.getData()) {
ObjectArray ob = new ObjectArray();
ob.setInformation5(p.getInformation5());
ob.setInformation6(p.getInformation6());
ob.setInformation7(p.getInformation7());
objects.add(ob);
}
createdObject.setArrayInformations(objects);
return createdObject;
}
Someone already got this incomplete JSON error using Retrofit?
I will keep it simple - trying to print the username ('user') value of this JSON file with JACKSON:
{
"creds" : {
"user": "Y9CJG1756",
"pass": "12222#$1"
},
"env": {
"qa": {
"url": "https://www.walla.com/"
}
}
}
I'm running this function but could only find a way to print the entire string of the object 'creds' instead of just the user name.
public static void isJsonStringWorks(String filePath) {
try {
JsonNode objectValue;
byte[] jsonData = Files.readAllBytes(Paths.get(filePath));
ObjectMapper objectMapper = new ObjectMapper();
JsonNode rootNode = objectMapper.readTree(jsonData);
objectValue = rootNode.get("creds");
System.out.println("object is: " + objectValue + " ,\n" + rootNode);
} catch (Exception e) {
System.out.println("Could not read the JSON file");
}
}
Really appreciate the help.
The correct code would be:
objectValue = rootNode.get("creds").get("user").asText()
Also you shall consider the following options:
Introduce Java representation of your data model and read source JSON string as Java object (using objectMapper.readValue(...) method). After that it will be possible to access values like usual Java beans (root.getCreds().getUser())
Using JsonPath to access "deep" values inside JSON to simplify JSON values lookup. For example creds/user value could be obtained like:
String json = "...";
Object document = Configuration.defaultConfiguration().jsonProvider().parse(json);
String value = JsonPath.read(document, "$.creds.user")
you are on right route.
You can call objectValue.get('user')
I want to use a Protocol Buffer Message in a Java project, but I don't know what type will be used during runtime. It can be a simple datatype or another message object.
Example:
proto file:
...
message MyMessage {
repeated google.protobuf.Any params = 1;
}
...
to serialize my values, I use the following code (type of payload is unknown):
Any.Builder anyBuilder = Any.newBuilder();
ByteString byteString;
if (ClassUtils.isPrimitiveOrWrapper(payload.getClass())) {
byte[] serialize = SerializationUtils.serialize((Serializable) payload);
byteString = ByteString.copyFrom(serialize);
} else {
//serialize custom message
}
anyBuilder.setValue(byteString);
myMessage.addParams(Any.pack(anyBuilder.build()));
to deserialize my values, I use the following code:
List<Any> paramsList = myMessage.getParamsList();
Object[] objects = new Object[paramsList.size()];
int i = 0;
for (Any any : paramsList) {
ByteString value = any.getValue();
objects[i++] = SerializationUtils.deserialize(value.toByteArray());
}
The code throws org.apache.commons.lang3.SerializationException: java.io.EOFException
Can I use SerializationUtils#serialize for a independent communication (e.g. Java to Python; Java to C++) at all or do I have to use something else?
Can I use any in Proto3 for a simple datatype or is it restricted to proto messages?
Thanks!
I am calling an API using Retrofit2 that is giving me a large and complicated response. This was fine since all I needed to do was deserialize the response into a String and then put it on an activeMQ.
However, now I would like to add two more Json attributes to the complicated response so that it looks like the following:
{
"event": "some event",
"link": "some link",
"details": {complicated response ...}
}
How do I deserialize a response as a Json (javax.json.Json), so then I can build onto it as a JsonObject with the new attributes, and then a String?
The JacksonConverterFactory forces me to fit this complicated response into POJOs and I do not want to do that! Right now I am adding strings to the top of the response, but this is not an ideal solution.
Assuming that your large and complicated response is in a string named input, you could perhaps do the following:
JsonReader reader = Json.createReader(new StringReader(input));
JsonObject response = reader.readObject();
JsonObject queueMessage =
Json.createObjectBuilder()
.add("event", "some event")
.add("link", "some link")
.add("details", response)
.build();
Another approach, which uses Jackson and doesn't force you to deserialize the complicated response into a structure of JSON-objects, is to use the #JsonRawValue annotation, which lets you mark a String field as already containing JSON that should be included verbatim during serialization.
This allows you to do something like:
public class MQMessage {
public String event, link;
#JsonRawValue
public String details;
}
MQMessage message = new MQMessage();
message.event = "some event";
message.link = "Some link";
message.details = input;
String forMQ = new ObjectMapper().writeValueAsString(message);
Be aware that Jackson doesn't do any verification that details actually contains valid JSON.
My JSON Structure will vary depend on the request. But the content inside each element remain same. For Example:
JSON1:
{
"h1": {
"s1":"s2"
},
"c1": {
"t1:""t2"
}
}
JSON2:
{
"h1": {
"s1":"s2"
},
"c2": {
"x1:""x2"
}
}
In the above example, elements inside h1,c1 and c2 are constant. Please let me know how to convert JSON to JAVA Object
Regards
Udhaya
First of all You need to understand Json Structure cause above format is incorrect visit this
and this
And you can use Google Gson or Json for parsing the result json String .
"t1:""t2" json format incorrect
Used
"t1":"t2"
Instead of
"t1:""t2"
and also used
"x1": "x2"
Instead of
"x1:""X2"
Code to take in java
try {
JSONObject jsonObject = new JSONObject(response);
JSONObject jsonsubObject = jsonObject.getJSONObject("h1");
String s1 = jsonsubObject.getString("s2");
JSONObject jsonsubObject1 = jsonObject.getJSONObject("c1");
String t1 = jsonsubObject1 .getString("t2");
}
catch (JSONException e) {
e.printStackTrace();
}
Use Google Gson:
Gson gson = new Gson();
ClassName object;
try {
object = gson.fromJson(json, ClassName.class);
} catch (com.google.gson.JsonSyntaxException ex) {
//the json wasn't valid json
}
String validJson = gson.toJson(obj); //obj is an instance of any class
json must be a valid JSON String
import org.json.JSONObject;
you can simple pass your data in constructor of JSONObject it automatically handle, you need to throws JSONException which may occur during conversion id format of data is not correct
String data = "{'h1':{'s1':'s2'},'c1':{'t1:''t2'}}";
JSONObject jsnobject = new JSONObject(data);