Customized JAXB xml output - java

Given the following class:
public class Customer {
public String name;
public String lastName;
}
I want to generate the following xml output using JAXB for a customer whose name is John and lastName is Doe:
<cst>John Doe</cst>
How can i do this with JAXB?
EDIT
The class Customer is used in several places, as shown here:
public class Sale {
private String productId;
private Date date;
private Customer customer;
}
public class Transaction {
private List<Sale> sales;
}
... and so on... The deal is, how can I tell JAXB: "whenever you see a customer, please use custom formatting"?
My problem is that there are many classes that contain a customer, and I want to programatically control the output (sometimes name + lastname, sometimes <name>name</name>, <lastname>lastname</lastname>) without adding annotations at every class that contains Customer. This requirement would rule out using JAXBElement<Customer>.

You could install an XmlAdapter that handles the translation:
public static void main(String[] args) throws Exception {
JAXBContext ctxt = JAXBContext.newInstance(CustomerWrapper.class);
Marshaller m = ctxt.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
Customer customer = new Customer("John", "Doe");
m.marshal(new JAXBElement<CustomerWrapper>(new QName("cwrapper"), CustomerWrapper.class, new CustomerWrapper(customer)), System.err);
}
static class CustomerWrapper {
private Customer customer;
public CustomerWrapper() {
}
public CustomerWrapper(Customer customer) {
this.customer = customer;
}
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
}
#XmlJavaTypeAdapter(CustomerAdapter.class)
static class Customer {
private String name;
private String lastName;
public Customer() {
}
public Customer(String name, String lastName) {
this.name = name;
this.lastName = lastName;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
static class CustomerAdapter extends XmlAdapter<String, Customer> {
#Override
public Customer unmarshal(String v) throws Exception {
String[] ss = v.split(" ");
return new Customer(ss[0], ss[1]);
}
#Override
public String marshal(Customer v) throws Exception {
return v.getName() + " " + v.getLastName();
}
}
outputs
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<cwrapper>
<customer>John Doe</customer>
</cwrapper>

Related

Hibernate nulls in DB with #Embedded

hello im learning Hibernate, currently I'm trying to use #Embedded annotation, but i got nulls from #Embeddable object in my DB.
the code is as follows:
#Entity
public class Employee {
#Id
#GeneratedValue
private int id;
private String firstName;
private String lastName;
private double salary;
#Embedded
private Adress adress;
public Adress getAdress() {
return adress;
}
public void setAdress(Adress adress) {
this.adress = adress;
}
public int getId() {
return id;
}
public void setId(int 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;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
So that is my Employee class which hold, #embedded field from Adress.class
Here comes Adress class:
#Embeddable
public class Adress {
private String locality;
private String streetNumber;
private String zipCode;
public String getLocality() {
return locality;
}
public void setLocality(String locality) {
this.locality = locality;
}
public String getStreetNumber() {
return streetNumber;
}
public void setStreetNumber(String streetNumber) {
this.streetNumber = streetNumber;
}
public String getZipCode() {
return zipCode;
}
public void setZipCode(String zipCode) {
this.zipCode = zipCode;
}
}
and thats my main class:
public class Main {
public static void main(String[] args) {
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("myDatabase");
EntityManager entityManager = entityManagerFactory.createEntityManager();
Employee employee = new Employee();
Adress adress = new Adress();
adress.setLocality("New York");
adress.setZipCode("55-5555");
adress.setStreetNumber("55");
employee.setFirstName("Andy");
employee.setLastName("Cole");
employee.setSalary(3333);
entityManager.getTransaction().begin();
entityManager.persist(employee);
entityManager.getTransaction().commit();
entityManager.close();
entityManagerFactory.close();
}
}
So fields related to class Employee go to the database without problem, but fields related to class Adress are set to null. I'd like to have them as setValues. Thanks in advance to all.
You're missing setAddress call
public class Test {
public static void main(String[] args) {
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("myDatabase");
EntityManager entityManager = entityManagerFactory.createEntityManager();
Employee employee = new Employee();
Adress adress = new Adress();
adress.setLocality("New York");
adress.setZipCode("55-5555");
adress.setStreetNumber("55");
employee.setFirstName("Andy");
employee.setLastName("Cole");
employee.setSalary(3333);
employee.setAdress(adress);
entityManager.getTransaction().begin();
entityManager.persist(employee);
entityManager.getTransaction().commit();
entityManager.close();
entityManagerFactory.close();
}
}
You need to set your created Adress object in your employee before persisting the employee, as in your current implementation your employee is not aware of his adress.
employee.setAdress(adress);

Designing Java Objects from Magento JSON

Below are the raw JSON string returned from Magento REST API call:
{
"1":{
"entity_id":"1",
"website_id":"1",
"email":"john.oliver#hbo.com",
"group_id":"1",
"created_at":"2015-04-21 12:47:00",
"disable_auto_group_change":"0",
"prefix":null,
"firstname":"John",
"middlename":null,
"lastname":"Oliver",
"suffix":null,
"taxvat":null,
"created_in":"Admin"
},
"2":{
"entity_id":"2",
"website_id":"1",
"email":"beck.johnson#yahoo.com",
"group_id":"1",
"created_at":"2015-04-21 13:40:48",
"disable_auto_group_change":"0",
"prefix":null,
"firstname":"Beckie",
"middlename":null,
"lastname":"Johnson",
"suffix":null,
"taxvat":null,
"created_in":"Admin"
}
}
I would like to construct the POJO for the first time and here are the classes:
public class Customers {
private Map<String, Customer> customerMap;
public Map<String, Customer> getCustomerMap() {
return customerMap;
}
public void setCustomerMap(Map<String, Customer> customerMap) {
this.customerMap = customerMap;
}
}
public class Customer {
private String entity_id;
private String website_id;
private String email;
private String group_id;
private String created_at;
private String disable_auto_group_change;
private String prefix;
private String firstname;
private String middlename;
private String lastname;
private String suffix;
private String taxvat;
private String created_in;
public String getEntity_id() {
return entity_id;
}
public void setEntity_id(String entity_id) {
this.entity_id = entity_id;
}
public String getWebsite_id() {
return website_id;
}
public void setWebsite_id(String website_id) {
this.website_id = website_id;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getGroup_id() {
return group_id;
}
public void setGroup_id(String group_id) {
this.group_id = group_id;
}
public String getCreated_at() {
return created_at;
}
public void setCreated_at(String created_at) {
this.created_at = created_at;
}
public String getDisable_auto_group_change() {
return disable_auto_group_change;
}
public void setDisable_auto_group_change(String disable_auto_group_change) {
this.disable_auto_group_change = disable_auto_group_change;
}
public String getPrefix() {
return prefix;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getMiddlename() {
return middlename;
}
public void setMiddlename(String middlename) {
this.middlename = middlename;
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public String getSuffix() {
return suffix;
}
public void setSuffix(String suffix) {
this.suffix = suffix;
}
public String getTaxvat() {
return taxvat;
}
public void setTaxvat(String taxvat) {
this.taxvat = taxvat;
}
public String getCreated_in() {
return created_in;
}
public void setCreated_in(String created_in) {
this.created_in = created_in;
}
}
Then, I tried using Gson to do the parsing:
Gson gson = new Gson();
Customers customers = gson.fromJson(response.getBody(), Customers.class);
System.out.println(customers.getCustomerMap());
But the result is null.
I am suspecting the class format might be wrong, can anyone suggest what's the right format? The number 1 and 2 at the beginning of each set are automatically generated by Magento.
This doesn't work by default because Gson expects to have a field named "customerMap" in order to use the default deserialization. The easiest (NOT NECESSARILY BEST) solution would be to simply do this:
String jsonText = "{\"customerMap\":"+response.getBody()+"}";
Customers customers = gson.fromJson(jsonText, Customers.class);
By adding the field name around the outside of your mapping, Gson knows what to do, and the println will output, for instance:
{1=Customer#2f56a6be, 2=Customer#61dd1c39}
However, it would be better to write a custom deserializer for your Customers class, or to modify the output of Magneto to add the surrounding {"customerMap": and }
Do NOT try to do this:
Map<String, Customer> cust = gson.fromJson(jsonText, Map.class);
This will actually generate a Map of type Map<String, LinkedTreeMap>, where LinkedTreeMap is an internal gson class.

Reading data from stored data in arraylist

Can someone help me i have those classes, and i want read out the getAllCustomer(), but i have no idea how i can implent it in my main method.
I tried already several things, but it didn't work well. Can anyone help me? :P
public static ArrayList<Customer> getAllCustomer() throws ClassNotFoundException, SQLException {
Connection conn=DBConnection.getDBConnection().getConnection();
Statement stm;
stm = conn.createStatement();
String sql = "Select * From Customer";
ResultSet rst;
rst = stm.executeQuery(sql);
ArrayList<Customer> customerList = new ArrayList<>();
while (rst.next()) {
Customer customer = new Customer(rst.getString("id"), rst.getString("name"), rst.getString("address"), rst.getDouble("salary"));
customerList.add(customer);
}
return customerList;
}
this is my model class
public class Customer {
private String id;
private String name;
private String salary;
private String address;
public Customer (String pId, String pName, String pSalary, String pAddress) {
id = pId;
name = pName;
salary = pSalary;
adress = pAddress;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSalary() {
return salary;
}
public void setSalary(String salary) {
this.salary = salary;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
Assuming that your getAllCustomer() method is in class A . then in your main method, you do as follows
public void main(String[] args){
List<Customer> customers = A.getAllCustomer();
}
Based on the nature of your question, this JDBC tutorial will help you
The data type of your Salary field is String but you are getting the value as double.
All you need to do is to change the rst.getDouble("salary") to rst.getString("salary")
To call the method:
public static void main(String[] args)
ArrayList<Customer> customers = YourDALClass.getAllCustomer();
for(Customer c : customers){
System.out.println(c.getName());
}
}

Deserialize yaml to list of objects

Say I have a Yaml file like this,
people:
- name : Joe
surname : Barber
age : 16
- name : Andy
surname : Lots
age : 17
And I have a class like this,
public class people {
private String name;
private String surname;
private String age;
<!-- With getters and setters -->
}
How would i go about getting a list of people objects from the Yaml file?
Just getting the value from a key in the file is fairly simple but mapping it to a collection of objects is not.
I am using the snakeYaml lib.
i hope this can help you.
public class StackOverflow {
public static void main(String[] args) {
final URL resource = StackOverflow.class.getResource("people.yaml");
final Constructor peopleContructor = new Constructor(Group.class);
final TypeDescription peopleDescription = new TypeDescription(People.class);
peopleDescription.putMapPropertyType("people", People.class, Object.class);
peopleContructor.addTypeDescription(peopleDescription);
final Yaml yaml = new Yaml(peopleContructor);
try {
final Group group = (Group) yaml.load(resource.openStream());
for (final People people : group.getPeople()) {
System.out.println(people);
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static class People {
private String name;
private String surname;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
#Override
public String toString() {
return "People: {name: " + this.name + ", surname: " + this.surname + ", age: " + this.age + "}";
}
}
public static class Group {
private List<People> people;
public List<People> getPeople() {
return people;
}
public void setPeople(List<People> people) {
this.people = people;
}
}}

JAXB #XmlIDREF in XmlAdapter for immutable objects

I'm using XmlAdapter for immutable objects as proposed in this blog post: http://blog.bdoughan.com/2010/12/jaxb-and-immutable-objects.html. This works fine, but not with references to other immutable objects in my adapters. Is there any way to handle this with JAXB?
Below there is an example which does not work if the person's xml tag comes after the company's xml tag which references the person.
Immutable objects:
#XmlJavaTypeAdapter(PersonAdapter.class)
public class Person {
private final String id;
private final String name;
public Person(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public String getName() {
return name;
}
}
#XmlJavaTypeAdapter(CompanyAdapter.class)
public class Company {
private final String name;
private final Person principal;
public Company(String name, Person principal) {
this.name = name;
this.principal = principal;
}
public String getName() {
return name;
}
public Person getPrincipal() {
return principal;
}
}
PersonAdapter:
public class PersonAdapter extends XmlAdapter<AdaptedPerson, Person> {
public static class AdaptedPerson {
#XmlID
#XmlAttribute
String id;
#XmlAttribute
String name;
}
#Override
public AdaptedPerson marshal(Person v) throws Exception {
AdaptedPerson a = new AdaptedPerson();
a.id = v.getId();
a.name = v.getName();
return a;
}
#Override
public Person unmarshal(AdaptedPerson v) throws Exception {
return new Person(v.id, v.name);
}
}
CompanyAdapter:
public class CompanyAdapter extends XmlAdapter<AdaptedCompany, Company> {
public static class AdaptedCompany {
#XmlAttribute
String name;
#XmlIDREF
#XmlAttribute
Person principal;
}
#Override
public AdaptedCompany marshal(Company v) throws Exception {
AdaptedCompany a = new AdaptedCompany();
a.name = v.getName();
a.principal = v.getPrincipal();
return a;
}
#Override
public Company unmarshal(AdaptedCompany v) throws Exception {
return new Company(v.name, v.principal);
}
}

Categories