I have a POJO class like this:
public class EsigObjectWithDisplayName {
private String objectCode;
private String objectDisplayName;
public EsigObjectWithDisplayName(Locale loc, String objectCode, String objectLocaleCode) {
this.objectCode = objectCode;
this.objectDisplayName = Res.s(loc, objectLocaleCode);
}
public EsigObjectWithDisplayName(){}
public String getObjectCode() {
return objectCode;
}
public String getObjectDisplayName() {
return objectDisplayName;
}
}
and a AS class like this:
package ...
{
[Bindable]
[RemoteClass(alias="...EsigObjectWithDisplayName")]
public class EsigObjectWithDisplayName
{
public var objectCode:String;
public var objectDisplayName:String;
public function toString():String {
return objectDisplayName;
}
}
}
The only way this gets populated is when i modify POJO fields' access to public.
I was under impression that defining public POJO accessors is all that BlazeDS needs for deserialization. What am missing here?
You need both a getter and a setter, see this link:
For Java objects that BlazeDS does not handle implicitly, values found
in public bean properties with get/set methods and public variables
are sent to the client as properties on an Object.
Related
I really feel like there must be a way around this.
Imagine I have a large number of objects as components of an owner class. I want to offer easy access to the clients of this owner class to its members, so I make all those objects public. Each of those objects also have all their members public. But one member of the components should not be accessible to the clients of their owner, only by their owner itself:
public class ComponentObject
{
public int int_field;
public float float_field;
public Object object_field;
public Object public_method1()
{
//something;
}
public Object public_method2()
{
//something;
}
public Object restricted_to_owner_only()
{
//something;
}
}
//all clients of Owner should be able to access all the members of its components, except
//restricted_to_owner_only, which only Owner should be able to access
public class Owner
{
public ComponentObject component1;
public ComponentObject component2;
public ComponentObject component3;
//... lots of others
public ComponentObject component300;
}
Is there a way to achieve this? Note that any class from any package can own a ComponentObject, so using package level visibility at restricted_to_owner_only doesn't seem to be an option. ComponentObject is like a utility class, reusable in other applications.
Maybe there's an annotation that enforces that at compile time in some nice lib out there?
EDIT: I forgot to mention that ComponentObject is a parameterized type in real life, and each field in Owner is parameterized differently. I tried to abstract off the details so we could focus on the design problem itself, but I abstracted too much. I will post bellow something more similar to the real problem:
public class ComponentObject<T>
{
public int int_field;
public float float_field;
public T object_field;
//any method could return T or take T as an argument.
public T public_method1()
{
//something;
}
public Object public_method2()
{
//something;
}
public Object restricted_to_owner_only()
{
//something;
}
}
//all clients of Owner should be able to access all the members of its components, except
//restricted_to_owner_only, which only Owner should be able to access
public class Owner
{
public ComponentObject<String> component1;
public ComponentObject<File> component2;
public ComponentObject<Consumer<Boolean>> component3;
//... lots of others
public ComponentObject<Integer> component300;
}
EDIT 2 (Possibly a solution): Guys, inspired by Romeo and Juliet's love, I wrote this solution, can you spot any faults with it? Or would it work as I intended?
//add this class
public class OwnershipToken
{
private static int id_gen = 0;
public final int id = id_gen++;
#Override
public boolean equals(Object obj)
{
return (obj instanceof OwnershipToken) && ((OwnershipToken)obj).id == id;
}
#Override
public int hashCode()
{
return id;
}
}
//Then change this in ComponentObject<T>:
public class ComponentObject<T>
{
//add this field:
private final OwnershipToken ownershipToken;
//add this constructor
public ComponentObject(OwnershipToken onwershipToken)
{
this.ownershipToken = ownershipToken;
}
//change restricted_to_owner_only signature:
public Object restricted_to_owner_only(OwnershipToken ownershipToken)
{
//add this condition
if(this.ownershipToken.equals(ownershipToken)
//something;
}
}
//finally, Owner gains a field:
public class Owner
{
private final OwnershipToken ownershipToken = new OwnershipToken();
//... etc, remainder of the class
}
would this work as intended?
I understand what you want and that is impossible i think.
But, there is still one way to do it!
Make an id in the owner class:
private int id = new Random().nextInt(10000);
In ComponentObject:
private id;
public ComponentObject(int id){
this.id = id;
}
public Object restricted(int id){
if(this.id != id)
return null;
else
return object;
}
In owner:
private ComponentObject<String> string;
public Owner() {
string = new ComponentObject<>(id);
string.restricted(id);
//if the id is right it will return the restricted object, if not i will
//return null
}
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
Having the get set model:
public class exampleclass
{
private Something something;
public Something getSomething()
{
return something;
}
public void setSomething(Something st)
{
something = st;
}
}
I wanna make something like this:
public class exampleclass
{
public Something something;
public void setSomething(Something st)
{
something = st;
}
}
But i want to have "something" var with readOnly feature out of the class (but rewritable in the own class). Any idea of how to do this for an optimized access. (Think this is gonna be used in android , but using a pure java only framework (libgdx) )
You can set thoose things in constructor and expose public final field:
public class ExampleClass
{
public final Something something;
public ExampleClass(Something st)
{
something = st;
}
}
You could use the final keyword.
The you can assign it once.
e.g
public class Exampleclass
{
public final Something something;
void Exampleclass(Something init) {
this.something = init;
}
}
However the content of Something still could be changed, so you may consider returning a clone() of something. (see the class java.util.Date, you still could set the timestamp, in such cases only clone() or a copy constructor helps) . But if your code is not a public lib, then you can leav that getter with clone() away
public class Exampleclass
{
private Something something;
void Exampleclass(Something init) {
this.something = init;
}
void Something getSomething() {
return something.clone();
}
}
But that depends on Something.
Another soultion is a Factory Pattern, such that only the Factory can create Something.
Then there is no public constructor in Something. Only the factory can create it.
public class Something() {
private int value;
protectectd Something(int value) {
this.value = value;
}
public tostring() {
System.out.println("values = " + value);
}
}
public class SomethingFactory() {
protected static Someting createSomething(int value) {
return new Something(value);
}
}
USage:
Something some = SomethingFactory.createSomething(3);
But read more by search "java Deisgn Patterns Factory" or FactoryPattern
I guess your issue is escaping reference, if you want to save your object while returning, send a copy of reference, you can send cloned object using clone method.
public Something getSomething()
{
return something.clone();
}
This will return object shallow copy, if you want make deep cloning override the clone() method Hope this will help..
public void test(Object obj){
//Here i have to set the values of the obj using its setter .
}
Test can be invoked with two objects as parameter. EG: test(standalone) and test(webapp), where standalone and webapp are beans.
public class standalone{
int version;
//setter and getter
}
public class Webapp{
String version;
//setter and getter
}
This test method has to set the values accordin to the parameter object.
Eg: IF i pass standalone as param. standalone's setter method shd be called. How to achieve this?
Note : Without using interface. How to do this?
Thanks.
public static void setVersion(Object obj, int v) throws Exception {
for (Method m : obj.getClass().getMethods()) {
final Class<?>[] t = m.getParameterTypes();
if (m.getName().equals("setVersion") && t.length == 1)
m.invoke(obj, t[0] == String.class? String.valueOf(v) : v);
break;
}
}
You could make both StandAlone and WebApp implement an interface, eg
interface VersionSettable {
void setVersion(int version);
}
public class Standalone implements VersionSettable{
int version;
//setter and getter
}
public class Webapp implements VersionSettable{
int version;
//setter and getter
}
public void test(VersionSettable versionSettable){
versionSettable.setVersion(42);
}
In the simpliest way you could do like this:
public void test(Object obj) {
if( obj instanceof Standalone ) {
((Standalone)obj).setVersion(1);
} else if (obj instanceof WebApp ) {
((WebApp)obj).setVersion(1);
}
}
Try to avoid use of reflection to achieve this because it will make refactoring tasks really hard. The same would be applied to compare the class name with a string.
If you want something more elegant you could do something like this:
public class abstract AbstractEnv {
int version = 0;
// setters and getters
}
public class Standalone extends AbstractEnv{
}
public class Webapp extends AbstractEnv{
}
with this approach you can configure it like this:
public void test(AbstractEnv obj) {
obj.setVersion(1);
}
Both of your classes should implement an interface like VersionSettable. Which declares the method setVersion(int version).
public class standalone implements VersionSettable {
int version;
//setter and getter
}
public class Webapp implements VersionSettable {
int version;
//setter and getter
}
interface VersionSettable {
setVersion(int version);
}
Then you can change your test method to this:
public void test(VersionSettable obj){
obj.setVersion(17);
}
I think would be best if you use inheritance in this case, because (as far as I can get it)
both Standalone and WebApp are Applications.
So you can define a top class "Application" and both StandaloneApp and WebApp extend it, because an "is a" relationship could be defined.
Skeleton code:
define class Application
define class StandaloneApp extends Application, implements method setVersion(int)
define class WebApp extends Application, implements method setVersion(int)
define test method, which accepts "Application" obj in the arguments
Also you can apply any of the interface solutions, presented above.
You can simply do this:
interface SetVersion{
void setVersion(int version);
}
class Standalone implements SetVersion{}
class WebApp implements SetVersion{}
public void test(SetVersion version){
version.setVersion(1);
}
Or the simplest way would be to use .instanceOf
if(obj.instanceOf(Standalone)){
}
I've a base class with a property that should be set in the derived class. I've to use annotations. How's that possible?
I know how do this with xml spring configurations, but not with annotations, because I've to write them at the property?
Here's some example code:
public class Base {
// This property should be set
private String ultimateProperty;
// ....
}
public class Hi extends Base {
// ultimate property should be "Hi" in this class
// ...
}
public class Bye extends Base {
// ultimate property should be "Bye" in this class
// ...
}
How is this possible with annotations?
Some options depending on what else Base has:
class Base {
private String ultimateProperty;
Base() {
}
Base(String ultimateProperty) {
this.ultimateProperty = ultimateProperty;
}
public void setUltimateProperty(String ultimateProperty) {
this.ultimateProperty = ultimateProperty;
}
}
class Hi extends Base {
#Value("Hi")
public void setUltimateProperty(String ultimateProperty) {
super.setUltimateProperty(ultimateProperty);
}
}
class Bye extends Base {
public Bye(#Value("Bye") String ultimateProperty) {
setUltimateProperty(ultimateProperty);
}
}
class Later extends Base {
public Later(#Value("Later") String ultimateProperty) {
super(ultimateProperty);
}
}
class AndAgain extends Base {
#Value("AndAgain")
private String notQuiteUltimate;
#PostConstruct
public void doStuff() {
super.setUltimateProperty(notQuiteUltimate);
}
}
Of course, if you really just want the name of the class there, then
class SmarterBase {
private String ultimateProperty = getClass().getSimpleName();
}
Annotations for fields are linked directly to the source code in the class. You may be able to do what you are looking for via Spring EL with-in an #Value annotation, but I think the complexity overrides the value.
A pattern you may want to consider is using #Configuration annotation to programmatically setup your application context. That way you can define what is injected into the base class.