I have a Java object as below
public class Command {
private String cmd;
private Object data;
}
I want JSON Conversion of this Object to look as below
{"cmd":"getorder","data":{"when":"today"}}
How do I do this without changing the Class definition?
I know how to use GSON or Jackson library. I am having trouble assigning values to or initializing (Object) data above, so that it properly converts to {"when":"today"} when I use those libraries.
Thanks
You can try Gson library
it's very easy to use and it can do the reverse operation as well
Depending on your needs you might consider to add a handwritten json formatter for your class (of yourse this interferes with your demand to not change the class definition) but in fact it gives you max flexibility without 3rd party dependencies. If you strictly let all your Objects overwrite toString() to give json formatted string representation you could e.g.
String toString() {
StringBuffer result = new StringBuffer();
result.add("{ \"cmd\":" + this.cmd);
result.add(",");
result.add( \"data\":" + data.toString());
result.add("}");
return result.toString();
}
In case your need to not change the class definition appears more important than the mentioned advanteges there is a a nice json library avaialble on code.google.com named "simple json" ( https://code.google.com/p/json-simple/ ).
Related
I have a Model consisting in a main Manager class, which has some variables, for example name but also has a big object called data. For a special case I want to pass from json to Model with Gson but ignoring the data Object of the json (for the normal case I will decode completely all the objects of the json).
I need to do this without anotations and without transient, just adding a deserializing rule to exclude Data class in case I want to do it.
How can I specify ad decode time that I want to ignore a class?
My model:
public class Manager{
String name;
Data data;
}
public class Data{
String dummy;
String dummy2;
}
Json sample:
{"manager":{"name":"testname","data":{"dummy":"testname", "dummy2":"testname2"}}}
Code sample that decodes all:
GsonBuilder gsonBuilder = new GsonBuilder();
new GraphAdapterBuilder()
.addType(Data.class)
.addType(Manager.class)
.registerOn(gsonBuilder);
Gson gson = gsonBuilder.create();
Manager manager = gson.fromJson(json, Manager.class);
Fortunately for you, I banged my head last week to sort out a derivative of what you're trying to achieve. So as i mention in this post there is a little trick in the release version that maybe suite what are you trying to do:
Apparently the toString() method inside the parsed class is needed to
make the Gson library work.
The toString() method expose the class to the serialization.
Having said that if you use a release version and don't add any proguard rules you can use the following method to exclude data:
#Override
public String toString() {
return "Manager{" +
"name='" + name + '\'}';
}
I'm realizing my second API with swagger/swagger-codegen.
After having a really good start with my first one I'm somewhat stuck with the following problem:
I'm having multiple definitions like the following:
TopIssueReference:
description: Id of a top issue
type: string
example:
itemid: 'd32c1213-4773-442e-9c5f-f5d516358869'
All those definitions only are aliases for type string, some with format date-time, some naked like the one above.
The swagger editor is fine with those definitions.
When I use one of them in a $ref clause within some object definition the generator produces a reference to a class named like my definition, TopIssueReference in this case.
The generated TopIssueReference class is the following (in java):
#ApiModel(description = "Id of a top issue")
public class TopIssueReference {
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("class TopIssueReference {");
sb.append("}");
return sb.toString();
}
}
which is not really useful.
Does anybody have an idea what's going wrong here?
Shouldn't the generator either produce a reference to a String or at least make TopIssueReference derive from a string (however useful that may be)?
For some of those definitions, the generator does not generate any class at all - but the references are still there, so the resulting code does not even compile.
I tried generating servers and clients with java and python, and both are having the same problem.
Try Bellow code to your swagger file to generate code.
TopIssueReference:
description: Id of a top issue
type: object
properties:
itemid:
type: string
i hope it's useful to you ...!
I'm having some cases where Jackson is changing cases of fields in a POJO during serialization in ways I would not expect. I'm using the following block to do the serialization:
ObjectMapper mapper = new ObjectMapper()
String json = mapper.writeValueAsString(o)
I'm noticing that all of the fields which are prepended with 'v' are getting the next capital letter also lowercased. For example, for the POJO field as below:
vStatus1 = "3424522"
I see after serialization the following JSON field:
vstatus1="3424522"
This is mainly important to me because I'm using a switch to go between two different web services which should provide the same output map, but this hiccup is preventing me from doing it cleanly.
If you are using Jackson, you can set the #JsonProperty on the field's getter and change it to whatever you like...
#JsonProperty("vStatus1")
public String getvStatus1() {
return vStatus1;
}
// Produces: {"vStatus1":"3424522"}
#JsonProperty("VStatus1")
public String getvStatus1() {
return vStatus1;
}
// Produces: {"VStatus1":"3424522"}
I'm using a switch to go between two different web services which should provide the same output map
In addition to the above, perhaps consider switching on the lowercased version of your string...
switch(myString.toLowerCase()) {
case "foo": doSomething();
...
}
In an android application I'm developing I need to get a json file containing some data to reconstruct the lines of code of a java class.
Is there any java/javascript library that allows to convert/parse a java class (that doesn't just have fields, but also methods defined inside it) in JSON format, and vice-versa?
EDIT: I'd also need to keep track of the whole project's structure (something like antlr?)
EDIT2: My bad, I wanted to store a java class code into a JSON object to represent it, I was also thinking to create my own json object, this way, by parsing the Java code and finding methods, classes, parameters.
{
"file": "PATH/TO/.java",
"language": "java",
"from": 0,
"to": 255,
"classes": [
"Test:2"
//...
],
"lines": [
[
"public class Test{"
//...
]
]
}
But if a good starting point is present, that would be great.
The trouble is that existing tools (such as GWT) are "only" able to create functioning JS code that is meant to be executed in browsers. But it does not necessarily resemble the original Java class. Your use case sounds quite different. It looks like you want to represent Java source code as JSON data and you don't need/want to execute it.
I fear you may have to create your own tool for that, that meets your specific requirements. I also fear that this tool must be able to parse the Java code because using simple regexes for extracting the data won't help here much because of nested types (interfaces, classes, enums) and also because a single Java file may contain multiple type declarations (even though not encouraged, but it is possible).
Here are a few links for Java parsers:
http://code.google.com/p/javaparser/ (unfortunately only Java 1.5)
http://www.ibm.com/developerworks/opensource/library/os-ast/ (discusses the Eclipse Java parser which is very robust and probably most suitable for your requirement)
You could also create your own parser using ANTLR as you suggest. The latest ANTLR version has some visitor pattern you need to implement in Java, as far as I know. You could implement a visitor that successively constructs your JSON output.
However, you really should use Eclipse's ASTParser for that, because you can easily iterate all methods of your class and get their implementation code as String.
You can use jackson library - http://jackson.codehaus.org/: http://www.mkyong.com/java/how-to-convert-java-object-to-from-json-jackson/
Use GSON: "GOOGLE for JSON" it's a google open source JSON Library, it can convert Java Object t o JSON object and vice-versa
You have Gson package that convert Json String to Java object and vice versa.
MyClass.java
public class MyClass {
private String mStr = "";
public String getStr() {
return mStr;
}
public void setStr(String mStr) {
this.mStr = mStr;
}
}
Main.java
public class Main {
public static void main(String[] args) {
String jsonString = "{ \"mStr\": \"foo\" }";
Gson mGson = new Gson();
MyClass res = mGson.fromJson(jsonString, MyClass.class);
System.out.println(res.getStr());
}
}
Output: foo
[Edit 1]
You can't store to Json class structure, only data
[Edit 2]
From your fix I understand followed thing:
This Json String represents behavior what to do with "text" file , suppose, you download from server. But no mater what inside Json String 1st of all you need to convert it to Object in Java (if you want to use Java) and after that according to rules (took from Json String) write any logic. For sure java code is able to generate Java files. Your example tells you:
to get text from line ... to line,
create file named xxxx.java
copy it to ...
So use my example above, create class, lets say Launcher:
public class Launcher{
private String file;
private String language;
private int from;
private int to;
private List<String> classes;
private List<SomeOtherClass> lines;
....
}
I'm trying to write a data access layer for an AJAX web project. This DAL has to convert data coming in via an AJAX servlet to objects that can be passed to a PreparedStatement for execution.
Data in the AJAX servlet, retrieved by using HttpServletRequest.getParameter(...), come in as strings.
In each data class, I have a known set of fields as well as their data types, e.g. CustomerId(integer), CustomerName(string).
I can of course write a method in the Customer class to handle the conversion, but this means I have to do it for every data object's class. I would much rather have a generic method that does conversion, e.g.
Object convert(String value, Class<?> targetType) { ... }
Can anyone point me in the right direction?
Create an utility class with all conversion methods you would like to use. Inside its static initializer, make use of reflection to collect all those methods by parameter type and return type in a map. Then, in the convert() method just pick the method which suits the given source and target type and invoke it. Make use of generics to fix the return type to be the same as the target type:
public static <T> T convert(Object from, Class<T> to)
You can find an example in this article.
But as bmargulies pointed out, JSON is also an interesting option. You could let ajax to send all parameters as one JSON string. Then, you can use a JSON-to-Javabean converter like Google Gson to convert the JSON string to a fullworthy Javabean like Customer. It'll be as simple as:
String jsondata = request.getParameter("jsondata");
Customer customer = new Gson().fromJson(jsondata, Customer.class);
// ...
See also this answer for another example.
There are JSON libraries that will do data type conversion. Jackson is one. Or, you could code the whole think using a JAX-RS service framework instead of a raw servlet, and it will take care of all this for you. Apache CXF is one framework that contains this support. Since you are asking for a generic solution, why not use one that's already out there.
We do this exact thing using a plethora of static converters in a utility class. It isn't elegant but it sure is easy and effective.
class Util {
public static Long StringToLong(String s) { ... }
public static Integer StringToInt(String s) { ... }
public static Date StringToDate(String s) { ... }
public static Date StringToDateYYMMDD(String s) { ... }
public static BigDecimal StringToBigDecimal(String s) { ... }
// etc ad naseum
}
Since you want to use the parameters in your PreparedStatement, why do you have to convert them at all?
When using setString(index, parameter) SQL will be happy to do the conversion for you.
Thus the only thing you might want to do is some kind of validation that the input is really valid (or you could even leave this part to your SQL engine which will throw an exception if it doesn't understand you.