I have a Strig variable.
String name = "xyz";
I want to convert it to json object
{"name" : "xyz"}
I am currently doing it by putting the name in the map and converting map to json.
Map<String, String > map = new HashMap<>();
map.put("name", name);
new Gson().toJson(map);;
Is there better way to do it?
You can use ObjectMapper from com.fasterxml.jackson as
public static String getString(Object object) {
try {
//Object to JSON in String
return objectMapper.writeValueAsString(object);
} catch (IOException e) {
log.error("Exception ", e);
return "";
}
}
You should create an Class Name. So it will automatically create mapping for you:
Sample Code:
public static void main(String[] args) {
Name name = new Name();
name.setName("xyz");
System.out.println(new Gson().toJson(name));
}
Output: {"name":"xyz"}
Name Class:
public class Name {
private String name;
/**
* #return the name
*/
public String getName() {
return name;
}
/**
* #param name
* the name to set
*/
public void setName(String name) {
this.name = name;
}
}
If you have a JSON object of any complexity, you should create a POJO to hold it for you as suggested by #notescrew. If this is a one-off (for example, in some Web controllers that return basic status information) and you are on at least Java 9, you can simplify it by using an inline map:
gson.toJson(Map.of("name", name));
Note that most frameworks (client and server) will take care of serializing to JSON for you, so in most cases you can simply pass or return the Map directly.
Related
I am trying to convert the following JSON structure (part of a larger JSON object) to a POJO but getting the exception copied below (using Java/Jackson).
JSON
"outputKeys":
{"ABC":"gGyIioUr4Jfr5QiCm6Z==",
"DEF":"RxHfNyD2JyPOpG5tv3Jaj5g=="}
Java class
private class OutputKeys {
private String key;
private String value;
public OutputKeys(String key, String value) {
this.key = key;
this.value = value;
}
}
&
ObjectMapper mapper = new ObjectMapper();
mapper.readValue(jsonString, Test.class);
exception:
no suitable constructor found, can not deserialize from Object value (missing default constructor or creator, or perhaps need to add/enable type information?
Test class has the OutputKeys as an attribute.
Any suggestions would be welcome. I have tried using a List of OutputKeys as well .
Update:
I have tried the following without success:
class OutputKeys {
public Map<String, String> keys;
///with constructor/setter/getters
}
&
class OutputKeys {
public List<OutputKey> keys;
///with constructor/setter/getters
public class OutputKey {
Map<String, String> outputs = new HashMap<>();
// tried this too:
// String key
//String value
}
You require below mentioned single class only, containing
All keys(ABC and DEF)
getters/setters
toString() which you'll use interact with JSON.
public class OutputKeys
{
private String ABC;
private String DEF;
public String getABC ()
{
return ABC;
}
public void setABC (String ABC)
{
this.ABC = ABC;
}
public String getDEF ()
{
return DEF;
}
public void setDEF (String DEF)
{
this.DEF = DEF;
}
#Override
public String toString()
{
return "ClassPojo [ABC = "+ABC+", DEF = "+DEF+"]";
}
}
Let me know if you require more details.
Since the keys were dynamic, I ended up deserializing the data using the iterator on the JsonNode:
jsonNode.get("outputKeys").iterator()
& then getting the relevant dynamic key information via the iterator.
I needed a similar tool for NodeJS. So that I can write tests on parts of a bigger model that was serialized (JSON).
So, if I need only "ABC":"gGyIioUr4Jfr5QiCm6Z==" or "XYZ":{"Hello": "My String", "Content": [1,2,3]}, the only property I care to test at the moment is:
var sutXYX = { Hello: "My String", Content: [ 1, 2, 2]};
I wrote this tool as a utility https://github.com/whindes/PojoScriptifyFromJSON
example:
public class User{
private String name;
private String age;
private String address;
.... set and get methods....
}
User user = new User();
user.setName("albert");
user.setAge("22");
i want convert user object to this string
name=albert&address=&age=22
Because i use new URL() to post this string.
I have much other object to convert to like this string,so i want a tool method
Is any good way to do?
Thanks in advance
Using reflection for any Object type:
import java.lang.reflect.Field;
public class ObjectToPostStringbyReflection {
public String getPostParamString(Object o) throws IllegalArgumentException, IllegalAccessException{
Class<? extends Object> clazz = o.getClass();
StringBuilder sb = new StringBuilder();
for(Field f : clazz.getDeclaredFields()){
f.setAccessible(true);
if(!sb.toString().isEmpty()){
sb.append("&");
}
sb.append(f.getName())
.append("=")
.append(f.get(o));
}
return sb.toString();
}
/**
* #param args
* #throws IllegalAccessException
* #throws IllegalArgumentException
*/
public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException {
// TODO Auto-generated method stub
User user = new User();
user.setName("John");
user.setAddress("address");
user.setAge("18");
ObjectToPostStringbyReflection reflector = new ObjectToPostStringbyReflection();
System.out.println(reflector.getPostParamString(user));
}
}
Result: name=John&age=18&address=address
You could try to find a framework which will do this for you (e.g. Spring), or you could just bite the bullet and write your own method:
public String toPost() {
StringBuilder sb = new StringBuilder();
sb.append("name=")
.append(this.name)
.append("&address=")
.append(this.address)
.append("&age=")
.append(this.age);
return sb.toString();
}
A simple method would be this:
public class user{
private String name;
private String age;
private String address;
.... set and get methods....
public String toText() {
return "name="+this.name+"&adress="+this.adress+"&age="+this.age;
}
}
If performance is important you can use StringBuilder
String postString = "name="+user.name+"&address="+user.address+"&age="+user.age;
There are no. of ways of doing this. it could be best for you to choose!
If you want to convert your object to pass by query String by Rest. It'll be impossible but if you want only a return that string when you use the toString() method. you need to overwriting the toString method in your class.
Like that:
#Override
public String toString() {
return "name="+ name + "&address=" +adress+ "&age=" +age+
}
This Json
{
"age":"23",
"name":"srinivas",
"blog":"A",
"messages":["msg1","msg2","msg3"]
}
I want convert a json to java class like this class and class use:
public class A
{
private String name;
private String age;
private String blog;
private String[] messages;
public String getName ()
{
return name;
}
public void setName (String name)
{
this.name = name;
}
public String getAge ()
{
return age;
}
public void setAge (String age)
{
this.age = age;
}
public String getBlog ()
{
return blog;
}
public void setBlog (String blog)
{
this.blog = blog;
}
}
No. You cant have class created automatically for you from your json.
However the below thing you might be needing that's related:
You need link
Excerpt from the link, below example code:
String carJson =
"{ \"brand\" : \"Mercedes\", \"doors\" : 5," +
" \"owners\" : [\"John\", \"Jack\", \"Jill\"]," +
" \"nestedObject\" : { \"field\" : \"value\" } }";
ObjectMapper objectMapper = new ObjectMapper();
try {
JsonNode node = objectMapper.readValue(carJson, JsonNode.class);
JsonNode brandNode = node.get("brand");
String brand = brandNode.asText();
System.out.println("brand = " + brand);
JsonNode doorsNode = node.get("doors");
int doors = doorsNode.asInt();
System.out.println("doors = " + doors);
JsonNode array = node.get("owners");
JsonNode jsonNode = array.get(0);
String john = jsonNode.asText();
System.out.println("john = " + john);
JsonNode child = node.get("nestedObject");
JsonNode childField = child.get("field");
String field = childField.asText();
System.out.println("field = " + field);
} catch (IOException e) {
e.printStackTrace();
}
You technically can create a class at runtime: see How to create a class dynamically in java or Creating classes dynamically with Java. However, if your code wants to use A in some way, it needs to be available during compilation. And if your code doesn't need to use A, why create it? You could implement some interface/extend some class which is available during compilation, but in your case there is no reasonable common interface and you could only access it using reflection.
A more reasonable alternative would be to generate a class from known JSON examples (or better, from some schema description) during your build process. Again, there are many ways to do this and you should search for one which fits your needs.
I'm fiddling around with an idea but can't get a grip on it.
I have an xml file with 100+ properties defining the runtime environment of a somewhat large program. These are exposed as variables through a class . At the moment, for each option in the xml file, there is a variable in the class plus public getter and private setter.
Each time we need a new option, we have to define it in the xml file and create the variable plus methods in the RuntimenEnvironment class.
Now, what I would like to do is something like this: I want to rewrite the class in such a way, that it exposes new options from the xml file as vars without having to touch the class.
My xml file uses this structure:
<option>
<name>theName</name>
<type>eg int</type>
<value>20</value>
<constant>THE_NAME</constant>
</option>
Can I write code in java that dynamically creates the vars at runtime and exposes them through a method without actually writing the method?
Is this possible?
Thanks in advance,
Chris
Couple of options I could think of are:
If the name is unique a map can be populated with name as the key.
If you are interested only in options then a list of Options can be
populated from the XML.
Below is the sample code implemented with SAX parser
Handler Class
public class OptionsParser extends DefaultHandler {
private final StringBuilder valueBuffer = new StringBuilder();
private final Map<String, Option> resultAsMap = new HashMap<String, Option>();
private final List<Option> options = new ArrayList<Option>();
//variable to store the values from xml temporarily
private Option temp;
public List<Option> getOptions() {
return options;
}
public Map<String, Option> getResultAsMap() {
return resultAsMap;
}
#Override
public void startElement(final String uri, final String localName, final String qName,
final Attributes attributes) throws SAXException {
if("option".equalsIgnoreCase(qName)) {
temp = new Option();
}
}
#Override
public void endElement(final String uri, final String localName, final String qName)
throws SAXException {
//read the value into a string to set them to option object
final String value = valueBuffer.toString().trim();
switch (qName) {
case "name":
temp.setName(value);
// set the value into map and name of the option is the key
resultAsMap.put(value, temp);
break;
case "type":
temp.setType(value);
break;
case "value":
temp.setValue(value);
break;
case "constant":
temp.setConstant(value);
break;
case "option":
// this is the end of option tag add it to the list
options.add(temp);
temp = null;
break;
default:
break;
}
//reset the buffer after every iteration
valueBuffer.setLength(0);
}
#Override
public void characters(final char[] ch, final int start, final int length)
throws SAXException {
//read the value into a buffer
valueBuffer.append(ch, start, length);
}
}
Option POJO
public class Option {
private String name;
private String type;
private String value;
private String constant;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getConstant() {
return constant;
}
public void setConstant(String constant) {
this.constant = constant;
}
}
Input XML
<options>
<option>
<name>option1</name>
<type>int</type>
<value>20</value>
<constant>const1</constant>
</option>
<option>
<name>option2</name>
<type>string</type>
<value>testValue</value>
<constant>const2</constant>
</option>
</options>
Sample Main class
public class ParseXML {
public static void main(String[] args) {
final OptionsParser handler = new OptionsParser();
try {
SAXParserFactory.newInstance().newSAXParser()
.parse("C:/luna/sample/inputs/options.xml", handler);
} catch (SAXException | IOException | ParserConfigurationException e) {
System.err.println("Somethig went wrong while parsing the input file the exception is -- " + e.getMessage() + " -- ");
}
Map<String, Option> result = handler.getResultAsMap();
Collection<Option> values = result.values();
for (Option option : values) {
System.out.println(option.getName());
}
}
}
I'll talk about json configuration files. But XML should also be similar. Jackson provides way to deserialise JSON and create dynamic object.
If the names of your options (theName) are unique, you can create dynamic beans. Your xml will then look like:
<theName>
<type>eg int</type>
<value>20</value>
<constant>THE_NAME</constant>
</theName>
See, I am talking about json, so its actually:
theName: {
type: "int"
value: 20
constant: "THE_NAME" }
Dynamic beans contain a Map, so your options will be stored in a Map<String, Option>, where Option is a POJO containing type, value and constant fields.
You should be able to access your options by iterating the map. There is no need to create variables dynamically.
This blog entry has got details about how to convert json to POJO
In my Android app I have json, which looks like :
{
"Records": [
{
"RowIndex": "0",
"NameValue": {
"Name": "PropertyName1",
"Value": "PropertyValue1"
}
}{
"RowIndex": "1",
"NameValue": {
"Name": "PropertyName2",
"Value": "PropertyValue2"
}
}
]
}
I need to parce this json to object, which looks like:
public class MyClass {
public String PropertyName1;
public String PropertyName2;
}
And result after parsing should be:
public String PropertyName1 = "PropertyValue1";
public String PropertyName2 = "PropertyValue2";
Basically, the first json is equivalent of:
{
"PropertyName1" : "PropertyValue1",
"PropertyName2" : "PropertyValue2"
}
Question: How can I parce first json without usage swith/case to search for the necessary Property?
You'll have to go down the dark path of reflection I'm afraid.
you can parse the json into an intermediary object which has a map for namevalue.
then you use the below code (ofcourse just copy paste the bits you need) to loop over the map of key/value pairs. for each key look up the field you want, and set it. If you're guaranteed only to need to set public variables then you can use getFields and can skip the setAccessible.
public class Test {
public static void main(String[] argv) {
MyClass myClass = new MyClass();
Class<?> classObject = myClass.getClass();
// Field fields[] = classObject.getFields(); // if you want to get only public fields.
Field fields[] = classObject.getDeclaredFields(); // any field
for(Field f : fields) {
System.out.println(f.getName());
try {
// if member is private: security managers may object but the default java allows it
f.setAccessible(true);
f.set(myClass, "abc");
} catch (IllegalAccessException e) {
// handle access exception:
e.printStackTrace();
}
}
System.out.println("prop 1: " + myClass.PropertyName1);
System.out.println("prop 2: " + myClass.PropertyName2);
}
public static class MyClass {
public String PropertyName1;
private String PropertyName2;
}
}
Actually.. there is a non-reflect way but that will replace your implementation of the object you have.
If you change your class:
public class MyClass {
public String PropertyName1;
public String PropertyName2;
}
to
public class MyClass {
private Map<String, String> properties = new HashMap<String, String>();
public void setProperties(Map<String, String> props) { this.properties = props; }
public String getPropertyName1() {
return lookupProperty("PropertyName1");
}
public String getPropertyName2() {
return lookupProperty("PropertyName2");
}
private String lookupProperty(String property) {
if (properties.containsKey(property) {
return properties.get(property);
} else {
return null;
}
}
}
then you could parse the name value map into a map, and construct a myclass with it.
just listing it for completeness, though changing your domain model to fit a json input is not ideal.
I would recommend either way to do the input parsing, and then copy over the model into your actual domain object rather than using the json-model in your application. that way if the json model ever changes, your domain model will not change.
One method I can think of (which doesn't sound too great) is to actually make an object that matches the JSON response you get back. Then, map THAT NameValue object to MyClass
So, something like
public class NameValue {
public string Name;
public String Value;
public MyClass getMyClass(){
MyClass myClass = new MyClass();
myClass.PropertyName2 = Value;
return myClass;
}
}
You can come up with a better way to map it, obviously. But this is just an example of something I might do if I was given a response JSON I didn't particularly care for. You can similarly reverse it (have MyClass be able to create a NameValue object) so you can send data back in the correct format.