Why is the static value different from appender(log4j custom appender)? - java

I make static variable like this in spring.
public class A {
private static final Map<String, Session> listMap = new HashMap<>();
public static Map<String> getMap() { return this.listMap.values() }
public static void addMap(String name, Session s) { return this.listMap.put(name, s) }
}
I save in service layer.
#Slf4j
public class BService {
public void addSession(String name, Session s) {
A.addMap("a", s);
log.info("added!");
}
}
After saving it, I used it in custom appender.(https://www.baeldung.com/log4j2-custom-appender)
#Plugin(
name = "MapAppender",
category = Core.CATEGORY_NAME,
elementType = Appender.ELEMENT_TYPE)
public class MapAppender extends AbstractAppender {
private ConcurrentMap<String, LogEvent> eventMap = new ConcurrentHashMap<>();
protected MapAppender(String name, Filter filter) {
super(name, filter, null);
}
#PluginFactory
public static MapAppender createAppender(
#PluginAttribute("name") String name,
#PluginElement("Filter") Filter filter) {
return new MapAppender(name, filter);
}
#Override
public void append(LogEvent event) {
Map<> resultMap = A.getMap();
send()
}
}
However, when the appender's append() method is executed, A.getMap() return nothing(size 0). (A.getMap() return correctly in service layer.)
Why is the static value different?..

listMap is loaded when you call addSessionso it is empty When append() method is called

Related

Inject Spring bean into enum and invoke it inside enums functional interface

Well I guess I am trying to achieve more than I can but I wanted to create an aggregator class for all my dictionary values in my application. Therefore I created an enum which would have two arguments - first being dictionary name and second being the Supplier. I went for Supplier because supplied value will be calculated for each dictionary differently. So far I came up with this:
public enum DictionaryAggregator {
STATUS_X("statusX", StatusX::getDictionary),
STATUS_Y("statusY", new Supplier<Map<String, ?>>() {
#Override
public Map<String, ?> get() {
return <would like to reference to statusYCache which is inside DictionaryAggregatorServiceInjector>;
}
});
private final String dictionaryName;
private final Supplier<Map<String, ?>> dictionary;
public String getDictionaryName() {
return dictionaryName;
}
public Supplier<Map<String, ?>> getDictionary() {
return dictionary;
}
DictionaryAggregator(String dictionaryName, Supplier<Map<String, ?>> dictionary) {
this.dictionaryName = dictionaryName;
this.dictionary = dictionary;
}
#Component
static class DictionaryAggregatorServiceInjector {
#Autowired
private StatusYService statusYService;
}
}
but whatever I tried I could not come up with an idea how could I supply values from StatusYCache service. Ideally what I would like to achieve is that the Supplier for STATUS_Y could easily invoke methods from StatusYService.
Guess I should use my brain more frequently. I came up with this:
public enum DictionaryAggregator {
STATUS_X("statusX", StatusX::getDictionary),
STATUS_Y("statusY", new Supplier<Map<String, ?>>() {
#Override
public Map<String, ?> get() {
return new StatusYDictionaryClass(DictionaryAggregatorServiceInjector.shipmentStatusVos).getDictionary();
}
});
private final String dictionaryName;
private final Supplier<Map<String, ?>> dictionary;
public String getDictionaryName() {
return dictionaryName;
}
public Supplier<Map<String, ?>> getDictionary() {
return dictionary;
}
DictionaryAggregator(String dictionaryName, Supplier<Map<String, ?>> dictionary) {
this.dictionaryName = dictionaryName;
this.dictionary = dictionary;
}
#Component
static class DictionaryAggregatorServiceInjector {
static List<StatusYObj> statusYList;
#Autowired
public StatusYService statusYService;
#PostConstruct
public void init() {
statusYList = statusYService.getStatusYList();
}
}
}
It seems to be working.

Not able to access InheritableThreadLocal object from parent thread in fall back method

I have InheritableThreadLocal<ConcurrentHashMap<String, Object>> thread that initializes when a request comes via the filter and set some transaction_id in it.
Now at the service layer, I'm calling 10 different API calls via CompletableFuture. All API service class have one execute method that is using RestTempate to make an API call. I put #HystrixCommand on execute method.
execute method is void type but it put the API response in InheritableThreadLocal object.
Problem is when an API call fails Hystrix call FallBackMethod and when I put error response in InheritableThreadLocal, I'm not able to send that error response to the client.
ThreadLocalUtil.class
public class ThreadLocalUtil {
private static InheritableThreadLocal<ConcurrentHashMap<String, Object>> transmittableThreadLocal = new InheritableThreadLocal<>();
public static void addDataToThreadLocalMap(String key, Object value) {
Map<String, Object> existingDataMap = transmittableThreadLocal.get();
if (value != null) {
existingDataMap.put(key, value);
}
}
public static Object getDataFromThreadLocalMap(String key) {
Map<String, Object> existingDataMap = transmittableThreadLocal.get();
return existingDataMap.get(key);
}
public static void clearThreadLocalDataMap() {
if (transmittableThreadLocal != null)
transmittableThreadLocal.remove();
}
public static Object getRequestData(String key) {
Map<String, Object> existingDataMap = transmittableThreadLocal.get();
if (existingDataMap != null) {
return existingDataMap.get(key);
}
return "-1";
}
public static void initThreadLocals() {
ConcurrentHashMap<String, Object> dataForDataMap = new ConcurrentHashMap<String, Object>();
String requestId = "REQUEST_ID_" + System.currentTimeMillis();
dataForDataMap.put("REQUEST_ID", requestId);
transmittableThreadLocal.set(dataForDataMap);
}
}
CommonFilter.class
#Component
#Order(1)
public class CommonFilter extends OncePerRequestFilter {
#Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
try {
ThreadLocalUtil.initThreadLocals();
filterChain.doFilter(request, response);
} catch (Exception e) {
if (e instanceof ServletException) {
throw (ServletException) e;
}
} finally {
ThreadLocalUtil.clearThreadLocalDataMap();
}
}
EmployeeService.class
#Component
public abstract class EmployeeService {
#Autowired
private ThreadLocalUtil threadLocalUtil;
public abstract void getEmployee(int employeeId);
public void fallbackMethod(int employeeid) {
threadLocalUtil.addDataToThreadLocalMap("ErrorResponse", "Fallback response:: No employee details available temporarily");
}
}
EmployeeServiceImpl.class
#Service
public class EmployeeServiceImpl extends EmployeeService {
#HystrixCommand(fallbackMethod = "fallbackMethod", commandProperties = {
#HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "900"),
#HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "10") })
public void getEmployee(int employeeId) {
System.out.println("Getting Employee details for " + employeeId + ", threadLocalUtil : " + threadLocalUtil.getDataFromThreadLocalMap("EMPLOYE_ID"));
String response = restTemplate.exchange("http://localhost:8011/findEmployeeDetails/{employeeid}",
HttpMethod.GET, null, new ParameterizedTypeReference<String>() {
}, employeeId).getBody();
threadLocalUtil.addDataToThreadLocalMap("Response", response);
}
#Autowired
RestTemplate restTemplate;
#Autowired
private ThreadLocalUtil threadLocalUtil;
}
So, first of all since internally Hystrix uses ThreadPoolExecutor (Threads created once and reused), so it is wrong to use InheritableThreadLocal.
From the above question and what you asked in my blog, I understand that you problem is
InheritableThreadLocal becomes null in hystrix fallback method
Further adding to this (you may verify this)
InheritableThreadLocal becomes null in hystrix fallback method only in case of timeouts and not in case of any other exception
I would recommend others to refer to my blog. Hystrix fallback in case of timeout, takes place in hystrix-timer thread.
Hystrix fallback execution thread
You can verify this by logging Thread.currentThread().getName()
Since the parent of hystrix-timer thread is not your calling thread, and so your transmittableThreadLocal.get() becomes null.
To solve this I would recommend using HystrixCommandExecutionHook and HystrixRequestVariableDefault. Using this you can implement hooks like onStart, onExecutionStart, onFallbackStart etc., in which you need to get/set the threadLocal variables. For more details you can refer to the last section in the blog.
Update:
For your use-case you can modify your code as follows:
ThreadLocalUtil.java
public class ThreadLocalUtil {
private static ThreadLocal<ConcurrentHashMap<String, Object>> transmittableThreadLocal = new ThreadLocal<>();
public static ConcurrentHashMap<String, Object> getThreadLocalData() {
return transmittableThreadLocal.get();
}
public static void setThreadLocalData(ConcurrentHashMap<String, Object> data) {
transmittableThreadLocal.set(data);
}
public static void addDataToThreadLocalMap(String key, Object value) {
Map<String, Object> existingDataMap = transmittableThreadLocal.get();
if (value != null) {
existingDataMap.put(key, value);
}
}
public static Object getDataFromThreadLocalMap(String key) {
Map<String, Object> existingDataMap = transmittableThreadLocal.get();
return existingDataMap.get(key);
}
public static void clearThreadLocalDataMap() {
if (transmittableThreadLocal != null)
transmittableThreadLocal.remove();
}
public static Object getRequestData(String key) {
Map<String, Object> existingDataMap = transmittableThreadLocal.get();
if (existingDataMap != null) {
return existingDataMap.get(key);
}
return "-1";
}
public static void initThreadLocals() {
transmittableThreadLocal.set(new ConcurrentHashMap<>());
String requestId = "REQUEST_ID_" + System.currentTimeMillis();
addDataToThreadLocalMap("REQUEST_ID", requestId);
}
}
EmployeeService.java
#Component
public abstract class EmployeeService {
public abstract void getEmployee(int employeeId);
public void fallbackMethod(int employeeid) {
threadLocalUtil.addDataToThreadLocalMap("ErrorResponse", "Fallback response:: No employee details available temporarily");
}
}
EmployeeServiceImpl.java
#Service
public class EmployeeServiceImpl extends EmployeeService {
#HystrixCommand(fallbackMethod = "fallbackMethod", commandProperties = {
#HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "900"),
#HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "10") })
public void getEmployee(int employeeId) {
System.out.println("Getting Employee details for " + employeeId + ", threadLocalUtil : " + threadLocalUtil.getDataFromThreadLocalMap("EMPLOYEE_ID"));
String response = restTemplate.exchange("http://localhost:8011/findEmployeeDetails/{employeeid}",
HttpMethod.GET, null, new ParameterizedTypeReference<String>() {
}, employeeId).getBody();
threadLocalUtil.addDataToThreadLocalMap("Response", response);
}
#Autowired
RestTemplate restTemplate;
}
HystrixHook.java
public class HystrixHook extends HystrixCommandExecutionHook {
private HystrixRequestVariableDefault<ConcurrentHashMap<String, Object>> hrv = new HystrixRequestVariableDefault<>();
#Override
public <T> void onStart(HystrixInvokable<T> commandInstance) {
HystrixRequestContext.initializeContext();
getThreadLocals();
}
#Override
public <T> void onExecutionStart(HystrixInvokable<T> commandInstance) {
setThreadLocals();
}
#Override
public <T> void onFallbackStart(HystrixInvokable<T> commandInstance) {
setThreadLocals();
}
#Override
public <T> void onSuccess(HystrixInvokable<T> commandInstance) {
HystrixRequestContext.getContextForCurrentThread().shutdown();
super.onSuccess(commandInstance);
}
#Override
public <T> Exception onError(HystrixInvokable<T> commandInstance, HystrixRuntimeException.FailureType failureType, Exception e) {
HystrixRequestContext.getContextForCurrentThread().shutdown();
return super.onError(commandInstance, failureType, e);
}
private void getThreadLocals() {
hrv.set(ThreadLocalUtil.getThreadLocalData());
}
private void setThreadLocals() {
ThreadLocalUtil.setThreadLocalData(hrv.get());
}
}
AbcApplication.java
public class AbcApplication {
public static void main(String[] args) {
HystrixPlugins.getInstance().registerCommandExecutionHook(new HystrixHook());
SpringApplication.run(Abc.class, args);
}
}
Hope this helps

Update events from ObjectProperty (just like in ObservableList)

I can use an extractor (Callback<E, Observable[]> extractor) to make a ListProperty fire change events if one of its elements changed one of its properties (update event).
Update Change Event in ObservableList
Is there an equivalent for ObjectProperty<>? I have an SimpleObjectProperty which I want to fire events when properties of it's value (another bean type) change (update change events).
Sample code:
public class TestBean {
public static <T extends TestBean> Callback<T, Observable[]> extractor() {
return (final T o) -> new Observable[] { o.testPropertyProperty() };
}
private final StringProperty testProperty = new SimpleStringProperty();
public final StringProperty testPropertyProperty() {
return this.testProperty;
}
public final String getTestProperty() {
return this.testPropertyProperty().get();
}
public final void setTestProperty(final String testProperty) {
this.testPropertyProperty().set(testProperty);
}
}
public class SomeType {
/**
* How can I listen for changes of TestBean#testProperty?
*/
private final ObjectProperty<TestBean> property = new SimpleObjectProperty<>();
}
I want to receive change events if the value of SomeType#property changes, but also, if SomeType#property#testProperty changes.
I cannot just listen for SomeType#property#testProperty, since I would not be notified when SomeType#property was changed (I would then listen on the wrong object for changes).
I want to receive change events if value of SomeType#property changes, but also, if SomeType#property#testProperty changes.
I cannot just listen for SomeType#property#testProperty, since I would not be notified, when SomeType#property was changed (I would then listen on the wrong object for changes).
This is a limitation of sorts of the current iteration of JavaFX. The built-in way is unreliable and you're better off using 3rd party libraries. See this answer for more information.
For you case, ReactFX can be utilized in a similar way:
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import org.reactfx.value.Val;
import org.reactfx.value.Var;
class TestBean {
private final StringProperty testProperty = new SimpleStringProperty();
public final StringProperty testPropertyProperty() { return testProperty; }
public final String getTestProperty() { return testProperty.get(); }
public final void setTestProperty(String newTestProperty) { testProperty.set(newTestProperty); }
}
public class SomeType {
private final ObjectProperty<TestBean> property = new SimpleObjectProperty<>();
public final ObjectProperty<TestBean> propertyProperty() { return property; }
public final TestBean getProperty() { return property.get(); }
public final void setProperty(TestBean newProperty) { property.set(newProperty); }
public static void main(String[] args) {
SomeType someType = new SomeType();
Var<String> chainedTestProperty = Val.selectVar(someType.propertyProperty(), TestBean::testPropertyProperty);
chainedTestProperty.addListener((obs, oldVal, newVal) -> System.out.println(obs + " " + oldVal + "->" + newVal));
//Tests
someType.setProperty(new TestBean());
someType.getProperty().setTestProperty("s1");
TestBean bean2 = new TestBean();
bean2.setTestProperty("s2");
someType.setProperty(bean2);
someType.setProperty(new TestBean());
}
}
Output:
org.reactfx.value.FlatMappedVar#7aec35a null->s1
org.reactfx.value.FlatMappedVar#7aec35a s1->s2
org.reactfx.value.FlatMappedVar#7aec35a s2->null
The key line
Var<String> chainedTestProperty = Val.selectVar(someType.propertyProperty(), TestBean::testPropertyProperty);
is a sort of listener chaining. The first argument is a property (OvservableValue) of some type Type. The second argument is the "sub"-property of some other type Type2 inside Type, which is given as a function from Type to that property.
Now whenever any "links" in the chain change, you are notified. You can continue to listen to changes in sub-sub-... properties by continuously chaining ovservables this way.
I came up with the following:
public class ObservableValueProperty<T> extends SimpleObjectProperty<T> {
private InvalidationListener listener = null;
private final Callback<T, Observable[]> extractor;
public ObservableValueProperty() {
this(null);
}
public ObservableValueProperty(final Callback<T, Observable[]> extractor) {
this.extractor = extractor;
}
#Override
protected void fireValueChangedEvent() {
super.fireValueChangedEvent();
}
#Override
public void setValue(final T v) {
if (extractor != null) {
final T oldValue = super.get();
if (oldValue != null) {
for (final Observable o : extractor.call(oldValue)) {
o.removeListener(listener);
}
}
listener = o -> fireValueChangedEvent();
for (final Observable o : extractor.call(v)) {
o.addListener(listener);
}
}
super.setValue(v);
}
}
public class ObservableValuePropertyTest4 implements ChangeListener<Object> {
#BeforeClass
public static void setUpBeforeClass() throws Exception {
}
#AfterClass
public static void tearDownAfterClass() throws Exception {
}
#Before
public void setUp() throws Exception {
}
#After
public void tearDown() throws Exception {
}
static class NestedBean {
StringProperty nestedProperty = new SimpleStringProperty("hans");
public static <T extends NestedBean> Callback<T, Observable[]> extractor() {
return (final T o) -> new Observable[] { o.nestedProperty };
}
#Override
public boolean equals(final Object obj) {
if (obj instanceof NestedBean) {
System.err.println(this.nestedProperty.get() + " " + ((NestedBean) obj).nestedProperty.get());
return Objects.equal(this.nestedProperty.get(), ((NestedBean) obj).nestedProperty.get());
}
return false;
}
}
private ObservableValueProperty<NestedBean> p;
private NestedBean nestedBean;
private String newNestedValue = null;
#Test
public void test01() {
p = new ObservableValueProperty<>(NestedBean.extractor());
nestedBean = new NestedBean();
p.setValue(nestedBean);
p.addListener(this);
nestedBean.nestedProperty.set("peter");
assertEquals("peter", newNestedValue);
}
#Override
public void changed(final ObservableValue<? extends Object> observable, final Object oldValue,
final Object newValue) {
System.err.println("Changed");
newNestedValue = nestedBean.nestedProperty.get();
}
}
Unfortunately, this does not fire any change events because of ExpressionHelper$SingleChange:
#Override
protected void fireValueChangedEvent() {
final T oldValue = currentValue;
currentValue = observable.getValue();
final boolean changed = (currentValue == null)? (oldValue != null) : !currentValue.equals(oldValue);
if (changed) {
try {
listener.changed(observable, oldValue, currentValue);
} catch (Exception e) {
Thread.currentThread().getUncaughtExceptionHandler().uncaughtException(Thread.currentThread(), e);
}
}
}
This checks for equality and only if not equal, notifies all listeners. When I trigger fireValueChangedEvent() the value has already changed, and new- and old values are equal, therefore no notification to listeners.
I had the same problem last week, and after many tries, I found a solution that seems to work as expected:
I created a new class called ObjectXProperty<E>, that has the same interface of an ObjectProperty<E>;
It has constructors that can accept a Callback<E,Observable[]>, our extractor function;
Inside the ObjectXProperty, I use a SimpleObjectProperty that deleguates all methods;
The magic trick lies in the set(E value) methods : I create an ObjectBinding that simply send back the value, but it uses the extractor function to decide when it's become invalidated!
This trick will not be applied if the bind method was used previously on the ObjectXProperty, to let the "real" binding do his job; it will work again if the unbind method is called;
Here's my new class ObjectXProperty<E> :
import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.beans.binding.Bindings;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.util.Callback;
/**
*
* #author Claude Bouchard - 2017
*/
public class ObjectXProperty<E> extends ObjectProperty<E> {
SimpleObjectProperty<E> p;
Callback<E, Observable[]> extractor;
boolean externalBound = false;
public ObjectXProperty(Callback<E, Observable[]> extractor) {
this.extractor = extractor;
}
public ObjectXProperty(E init, Callback<E, Observable[]> extractor) {
p = new SimpleObjectProperty();
this.extractor = extractor;
set(init);
}
public ObjectXProperty(Object bean, String name, Callback<E, Observable[]> extractor) {
p = new SimpleObjectProperty(bean, name);
this.extractor = extractor;
}
public ObjectXProperty(Object bean, String name, E init, Callback<E, Observable[]> extractor) {
p = new SimpleObjectProperty(bean, name);
this.extractor = extractor;
set(init);
}
#Override
public void set(E value) {
if (!externalBound) {
if (value != null) {
p.bind(Bindings.createObjectBinding(() -> {
return value;
}, extractor.call(value)));
} else {
p.bind(Bindings.createObjectBinding(() -> {
return value;
}, new Observable[]{}));
}
} else {
p.set(value); //As expected, it will throw a java.lang.RuntimeException
}
}
#Override
public E get() {
return p.get();
}
#Override
public void addListener(ChangeListener<? super E> listener) {
p.addListener(listener);
}
#Override
public void removeListener(ChangeListener<? super E> listener) {
p.removeListener(listener);
}
#Override
public void addListener(InvalidationListener listener) {
p.addListener(listener);
}
#Override
public void removeListener(InvalidationListener listener) {
p.removeListener(listener);
}
#Override
public Object getBean() {
return p.getBean();
}
#Override
public String getName() {
return p.getName();
}
#Override
public void bind(ObservableValue<? extends E> observable) {
p.bind(observable);
externalBound = true;
}
#Override
public void unbind() {
p.unbind();
externalBound = false;
set(get()); //to reactivate the extractor on the last value
}
#Override
public boolean isBound() {
return externalBound;
}
}
I think you need to add a listener to your object. This can be done simply. First of all you should write your class with a constructor and with getters this way:
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
public class SomeType {
public ObjectProperty<TestProperty> property;
public SomeType(TestProperty testProperty) {
this.property = new SimpleObjectProperty<>(testProperty);
}
public TestProperty getProperty() {
return property.get();
}
public ObjectProperty<TestProperty> propertyProperty() {
return property;
}
}
Then anywhere you have an instance of SomeType you can chain the properties, so you get the property the property's testProperty() and then simply add a listener to it.
someType.getProperty().testProperty().addListener((observable, oldValue, newValue) -> {
// Do whatever you want if the its value changed.
// You can also use its old or new value.
});

How to refactor a class with multiple Lists + getters and setters for each list

I have the following class:
public class RefactorMe {
private static List<Event<Apple>> mAppleEventList = new ArrayList<Event<Apple>>();
private static List<Event<Banana>> mBananaEventList = new ArrayList<Event<Banana>>();
private static List<Event<Orange>> mOrangeEventList = new ArrayList<Event<Orange>>();
public static List<Event<Apple>> getAppleList() {
return mAppleEventList;
}
public static List<Event<Banana>> getBananaEventList() {
return mBananaEventList;
}
public static List<Event<Orange> getOrangeList() {
return mOrangeEventList;
}
public static void addAppleEvent(Event<Apple> pEvent) {
mAppleEventList.add(pEvent);
}
public static void addBananaEvent(Event<Banana> pEvent) {
mBananaEventList.add(pEvent);
}
public static void addOrangeEvent(Event<Orange> pEvent) {
mOrangeEventList.add(pEvent);
}
}
I tried refactoring it using the Visitor pattern but could not get it to work because of the generics.. Is there a better way to do this?
Following on #user902383 by using the Map here is a solution for you in Java 7:
public class RefactorMe {
class Event<K> {
public K getNewObject() {
return null;
}
}
private static Map<Class<?>, List<Event<?>>> eventLists = new HashMap<>();
public static <E> List<Event<E>> getEventList(Class<E> clazz) {
return (List) eventLists.get(clazz);
}
public static <E extends Event<E>> void addEvent(Event<E> pEvent) {
Class<E> key = (Class<E>) pEvent.getNewObject().getClass();
List<Event<?>> events = eventLists.get(key);
if (events == null) {
events = new ArrayList<>();
eventLists.put(key, events);
}
events.add(pEvent);
}
}

Robospice Cached Object is Always null

For some reason pulling a cached object back from the cache in Robospice is always null. Is there something I'm doing wrong?
getSpiceManager().execute(cardRequest, Card.class.getName(),
DurationInMillis.ONE_DAY, new CardRequestListener());
Is how it's executed. The spice manager is created as follows:
mSpiceManager = new SpiceManager(JacksonGoogleHttpClientSpiceService.class);
And the card class is as follows:
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonPropertyOrder({
"iosThumbHighRes",
"iosThumb",
"iosLargeHiRes",
"iosLargeHighRes",
"iosLarge"
})
public class Card {
#JsonProperty("iosThumbHighRes")
private String iosThumbHighRes;
#JsonProperty("iosThumb")
private String iosThumb;
#JsonProperty("iosLargeHiRes")
private String iosLargeHiRes;
#JsonProperty("iosLargeHighRes")
private String iosLargeHighRes;
#JsonProperty("iosLarge")
private String iosLarge;
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
#JsonProperty("iosThumbHighRes")
public String getIosThumbHighRes() {
return iosThumbHighRes;
}
#JsonProperty("iosThumbHighRes")
public void setIosThumbHighRes(String iosThumbHighRes) {
this.iosThumbHighRes = iosThumbHighRes;
}
#JsonProperty("iosThumb")
public String getIosThumb() {
return iosThumb;
}
#JsonProperty("iosThumb")
public void setIosThumb(String iosThumb) {
this.iosThumb = iosThumb;
}
#JsonProperty("iosLargeHiRes")
public String getIosLargeHiRes() {
return iosLargeHiRes;
}
#JsonProperty("iosLargeHiRes")
public void setIosLargeHiRes(String iosLargeHiRes) {
this.iosLargeHiRes = iosLargeHiRes;
}
#JsonProperty("iosLargeHighRes")
public String getIosLargeHighRes() {
return iosLargeHighRes;
}
#JsonProperty("iosLargeHighRes")
public void setIosLargeHighRes(String iosLargeHighRes) {
this.iosLargeHighRes = iosLargeHighRes;
}
#JsonProperty("iosLarge")
public String getIosLarge() {
return iosLarge;
}
#JsonProperty("iosLarge")
public void setIosLarge(String iosLarge) {
this.iosLarge = iosLarge;
}
#Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
#Override
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this);
}
#Override
public boolean equals(Object other) {
return EqualsBuilder.reflectionEquals(this, other);
}
#JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
#JsonAnySetter
public void setAdditionalProperties(String name, Object value) {
this.additionalProperties.put(name, value);
}
}
Is there something else I need to set?
Thanks, Graeme
The Google Http Client uses the #Key annotation. You are using Jackson annotation which is not supported by Googe Http Java Client, as it provides an abstraction layer over all serialisation solutions (gson/jackson).

Categories

Resources