Converting JSON object to string in JAXB - java

Am writing an Webservice endpoint which will produce JSON and XML response. Here i would like to convert an object to JSON and setting it to string. When i try to do with the below code
Webservice Endpoint
package com.test1;
import java.util.ArrayList;
import java.util.List;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;`
#Path("v1")
public class Impl1 {
#POST
#Path("method")
#Produces({"text/xml","application/json"})
public XML method() throws JSONException
{
//JSONObject obj = new JSONObject();
JSONArray ary = new JSONArray();
Main main = new Main();`
List<Student> details = new ArrayList<Student>() ;
Student s1 = new Student();
Student s2 = new Student();
Student s3 = new Student();
s1.setId("ID1");
s1.setValue("1");
s2.setId("ID2");
s2.setValue("2");
s3.setId("ID3");
s3.setValue("3");
details.add(s1);
details.add(s2);
details.add(s3);
main.setDetails(details);
ary.put(details);
Employee emp = new Employee();
emp.setName("Mike");
emp.setSalary(1000);
XML xml = new XML();
xml.setDetails(ary.toString());
xml.setEmp(emp);
xml.setId("1");
return xml;
}
}
XML class (JAXB)
package com.test1;
import java.util.HashMap;
import java.util.Map;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement
public class XML {
String id;
Employee emp;
String details;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Employee getEmp() {
return emp;
}
public void setEmp(Employee emp) {
this.emp = emp;
}
public String getDetails() {
return details;
}
public void setDetails(String details) {
this.details = details;
}
}
Student Class
package com.test1;
public class Student {
String id;
String Value;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getValue() {
return Value;
}
public void setValue(String value) {
Value = value;
Main Class
package com.test1;
import java.util.List;
public class Main {
List<Student> details;
public List<Student> getDetails() {
return details;
}
public void setDetails(List<Student> details) {
this.details = details;
}
}
So when i hit my service am getting response as
{
"details" : "[[{\"id\":\"ID1\",\"value\":\"1\"},{\"id\":\"ID2\",\"value\":\"2\"},{\"id\":\"ID3\",\"value\":\"3\"}]]",
"emp" : {
"name" : "Arun",
"salary" : "1000.0"
},
"id" : "1"
}
Expected String valuse as
[{"id":"ID1","value":"1"},{"id":"ID2","value":"2"},{"id":"ID3","value":"3"}]
My Question is Why JSONArray which was converted as String contains "\" on every key value pair. is there any way to overcome this?

Use Jackson or google-gson or any other library.
For example
http://howtodoinjava.com/2014/06/16/jackson-examples-convert-java-object-to-from-json/

Related

Generics with Java REST API

I have a problem in accessing get method of a generic class in REST API project. there are no errors but it returns null. here I mention the code. The idea working fine when I implemented without REST API. Insert and GetALL methods are working fine in REST API but problem is Repo class Get method couldn't work with REST.
package lk.ac.jfn.vau.DeptApi.Model;
public class Department extends PrimaryID<Long>{
private String Name;
private String Location;
public Department() {
//super();
}
public Department(long id, String name, String location) {
super(id);
Name = name;
Location = location;
}
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
public String getLocation() {
return Location;
}
public void setLocation(String location) {
Location = location;
}
}
package lk.ac.jfn.vau.DeptApi.Model;
public class PrimaryID<U> {
private U Id;
public PrimaryID() {
}
public PrimaryID(U id) {
Id = id;
}
public U getId() {
return Id;
}
public void setId(U id) {
Id = id;
}
}
package lk.ac.jfn.vau.DeptApi.Repo;
import java.util.ArrayList;
import java.util.List;
import lk.ac.jfn.vau.DeptApi.Model.PrimaryID;
public class Repo<T extends PrimaryID<U>,U> {
List<T> list= new ArrayList<T>();
public List<T> getAll(){
return list;
}
public void insert(T obj) {
list.add(obj);
}
public T get(U id) {
for(T obj:list) {
//objects are there
System.out.println(obj);
//but getId returns null
if(obj.getId().equals(id)) {
return obj;
}
}
return null;
}
public void Delete(U id) {
list.remove(get(id));
}
public void Update(U id,T obj) {
list.set(list.indexOf(get(id)), obj);
}
}
package lk.ac.jfn.vau.DeptApi.Repo;
import lk.ac.jfn.vau.DeptApi.Model.Department;
public class DepartmentRepo extends Repo<Department, Long> {
}
package lk.ac.jfn.vau.DeptApi;
import java.util.List;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import lk.ac.jfn.vau.DeptApi.Model.Department;
import lk.ac.jfn.vau.DeptApi.Repo.DepartmentRepo;
#Path("/dept")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public class DepartmentResource {
private static DepartmentRepo repo = new DepartmentRepo();
#GET
public List<Department> getDepartments() {
return repo.getAll();
}
#POST
public void addDepartment(Department department) {
repo.insert(department);
}
#GET
#Path("/{id}")
public Department getDepartment(#PathParam("id") long id) {
return repo.get(id);
}
#DELETE
#Path("/{id}")
public void deleteDepartment(#PathParam("id") long id) {
repo.Delete(id);
}
}
I found the problem. Problem is Object to JSON conversion. when I updated the JSON library it worked fine.
<!-- https://mvnrepository.com/artifact/org.glassfish.jersey.media/jersey-media-json-jackson -->
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
</dependency>

Creating multiple XML files from a hashmap in Java

I'm trying to create a XML file from a HashMap. For each key of the hash i want an XML file. The value of the key is an ArrayList of Objects. I am using JAXB but the XML files are not created, as the output is not XML valid.
The object class:
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement(name = "Product")
public class Product implements Comparable<Product>{
String ID,description, gtin;
double price;
String date;
Product()
{
}
public String toString()
{
return ID+" "+description+" "+gtin+" "+price+" "+date;
}
public String getID() {
return ID;
}
#XmlElement
public void setID(String ID) {
this.ID = ID;
}
public String getDescription() {
return description;
}
#XmlElement
public void setDescription(String description) {
this.description = description;
}
public String getGtin() {
return gtin;
}
#XmlElement
public void setGtin(String gtin) {
this.gtin = gtin;
}
public double getPrice() {
return price;
}
#XmlElement
public void setPrice(Double price) {
this.price = price;
}
}
The class where i try to create the XMLs:
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
public class CreateXML {
static void create(HashMap<String, ArrayList<Product> > map) {
try {
JAXBContext jaxbContext = JAXBContext.newInstance(ProdsList.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
Set setOfKeys = map.keySet();
Iterator iterator = setOfKeys.iterator();
while (iterator.hasNext()) {
String keys = (String) iterator.next();
String filename= "C:\\Users\\As\\Desktop\\Sups\\"+keys+22+".xml";
File file = new File(filename);
ArrayList<Product> value = map.get(keys);
jaxbMarshaller.marshal(value, file);
jaxbMarshaller.marshal(value, System.out);
}
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
The class for the root of the xml:
import java.util.*;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSeeAlso;
//#XmlAccessorType(XmlAccessType.FIELD)
#XmlRootElement(name="Products")
//#XmlSeeAlso({ArrayList.class})
class ProdsList {
#XmlElement(name="Product")
ArrayList<Product> prods;
public ProdsList(){
prods=new ArrayList<Product>();
}
public ArrayList<Product> getProducts() {
return prods;
}
public void setProducts(ArrayList<Product> prods) {
this.prods = prods;
}
}
How can i fix this. Thanks in advance.
You need to marshal an instance of ProdsList. Instead you are trying to marshall
an ArrayList of Products.
Change
jaxbMarshaller.marshal(value, file);
jaxbMarshaller.marshal(value, System.out);
To
jaxbMarshaller.marshal(new ProdsList(value), file);
jaxbMarshaller.marshal(new ProdsList(value), System.out);

JAXB unmarshalling elements with same name

this is my xml structure
<catalog>
<course>
<course_id></course_id>
<subjects>
<subject>
<subject_id></subject_id>
</subject>
<subject>
<subject_id></subject_id>
</subject>
</subjects>
</course>
</catalog>
So, i'v tried to bind this xml to a class using JAXB Unmarshalling, but the result was nothing.
I was thinking, i have 2 base elements, course and subject, so i built 2 classes based on these elements.
This to control the course tag
#XmlRootElement(name="catalog")
#XmlAccessorType(XmlAccessType.FIELD)
public class curso {
#XmlElement(name="course_id")
int course_id;
#XmlElementWrapper(name="subjects")
#XmlElement(name="subject")
List <subject> subjects = new ArrayList<>();
public void setCourse_id(int curso_id) {
this.curso_id = curso_id;
}
public void setSubjects(List<subject> subjects) {
this.subjects = subjects;
}
}
And This to control the subject tag.
public class subject {
String subject_id;
#XmlElement(name="subject_id")
public void setSubjectId(String id) {
this.subject_id = id;
}
}
I made some to string functions, and my output was nothing.
What is the problem?
The course element also have a wrapper tag <course> So either you need to change you xml to remove <catalog> tag and make <course> as the root. Or you should create a new class catalog and make course as a field. Like
#XmlRootElement(name="catalog")
#XmlAccessorType(XmlAccessType.FIELD)
class catalog {
#XmlElement(name="course")
curso course;
public curso getCourse() {
return course;
}
public void setCourse(curso course) {
this.course = course;
}
#Override
public String toString() {
return "catalog [course=" + course + "]";
}
}
A complete example
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement(name="catalog")
#XmlAccessorType(XmlAccessType.FIELD)
class catalog {
#XmlElement(name="course")
curso course;
public curso getCourse() {
return course;
}
public void setCourse(curso course) {
this.course = course;
}
#Override
public String toString() {
return "catalog [course=" + course + "]";
}
}
class curso {
#XmlElement(name = "course_id")
int course_id;
#XmlElementWrapper(name = "subjects")
#XmlElement(name = "subject")
List<subject> subjects = new ArrayList<>();
public void setCourse_id(int curso_id) {
this.course_id = curso_id;
}
public void setSubjects(List<subject> subjects) {
this.subjects = subjects;
}
#Override
public String toString() {
return "curso [course_id=" + course_id + ", subjects=" + subjects + "]";
}
}
class subject {
String subject_id;
#XmlElement(name = "subject_id")
public void setSubjectId(String id) {
this.subject_id = id;
}
#Override
public String toString() {
return "subject [subject_id=" + subject_id + "]";
}
}
public class JaxbExample2 {
public static void main(String[] args) {
try {
File file = new File("file.xml");
JAXBContext jaxbContext = JAXBContext.newInstance(catalog.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
catalog customer = (catalog) jaxbUnmarshaller.unmarshal(file);
System.out.println(customer);
} catch (JAXBException e) {
e.printStackTrace();
}
}
}

getting null in Object passing JSON to #POST using Apache CXF

I am using Json to get object details in my POST method to save it in database. The id field is stored correctly but the rest are just taken as null. Can someone point out why.
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.ws.rs.GET;
import javax.ws.rs.*;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.MediaType;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import org.ocpsoft.example.hibernate.model.SimpleObject;
import org.ocpsoft.example.hibernate.util.EntityManagerUtil;
import org.ocpsoft.example.hibernate.dao.SimpleObjectDao;
#Stateless
#Path("/pid")
public class Service {
#GET
#Path("{id}")
public String get(#PathParam("id") long id){
System.out.println("in GET request");
SimpleObjectDao objDao=new SimpleObjectDao();
objDao.startConnection();
SimpleObject obj=objDao.find(id);
objDao.closeConnection();
Gson gson=new Gson();
return gson.toJson(obj);
}
#POST
#Path("/add")
#Consumes("application/json")
//#Produces({MediaType.APPLICATION_JSON})
public String postdata(SimpleObject obj)
{
//SimpleObject obj = (SimpleObject) ob;
//Gson gson=new Gson();
//System.out.println(obj.toString());
//System.out.println("object "+obj.toString());
SimpleObjectDao objDao=new SimpleObjectDao();
objDao.startConnection();
objDao.save(obj);
objDao.closeConnection();
return "Success";
}
}
My object definition is
package org.ocpsoft.example.hibernate.model;
import javax.persistence.*;
import java.io.Serializable;
import javax.persistence.Id;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Column;
import javax.persistence.Version;
import javax.xml.bind.annotation.XmlRootElement;
import java.lang.Override;
/**
* #author Lincoln Baxter, III
*/
#Entity
#XmlRootElement(name="SimpleObject")
public class SimpleObject implements Serializable
{
private static final long serialVersionUID = -2862671438138322400L;
#Id
//#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id", updatable = false, nullable = false)
private Long id = null;
//private int Pid;
#Column(name= "Pname")
private String Pname = null;
#Column(name= "Pcost")
private double Pcost = 0.0f;
#Column(name= "Pcat")
private String Pcat = null;
public Long getId()
{
return this.id;
}
public String getPname() {
return Pname;
}
public void setPname(String pname) {
Pname = pname;
}
public double getPcost() {
return Pcost;
}
public void setPcost(double pcost) {
Pcost = pcost;
}
public String getPcat() {
return Pcat;
}
public void setPcat(String pcat) {
Pcat = pcat;
}
public void setId(final Long id)
{
this.id = id;
}
public String toString()
{
String result = "";
if (id != null)
result += id;
return result;
}
#Override
public boolean equals(Object that)
{
if (this == that)
{
return true;
}
if (that == null)
{
return false;
}
if (getClass() != that.getClass())
{
return false;
}
if (id != null)
{
return id.equals(((SimpleObject) that).id);
}
return super.equals(that);
}
#Override
public int hashCode()
{
if (id != null)
{
return id.hashCode();
}
return super.hashCode();
}
}
Apart from Id all the others are not transferred to the object. com where I am going wrong.
I am checking using chrome postman with json as
{ "SimpleObject" :{"id":1,"Pname":"watch","Pcost":200.12,"Pcat":"wearables"}}
Maybe your ID column is auto generate, I think values on POST method cannot cast to your object
Try this :
#POST
#Path("/add")
#Consumes("application/x-www-form-urlencoded")
#Produces(MediaType.APPLICATION_JSON)
public String postdata(MultivaluedMap<String, String> formParams)
we need build SimpleObject object from form params.
hope this help !

Deserializing with Jackson

I need a way to deserialize this object:
{
"rows": [
{
"id": 0,
"name": "qwe"
}
],
"total": 0
}
to Row[] (i don't need "total") WITHOUT USING OF WAPPER OBJECT:
public class ReviewsWrapper {
private Row[] rows;
#JsonIgnore
private Integer total;
}
directly deserializing it to Rows[]? If there was no "total" object, i would just deserialize using this method:
public static <T> T fromJsonWithRootName(InputStream is, Class<T> type, String rootName) {
try {
return objectMapper.reader(type).withRootName(rootName).readValue(is);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
passing "rows" as a rootName and will get Row[] as output. Is there any way to avoid using WrapperObject for Row[]? It's an Android project I define entities using Jackson Annotations.
Your JSON data Model classes should be like this
package com.example;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonPropertyOrder({
"rows",
"total"
})
public class ReviewsWrapper {
#JsonProperty("rows")
private List<Row> rows = new ArrayList<Row>();
#JsonProperty("total")
private long total;
#JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
/**
*
* #return
* The rows
*/
#JsonProperty("rows")
public List<Row> getRows() {
return rows;
}
/**
*
* #param rows
* The rows
*/
#JsonProperty("rows")
public void setRows(List<Row> rows) {
this.rows = rows;
}
public ReviewsWrapper withRows(List<Row> rows) {
this.rows = rows;
return this;
}
/**
*
* #return
* The total
*/
#JsonProperty("total")
public long getTotal() {
return total;
}
/**
*
* #param total
* The total
*/
#JsonProperty("total")
public void setTotal(long total) {
this.total = total;
}
public ReviewsWrapper withTotal(long total) {
this.total = total;
return this;
}
#JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
#JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
public ReviewsWrapper withAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
return this;
}
}
-----------------------------------com.example.Row.java-----------------------------------
package com.example;
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonPropertyOrder({
"id",
"name"
})
public class Row {
#JsonProperty("id")
private long id;
#JsonProperty("name")
private String name;
#JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
/**
*
* #return
* The id
*/
#JsonProperty("id")
public long getId() {
return id;
}
/**
*
* #param id
* The id
*/
#JsonProperty("id")
public void setId(long id) {
this.id = id;
}
public Row withId(long id) {
this.id = id;
return this;
}
/**
*
* #return
* The name
*/
#JsonProperty("name")
public String getName() {
return name;
}
/**
*
* #param name
* The name
*/
#JsonProperty("name")
public void setName(String name) {
this.name = name;
}
public Row withName(String name) {
this.name = name;
return this;
}
#JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
#JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
public Row withAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
return this;
}
}
Then in Java Class to de-serialize using Jackson use below code
ObjectMapper mapper = new ObjectMapper();
JsonFactory jf = new JsonFactory();
JsonParser jp = jf.createJsonParser("your json data as a String");
ReviewsWrapper reviewWrapper = mapper.readValue(jp,ReviewsWrapper.class);
after this You can get all your response from "ReviewsWrapper.class"
Here is Example using JsonNode try this. is this what you want?
Here is one Example using Nodes.
public class App {
public static class Foo {
public int foo;
}
public static void main(String[] args) {
String json = "{\"someArray\":[{\"foo\":5},{\"foo\":6},{\"foo\":7}]}";
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.readTree(json);
node = node.get("someArray");
TypeReference<List<Foo>> typeRef = new TypeReference<List<Foo>>(){};
List<Foo> list = mapper.readValue(node.traverse(), typeRef);
for (Foo f : list) {
System.out.println(f.foo);
} }}

Categories

Resources