I am writing a JSP webapp and right now I'm kind of stuck. I have been using an ArrayList of Java Objects, each with a list of properties. They are Order objects with properties like firstName, lastName, etc. At this point in my development I need to store the individual orders as JSON arrays in javascript variables. I am able using a servlet to convert the arraylist to JSON but the JSON has repeat properties for each of the Order objects, like this:
[{firstName : Mike, lastName : Daniels, ..... firstName : John, lastName : Doe ... etc ...}]
Clearly, the JSON is made up of all of my Order objects, strung together as one JSON array. What I am wondering is how I need to split up the string into separate variables depending on the number of Orders in the app at the time.
Here's how the object is set if it helps. Thanks!
Object orders = request.getSession().getAttribute("orders");
//this is a string of order properies/values
String json = new Gson().toJson(orders);
HttpSession session = request.getSession();
session.setAttribute("jsonOrders", json);
Try iterating through the array list, creating a JSON object for each of the objects instead of converting the array list as a whole.
Let's suppose your orders entity is something like this:
public class Order {
private String firstName;
private String lastName;
// getters & setters
}
and you get your orders data in request like:
[{
"firstName": "Mike",
"lastName": "Daniels"
}, {
"firstName": "John",
"lastName": "Doe"
}]
You should be able to convert it to List<Order> using
List<Order> orders = gson.fromJson(response, Order.class);
You can then iterate over the list like:
for (Order order: orders) {
// Whatever you want to do
}
Or, if you are using java 8:
orders.forEach (order -> System.out::println);
Here is the solution using Gson library,
//Order.java
public class Order {
private String firstName;
private String lastName;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
//Orders.java
public class Orders {
Order[] order;
public Order[] getOrder() {
return order;
}
public void setOrder(Order[] order) {
this.order = order;
}
}
import com.google.gson.Gson;
//Solution.java
public class Solution {
public static void main(String[] args) {
String json = "{\"order\":[{\"firstName\":\"Mike\",\"lastName\":\"Daniels\"},{\"firstName\":\"John\",\"lastName\":\"Doe\"}]}";
Orders orders = new Gson().fromJson(json, Orders.class);
Order[] orderArr = orders.getOrder();
for(int i=0; i<orderArr.length;i++){
System.out.println("First Name : "+ orderArr[i].getFirstName());
System.out.println("Last Name "+orderArr[i].getLastName());
}
}
}
**Output**
First Name : Mike
Last Name Daniels
First Name : John
Last Name Doe
Answer by ssc looks right. Best way to do is iterate through the list.
Related
I have a Json response as follows:
{
"data": {
"date": "7 Apr 2022",
"employee": [
{
"id": [
"1288563656"
],
"firstname": [
"Mohammed"
],
"lastname": [
"Ali"
]
}
]
}
}
I am trying to create a POJO called Employee and map it to the "employee" attribute in the JSON response.
This is what I did as an attempt:
Employee.java
public class Emoloyee {
private Integer[] id;
private String[] firstname;
private String[] lastname;
public Employee(Integer[] id, String[] firstname, String[] lastname){
this.id = id;
this.firstname = firstname;
this.lastname = lastname;
}
public Employee(){
}
public Integet[] getId(){
return id;
}
public void setId(Integer[] id){
this.id = id;
}
public String[] getFirstname(){
return firstname;
}
public void setFirstname(String[] firstname){
this.firstname = firstname;
}
public String[] getLastname(){
return lastname;
}
public void setLastname(String[] lastname){
this.lastname = lastname;
}
}
Using Jackson:
ObjectMapper mapper = new ObjectMapper();
URL jsonUrl = new URL("[API_URL]");
final ObjectNode node = mapper.readValue(jsonUrl, ObjectNode.class);
Employee[] employees = mapper.treeToValue(node.get("data").get("employee"), Employee[].class);
When I execute the app, I get the following error:
Caused by: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type 'long' from Array value (toke 'JsonToken.START_ARRAY')
As you may noticed, I am not interested of the date attribute, I only need to get the values of the employee and create an Employee object out of it.
The Employee POJO should look like this:
#JsonProperty("id")
private final List<String> ids;
#JsonProperty("firstname")
private final List<String> firstNames;
#JsonProperty("lastname")
private final List<String> lastNames;
#JsonCreator
public Employee(#JsonProperty(value = "id") List<String> ids, #JsonProperty(value = "firstname") List<String> firstNames, #JsonProperty(value = "lastname") List<String> lastNames) {
this.ids = ids;
this.firstNames = firstNames;
this.lastNames = lastNames;
}
//getters code
Then, you have an object Data:
#JsonProperty("date")
private final String date;
#JsonProperty("employee")
private final List<Employee> employees;
#JsonCreator
public Data(#JsonProperty(value = "date") String date, #JsonProperty(value = "employee") List<Employee> employees) {
this.date = date;
this.employees = employees;
}
//getters code
Finally, the whole Answer that you want to parse has this shape:
#JsonProperty("data")
private final Data data;
#JsonCreator
public Answer(#JsonProperty(value = "data") Data data) {
this.data = data;
}
//getter code
Once you have defined these 3 classes, then you will be able to do:
ObjectMapper objectMapper = new ObjectMapper();
Answer answer = objectMapper.readValue(yourStringAnswer, Answer.class);
Note: in your question, you are trying to parse an URL to an ObjectNode. I hardly doubt you would be able to do that.
I guess you want to perform the HTTP request to the URL, then getting the response stream and that's what you want to parse into Answer (not the URL itself).
Also, a few notes on the API response (in case you own it and so you can act on it):
All the lists would be more naturally declared with a plural name (e.g. employee should be employees)
The list of ids are numeric but are returned as strings. Also, why an employee would have a list of ids, and not a single id?
Why would an employee have a list of first names and last names? Shouldn't this be a simple string each (even if composed by more than one name)?
Use camel case (firstName, not firstname)
I don't see the point of putting everything into data, it may simply be the response containing date and employees
I have a POJO populated with a list of items in a Controller (after a rest ajax submit). This is the structure of the model that is populated:
public class AllNamesDto {
private List<Long> id;
private List<String> firstName;
private List<String> LastName;
private List<Boolean> manualSubmit;
private List<String> program;
//getters setters
}
I would like to extract all the list items from the model above and store them individually into a model List, e.g. the following model:
public class AllNamesDtoList {
private long id;
private String firstName;
private String LastName;
private Boolean manualSubmit;
private String program;
//getters setters
}
So something like
List<AllNamesDtoList> allNamesDtoList = new ArrayList<>();
allNameDtoList.add(AllNamesDto.items);
I know the syntax isn't correct, just ruffing it in to show quickly what I am trying to accomplish. My goal is to create a proper list of items (since I couldn't figure out a way to send a LIST through ajax properly, just a sublist of items in one POJO) to iterate over and save to the db.
Any help is appreciated!
Assuming that in the lists the order is correct and they are all the same size:
First put a constructor with fields:
public AllNamesDtoList(long id, String firstName, String lastName, Boolean manualSubmit, String program) {
super();
this.id = id;
this.firstName = firstName;
LastName = lastName;
this.manualSubmit = manualSubmit;
this.program = program;
}
And then we take the size of one of the lists and create an IntStream to iterate on the indices
List<AllNamesDtoList> allNamesDtoList = new ArrayList<>();
IntStream.range(0, id.size()).forEach(index -> allNamesDtoList.add(new AllNamesDtoList(id.get(index), firstName.get(index), LastName.get(index), manualSubmit.get(index), program.get(index))));
and the allNamesDtoList list would be full.
I have 3 entities : Country, State, City
I have written their POJOs as :
class Country{
String countryName;
List<State> states;
}
class State{
String stateName;
List<City> cities;
}
class City{
String cityName;
}
My database table is as below :
Goegraphy
---------
countryName | stateName | cityName
Now, for fetching data from database, I made another POJO :
class Geography{
String countryName;
String stateName;
String cityName;
}
I have a List of Geography objects.
But my requirement is to convert this list into the earlier Country-State-City model now. Can someone please help how this can be achieved.
What you are looking for is the One to Many association of relation databases. All JPA implementations can do it nicely for you, without the need of implementing your Geography Pojo.
But if you are stuck to do it manually, here is a not very optimized way of doing it with java 8 streams
class Country {
public Country(String countryName) {
this.countryName = countryName;
this.states = new ArrayList<>();
}
String countryName;
List<State> states;
}
class State {
public State(String stateName) {
this.stateName = stateName;
this.cities = new ArrayList<>();
}
String stateName;
List<City> cities;
}
class City {
public City(String cityName) {
this.cityName = cityName;
}
String cityName;
}
class Geography {
String countryName;
String stateName;
String cityName;
}
List<Country> buildFromGeographies(List<Geography> geos) {
List<Country> result = new ArrayList<>();
for (Geography geo : geos) {
Optional<Country> country1 = result.stream().filter(country -> country.countryName.equals(geo.countryName)).findFirst();
Country country = country1.orElseGet(() -> {
Country newOne = new Country(geo.countryName);
result.add(newOne);
return newOne;
});
Optional<State> state1 = country.states.stream().filter(state -> state.stateName.equals(geo.stateName)).findFirst();
State state = state1.orElseGet(() -> {
State newOne = new State(geo.stateName);
country.states.add(newOne);
return newOne;
});
// taking for granted there is no duplicates in your data set
state.cities.add(new City(geo.cityName));
}
return result;
}
If I understand it correctly you have List from table and you want it to map on you POJO classes. But the problem is that you have duplicated values in table if I understand it correctly. I think you have this data in table
1. USA, Florida, Miami
2. USA, Florida, Sarasota
The Problem will be with dupplication in table. I think you should split each column in separate table and join via foreing key and it will be better. Than you can create select and join to another table and result add to your list. Now you need to create loop.
I need to update entity in hibernate, like
class EntityA {
private String name
//one-to-many, orhpan removal = true, bidirectioanl
private List<EntityB> listB;
}
I recieve the object from REST API, and I need to update item in the listB and name for Entity A.
Items in the list can be updated/removed/added
What is the best practice to this, from hibernate perpective ?
The first thing is what is the format of representation resources which you invoking using http request.
JSON
XML
If your resource format is json then you gonna map json object to your java object and manage it with JPA.
Example :
Lets say your json format resource contain following user data called user_info.json
{
"firstName" : "jack",
"lastName" : "Dawson",
"contacts" : [
{
"cellphone" : "434343",
"address" : "agrabad",
"city" : "ctg"
},
{
"cellphone" : "+88667755",
"address" : "chokbazar",
"city" : "dhk"
}
]
}
And your user pojo class is :
public class User {
Private String firstName;
Private String lastName;
private Collection<Contact> contacts;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Collection<Contact> getContacts() {
return contacts;
}
public void setContacts(Collection<Contact> contacts) {
this.contacts = contacts;
}
}
There is lot of json lib, i personally prefer Gson developed by Google.
So using Gson you can map json object to java object. Following code snippet about mapping json to java object :
User user = new Gson().fromJson("user_info_Json_String", User.class)
So you have done with mapping. All you have to do execute user object according to EntityManager operation.
Note: User class state has to match json key string during mapping.
If resource format is XML then JAXB is great feature for marshalling and unmarshalling e.g object to xml and vice-versa.
Update : To update collection of contacts to database we don't need to add element one by one. Java Collection has method call addAll(). Just using it . Here is the example :
Collection<Contacts> jsonUserContacs = user.getContacts();
Collection<Contacts> dbContacts = dbuser.getContacts();
dbContacts.addAll(jsonUserContacs);
Thats it. You don't need to add contact one by one.
Hope This knowledge transfer helps you. Thanks.
I want to create DTO class for User. my input to program is
firstname, lastname,lastname.role,group1,group2,group3.
so for each user role consist of group_1,group_2,group_3.....
In database i want to store in following format
demo,demo,demo,roleId, gorup_1_name group_1_Id
demo,demo,demo,roleId, gorup_2 and group_2_Id
demo,demo,demo,roleId, gorup_3 and group_3_Id
I was able separate all this things , but i want to assign this value to userDTO class and stored into database. basically im new to core java part. so how can create structure for this?
A Data Transfer Object (DTO) class is a java-bean like artifact that holds the data that you want to share between layer in your SW architecture.
For your usecase, it should look more or less like this:
public class UserDTO {
String firstName;
String lastName;
List<String> groups;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public List<String> getGroups() {
return groups;
}
public void setGroups(List<String> groups) {
this.groups = groups;
}
// Depending on your needs, you could opt for finer-grained access to the group list
}
One thing to add:
The essence of a DTO is that it transfers data across the wire. So it will need to be Serializable.
http://martinfowler.com/eaaCatalog/dataTransferObject.html