My java class is throwing some error. In my class i am using this to get my data.
((myDataDetails) Names.get(0)).InputParamNames().add("SomeValue");
But it is throwing error
Here is my Pohjo Class.
package common.pojo;
import java.util.Date;
import java.util.List;
public class myDataDetails
{
private String myID;
private List<String> InputParamNames;
private List InputParamData;
public String getmyID() {
return this.myID;
}
public void setmyID(String myID) {
this.myID = myID;
}
public List<String> getInputParamNames() {
return this.InputParamNames;
}
public void setInputParamNames(List<String> InputParamNames) {
this.InputParamNames = InputParamNames;
}
public List getInputParamData() {
return this.InputParamData;
}
public void setInputParamData(List InputParamData) {
this.InputParamData = InputParamData;
}
}
What should I need to change in pojo to avoid this exception.
Your class 'myDataDetails' needs to extend from LinkedHashMap in order to cast it.
What you have right now is a regular POJO class that is not an instance of LinkedHashMap, so you can't cast it as such.
EDIT: It should look like this
package common.pojo;
import java.util.Date;
import java.util.List;
import java.util.LinkedHashMap;
public class myDataDetails extends LinkedHashMap<Object, Object>
{
private String myID;
private List<String> InputParamNames;
private List InputParamData;
public String getmyID() {
return this.myID;
}
public void setmyID(String myID) {
this.myID = myID;
}
public List<String> getInputParamNames() {
return this.InputParamNames;
}
public void setInputParamNames(List<String> InputParamNames) {
this.InputParamNames = InputParamNames;
}
public List getInputParamData() {
return this.InputParamData;
}
public void setInputParamData(List InputParamData) {
this.InputParamData = InputParamData;
}
}
Related
I'm using the Gson library and jakarta. Although I have been able to use the conversion in CarrinhoResource.java as below, my ClienteTest.java cannot use the String content (already in json) inside the cart. I cant run my test a just only message into my intellij is (Cannot resolve method 'fromJson(java.lang.String)').
Can someone help me?
Class CarrinhoResource.java
package br.com.alura.loja.resource;
import br.com.alura.loja.dao.CarrinhoDAO;
import br.com.alura.loja.modelo.Carrinho;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
#Path("/v1/carrinhos")
public class CarrinhoResource {
#GET
#Produces(MediaType.APPLICATION_JSON)
public String busca(){
Carrinho carrinho = new CarrinhoDAO().busca(1L);
return carrinho.toJson();
}
}
Carrinho.java
package br.com.alura.loja.modelo;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import com.google.gson.Gson;
public class Carrinho {
private List<Produto> produtos = new ArrayList<Produto>();
private String rua;
private String cidade;
private long id;
public Carrinho adiciona(Produto produto) {
produtos.add(produto);
return this;
}
public Carrinho para(String rua, String cidade) {
this.rua = rua;
this.cidade = cidade;
return this;
}
public Carrinho setId(long id) {
this.id = id;
return this;
}
public String getRua() {
return rua;
}
public void setRua(String rua) {
this.rua = rua;
}
public void setCidade(String cidade) {
this.cidade = cidade;
}
public long getId() {
return id;
}
public void remove(long id) {
for (Iterator iterator = produtos.iterator(); iterator.hasNext();) {
Produto produto = (Produto) iterator.next();
if(produto.getId() == id) {
iterator.remove();
}
}
}
public void troca(Produto produto) {
remove(produto.getId());
adiciona(produto);
}
public void trocaQuantidade(Produto produto) {
for (Iterator iterator = produtos.iterator(); iterator.hasNext();) {
Produto p = (Produto) iterator.next();
if(p.getId() == produto.getId()) {
p.setQuantidade(produto.getQuantidade());
return;
}
}
}
public List<Produto> getProdutos() {
return produtos;
}
public String toJson() {
return new Gson().toJson(this);
}
}
ClienteTest.java
package br.com.alura.loja;
import br.com.alura.loja.modelo.Carrinho;
import com.google.gson.*;
import jakarta.ws.rs.client.Client;
import jakarta.ws.rs.client.ClientBuilder;
import jakarta.ws.rs.client.WebTarget;
import org.junit.Assert;
import org.junit.Test;
public class ClienteTest {
#Test
public void testaConexaoServidor() {
Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://localhost:8085");
String conteudo = target.path("/v1/carrinhos").request().get(String.class);
Carrinho carrinho = (Carrinho) new Gson().fromJson(conteudo); **//Cannot resolve method 'fromJson(java.lang.String)'/**
System.out.println(carrinho);
Assert.assertEquals("Rua Vergueiro, 3185", carrinho.getRua());
}
}
Carrinho carrinho = (Carrinho) new Gson().fromJson(conteudo); **//Cannot resolve method 'fromJson(java.lang.String)'/**
The reason for this is that there is no Gson.fromJson(String) method, see the Gson class documentation. For deserialization Gson needs to know which type you are expecting, so all fromJson methods have a second parameter representing the type.
You can simply change your code to:
Carrinho carrinho = new Gson().fromJson(conteudo, Carrinho.class);
I am using following class to create bean from Spark Encoders
Class OuterClass implements Serializable {
int id;
ArrayList<InnerClass> listofInner;
public int getId() {
return id;
}
public void setId (int num) {
this.id = num;
}
public ArrayList<InnerClass> getListofInner() {
return listofInner;
}
public void setListofInner(ArrayList<InnerClass> list) {
this.listofInner = list;
}
}
public static class InnerClass implements Serializable {
String streetno;
public void setStreetno(String streetno) {
this.streetno= streetno;
}
public String getStreetno() {
return streetno;
}
}
Encoder<OuterClass> outerClassEncoder = Encoders.bean(OuterClass.class);
Dataset<OuterClass> ds = spark.createDataset(Collections.singeltonList(outerclassList), outerClassEncoder)
And I am getting the following error
Exception in thread "main" java.lang.UnsupportedOperationException: Cannot infer type for class OuterClass$InnerClass because it is not bean-compliant
How can I implement this type of use case for Spark in Java? This worked fine if I remove the inner class. But I need to have an inner class for my use case.
Your JavaBean class should have a public no-argument constructor, getter and setters and it should implement Serializable interface. Spark SQL works on valid JavaBean class.
EDIT : Adding working sample with inner class
OuterInnerDF.java
package com.abaghel.examples;
import java.util.ArrayList;
import java.util.Collections;
import org.apache.spark.sql.Dataset;
import org.apache.spark.sql.Encoder;
import org.apache.spark.sql.Encoders;
import org.apache.spark.sql.SparkSession;
import com.abaghel.examples.OuterClass.InnerClass;
public class OuterInnerDF {
public static void main(String[] args) {
SparkSession spark = SparkSession
.builder()
.appName("OuterInnerDF")
.config("spark.sql.warehouse.dir", "/file:C:/temp")
.master("local[2]")
.getOrCreate();
System.out.println("====> Create DataFrame");
//Outer
OuterClass us = new OuterClass();
us.setId(111);
//Inner
OuterClass.InnerClass ic = new OuterClass.InnerClass();
ic.setStreetno("My Street");
//list
ArrayList<InnerClass> ar = new ArrayList<InnerClass>();
ar.add(ic);
us.setListofInner(ar);
//DF
Encoder<OuterClass> outerClassEncoder = Encoders.bean(OuterClass.class);
Dataset<OuterClass> ds = spark.createDataset(Collections.singletonList(us), outerClassEncoder);
ds.show();
}
}
OuterClass.java
package com.abaghel.examples;
import java.io.Serializable;
import java.util.ArrayList;
public class OuterClass implements Serializable {
int id;
ArrayList<InnerClass> listofInner;
public int getId() {
return id;
}
public void setId(int num) {
this.id = num;
}
public ArrayList<InnerClass> getListofInner() {
return listofInner;
}
public void setListofInner(ArrayList<InnerClass> list) {
this.listofInner = list;
}
public static class InnerClass implements Serializable {
String streetno;
public void setStreetno(String streetno) {
this.streetno = streetno;
}
public String getStreetno() {
return streetno;
}
}
}
Console Output
====> Create DataFrame
16/08/28 18:02:55 INFO CodeGenerator: Code generated in 32.516369 ms
+---+-------------+
| id| listofInner|
+---+-------------+
|111|[[My Street]]|
+---+-------------+
I have a base class called GenericOrder that can be used to create an order with any type of products, then I have subclasses of that order that are more specific. My problem is with my ComputerOrder class and a method that I'm overriding. Here's the base class code.
import java.util.List;
import java.util.ArrayList;
public class GenericOrder<T> {
private long orderNumber;
private List<T> products;
private T theClass;
public GenericOrder()
{
products = new ArrayList<T>();
orderNumber = System.currentTimeMillis();
}
public long getOrderNumber() {
return orderNumber;
}
public void addProduct(T newProduct) {
products.add(newProduct);
}
public int getNumberOfProducts() {
return products.size();
}
public List<T> getProducts()
{
return products;
}
public void setProducts(List<T> products)
{
this.products = products;
}
public T get()
{
return theClass;
}
public void set(T theClass)
{
this.theClass = theClass;
}
}
And here is my subClass code. The getProducts is the method I'm having trouble with.
import java.util.ArrayList;
import java.util.List;
public class ComputerOrder<T> extends GenericOrder<T> {
private List<ComputerPart> computerParts = new ArrayList<ComputerPart>();
private String orderType = "Computer Parts";
public ComputerOrder() {
super();
}
public void addProduct(ComputerPart newProduct) {
computerParts.add(newProduct);
}
public String getOrderType() {
return orderType;
}
public int getNumberOfProducts() {
return computerParts.size();
}
public List<T> getProducts()
{
return computerParts;
}
}
The Error I get says cannot convert from List(ComputerPart) to List<T>
The error is pretty clear: getProducts() is declared to return a List<T> yet you're returning a List<ComputerPart>. I think we agree that these two are not equivalent.
Looking at your code it looks like that you actually don't want a generic class since ComputerOrder only accepts ComputerParts. What you want is something like the following:
public class ComputerOrder extends GenericOrder<ComputerPart> {
#Override
public List<ComputerPart> getProducts() {
return computerParts;
}
}
Design wise, I think you should reconsider whether products should be in the GenericOrder class. If GenericOrder is meant only to handle the orders, then it might not make sense to have any product related methods or fields defined there. As it is now you have a products List array in GenericOrder that is not being used because you have defined computerParts List array in ComputerOrder. This makes for bad code. In this case your classes would look like:
public class GenericOrder<T> {
private long orderNumber;
private String orderType;
private T theClass;
public GenericOrder(String orderType) {
this.orderType = orderType;
orderNumber = System.currentTimeMillis();
}
public String getOrderType() {
return orderType;
}
public long getOrderNumber() {
return orderNumber;
}
public T get() {
return theClass;
}
public void set(T theClass) {
this.theClass = theClass;
}
}
and
import java.util.ArrayList;
import java.util.List;
public class PartOrder<T> extends GenericOrder<T> {
private List<T> parts = new ArrayList<T>();
public PartOrder(String orderType) {
super(orderType);
}
public void addProduct(T newProduct) {
parts.add(newProduct);
}
public int getNumberOfProducts() {
return parts.size();
}
public List<T> getProducts() {
return parts;
}
}
and you would have a ComputerPartOrder class like so:
public class ComputerPartOrder extends PartOrder<ComputerPart> {
public ComputerPartOrder() {
super("Computer Parts");
}
}
Otherwise, you might also define the GenericOrder.getProducts method as abstract as per this stackoverflow post.
It actually looks like you don't want your ComputerOrder to be generic.
While a GenericOrder<T> is generic and can be an order of anything, ComputerOrder seems specific to ComputerPart(s) and should extend GenericOrder<ComputerPart>.
This way you will only have to implement List<ComputerPart> getProducts() and your code will be fine.
As your ComputerOrders class looks more specific, consider refactoring your code as below :
public class ComputerOrder extends GenericOrder<ComputerPart> {
#Override
public List<ComputerPart> getProducts() { return computerParts; }
}
OK. i made a listview that can see my custom object names I put in the arraylist. I then wrote code to sort the Object List based on their startdate (sdate).
Cannot find solution to my problem.
However, I do not know how to test if my implementation is working since the listview where I see the objects is NOT being sorted, and retains the order in which I added them to the list. here is the code for reference.
Comparator:
package app.zioueche_travelexpense;
import java.util.Comparator;
public class CustomComparator implements Comparator<Claim> {
#Override
public int compare(Claim c1, Claim c2) {
return c1.getSDate().compareTo(c2.getSDate());
}
}
where getSDate is a method in object Claim that simply returns the attribute sdate assigned to it on creation by the user.
now for the sorting problem:
here is where I sort. look for the comment
package app.zioueche_travelexpense;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import android.text.InputFilter.LengthFilter;
import android.widget.Toast;
public class ClaimsList implements Serializable{
/**
* Claim List Serialization ID
*/
private static final long serialVersionUID = 372301924739907840L;
protected static ArrayList<Claim> claimList;
protected ArrayList<Listener> listeners;
public ClaimsList(){
claimList = new ArrayList<Claim>();
listeners = new ArrayList<Listener>();
}
public Collection<Claim> getClaim(){
return claimList;
}
public void addClaim(Claim string){
claimList.add(string);
if (claimList.size() < 1){//SORTING HAPPENS HERE
Collections.sort(claimList, new CustomComparator());
notifyListeners();
}else{
notifyListeners();
}}
public void deleteClaim(Claim removeclaim){
claimList.remove(removeclaim);
notifyListeners();
}
public static boolean isEmpty(){
return claimList.size()== 0;
}
public void notifyListeners(){
for (Listener listener: listeners){
listener.update();
}
}
public void addListener(Listener l){
listeners.add(l);
}
public void removeListener(Listener l){
listeners.remove(l);
}
}
if you need any more information let me know, but I really need to solve this problem
Here is the CLaim object code:
package app.zioueche_travelexpense;
import java.io.Serializable;
import java.util.Date;
import java.util.ArrayList;
public class Claim implements Serializable{
/**
* Student serialized ID
*/
private static final long serialVersionUID = 3325687864575767244L;
private String Name;
private ArrayList<Expense> expenseList;
static Date sdate;
private Date edate;
private String status;
//Claim object constructor NEED TO ADD STATUS
public Claim(String Name, Date sdate2, Date edate2){
this.Name = Name;
this.expenseList = new ArrayList<Expense>();
this.sdate = sdate2;
this.edate = edate2;
//this.status = status;
}
//get the claim name
public String getName(){
return this.Name;
}
//add an expense to the claim's expense list
public void addExpense(Expense expense){
expenseList.add(expense);
}
//change the name to a string.
public String toString(){
return getName();
}
//return the status of the string
public String getStatus(){
return status;
}
//get the start date of the claim
public Date getSDate(){
return sdate;
}
//get the end date of the claim
public Date getEDate(){
return edate;
}
//change the status of the Claim.
public void editStatus(String status){
this.status = status;
}
public boolean equal(Object compareClaim){
if (compareClaim != null && compareClaim.getClass()==this.getClass()){
return this.equals((Claim) compareClaim);
}else{
return false;
}
}
public int hashCode(){
return ("Claim"+getName()).hashCode();
}
//return the expenses list of the Claim
public ArrayList<Expense> getExpenses() {
// TODO Auto-generated method stub
return expenseList;
}
}
and then the Controller and ClaimsList:
package app.zioueche_travelexpense;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
public class ClaimListController {
private static ClaimsList claimList = null;
static public ClaimsList getClaimList(){
if (claimList == null){
claimList = new ClaimsList();
}
return claimList;
}
public void addClaim(Claim claim){
getClaimList().addClaim(claim);
}
}
package app.zioueche_travelexpense;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import android.text.InputFilter.LengthFilter;
import android.widget.Toast;
public class ClaimsList implements Serial
izable{
/**
* Claim List Serialization ID
*/
private static final long serialVersionUID = 372301924739907840L;
protected static ArrayList<Claim> claimList;
protected ArrayList<Listener> listeners;
public ClaimsList(){
claimList = new ArrayList<Claim>();
listeners = new ArrayList<Listener>();
}
public Collection<Claim> getClaim(){
return claimList;
}
public void addClaim(Claim string){
claimList.add(string);
if (claimList.size() > 1){
Collections.sort(claimList, new CustomComparator());
notifyListeners();
}else{
notifyListeners();
}}
public void deleteClaim(Claim removeclaim){
claimList.remove(removeclaim);
notifyListeners();
}
public static boolean isEmpty(){
return claimList.size()== 0;
}
public void notifyListeners(){
for (Listener listener: listeners){
listener.update();
}
}
public void addListener(Listener l){
listeners.add(l);
}
public void removeListener(Listener l){
listeners.remove(l);
}
}
here is the claim List adapter:
ListView listView = (ListView) findViewById(R.id.claimListView);
Collection<Claim> claims = ClaimListController.getClaimList().getClaim();
final ArrayList<Claim> list = new ArrayList<Claim>(claims);
final ArrayAdapter<Claim> claimAdapter = new ArrayAdapter<Claim>(this, android.R.layout.simple_list_item_1, list);
listView.setAdapter(claimAdapter);
You sort your list only when it has 0 size
Change this condition
if (claimList.size() < 1)
to
if (claimList.size() > 1)
Additionally you have to call the notifyDataSetChanged() method on your adapter to refresh list.
There's ugly XML file that has to be unmarshalled:
<?xml version="1.0" ?>
<configuration>
<section name="default_options">
<value name="default_port">8081</value>
<value name="log_level">WARNING</value>
</section>
<section name="custom_options">
<value name="memory">64M</value>
<value name="compatibility">yes</value>
</section>
</configuration>
Resulting Java Objects should be:
public class DefaultOptions {
private int defaultPort;
private String logLevel;
// etc...
}
public class CustomOptions {
private String memory;
private String compatibility;
// etc...
}
This question's answer is very close but I can't figure out the final solution.
How about?
Introduce a common super class called Options:
import javax.xml.bind.annotation.XmlAttribute;
public abstract class Options {
private String name;
#XmlAttribute
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Then on your class with the list of options (Configuration in this example), specify an #XmlJavaTypeAdapter on that property:
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
#XmlRootElement
public class Configuration {
private List<Options> section = new ArrayList<Options>();
#XmlJavaTypeAdapter(OptionsAdapter.class)
public List<Options> getSection() {
return section;
}
public void setSection(List<Options> section) {
this.section = section;
}
}
The XmlAdapter will look something like this:
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class OptionsAdapter extends XmlAdapter<AdaptedOptions, Options> {
#Override
public Options unmarshal(AdaptedOptions v) throws Exception {
if("default_options".equals(v.name)) {
DefaultOptions options = new DefaultOptions();
options.setName(v.getName());
options.setDefaultPort(Integer.valueOf(v.map.get("default_port")));
options.setLogLevel(v.map.get("log_level"));
return options;
} else {
CustomOptions options = new CustomOptions();
options.setName(v.getName());
options.setCompatibility(v.map.get("compatibility"));
options.setMemory(v.map.get("memory"));
return options;
}
}
#Override
public AdaptedOptions marshal(Options v) throws Exception {
AdaptedOptions adaptedOptions = new AdaptedOptions();
adaptedOptions.setName(v.getName());
if(DefaultOptions.class == v.getClass()) {
DefaultOptions options = (DefaultOptions) v;
adaptedOptions.map.put("default_port", String.valueOf(options.getDefaultPort()));
adaptedOptions.map.put("log_level", options.getLogLevel());
} else {
CustomOptions options = (CustomOptions) v;
adaptedOptions.map.put("compatibility", options.getCompatibility());
adaptedOptions.map.put("memory", options.getMemory());
}
return adaptedOptions;
}
}
AdaptedOptions looks like:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlValue;
public class AdaptedOptions extends Options {
#XmlAttribute String name;
#XmlElement List<Value> value = new ArrayList<Value>();
Map<String, String> map = new HashMap<String, String>();
public void beforeMarshal(Marshaller marshaller) {
for(Entry<String, String> entry : map.entrySet()) {
Value aValue = new Value();
aValue.name = entry.getKey();
aValue.value = entry.getValue();
value.add(aValue);
}
}
public void afterUnmarshal(Unmarshaller unmarshaller, Object parent) {
for(Value aValue : value) {
map.put(aValue.name, aValue.value);
}
}
private static class Value {
#XmlAttribute String name;
#XmlValue String value;
}
}
You may create a separate classes to represent structure of your XML:
public class Section {
#XmlAttribute
public String name;
#XmlElement(name = "value")
public List<Value> values;
}
public class Value {
#XmlAttribute
public String name;
#XmlValue
public String value;
}
and then use an XmlAdapter to perform conversion:
public class OptionsAdapter extends XmlAdapter<Section, Options> {
public Options unmarshal(Section s) {
if ("default_options".equals(s.name)) {
...
} else if (...) {
...
}
...
}
...
}
#XmlElement
public class Configuration {
#XmlElement(name = "section")
#XmlJavaTypeAdapter(OptionsAdapter.class)
public List<Options> options;
}
public class DefaultOptions extends Options { ... }
public class CustomOptions extends Options { ... }