just a quick question around Lambda Expressions. I have the following text:
{"hosts":[{"disks":[{"path":"/","space_used":0.608}],"hostname":"host1"},{"disks":[{"path":"/","space_used":0.79},{"path":"/opt","space_used":0.999}],"hostname":"host2"},{"disks":[{"path":"/","space_used":0.107}],"hostname":"host3"}]}
Which I'd like to format the above to each line reading:
{"hostname": "host1", "disks":["Path '/' had utilised 60.8%"]}
{"hostname": "host2", "disks":["Path '/' had utilised 79%", "Path '/opt' had utilised 99.9%"]}
{"hostname": "host3", "disks":["Path '/' had utilised 10.7%"]}
I've tried a few permutations around .stream().map() and then .collect() but somehow I came up short in getting to the output I needed. Any help is much appreciated and apologies if the question is rather n00bish. Thanks.
You could use the Jackson 2 Library to convert your JSON-String to Java objects.
In your concrete case you could e.g. create the following classes:
Disk.java
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonPropertyOrder({"path", "space_used"})
public class Disk implements Serializable {
private final static long serialVersionUID = -6127352847480270783L;
#JsonProperty("path")
private String path;
#JsonProperty("space_used")
private Double spaceUsed;
#JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
#JsonProperty("path")
public String getPath() {
return path;
}
#JsonProperty("path")
public void setPath(String path) {
this.path = path;
}
#JsonProperty("space_used")
public Double getSpaceUsed() {
return spaceUsed;
}
#JsonProperty("space_used")
public void setSpaceUsed(Double spaceUsed) {
this.spaceUsed = spaceUsed;
}
#JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
#JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
}
Host.java
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonPropertyOrder({"disks", "hostname"})
public class Host implements Serializable {
private final static long serialVersionUID = -1972892789688333505L;
#JsonProperty("disks")
private List<Disk> disks = null;
#JsonProperty("hostname")
private String hostname;
#JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
#JsonProperty("disks")
public List<Disk> getDisks() {
return disks;
}
#JsonProperty("disks")
public void setDisks(List<Disk> disks) {
this.disks = disks;
}
#JsonProperty("hostname")
public String getHostname() {
return hostname;
}
#JsonProperty("hostname")
public void setHostname(String hostname) {
this.hostname = hostname;
}
#JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
#JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
}
HostContainer.java
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonPropertyOrder({"hosts"})
public class HostContainer implements Serializable {
private final static long serialVersionUID = 7917934809738573749L;
#JsonProperty("hosts")
private List<Host> hosts = null;
#JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
#JsonProperty("hosts")
public List<Host> getHosts() {
return hosts;
}
#JsonProperty("hosts")
public void setHosts(List<Host> hosts) {
this.hosts = hosts;
}
#JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
#JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
}
Usage:
public void parseMessage() throws IOException {
String msg = "{\"hosts\":[{\"disks\":[{\"path\":\"/\",\"space_used\":0.608}]," +
"\"hostname\":\"host1\"},{\"disks\":[{\"path\":\"/\",\"space_used\":0.79}," +
"{\"path\":\"/opt\",\"space_used\":0.999}],\"hostname\":\"host2\"}," +
"{\"disks\":[{\"path\":\"/\",\"space_used\":0.107}],\"hostname\":\"host3\"}]}";
ObjectMapper mapper = new ObjectMapper();
// This object will contain all the information you need, access it using e.g. getHosts();
HostContainer hostContainer = mapper.readValue(msg, HostContainer.class);
}
Related
I am very novice to Java programming. I am C# developer. I was working on one of the small project where we want to use the redis cache instead of ehcache.
We are using spring.data.redis version 2.2.3.RELEASE and redis.client.jedis version 3.2.0.
Here is my redisconf class which contains RedisTemplate as well:
public class RedisConf {
private String REDIS_HOSTNAME = "localhost";
private int REDIS_PORT = 6379;
protected JedisConnectionFactory jedisConnectionFactory() {
RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration(REDIS_HOSTNAME, REDIS_PORT);
JedisClientConfiguration jedisClientConfiguration = JedisClientConfiguration.builder().usePooling().build();
JedisConnectionFactory factory = new JedisConnectionFactory(configuration,jedisClientConfiguration);
factory.afterPropertiesSet();
return factory;
}
public RedisTemplate<String,Element> redisTemplate() {
final RedisTemplate<String,Element> redisTemplate = new RedisTemplate<String,Element>();
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new GenericToStringSerializer<Object>(Object.class));
redisTemplate.setHashValueSerializer(new JdkSerializationRedisSerializer());
redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
redisTemplate.setConnectionFactory(jedisConnectionFactory());
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}
Here is how instantiate RedisConf class:
RedisConf rf = new RedisConf();
RedisTemplate<String, Element> redisTemplate = rf.redisTemplate();
redisTemplate.getConnectionFactory().getConnection().ping();
cache = new RedisDelegate(redisTemplate);
Here is my RedisDeligate class where I do all my get and put operation:
public class RedisDelegate implements Cache {
private final RedisTemplate<String,Element> redisTemplate;
private final Logger LOGGER = LoggerFactory.getLogger(RedisDelegate.class);
private static String REDIS_KEY = "Redis";
public RedisDelegate(RedisTemplate<String,Element> redisTemplate) {
this.redisTemplate = redisTemplate;
}
#Override
public String getName() {
return "my-redis";
}
#Override
public Object getNativeCache() {
return this.redisTemplate;
}
#Override
public Element get(Object key) {
try {
LOGGER.debug("Key is: {}", key);
Object element = this.redisTemplate.opsForHash().get(REDIS_KEY, key);
LOGGER.debug("element Object is: {}", element);
return (element == null) ? null : (Element) element;
//return (Element) this.redisTemplate.opsForHash().get(REDIS_KEY, key);
} catch (Exception e) {
LOGGER.error(e.getMessage());
}
return null;
}
#Override
public void put(Element element) {
this.redisTemplate.opsForHash().put(REDIS_KEY, element.key(), element);
}
#Override
public void evict(Object key) {
this.redisTemplate.opsForHash().delete(REDIS_KEY, key);
}
#Override
public void clear() {
redisTemplate.execute((RedisCallback<Object>) connection -> {
connection.flushDb();
return null;
});
}
}
Here is CacheElement Object that I am trying to put in the cache which implements Serializable as seen below:
public class CacheElement implements Element, Serializable {
.
.
.
}
When I try to put an object into cache, it fails with an error that serialization failed. I know there is some problem with my RedisTemplate but I can't seen to figure out. Here is the error I am receiving:
Cannot serialize; nested exception is
org.springframework.core.serializer.support.SerializationFailedException:
Failed to serialize object using DefaultSerializer; nested exception
is java.lang.IllegalArgumentException: DefaultSerializer requires a
Serializable payload but received an object of type
[io.gravitee.policy.cache.resource.CacheElement]
EDIT
I am trying to store the instance of CacheElement class into Redis:
public class CacheElement implements Element {
private final String key;
private final CacheResponse response;
private int timeToLive = 0;
public CacheElement(String key, CacheResponse response) {
this.key = key;
this.response = response;
}
public int getTimeToLive() {
return timeToLive;
}
public void setTimeToLive(int timeToLive) {
this.timeToLive = timeToLive;
}
#Override
public Object key() {
return key;
}
#Override
public Object value() {
return response;
}
#Override
public int timeToLive() {
return timeToLive;
}
}
CacheResponse object contains Buffer.
public class CacheResponse {
private int status;
private HttpHeaders headers;
private Buffer content;
public Buffer getContent() {
return content;
}
public void setContent(Buffer content) {
this.content = content;
}
public HttpHeaders getHeaders() {
return headers;
}
public void setHeaders(HttpHeaders headers) {
this.headers = headers;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
}
I would like to serialize this CacheElement object and store it in Redis.
I also would like to deserialize it on get operation.
I will appreciate help fixing this issue. As I mentioned, I am not a Java developer. I am coming from C# and visual studio world.
Thanks
Please implement your paypload object class with Serializable interface
I am currently using the jackson gwt library and I was wondering how I can access values that are nested within a json string. My current setup code looks like this:
public static interface PremiumMapper extends ObjectMapper<Premium> {}
public static class Premium {
public float getFaceAmount() {
return faceAmount;
}
public void setFaceAmount(float faceAmount) {
this.faceAmount = faceAmount;
}
public float getStart() {
return start;
}
public void setStart(float start) {
this.start = start;
}
public float getEnd() {
return end;
}
public void setEnd(float end) {
this.end = end;
}
public float start;
public float end;
public float faceAmount;
}
while my access code looks like this:
String json = "{\"errorCode\":\"validation.failed\",\"statusCode\":400,\"details\":[{\"code\":\"targetPremium.monthlyPremiumsCents.outOfBounds\",\"validChoices\":[{\"start\":9450,\"end\":125280}]}]}";
PremiumMapper mapper = GWT.create( PremiumMapper.class );
Premium premium = mapper.read( json );
System.out.println("VALUES OUTPUTTED: " + premium.getStart());
How am I able to get the start value within the json string?
Try This as your Premium class:
-----------------------------------com.example.Premium.java-----------------------------------
package com.example;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Premium {
private String errorCode;
private Integer statusCode;
private List<Detail> details = null;
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
public String getErrorCode() {
return errorCode;
}
public void setErrorCode(String errorCode) {
this.errorCode = errorCode;
}
public Integer getStatusCode() {
return statusCode;
}
public void setStatusCode(Integer statusCode) {
this.statusCode = statusCode;
}
public List<Detail> getDetails() {
return details;
}
public void setDetails(List<Detail> details) {
this.details = details;
}
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
}
-----------------------------------com.example.Detail.java-----------------------------------
package com.example;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Detail {
private String code;
private List<ValidChoice> validChoices = null;
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public List<ValidChoice> getValidChoices() {
return validChoices;
}
public void setValidChoices(List<ValidChoice> validChoices) {
this.validChoices = validChoices;
}
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
}
-----------------------------------com.example.ValidChoice.java-----------------------------------
package com.example;
import java.util.HashMap;
import java.util.Map;
public class ValidChoice {
private Integer start;
private Integer end;
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
public Integer getStart() {
return start;
}
public void setStart(Integer start) {
this.start = start;
}
public Integer getEnd() {
return end;
}
public void setEnd(Integer end) {
this.end = end;
}
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
}
And get start value like this: premium.getDetails().get(0).getValidChoices(0).getStart()
I have to create a REST response. The data is json formatted, and must be structured as the following :
{
"device_id" : { "downlinkData" : "deadbeefcafebabe"}
}
"device_id" has to replaced for the DeviceId, for instance:
{
"333ee" : { "downlinkData" : "deadbeefcafebabe"}
}
or
{
"9886y" : { "downlinkData" : "deadbeefcafebabe"}
}
I used http://www.jsonschema2pojo.org/ and this is the result:
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonPropertyOrder({
"device_id"
})
public class DownlinkCallbackResponse {
#JsonProperty("device_id")
private DeviceId deviceId;
#JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
#JsonProperty("device_id")
public DeviceId getDeviceId() {
return deviceId;
}
#JsonProperty("device_id")
public void setDeviceId(DeviceId deviceId) {
this.deviceId = deviceId;
}
#JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
#JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
}
and
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonPropertyOrder({
"downlinkData"
})
public class DeviceId {
#JsonProperty("downlinkData")
private String downlinkData;
#JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
#JsonProperty("downlinkData")
public String getDownlinkData() {
return downlinkData;
}
#JsonProperty("downlinkData")
public void setDownlinkData(String downlinkData) {
this.downlinkData = downlinkData;
}
#JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
#JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
}
But based on this POJOs I can't set the deviceID:
DownlinkCallbackResponse downlinkCallbackResponse = new DownlinkCallbackResponse ();
DeviceId deviceId = new DeviceId();
deviceId.setDownlinkData(data);
downlinkCallbackResponse.setDeviceId(deviceId);
return new ResponseEntity<>(downlinkCallbackResponse, HttpStatus.OK);
get following json string
{ "downlinkData" : "deadbeefcafebabe"}
create json object ( Lib : java-json.jar )
JSONObject obj = new JSONObject();
put above json string into json object.
obj.put("333ee", jsonString);
that will create following json string
{
"333ee" : { "downlinkData" : "deadbeefcafebabe"}
}
I hope this will help you. :-)
Is it possible to solve the following problem using inbuilt Java API? (I want to retain the strict private access as shown)
I have n subclasses of an abstract class BaseModel.
Each of these subclasses declare their own set of private String fields.
Within the subclass constructor, I wish to set the private fields from a Map using Java Reflection. An example of this function:
void setPrivateFields(Map<String, String> fieldsValuesMap) throws NoSuchFieldException, IllegalAccessException {
for (Map.Entry<String, String> entry : fieldsValuesMap.entrySet()) {
String fieldName = entry.getKey();
String fieldValue = entry.getValue();
Field field = this.getClass().getDeclaredField(fieldName);
field.set(this, fieldValue);
}
}
Is it possible to extract out the function I have described in 3) such that I do not have to rewrite the algorithm in all the constructors of the subclasses?
class BaseModel {}
class Project extends BaseModel {
private String name;
private String type;
public Project(Map<String, String> fieldsValuesMap) {
setPrivateFields(fieldsValuesMap);
}
}
class Task extends BaseModel {
private String description;
private String rawDescription;
public Task(Map<String, String> fieldsValuesMap) {
setPrivateFields(fieldsValuesMap);
}
}
class SubTask extends BaseModel {
...
}
...
You could simply add it to the superclass.
class BaseModel {
protected void setPrivateFields(Map<String, String> fieldsValuesMap) {
for (Map.Entry<String, String> entry : fieldsValuesMap.entrySet()) {
String fieldName = entry.getKey();
String fieldValue = entry.getValue();
try {
Field field = this.getClass().getDeclaredField(fieldName);
boolean access = field.isAccessible();
field.setAccessible(true);
field.set(this, fieldValue);
field.setAccessible(access);
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
BaseModel.java
abstract class BaseModel {
}
Project.java
import java.util.Map;
class Project extends BaseModel {
private String name;
private String type;
public Project(Map<String, String> fieldsValuesMap) throws NoSuchFieldException, IllegalAccessException {
Utils.setPrivateFields(this, fieldsValuesMap);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
Task.java
import java.util.Map;
class Task extends BaseModel {
private String description;
private String rawDescription;
public Task(Map<String, String> fieldsValuesMap) throws NoSuchFieldException, IllegalAccessException {
Utils.setPrivateFields(this, fieldsValuesMap);
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getRawDescription() {
return rawDescription;
}
public void setRawDescription(String rawDescription) {
this.rawDescription = rawDescription;
}
}
Utils.java
import java.lang.reflect.Field;
import java.util.Map;
public class Utils {
static void setPrivateFields(BaseModel baseModel, Map<String, String> fieldsValuesMap) throws NoSuchFieldException, IllegalAccessException {
for (Map.Entry<String, String> entry : fieldsValuesMap.entrySet()) {
String fieldName = entry.getKey();
String fieldValue = entry.getValue();
Field field = baseModel.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(baseModel, fieldValue);
}
}
}
Main.java
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
Map<String, String> map = new HashMap<>();
map.put("name", "ABC");
map.put("type", "XYZ");
Project project = new Project(map);
System.out.println(project.getName());
System.out.println(project.getType());
}
}
I am trying to get java object from dynamic JSON.
One Important point these given classes are from third party API.
#JsonTypeInfo(
use = Id.NAME,
include = As.PROPERTY,
property = "nodeType"
)
#JsonSubTypes({ #Type(
name = "Filter",
value = Filter.class
), #Type(
name = "Criterion",
value = Criterion.class
)})
public abstract class Node {
public Node() {
}
#JsonIgnore
public EvaluationResult evaluate(Map<UUID, List<AnswerValue>> answers) {
Evaluator evaluator = new Evaluator();
return evaluator.evaluateAdvancedLogic(this, answers);
}
}
Filter.java
#JsonInclude(Include.NON_NULL)
#JsonPropertyOrder({"evaluationType", "filters"})
public class Filter extends Node {
#JsonProperty("evaluationType")
private EvaluationType evaluationType;
#NotNull
#JsonProperty("filters")
#Valid
private List<Node> filters = new ArrayList();
#JsonIgnore
private Map<String, Object> additionalProperties = new HashMap();
public Filter() {
}
#JsonProperty("evaluationType")
public EvaluationType getEvaluationType() {
return this.evaluationType;
}
#JsonProperty("evaluationType")
public void setEvaluationType(EvaluationType evaluationType) {
this.evaluationType = evaluationType;
}
#JsonProperty("filters")
public List<Node> getFilters() {
return this.filters;
}
#JsonProperty("filters")
public void setFilters(List<Node> filters) {
this.filters = filters;
}
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
#JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
}
Criterion.java
#JsonInclude(Include.NON_NULL)
#JsonPropertyOrder({"fieldSourceType", "fieldCategoryName", "sequenceNumber", "fieldName", "values", "operator", "fieldId"})
public class Criterion extends Node {
#JsonProperty("fieldSourceType")
private FieldSourceType fieldSourceType;
#JsonProperty("fieldCategoryName")
private String fieldCategoryName;
#NotNull
#JsonProperty("sequenceNumber")
private Long sequenceNumber;
#JsonProperty("fieldName")
private String fieldName;
#JsonProperty("values")
#Valid
private List<String> values = new ArrayList();
#JsonProperty("operator")
#Valid
private Operator operator;
#NotNull
#JsonProperty("fieldId")
private UUID fieldId;
#JsonIgnore
private Map<String, Object> additionalProperties = new HashMap();
public Criterion() {
}
#JsonProperty("fieldSourceType")
public FieldSourceType getFieldSourceType() {
return this.fieldSourceType;
}
#JsonProperty("fieldSourceType")
public void setFieldSourceType(FieldSourceType fieldSourceType) {
this.fieldSourceType = fieldSourceType;
}
#JsonProperty("fieldCategoryName")
public String getFieldCategoryName() {
return this.fieldCategoryName;
}
#JsonProperty("fieldCategoryName")
public void setFieldCategoryName(String fieldCategoryName) {
this.fieldCategoryName = fieldCategoryName;
}
#JsonProperty("sequenceNumber")
public Long getSequenceNumber() {
return this.sequenceNumber;
}
#JsonProperty("sequenceNumber")
public void setSequenceNumber(Long sequenceNumber) {
this.sequenceNumber = sequenceNumber;
}
#JsonProperty("fieldName")
public String getFieldName() {
return this.fieldName;
}
#JsonProperty("fieldName")
public void setFieldName(String fieldName) {
this.fieldName = fieldName;
}
#JsonProperty("values")
public List<String> getValues() {
return this.values;
}
#JsonProperty("values")
public void setValues(List<String> values) {
this.values = values;
}
#JsonProperty("operator")
public Operator getOperator() {
return this.operator;
}
#JsonProperty("operator")
public void setOperator(Operator operator) {
this.operator = operator;
}
#JsonProperty("fieldId")
public UUID getFieldId() {
return this.fieldId;
}
#JsonProperty("fieldId")
public void setFieldId(UUID fieldId) {
this.fieldId = fieldId;
}
}
The json used to conversion is this.
{
"evaluationType":"AND",
"nodeType":"Criterion",
"Criterion":[
{
"fieldName":"sdada",
"values":"sdad",
"operator":{
"operatorType":"Equals"
}
},
{
"nodeType":"Criterion",
"fieldName":"dasa",
"values":"das",
"operator":{
"operatorType":"Equals"
}
},
{
"nodeType":"Criterion",
"fieldName":"dada",
"values":"dads",
"operator":{
"operatorType":"Equals"
}
}
]
}
The problem is that deserialization of this JSON fails with following error:
{
"message": "Class com.cvent.logic.model.Criterion is not assignable to com.cvent.logic.model.Filter"
}
The first part of the JSON is wrong
{
"evaluationType":"AND",
"nodeType":"Criterion",
"Criterion":[
It says that the type is Criterion but it has evaluationType from Filter.
Also, probably "Criterion" : [ should be "filters" : [