How to insert JSON using quarkus-redis-client?
I tried writing the json as a String, but I don't know if it's correct.
#Singleton
public class EmployeeService {
#Inject
RedisClient redisClient;
public void insert(Employee employee) throws JsonProcessingException{
ObjectMapper mapper = new ObjectMapper();
String str = mapper.writeValueAsString(employee);
redisClient.set(Arrays.asList("employee", str ));
}
Employee get(String key) throws JsonMappingException, JsonProcessingException {
///Response res = redisClient.get(key);
String str = redisClient.get(key).toString();
ObjectMapper mapper = new ObjectMapper();
Employee emp = mapper.readValue(str, Employee.class);
return emp;
}
}
source code: https://github.com/alissonmelonascimento/quarkus-app-redis
Redis does not support JSON out of the box. It does only support the following datatypes. So it is OK to store JSON as a string.
But if you really need JSON support, you can try installing RedisJSON module in your server.
Do you can use this line to persist the information at Redis, the unique thing that you need to change is to replace the " to ' in your JSON content.
redisClient.set(Arrays.asList("employee", str ));
Related
i have a json string like this
{"jobs":[{"id":"1","state":"Visited","runTime":6224,"finalJobAssignment":{"owner":"10.107.181.236:5363",
"resourceId":"11",
"listingPositions":["11"]},"keys":1765624,"range":{"startPrefix":"aa",
"endPrefix":"bb"},"resources":[{"resourceId":"11"}]},{"id":"2","state":"Visited","runTime":6224,"finalJobAssignment":{"owner":"10.107.181.236:5363",
"resourceId":"22",
"listingPositions":["22","33"]},"keys":1765624,"range":{"startPrefix":"cc",
"endPrefix":"dd"},"resources":[{"resourceId":"22"}]}]}
im trying to deserialize using a custom deserializer, i only need resourceId, startPrefix, endPrefix and listingPositions(which is a list) from the json array, how do i get rid of "jobs" and return a list of my custom object?
custom object only has above useful fields
Currently i have something like this
private List<AuditEntry> deserialize(final JsonNode node,
final DeserializationContext deserializationContext) throws IOException {
List<AuditEntry> res = new ArrayList<>();
Iterator<JsonNode> iterator = node.get(JOBS_KEY).elements();
while (iterator.hasNext()) {
JsonNode jsonNode = iterator.next();
final String startKey = jsonNode.get(RANGE_KEY).get(START_PREFIX_KEY).asText();
final String endKey = jsonNode.get(RANGE_KEY).get(END_PREFIX_KEY).asText();
final String partitionId;
final String resourceId;
final List<JournalChapterAndSN> listingPositions;
final JsonParser listingPositionsParser;
resourceId = jsonNode.get(FINAL_JOB_ASSIGNMENT_KEY).get(RESOURCE_ID_KEY).asText();
listingPositionsParser = jsonNode.get(FINAL_JOB_ASSIGNMENT_KEY).get(LISTING_POSITIONS_KEY).traverse();
listingPositionsParser.nextToken();
List<String> listingPositionsString = deserializationContext.readValue(listingPositionsParser, List.class);
}
}
res.add(new AuditEntry(range, partitionId, listingPositions));
}
return res;
}
However when processing listingPositionString, DeserializationContext seems to be using my custom deserializer instead of the default one, resulting npe, how can i resolve this?
I am using the Jackson library to convert Java objects to YAML format. Based on the documentation I found on the Internet, I was able to quickly write a function that does the conversion.
I am seeking to convert the following classes to YAML:
public class RequestInfo
{
private String thePath;
private String theMethod;
private String theURL;
private List<ParamInfo> theParams = new ArrayList<>();
// getters and setters
}
public class ParamInfo
{
private String paramName;
private String paramType;
// getters and setters
}
Using Jackson's ObjectMapper, I can easily generate the YAML:
public String basicTest()
{
ObjectMapper theMapper = new ObjectMapper(new YAMLFactory());
RequestInfo info = new RequestInfo();
info.setThePath("/");
info.setTheMethod("GET");
info.setTheURL("http://localhost:8080/");
List<ParamInfo> params = new ArrayList<>();
params.add(new ParamInfo("resource","path"));
info.setTheParams(params);
String ret = null;
try
{
ret = theMapper.writeValueAsString(info);
}
catch(Exception exe)
{
logger.error(exe.getMessage());
}
return(ret);
}
The YAML I get is below:
---
thePath: "/"
theMethod: "GET"
theURL: "http://localhost:8080/"
theParams:
- paramName: "resource"
paramType: "path"
The YAML I get is OK, but it has some problems in my eyes. One probem is the "---" that it begins with. Another is the fact that I would like to be able to group the information in a manner similar to the YAML below:
RequestInfo:
thePath: "/"
theMethod: "GET"
theURL: "http://localhost:8080/"
theParams:
- paramName: "resource"
paramType: "path"
All of the examples I am seeing on the Internet use an Employee class, and talk about how to convert that class to YAML, but do not tell how to avoid the "---" (or change it into soething more descriptive). I also cannot find anything that tells how to group the YAML in the manner I describe.
Does anyone know how to do this? Is there a way to eliminate the "---", or create a name (like "RequestInfo") that groups together the translated data in an object?
You can ignore --- by disable YAMLGenerator.Feature.WRITE_DOC_START_MARKER..
If you want to wrap value under class name then u need to use #JsonRootName...
Try with this:
RequestInof class:
#JsonRootName("RequestInfo")
public class RequestInfo
{
private String thePath;
private String theMethod;
private String theURL;
private List<ParamInfo> theParams = new ArrayList<>();
// getters and setters
}
Test:
public String basicTest()
{
ObjectMapper theMapper = new ObjectMapper(new YAMLFactory().disable(YAMLGenerator.Feature.WRITE_DOC_START_MARKER));
theMapper.enable(SerializationFeature.WRAP_ROOT_VALUE); RequestInfo info = new RequestInfo();
info.setThePath("/");
info.setTheMethod("GET");
info.setTheURL("http://localhost:8080/");
List<ParamInfo> params = new ArrayList<>();
params.add(new ParamInfo("resource","path"));
info.setTheParams(params);
String ret = null;
try
{
ret = theMapper.writeValueAsString(info);
}
catch(Exception exe)
{
logger.error(exe.getMessage());
}
return(ret);
}
I am using a library com.fasterxml.jackson library for JsonSchema,
I am creating an IntegerSchema object, when I set range for integer schema using below code:
main(){
IntegerSchema intSchema = new IntegerSchema();
// setMaximum accepts Double object
intSchema.setMaximum(new Double(102000000));
// setMaximum accepts Double object
intSchema.setMinimum(new Double(100));
printJsonSchema(intSchema);
}
public void printJsonSchema(JsonSchema schema){
ObjectMapper mapper = new ObjectMapper();
try {
logger.info(mapper.writeValueAsString(schema));
} catch (JsonProcessingException e) {
throw new IllegalStateException(e);
}
}
When I convert IntegerSchema to string using ObjectMapper getting below response:
{"type":"integer","maximum":1.02E8,"minimum":100.0}
maximum and minimum values are getting converted to scientific notation.
But I need output in non scientific notation as below:
{"type":"integer","maximum":102000000,"minimum":100}
I cannot change IntegerSchema class.
Please suggest how to get the required output without extending IntegerSchema class?
Thanks in advance
this is a java issue somewhat I believe. If you debug your program, your Double will always be displayed scientifically, so what we'll want is to force it into a String. This can be achieved in Java in multiple ways, and you can look it up here:
How to print double value without scientific notation using Java?
In terms of your specific question about Jackson, I've written up some code for you:
public class ObjectMapperTest {
public static void main(String[] args) throws JsonProcessingException {
IntegerSchema schema = new IntegerSchema();
schema.type = "Int";
schema.max = 10200000000d;
schema.min = 100d;
ObjectMapper m = new ObjectMapper();
System.out.println(m.writeValueAsString(schema));
}
public static class IntegerSchema {
#JsonProperty
String type;
#JsonProperty
double min;
#JsonProperty
#JsonSerialize(using=MyDoubleDesirializer.class)
double max;
}
public static class MyDoubleDesirializer extends JsonSerializer<Double> {
#Override
public void serialize(Double value, JsonGenerator gen, SerializerProvider serializers)
throws IOException, JsonProcessingException {
// TODO Auto-generated method stub
BigDecimal d = new BigDecimal(value);
gen.writeNumber(d.toPlainString());
}
}
}
The trick is to register a custom Serializer for your Double value. This way, you can control what you want.
I am using the BigDecimal value to create a String representation of your Double. The output then becomes (for the specific example):
{"type":"Int","min":100.0,"max":10200000000}
I hope that solves your problem.
Artur
Feature.WRITE_BIGDECIMAL_AS_PLAIN
set this for your Object Mapper
I know I am answering late, but something I faced may help other
While converting a BigDecimal I have faced below is working
mapper = mapper.setNodeFactory(JsonNodeFactory.withExactBigDecimals(true));
while this is not working for me
mapper.configure(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN, true);
Update for Jakson 2.9.10:
Property WRITE_BIGDECIMAL_AS_PLAIN replaced to com.fasterxml.jackson.core.JsonGenerator. You could use:
mapper.enable(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN);
If you are using ValueToTree then no need of any factory settings. only problem with ValueToTree is it is converting as TextNode (String Fromat), So if you have any logic based on ObjectNodes it will not work
You should use
mapper.configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true);
To avoid scientific notation on floating numbers.
You can find an example below.
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true);
String test ="{\"doubleValue\" : 0.00001}";
try {
System.out.println(mapper.readTree(test).toPrettyString());
} catch (JsonProcessingException e) {
e.printStackTrace();
}
Output
{
"doubleValue" : 0.00001
}
A library is using Map to use some extra information. This map eventually is being converted a JSON object and I need to set request information to display for debugging purposes as this:
map.put("request", requestString);
I am considering to use Jackson specifically to create a JSON without quotes and want to set as requestString.
I am building necessary information regarding Request and building a Map including request headers, parameters, method etc.
Jackson is creating perfectly valid JSON with quotes but when I set this generated value inside map, It is displayed ugly because of having escaped quotes.
So Jackson is creating this:
{
method : "POST",
path : "/register"
}
When I set this in map, it turns to this:
{
method : \"POST\",
path : \"/register\"
}
Consider this as a huge map including all parameters and other information about request.
What I would like to want this:
{
method : POST,
path : /register
}
I know that this is not a valid JSON but I am using this as a String to a Map which is accepting String values.
public class UnQuotesSerializer extends NonTypedScalarSerializerBase<String>
{
public UnQuotesSerializer() { super(String.class); }
/**
* For Strings, both null and Empty String qualify for emptiness.
*/
#Override
public boolean isEmpty(String value) {
return (value == null) || (value.length() == 0);
}
#Override
public void serialize(String value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
jgen.writeRawValue(value);
}
#Override
public JsonNode getSchema(SerializerProvider provider, Type typeHint) {
return createSchemaNode("string", true);
}
#Override
public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException {
if (visitor != null) visitor.expectStringFormat(typeHint);
}
}
and
ObjectMapper objectMapper = new ObjectMapper();
SimpleModule module = new SimpleModule("UnQuote");
module.addSerializer(new UnQuotesSerializer());
objectMapper.configure(JsonGenerator.Feature.QUOTE_FIELD_NAMES, false);
objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
objectMapper.registerModule(module);
This is generating without quotes strings.
The following test passes (Jackson 2.5.0)
#Test
public void test() throws Exception {
ObjectMapper mapper = new ObjectMapper();
Map map = new HashMap();
map.put("method", "POST");
map.put("request", "/register");
String s = mapper.writeValueAsString(map);
Map map2 = mapper.readValue(s, Map.class);
Assert.assertEquals(map, map2);
}
so your pseudo JSON without quotes does not seem the way to go
I'm trying to populate a POJO from a JSON that doesn't really match in any way and am having trouble getting this resolved. I can't change the JSON since it is an external service but I maybe able to modify the POJO if needed.
Below is an example JSON:
{"Sparse":[{"PixId":1,"PixName":"SWE","Description":"Unknown"},{"PixId":2,"PixName":"PUMNW","Description":"Power Supplement"}],"Status":0,"Message":null}
Below is the POJO:
#JsonIgnoreProperties(ignoreUnknown = true)
public class Pix {
#JsonProperty("Description")
private String description;
#JsonProperty("PixId")
private int pixId;
#JsonProperty("PixName")
private String pixName;
// getters and setters
}
And here is my code to do the conversion:
ObjectMapper om = new ObjectMapper();
om.configure(DeserializationConfig.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
om.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
List<Pix> pixList = om.readValue(pixJson, new TypeReference<List<Pix>>() {});
The pixList contains only 1 element (should be 2 using the JSON above) and all the properties have not been populated. I'm using Jackson 1.9.9. Any ideas on how to get this to work? TIA.
You have to create new POJO class for main object which contains the List<Pix>. It could looks like this:
class Root {
#JsonProperty("Status")
private int status;
#JsonProperty("Message")
private String message;
#JsonProperty("Sparse")
private List<Pix> sparse;
//getters/setters
}
And now your deserialization code could looks like this:
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
List<Pix> pixList = mapper.readValue(pixJson, Root.class).getSparse();