Unable to display instance variables of object in Apache velocity - java

I'm trying to display some info using Apache velocity , however it does not seem to work.
Follwing is the code snippet.
package velocitydemo;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
class Vehicle {
private String vname;
private Wheel wheel;
private String type;
/**
* #return the vname
*/
public String getVname() {
return vname;
}
/**
* #param vname the vname to set
*/
public void setVname(String vname) {
this.vname = vname;
}
/**
* #return the wheel
*/
public Wheel getWheel() {
return wheel;
}
/**
* #param wheel the wheel to set
*/
public void setWheel(Wheel wheel) {
this.wheel = wheel;
}
/**
* #return the type
*/
public String getType() {
return type;
}
/**
* #param type the type to set
*/
public void setType(String type) {
this.type = type;
}
/**
* #return the model
*/
public int getModel() {
return model;
}
/**
* #param model the model to set
*/
public void setModel(int model) {
this.model = model;
}
private int model;
public Vehicle(String name, Wheel wheel, String type, int model) {
super();
this.vname = name;
this.wheel = wheel;
this.type = type;
this.model = model;
}
}
class Wheel {
private String type;
private String name;
/**
* #return the type
*/
public String getType() {
return type;
}
/**
* #param type the type to set
*/
public void setType(String type) {
this.type = type;
}
/**
* #return the name
*/
public String getName() {
return name;
}
/**
* #param name the name to set
*/
public void setName(String name) {
this.name = name;
}
public Wheel(String type, String name) {
super();
this.type = type;
this.name = name;
}
}
public class HelloWorld {
private static List<String> list = new ArrayList<String>();
public static void main(String[] args) throws Exception {
Vehicle vh = constructVehicle("Model S", "Vinyl", "JK", "Electric", 2014);
VelocityEngine ve = new VelocityEngine();
ve.init();
/* next, get the Template */
Template t = ve.getTemplate("helloworld.vm");
/* create a context and add data */
VelocityContext context = new VelocityContext();
context.put("name", "World");
context.put("name2", "foobar");
context.put("name3", "flash");
context.put("vehicle", vh);
StringWriter writer = new StringWriter();
t.merge(context, writer);
System.out.println(writer.toString());
}
public static Vehicle constructVehicle(String vehicleName, String wheelType, String wheelName, String vhType, int model) {
Wheel wl = new Wheel(wheelType, wheelName);
Vehicle vh = new Vehicle(vehicleName, wl, vhType, model);
return vh;
}
}
The velocity template is helloworld.vm with the following info
Hello $name! Welcome to Velocity!
Hello $name2! Welcome to Velocity!
Hello $name3! Welcome to Velocity!
Car is $vehicle.vname
Car is $vehicle.getVname()
Car is $vehicle.hashCode() and model is $vehicle.getModel()
However the output is :
Hello World! Welcome to Velocity!
Hello foobar! Welcome to Velocity!
Hello flash! Welcome to Velocity!
Car is $vehicle.vname
Car is $vehicle.getVname()
Car is 14872264 and model is $vehicle.getModel()
I don't understand why variables of class Vehicle are not getting resolved.

Related

How do I deserialize my immutable subclass?

I'm currently trying to deserialize a json-response. My object uses the builder pattern and the consumer interface.
I'm doing a http-request to an external source and get my response as json. All the responses are strings and look like:
{
"a": "198",
"b": "F",
"c": "30",
"d": "2019-02-01",
"e": "2019-12-31"
}
I've changed the name of my model and my key to Model and Key so there might be typos, sorry for that.
#JsonDeserialize(builder = Model.Builder.class)
public class Model {
private final Data data;
private Model() {
this.data = new Data();
}
/**
* #return key
*/
public Key getKey() {
return data.key;
}
/**
* #return Tax Form
*/
public String getTaxForm() {
return data.taxForm;
}
/**
* #return tax table
*/
public int getTaxTable() {
return data.taxTable;
}
/**
* #return tax percent
*/
public BigDecimal getTaxPercent() {
return data.taxPercent;
}
/**
* #return Valid from
*/
public LocalDate getValidFrom() {
return data.validFrom;
}
/**
* #return Valid to
*/
public LocalDate getValidTo() {
return data.validTo;
}
/**
* #param key key
* #return builder
*/
public static Builder getBuilder(Key key) {
return new Builder(key);
}
/**
* #param model the response
* #return builder
*/
public static Builder getBuilder(Model model) {
return new Builder(model);
}
/**
* builder
*/
public static class Builder {
#JsonDeserialize(as = Model.Data.class)
private final Data data;
#JsonCreator
private Builder(Key key) {
this.data = new Data();
this.data.key = key;
}
private Builder(Model model) {
this(model.data.key);
data.taxForm = model.data.taxForm;
data.taxTable = model.data.taxTable;
data.taxPercent = model.data.taxPercent;
data.validFrom = model.data.validFrom;
data.validTo = model.data.validTo;
}
public Builder with(Consumer<Data> consumer) {
consumer.accept(this.data);
return this;
}
public Model build() {
Model internalModel = new Model();
internalModel.data.key = data.key;
internalModel.data.taxForm = data.taxForm;
internalModel.data.taxTable = data.taxTable;
internalModel.data.taxPercent = data.taxPercent;
internalModel.data.validFrom = data.validFrom;
internalModel.data.validTo = data.validTo;
return internalModel;
}
}
/**
* Data
*/
public static final class Data implements Serializable {
private Key key;
#JsonProperty("b")
public String taxForm;
public int taxTable;
public BigDecimal taxPercent;
public LocalDate validFrom;
public LocalDate validTo;
}
}
public class Key {
private final String personalNumber;
public Key(#JsonProperty("a") String personalNumber) {
this.personalNumber = personalNumber;
}
public String getPersonalNumber() {
return personalNumber;
}
}
Currently I am able to deserialize a, but all the other fields are missed. I tried using #JsonProperty in the Data class but that doesn't work. Any ideas?

Return List within List REST API Jax Rs

I am creating a REST API from java where I am returning an object list as follows:
#Path("/order")
public class OrderService implements IService
{
#Override
public Response get()
{
List<DataObj> list = new ArrayList<>();
List<SubDataObj> subList = new ArrayList<>();
subList.add(new SubDataObj("1"));
GenericEntity<List<DataObj>> entity;
list.add(new DataObj("A", "22", TestEnum.test1, DateTime.now(), subList));
list.add(new DataObj("B", "23", TestEnum.test2, DateTime.now(), subList));
entity = new GenericEntity<List<DataObj>>(list){};
return Response.ok(entity).build();
}
}
Here the service returns the Response fine when not using the subList, which is a object list within the DataObj class. However, when I am using it, i get an error as:
SEVERE: MessageBodyWriter not found for media type=application/json, type=class java.util.ArrayList, genericType=java.util.List<dyno.scheduler.restservice.DataObj>.
Here are the DataObj and the SubDataObj classes:
#XmlRootElement
class DataObj
{
private String name;
private String age;
private TestEnum enumVal;
private DateTime currentDate;
private List<SubDataObj> subData;
public DataObj(String name, String age, TestEnum enumVal, DateTime currentDate, List<SubDataObj> subData)
{
this.name = name;
this.age = age;
this.enumVal = enumVal;
this.currentDate = currentDate;
this.subData = subData;
}
public DataObj() {}
/**
* #return the name
*/
public String getName()
{
return name;
}
/**
* #param name the name to set
*/
public void setName(String name)
{
this.name = name;
}
/**
* #return the age
*/
public String getAge()
{
return age;
}
/**
* #param age the age to set
*/
public void setAge(String age)
{
this.age = age;
}
/**
* #return the enumVal
*/
public TestEnum getEnumVal()
{
return enumVal;
}
/**
* #param enumVal the enumVal to set
*/
public void setEnumVal(TestEnum enumVal)
{
this.enumVal = enumVal;
}
/**
* #return the currentDate
*/
public DateTime getCurrentDate()
{
return currentDate;
}
/**
* #param currentDate the currentDate to set
*/
public void setCurrentDate(DateTime currentDate)
{
this.currentDate = currentDate;
}
/**
* #return the subData
*/
public List<SubDataObj> getSubData()
{
return subData;
}
/**
* #param subData the subData to set
*/
public void setSubData(List<SubDataObj> subData)
{
this.subData = subData;
}
}
DataSubObj class:
class SubDataObj
{
private String subId;
public SubDataObj(String subId)
{
this.subId = subId;
}
/**
* #return the subId
*/
public String getSubId()
{
return subId;
}
/**
* #param subId the subId to set
*/
public void setSubId(String subId)
{
this.subId = subId;
}
}
I tried adding #XmlRootElement annotation to my SubDataObj class as well, which didn't work.
Any help would be appreciated!

TreeView of objects having child nodes that are fields of the object

I have an object with fields of varying datatypes:
public class MyObject{
private String field1;
private CustomObject field2;
private int field3;
...
}
I want to create a tree view of MyObject that will have multiple MyObject nodes, each with the fields (field1, field2, field3..etc) as children.
I know I can make a TreeView of Strings and populate it myself with an addNode(MyObject obj) method in which I would add the individual TreeItems I need. However, I did this with a TableView where I was able to bind a column with a field property. Such as:
TableView<MyObject> table;
TableColumn<MyObject, String> myColumn;
myColumn.setCellValueFactory(new PropertyValueFactory<>("field1"));
Is there any way to do something similar for a TreeView<MyObject>? Im not opposed to creating a subclass that extends TreeItem<?>
The ending result I'm looking for would be something like this:
--> First My Object
->field1: "Value at Field 1"
->field2: "Value at Field 2"
->field3: 3
--> Second My Object
->field1: "Value at Field 1"
->field2: "Value at Field 2"
->field3: 3
Pretty much any time you use a TreeView with different types in different nodes of the tree, you will need some casting and/or type checking somewhere.
One possible approach here is to subclass TreeItem to provide a field for the property you want to show, and then to use a TreeCell that shows the string value of that property.
Here's a very basic example of that:
import java.util.Arrays;
import java.util.List;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TreeCell;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.stage.Stage;
public class TreeViewWithProperties extends Application {
#Override
public void start(Stage primaryStage) {
List<SomeEntity> entities = Arrays.asList(
new SomeEntity("First object", "String value 1", 42),
new SomeEntity("Second object", "String value 2", 3)
);
TreeView<SomeEntity> tree = new TreeView<>();
tree.setShowRoot(false);
TreeItem<SomeEntity> treeRoot = new TreeItem<>();
tree.setRoot(treeRoot);
for (SomeEntity entity : entities) {
TreeItem<SomeEntity> item = PropertyTreeItem.baseItem(entity);
treeRoot.getChildren().add(item);
item.getChildren().add(new PropertyTreeItem<String>(entity, entity.getStringField()));
item.getChildren().add(new PropertyTreeItem<Integer>(entity, entity.getValue()));
}
tree.setCellFactory(tv -> new TreeCell<SomeEntity>() {
#Override
protected void updateItem(SomeEntity entity, boolean empty) {
super.updateItem(entity, empty);
PropertyTreeItem<?> item = (PropertyTreeItem<?>) getTreeItem();
if (empty) {
setText(null);
} else {
setText(item.getPropertyValue().toString());
}
}
});
Scene scene = new Scene(tree);
primaryStage.setScene(scene);
primaryStage.show();
}
public static class PropertyTreeItem<T> extends TreeItem<SomeEntity> {
private final T propertyValue ;
public PropertyTreeItem(SomeEntity entity, T value) {
super(entity);
this.propertyValue = value ;
}
public static PropertyTreeItem<SomeEntity> baseItem(SomeEntity entity) {
return new PropertyTreeItem<>(entity, entity);
}
public T getPropertyValue() {
return propertyValue ;
}
}
public class SomeEntity {
private String name ;
private String stringField ;
private int value ;
public SomeEntity(String name, String stringField, int value) {
this.name = name;
this.stringField = stringField;
this.value = value;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getStringField() {
return stringField;
}
public void setStringField(String stringField) {
this.stringField = stringField;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
#Override
public String toString() {
return name ;
}
}
public static void main(String[] args) {
launch(args);
}
}
Some variations on this are possible, of course. If you wanted to use JavaFX properties in the entity class, and be able to change those values externally to the tree, you could bind the text to the property in the cell instead of simply setting it.
Using some ideas from the link I posted under your question. This example uses a helper Class to create the TreeItems.
Main
import java.util.ArrayList;
import java.util.List;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
/**
*
* #author blj0011
*/
public class JavaFXApplication128 extends Application
{
#Override
public void start(Stage primaryStage)
{
MyObject myObject1 = new MyObject("myObject1", "field 1 a", new CustomObject("customObject 1", 3), 5);
MyObject myObject2 = new MyObject("myObject2", "field 1 b", new CustomObject("customObject 2", 36), 10);
MyObject myObject3 = new MyObject("myObject3", "field 1 c", new CustomObject("customObject 3", 23), 8);
List<MyObject> list = new ArrayList();
list.add(myObject1);
list.add(myObject2);
list.add(myObject3);
List<TreeItem<String>> treeItemsContainer = new ArrayList();
for (MyObject object : list) {
ObjectToTreeView objectToTreeView = new ObjectToTreeView(object);
treeItemsContainer.add(objectToTreeView.getRootItem());
}
TreeItem<String> rootItem = new TreeItem();
rootItem.setExpanded(true);
rootItem.getChildren().addAll(treeItemsContainer);
TreeView treeView = new TreeView(rootItem);
Scene scene = new Scene(treeView, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args)
{
launch(args);
}
}
ObjectToTreeView Class <- a helper class
import javafx.scene.control.TreeItem;
/**
*
* #author blj0011
*/
public class ObjectToTreeView
{
private final TreeItem<String> rootItem = new TreeItem();
public ObjectToTreeView(MyObject myObject)
{
rootItem.setValue(myObject.getTitle());
rootItem.getChildren().add(new TreeItem(myObject.getField1()));
CustomObject customObject = myObject.getField2();
rootItem.getChildren().add(new TreeItem(customObject.getName()));
rootItem.getChildren().add(new TreeItem(customObject.getNumber()));
rootItem.getChildren().add(new TreeItem(myObject.getField3()));
}
/**
* #return the rootItem
*/
public TreeItem<String> getRootItem()
{
return rootItem;
}
}
MyObject Class
/**
*
* #author blj0011
*/
public class MyObject
{
private String title;
private String field1;
private CustomObject field2;
private int field3;
public MyObject(String title, String field1, CustomObject field2, int field3)
{
this.title = title;
this.field1 = field1;
this.field2 = field2;
this.field3 = field3;
}
/**
* #return the title
*/
public String getTitle()
{
return title;
}
/**
* #param title the title to set
*/
public void setTitle(String title)
{
this.title = title;
}
/**
* #return the field1
*/
public String getField1()
{
return field1;
}
/**
* #param field1 the field1 to set
*/
public void setField1(String field1)
{
this.field1 = field1;
}
/**
* #return the field3
*/
public int getField3()
{
return field3;
}
/**
* #param field3 the field3 to set
*/
public void setField3(int field3)
{
this.field3 = field3;
}
/**
* #return the field2
*/
public CustomObject getField2()
{
return field2;
}
/**
* #param field2 the field2 to set
*/
public void setField2(CustomObject field2)
{
this.field2 = field2;
}
}
CustomObject Class
/**
*
* #author blj0011
*/
public class CustomObject
{
private String name;
private int number;
public CustomObject(String name, int number)
{
this.name = name;
this.number = number;
}
/**
* #return the name
*/
public String getName()
{
return name;
}
/**
* #param name the name to set
*/
public void setName(String name)
{
this.name = name;
}
/**
* #return the number
*/
public int getNumber()
{
return number;
}
/**
* #param number the number to set
*/
public void setNumber(int number)
{
this.number = number;
}
}
I ended up just creating a helper function by doing the following:
public TreeItem<String> createNode(MyObject obj) {
TreeItem<String> node = null;
if(obj != null) {
node = new TreeItem<String>("MyObject:" + obj.getId());
node.getChildren().add(new TreeItem<String>("Field1: "+ obj.getField1()));
node.getChildren().add(new TreeItem<String>("Field2: "+ obj.getField2()));
node.getChildren().add(new TreeItem<String>("Field3: "+ obj.getField3()));
}
}

json to table structure api in Java

I have been searching in internet for a while to get a API that convert json into tabular format. I don't have any code which I tried. Please direct me if you have any idea about it.
Eg : Json
{"name":"rinu","age":"14","Phone":[{"countryCode":91,"number":"99862656"},{"countryCode":91,"number":"675432"}],"OtherDetails":[{"Active":true}]}
Output can be(with any separated)
rinu|14|91|99862656|true
rinu|14|91|675432|true
I don't want any ready-made stuff, If I get anything similar to this, I can re-write it.
You might need this:
JacksonRead.java
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import org.codehaus.jackson.map.ObjectMapper;
public class JacksonRead {
public static void main(String[] args) {
ObjectMapper mapper = new ObjectMapper();
try {
Example example = mapper.readValue(new File("d:\\user.json"),
Example.class);
StringBuilder builder = new StringBuilder();
int i = 0;
for (Phone phone : example.getPhone()) {
builder.append(example.getName()).append("|");
builder.append(example.getAge()).append("|");
builder.append(phone.getCountryCode()).append("|")
.append(phone.getNumber()).append("|")
.append(example.getOtherDetails().get(i).getActive())
.append("|");
builder.append("\n");
}
File file = new File("d:\\user.txt");
// if file doesnt exists, then create it
if (!file.exists()) {
file.createNewFile();
}
FileWriter fw = new FileWriter(file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
bw.write(builder.toString());
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Example.java
import java.util.ArrayList;
import java.util.List;
import org.codehaus.jackson.annotate.JsonProperty;
public class Example {
#JsonProperty("name")
private String name;
#JsonProperty("age")
private String age;
#JsonProperty("Phone")
private List<Phone> Phone = new ArrayList<Phone>();
#JsonProperty("OtherDetails")
private List<OtherDetail> OtherDetails = new ArrayList<OtherDetail>();
/**
*
* #return The name
*/
#JsonProperty("name")
public String getName() {
return name;
}
/**
*
* #param name
* The name
*/
#JsonProperty("name")
public void setName(String name) {
this.name = name;
}
/**
*
* #return The age
*/
#JsonProperty("age")
public String getAge() {
return age;
}
/**
*
* #param age
* The age
*/
#JsonProperty("age")
public void setAge(String age) {
this.age = age;
}
/**
*
* #return The Phone
*/
#JsonProperty("Phone")
public List<Phone> getPhone() {
return Phone;
}
/**
*
* #param Phone
* The Phone
*/
#JsonProperty("Phone")
public void setPhone(List<Phone> Phone) {
this.Phone = Phone;
}
/**
*
* #return The OtherDetails
*/
#JsonProperty("OtherDetails")
public List<OtherDetail> getOtherDetails() {
return OtherDetails;
}
/**
*
* #param OtherDetails
* The OtherDetails
*/
#JsonProperty("OtherDetails")
public void setOtherDetails(List<OtherDetail> OtherDetails) {
this.OtherDetails = OtherDetails;
}
#Override
public String toString() {
return "Example [name=" + name + ", age=" + age + ", Phone=" + Phone
+ ", OtherDetails=" + OtherDetails + "]";
}
}
Phone.java
import org.codehaus.jackson.annotate.JsonProperty;
public class Phone {
#JsonProperty("countryCode")
private Integer countryCode;
#JsonProperty("number")
private String number;
/**
*
* #return The countryCode
*/
#JsonProperty("countryCode")
public Integer getCountryCode() {
return countryCode;
}
/**
*
* #param countryCode
* The countryCode
*/
#JsonProperty("countryCode")
public void setCountryCode(Integer countryCode) {
this.countryCode = countryCode;
}
/**
*
* #return The number
*/
#JsonProperty("number")
public String getNumber() {
return number;
}
/**
*
* #param number
* The number
*/
#JsonProperty("number")
public void setNumber(String number) {
this.number = number;
}
#Override
public String toString() {
return "Phone [countryCode=" + countryCode + ", number=" + number + "]";
}
}
OtherDetail.java
import org.codehaus.jackson.annotate.JsonProperty;
public class OtherDetail {
#JsonProperty("Active")
private Boolean Active;
/**
*
* #return The Active
*/
#JsonProperty("Active")
public Boolean getActive() {
return Active;
}
/**
*
* #param Active
* The Active
*/
#JsonProperty("Active")
public void setActive(Boolean Active) {
this.Active = Active;
}
#Override
public String toString() {
return "OtherDetail [Active=" + Active + "]";
}
}
user.json
{"name":"rinu","age":"14","Phone":[{"countryCode":91,"number":"99862656"},{"countryCode":91,"number":"675432"}],"OtherDetails":[{"Active":true}]}
I tried the library json2flat with the json
{"name":"rinu","age":"14","Phone":[{"countryCode":91,"number":"99862656"},{"countryCode":91,"number":"675432"}],"OtherDetails":[{"Active":true}]}
it gives a CSV like ::
rinu|14|91|99862656|
rinu|14|91|675432 |
rinu| | | |true
But if you tweak the json a little bit like ::
{"name":"rinu","age":"14","Phone":[{"countryCode":91,"number":"99862656","Active":true},{"countryCode":91,"number":"675432","Active":true}]}
it gives the csv exactly as you require.
rinu|14|91|99862656|true
rinu|14|91|675432|true
Give it a try. After all the solution depends upon how the user wants to interpret the json.

How to fix Out of START_ARRAY token Error

Can anybody say where I am doing wrong. I have json like that
[{"name":"foo","slug":"foo2","locales":["foo3"],"hostname":"foo4","region_tag":"foo5"},{"name":"foo","slug":"foo2","locales":["foo3"],"hostname":"foo4","region_tag":"foo5"},{"name":"foo","slug":"foo2","locales":["foo3"],"hostname":"foo4","region_tag":"foo5"},{"name":"foo","slug":"foo2","locales":["foo3"],"hostname":"foo4","region_tag":"foo5"}]
And I parse to this class.
#JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
#JsonPropertyOrder({
"shards"
})
public class ShardsResponse extends Response{
#JsonProperty("shards")
private List<Shards> shards = new ArrayList<Shards>();
/**
*
* #return
* The shards
*/
#JsonProperty("shards")
public List<Shards> getShards() {
return shards;
}
/**
*
* #param shards
* The shards
*/
#JsonProperty("shards")
public void setShards(List<Shards> shards) {
this.shards = shards;
}
}
And Shards class is :
/**
*
* #return
* The locales
*/
#JsonProperty("locales")
public List<String> getLocales() {
return locales;
}
/**
*
* #param locales
* The locales
*/
#JsonProperty("locales")
public void setLocales(List<String> locales) {
this.locales = locales;
}
/**
*
* #return
* The name
*/
#JsonProperty("name")
public String getName() {
return name;
}
/**
*
* #param name
* The name
*/
#JsonProperty("name")
public void setName(String name) {
this.name = name;
}
/**
*
* #return
* The hostname
*/
#JsonProperty("hostname")
public String getHostname() {
return hostname;
}
/**
*
* #param hostname
* The hostname
*/
#JsonProperty("hostname")
public void setHostname(String hostname) {
this.hostname = hostname;
}
/**
*
* #return
* The slug
*/
#JsonProperty("slug")
public String getSlug() {
return slug;
}
/**
*
* #param slug
* The slug
*/
#JsonProperty("slug")
public void setSlug(String slug) {
this.slug = slug;
}
}
So I'm using ObjectMapper.readValue(jsontext, responseclass)
JSONObject object = new JSONObject(JsonString);
JsonString = "";
Iterator<String> keys= object.keys();
while (keys.hasNext()){
String keyValue = (String)keys.next();
JsonString= JsonString+ object.getString(keyValue);
}
JsonString= JsonString.substring(1, JsonString.length()-1);
Object response = ObjectMapper.readValue(JsonString, ShardsResponse.class);
At the last I am getting out of START_ARRAY token. Please anybody tell me what's wrong.
Cause I'm trying so much things, but I never find the solution.
How can I fix it.
Your json string is correct, but not for the object you expect, as someone mentioned already, you need to use a List
import java.io.IOException;
import java.util.List;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
public class ParseJson {
private static final String jsonString = "[{\"name\":\"foo\",\"slug\":\"foo2\",\"locales\":[\"foo3\"],\"hostname\":\"foo4\",\"region_tag\":\"foo5\"},{\"name\":\"foo\",\"slug\":\"foo2\",\"locales\":[\"foo3\"],\"hostname\":\"foo4\",\"region_tag\":\"foo5\"},{\"name\":\"foo\",\"slug\":\"foo2\",\"locales\":[\"foo3\"],\"hostname\":\"foo4\",\"region_tag\":\"foo5\"},{\"name\":\"foo\",\"slug\":\"foo2\",\"locales\":[\"foo3\"],\"hostname\":\"foo4\",\"region_tag\":\"foo5\"}]";
public static void parse() {
try {
TypeReference<List<Shards>> typeRef = new TypeReference<List<Shards>>() { };
ObjectMapper mapper = new ObjectMapper();
List<Shards> list = mapper.readValue(jsonString, typeRef);
for ( Shards s : list )
{
s.printDebug();
}
ShardsResponse sr = new ShardsResponse(list);
String srString = mapper.writeValueAsString(sr);
System.out.println("srString: " + srString );
TypeReference<ShardsResponse> typeRef2 = new TypeReference<ShardsResponse>() { };
ShardsResponse sr2 = mapper.readValue(srString, typeRef2);
sr2.printDebug();
} catch ( IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
ParseJson.parse();
}
}
Edit:
If you expect a ShardsResponse back, your json string should look like this:
{"shards":[{"locales":["foo3"],"name":"foo","hostname":"foo4","slug":"foo2","region_tag":"foo5"},{"locales":["foo3"],"name":"foo","hostname":"foo4","slug":"foo2","region_tag":"foo5"},{"locales":["foo3"],"name":"foo","hostname":"foo4","slug":"foo2","region_tag":"foo5"},{"locales":["foo3"],"name":"foo","hostname":"foo4","slug":"foo2","region_tag":"foo5"}]}
Easiest way to figure out what the json will look like is to dump it out:
ShardsResponse sr = new ShardsResponse(list);
String srString = mapper.writeValueAsString(sr);
System.out.println("srString: " + srString );
Edit:
Adding additional Classes for clarity:
ShardsResponses.java
import java.util.ArrayList;
import java.util.List;
public class ShardsResponse {
private List<Shards> shards = new ArrayList<Shards>();
public ShardsResponse() { }
public ShardsResponse( List<Shards> shards)
{
this.shards = shards;
}
public List<Shards> getShards() {
return shards;
}
public void setShards(List<Shards> shards) {
this.shards = shards;
}
public void printDebug()
{
for ( Shards s : shards)
{
s.printDebug();
System.out.println("");
}
}
}
Shards.java:
import java.util.List;
public class Shards {
private List<String> locales;
private String name;
private String hostname;
private String slug;
private String region_tag;
public List<String> getLocales() {
return locales;
}
public void setLocales(List<String> locales) {
this.locales = locales;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getHostname() {
return hostname;
}
public void setHostname(String hostname) {
this.hostname = hostname;
}
public String getSlug() {
return slug;
}
public void setSlug(String slug) {
this.slug = slug;
}
public void printDebug()
{
System.out.println("name: " + name);
System.out.println("hostname: " + hostname);
System.out.println("slug: " + slug);
System.out.println("region_tag: " + region_tag);
for ( String s : locales )
{
System.out.println("Locals: " + locales);
}
}
public String getRegion_tag() {
return region_tag;
}
public void setRegion_tag(String region_tag) {
this.region_tag = region_tag;
}
}
you have an jsonArray but you are trying to parse a jsonObject. change your method to return a list of objects instead of one object.

Categories

Resources