Not possible to create List of inner class with jackson - java

Is it not possible to create a list with an inner class with Jackson? The external class Tradables will work perfectly. But the inner class Underlyings will not work (Same of course if I make Tradables an inner class).
Is there a way to solve this without making every class that belong to an array of json objects be in it's own class?
Also it does not matter if the JsonProperty is above the set method. Any inner class that is not part of an array will also work.
private String sector_group;
#JsonProperty("underlyings")
private List<Underlyings> listUnderlyings;
#JsonProperty("tradables")
private List<Tradables> listTradables;
public class Underlyings {
private long instrument_id;
private String symbol;
private String isin_code;
public long getInstrument_id() {
return instrument_id;
}
public void setInstrument_id(long instrument_id) {
this.instrument_id = instrument_id;
}
public String getSymbol() {
return symbol;
}
public void setSymbol(String symbol) {
this.symbol = symbol;
}
public String getIsin_code() {
return isin_code;
}
public void setIsin_code(String isin_code) {
this.isin_code = isin_code;
}
}
Mapping method
ObjectMapper mapper = new ObjectMapper();
try {
String json = RestLogin.getBaseResource()
.path("instruments").path("lookup").path("market_id_identifier").path(market_id + ":" + identifier)
.request(RestLogin.getResponsetype()).get(String.class);
List<Instrument> tmpInstruments = mapper.readValue(json, mapper.getTypeFactory().constructCollectionType(List.class, Instrument.class));

Jackson and Inner Classes: yes, you can use, but they must be STATIC inner classes
Here's a snippet (but you should read the entire article for more explanation).
If you do not add static, resulting class is generally useless for Jackson as well as any other data binding framework (Hibernate, JAXB); can often be serialized, but never serialized into

Related

Java constructor use parameter to create new list

New to Java. I'm trying to create a class to convert to JSON string to send as POST request using GSON. This class was created within a public class Called BertClient:
private class BertJsonRequest {
private Integer id;
private List<String> texts;
public BertJsonRequest(int x, String text) {
this.id = x;
this.texts = new ArrayList<>();
this.texts.add(text);
}
}
How I use that:
BertJsonRequest rawRequestBody = new BertJsonRequest(1, text);
Gson gsonToJson = new Gson();
String requestBody = gsonToJson.toJson(rawRequestBody);
For the line where I'm creating new BertJsonRequest My IDE tells me that BertClient.this cannot be referenced from a static content.
I wonder what that means.
Am I building the constructor correctly?
I think I'm not. I just want to be able to pass in a String so that constructor can create a List of String using that String.
Your class access modifier is set to private. Try setting the access modifier to public instead.
public class BertJsonRequest {
private Integer id;
private List<String> texts = new ArrayList<>();
public BertJsonRequest(int x, String text) {
id = x;
texts.add(text);
}
}
What I understood by reading your comments on other's answers was, that your BertClientRequest probably is an inner class.
In case it really is an inner class, and you try to call it in a static method of your containing class, it becomes apparent that you cannot instantiate your inner class as that inner class is not static.
public class BertClient {
private class BertClientRequest {
/* some code */
}
static void aStaticMethod() {
// ...
// Inner class BertClientRequest is unknown to your static method as it is not static,
// thus giving you a compile time error
BertClientRequest rawRequest = new BertClientRequest(1, text);
// ...
}
}
The fix would be in this case to change your inner class to static:
private static class BertClientRequest
I guess your BertJsonRequest is a inner class of BertClient. You can't instantiate BertJsonRequest outside of BertClient. You can make BertJsonRequest class static for this to work.

Creating Constants For Use In Annotation Fields

I'm incorporating cache in an existing spring project using Spring annotations. I have created this class for storing cache configuration -
public class CacheParams {
public final String name;
public final int lifeTime;
public final TimeUnit lifeTimeUnit;
public final String key;
public CacheParams(args here) {/*implementation here*/}
}
and this is how I intend to use it -
class FooDaoCache extends FooDaoImpl {
private static final CacheParam USER_BY_ID_CACHE = new CacheParams(values here);
#Override
#Cacheable(cacheNames = USER_BY_ID_CACHE.name, key = USER_BY_ID_CACHE.key)
public User getUser(int userId) {
implementation here
}
}
But this does not work as USER_BY_ID_CACHE will be created on compile time. If I simply create a string constant containing cache name I can successfully use it -
class FooDaoCache extends FooDaoImpl {
private static final String CACHE_NAME = "baz";
#Override
#Cacheable(cacheNames = CACHE_NAME)
public User getUser(int userId) {
//implementation here
}
}
Is there any way to deal with this or an alternate design? I need the class CacheParams because I have to perform other operations using cache name, lifetime etc in other parts of code too.
CacheParam needs to be an enum or the name field needs to be a static final String.
Annotation return types may only be primitive types, enums, Strings, classes and arrays of these.

Understanding generics and reflection

I need some help with generics and reflection in java.
What I try to achieve is a factory class that based on a class MyClass returns another class MyClassStore that implements an interface Store<MyClass>.
How can I make sure that the right type of store is returned with reflection.
See sample code:
public class Application {
public static void main(String[] args) {
Store<MyClass> store = Factory.getFactory(MyClass.class);
MyClass myClass = store.get();
System.out.println(myClass.getId());
}
}
public class Factory {
public static <T> Store<T> getFactory(Class<T> type) {
Store<T> store = null;
// TODO: How to implement this
return store;
}
}
public class MyClassStore implements Store<MyClass>{
public MyClass get() {
return new MyClass("1000");
}
}
public interface Store<T> {
public T get();
}
public class MyClass {
private String id;
public MyClass(String id) {
this.id = id;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
I have tried different ways but can't get it to work the way I want. This is the implementation I have tried. But is there a better way?
public static <T> Store<T> getFactory(Class<T> type) {
Store<T> store = null;
if (type == MyClass.class) {
store = (Store<T>) new MyClassStore();
}
return store;
}
Just taking the problem as stated, the best solution I can come up with is to have a static final Map<Class, Class> in the Factory that maps (in this example) from MyClass.class to MyClassStore.class, use it to look up which class to instantiate, and call newInstance() on the Class retrieved from the map.
Taking a bit more liberty with your design, you could replace MyClassStore with a more general generic class that takes a Class<T> parameter, stores it locally, and implements get() with a call to newInstance() on the stored Class. getFactory() could then simply make a generic store regardless and pass the Class object on.
However, this type of code strikes me as unlikely to be a good solution to whatever your real problem is. Why does MyClassStore need to create new MyClass objects? Why does the internal logic of any implementation of Store need to care about what type T actually is? That latter question in particular is usually a strong indicator of poor design in my opinion.

Determine which subclass to choose by accessing static variables from the Class object

I am trying to implement an interface in Java to use different types of databases for one application.
My though was to create an abstract class with the common interface and two static variables which are then overwritten by the subclasses. I then wanted to add a Class[] List with the classes of all available subclasses to the abstract class as well as a couple of functions that allow the determination of the correct class to be used.
The goal is to first get a list of all available database types and let the user choose one. Afterwards another function should translate the name (which could be localized) to the IDENTIFIER which is specified in the subclass. Finally a third function allows the instantiation of an object by giving such an IDENTIFIER.
My abstract class would look something like this:
public abstract class DataBase {
public static final IDENTIFIER = "";
public static final NAME = "";
private static final Class[] dbTypes = new Class[]{PostgreSQL.class, MySQL.class};
public static String[] getNameList() {
String[] names = new String[dbTypes.length];
for(int i = 0; i < dbTypes.length; i++){
names[i] = dbTypes[i].NAME; //Cannot access the static variable this way.
}
return names;
}
public static String getIdentifierForName(String name) {
for(int i = 0; i < dbTypes.length; i++){
if(name.equals(dbTypes[i].NAME){
return dbTypes[i].IDENTIFIER;
}
}
return "";
}
public static DataBase getInstanceOf(String identifier) {
for(int i = 0; i < dbTypes.length; i++){
if(identifier.equals(dbTypes[i].IDENTIFIER) {
return dbTypes[i].newInstance();
}
}
return null;
}
}
The Child classes would look something like this:
public class MySQL extends DataBase {
public static final IDENTIFIER = "ab.cde.MySQL";
public static final NAME = "MySQL";
...
}
public class PostgreSQL extends DataBase{
public static final IDENTIFIER = "ab.cde.PostgreSQL";
public static final NAME = "PostgreSQL";
...
}
My problem now is, that I cannot access the static variables from the Class object. Obviously the dbTypes list does not contain any typed classes. I tried changing the type of the Array to Class<? extends DataBase>, but I get an error Cannot create a generic array of Class<? extends DataBase> I also tried checking the classes with isAssignableFrom() and then casting the class, but I was still not able to access the static variables.
For now I have two solutions which are working:
Hardcode all existing subclasses into each function if(PostgreSQL.NAME.equals(name)){...}etc.
However, if I add new subclasses, I only want to have to add them at one point in my implementation.
Instead of using a Class[] array, I can use an array of DataBase[] with instances of each class. However, I would think this is bad practice to instantiate each available DataBase subclass, even though I only need one in the end.
Since I have never done such a thing before I might also be approaching the problem completely wrong. Maybe I am missing the correct way in which something like this is usually done?
Thank you for your help.
There are no "abstract properties" in Java. You have to create two astract methods in the DataBase class, like this:
public abstract class DataBase {
// No "abstract propeties"
public abstract String getDBName();
public abstract String getDBIdentifier();
// etc etc...
}
and then, in each subclass:
public class MySQL extends DataBase {
public static final IDENTIFIER = "ab.cde.MySQL";
public static final NAME = "MySQL";
#Override
public String getDBName() {
return NAME;
}
#Override
public String getDBIdentifier() {
return IDENTIFIER;
}
// etc etc...
}
When using the classes, you can just cast to DataBase (not MySQL or PostgreSQL) and call the two abstract methods.
Therefore, in order to solve your "pick a database class" problem, I would create a configuration file that contains the names of the databases and the corresponding class, and instantiate it with reflection (newInstance()) as needed.
As an alternative, you can use reflection to access the static variables like Nikita's answers suggested, or you can just use the name of the class as the identifier of the database it supports, like this (not tested):
public abstract class DataBase {
private static final Class[] dbTypes = new Class[]{PostgreSQL.class, MySQL.class};
public static Class getDBClass(String type) {
for (Class c : dbTypes) {
if (c.getSimpleName().toLowerCase().equals(type.toLowerCase())) {
return c;
}
}
return null;
}
public static Set<String> getSupportedDB() { // <-- you populate a dropdown menu with this
Set<String> supported = new HashSet<String>();
for (Class c : dbTypes) {
supported.add(c.getSimpleName());
}
return supported;
}
// etc etc...
}
However, I don't like this solution and I would not use it.
You can use reflection to get values for each class:
public static String[] getNameList(){
String[] names = new String[dbTypes.length];
for(int i=0; i<dbTypes.length; i++){
Field f = dbTypes[i].getField("NAME");
names[i] = f.get(null);
}
return names;
}
But it might be slow.
Also I'd suggest to create separate enum DBRegistry that will contain names, identifiers and classes:
public enum DBRegistry {
MYSQL("ab.cde.MySQL", "MySQL", MySQL.class),
POSTGRESQL("ab.cde.PostgreSQL", "PostgreSQL", PostgreSQL.class);
private String name;
private String identifier;
private Class<?> dbClass;
private DBRegistry(String identifier, String name, Class<?> dbClass) {
this.identifier = identifier;
this.name = name;
this.dbClass = dbClass;
}
// Getters...
}
You can iterate on all items in registry using DBRegistry.values
Not tested, but I would suggest something like this. You could register databases by calling DataBase.registerDataBase(new DataBase(...))); which may be invoked from the main file.
public class DataBase {
private final static List<DataBase> INSTANCES = new ArrayList<DataBase>();
private final String identifier;
private final String name;
private final Class<?> dbType;
public DataBase(String identifier, String name, Class<?> dbType) {
this.identifier=identifier.toString();
this.name=name.toString();
this.dbType=dbType;
}
String getIdentifier() {return identifier;}
String getName() {return identifier;}
Class<?> getDbType() {return dbtype;}
public synchronized static void registerDatabase(DataBase database) {
database.getClass();
INSTANCES.add(database);
//may check if already registered and either fail or replace it
}
public synchronized static List<DataBase> getNameList() {
return new ArrayList<DataBase>(INSTANCES);
}
public synchronized static List<String> getNameList() {
List<String> names = new ArrayList<String>(INSTANCES.size());
for (Database db:INSTANCES) names.add(db.getName());
return names;
}
public synchronized static String getIdentifierForName(String name) {
for(DataBase db:INSTANCES){
if(name.equals(db.getName())) return db;
}
return null;
}
public synchronized static DataBase getInstanceOf(String identifier) {
for(DataBase db:INSTANCES){
if(identifier.equals(db.getIdentifier())) return db;
}
return null;
}
}
}
I would advise to keep it simple, never more than necessary to utilize in the actual application. It is easier to extend things than to re-factor code to accomodate for additional complexity. Most of the stuff you mention are merely artefacts of your problem solving, not the actual requirements of your application per se. And it so happens, that a modern object-oriented language has everything you need, and you can implement a good design without reflection and without resorting to static properties and string identifiers.
Remember to rely on the compiler rather than runtime for whatever you know in advance - anything that is known not to change from one application run to another, does not need reflection, because it does not involve runtime variables! I would go for interfaces, classes implementing them, and more importantly the Factory pattern to abstract using these classes:
interface Database
{
void query(String sqlString);
}
class MySQLDatabase implements Database
{
public void query(String sqlString)
{
}
}
class PostgreSQLDatabase implements Database
{
public void query(String sqlString)
{
}
}
class DatabaseFactory
{
Database connectDatabase()
{
/// F.e. return new MySQLDatabase();
}
}
The whole "database abstraction layer" has been done to death already anyway, giving birth to DBA, ODBC and other software stacks that solve your problem. You should let yourself be inspired by these, unless you are sure your particular way of solving this yields advantages that can be proven. If you want to go about this in a professional way, of course. If you want to educate yourself, by all means, use reflection, strings in place of more specific objects, and tight-coupling instead of aggressive modularity.

Usage of inner class

I can understand what inner class is and how to write program. My question is in what situation do programmers really need inner class?
Sometimes there is some functionality which is best represented as an object, but which is only meaningful within the context of another object, which does not necessarily need to be exposed to the outside world, and which can benefit from having access to the parent classes data (so as to not violate encapsulation).
The best example that I can think of is putting a Node class inside of a LinkedList. Nodes are only meaningful to the LinkedList, so they only exist within one. No one outside of the LinkedList cares about nodes or should have access to them.
An inner class allows us to remove that logic and place it into its own class. So from an object-oriented point of view, we've taken functionality out of where it doesn't belong and have put it into its own class.
Please go through this link....
http://www.javaworld.com/javaworld/javaqa/2000-03/02-qa-innerclass.html
Also as you know in Java exists nested classes, which is static inner clasess.
From previous posts becomes clear when we need to use an inner class but I think you also interested in the question "Why we need nested classes (static inner class)".
The answer is simply, there is the same purpose as for the inner class except few things.
1) The nested class (static inner) is required when we whant to exclude some logic that concerns another object but this logic might be used in outworld.
The simpliest examples is a builders or editors of some object. For example we have class Foo
which may have a lot of optional fields, to construct such object we may decide to introduce a builder class which will do this work.
public class Foo {
private int param1;
private int param2;
private int param3;
private Foo(FooBuilder builder) {
this.param1 = builder.param1;
this.param2 = builder.param2;
this.param3 = builder.param3;
}
public int getParam1() {
return param1;
}
public void setParam1(int param1) {
this.param1 = param1;
}
public int getParam2() {
return param2;
}
public void setParam2(int param2) {
this.param2 = param2;
}
public int getParam3() {
return param3;
}
public void setParam3(int param3) {
this.param3 = param3;
}
public static class FooBuilder {
private int param1;
private int param2;
private int param3;
public FooBuilder() {
}
public FooBuilder withParameter1(int param1) {
this.param1 = param1;
return this;
}
public FooBuilder withParameter2(int param2) {
this.param2 = param2;
return this;
}
public FooBuilder withParameter3(int param3) {
this.param3 = param3;
return this;
}
public Foo build() {
return new Foo(this);
}
}
}
This example illustrates at leas one reason why we need such classes
2) The second difference between inner and static inner classes is that the first one always has pointer to the parent class. Actully compiler creates synthetic field member for the non static inner class of the type of it's parent, exectly of this reason we can access private members of the parent class. The static inner clasess doesn't has such generated field member. For instance we has just simple parent class with declared non static inner class:
public class Foo {
public class FooBuilder {
}
}
but in fact if take into account the byte code it looks like:
public class Foo {
public class FooBuilder {
private Foo generatedNameHere;
}
}
if you want you can figure out this throught generated byte code.
One of the use of inner class is :
Inner class helps in multiple-inheritance. Inner class allows you to inherit from more than one non-interface.
//first case; can implement if two classes are interface
interface A { }
interface B { }
class X implements A, B { }
//second case; you can extend only one class. This case inner class can help to inherit other class as well
class D { }
abstract class E { }
class Z extends D {
void method() {
return new E() { }; //Anonymous inner class
}
}
When you want to specify a class that has sence only in context with the bounded one.
For example you write a MathOperations class that can execute four operations. So the operations can be represented as inner enum MathOps.
When the inner class is not used anywhere except the inbounded one.
You use anonymous inner classes to specify only the operation, for exmple if you want to sort a collection, you specify a Comparable class just for one method compare.
Collections.sort(employments, new Comparator<Employment>() {
#Override
public int compare(Employment o1, Employment o2) {
return o1.getStartDate().before(o2.getStartDate()) ? 1 : -1 ;
}
});
With inner classes you can access private members of the enclosing class.
They are useful for interface implementations that are only used by the enclosing class (event handlers in a application).
They are useful for providing fine grained access and creation control over an interface implementation that is retrieved externally (maybe something like an Iterator implementation).

Categories