I am relatively new to redis .
I am designing an rest API, to get the entire data set in the redis db.
I used the below code to get all the keys
public Map getAllRedisData() {
Map<Object, Object> map = new HashMap<>();
Set<byte[]> keys = redisService.getTemplate().getConnectionFactory().getConnection().keys("*".getBytes());
Iterator<byte[]> it = keys.iterator();
while(it.hasNext()){
byte[] data = (byte[])it.next();
// String key = new String(data,0,data.length);
Object key = null;
try {
key = getObjectFromByteArray(data);
System.out.println(key);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return map;
}
private Object getObjectFromByteArray(byte[] bytes) throws IOException, ClassNotFoundException
{
try (ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
ObjectInput in = new ObjectInputStream(bis)) {
return in.readObject();
}
}
I was able to get all the keys, but wasnt able to retrieve the value for all the keys. Below is the approach
"Object value = redisService.getTemplate().opsForValue().get("");"
I guess this is because some keys are of different datatypes.
Let me know if I have to modify/change my approach.
First keys should not be used in production. Instead you can use scan command.
When you have the key you can call the redis type command, to retrieve the DataType for the object.
DataType -> NONE, STRING, LIST, SET, ZSET, HASH
Then you can call the right function to get the data
On large data set this could take a while. Are you sure that you rest api need to get all data into the redis? You can use a pattern with scan to only retrieve the data you really need.
i didn't test it, but try this
try {
Object value = getObjectFromByteArray(redisService.getTemplate().getConnectionFactory().getConnection().get(data));
key = getObjectFromByteArray(data);
System.out.println(key);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Related
This question already has answers here:
java.io.FileNotFoundException when creating FileInputStream
(2 answers)
Closed 6 years ago.
For my application I want to use a Map to act as a database. To save and load a map, I am writing/reading it to/from database.ser using this 2 methods:
private synchronized void saveDB() {
try {
fileOut = new FileOutputStream(db);
out = new ObjectOutputStream(fileOut);
out.writeObject(accounts);
fileOut.close();
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
#SuppressWarnings("unchecked")
private void loadDB() {
try {
fileIn = new FileInputStream(db);
in = new ObjectInputStream(fileIn); // that is where error is produced if fileIn is empty
accounts = (Map<String, Client>) in.readObject();
in.close();
fileIn.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I want to load into Map when application starts, so I invoke method in constructor like this:
protected DriveatorImpl() {
accounts = new ConcurrentHashMap<String, Client>();
db = new File("C:/Users/eduar/git/Multy-Threaded-Bank-System/Bank-Services/database.ser");
// also, any suggestions how can I make path to a file more flexible in case I want to run Server side of an app on different machine?
if (!db.exists()) {
try {
db.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
loadDB(); // loads database when server start
}
I am aware of what causing an error, but I don't know what should I change in my design to avoid ObjectInputStream constructor receiving empty stream!
Any suggestions on what I can do differently?
Edit: I want to note that in fresh application run database.ser is empty since there was no entries made into Map yet.
Thank You!
First why the EOFExcpetion occur?
There are no contents in file or file is empty and you tried to read file.
You can avoid the EOFException for an empty file by checking file content length if it is less than or equal to zero means file is empty. another way to check if file is empty
Some code change and it worked for me.
#SuppressWarnings("unchecked")
private void loadDB() {
try {
if (db.length() <= 0) {
// if statement evaluates to true even if file doesn't exists
saveDB(); // save to a file an empty map
// if file doesn't exist, it creates a new one
// call loadDB inside constructor
}
FileInputStream fileIn = new FileInputStream(db);
ObjectInputStream in = new ObjectInputStream(fileIn); // that is where error is produced if fileIn is empty
in.readObject();
in.close();
fileIn.close();
System.out.println(accounts);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Get rid of the file.exists()/file.createNewFile() crap. All it is doing for you is masking the original FileNotFoundException problem, and turning into a thoroughly predictable EOFException because of trying to construct an ObjectInputStream around an empty stream. Handle the original problem. Don't just move it, or turn it into something else.
I have this spring boot java controller having code that utilizes the OpenKM document management API to search the document management system for documents and display results using Ajax, HTML, CSS and Jquery datatables on the front-end.
Due to the way the API was written, I cannot get a document object with its metadata in one call but will need to use an output of the first API operation's call as a filter for another API operation method in two nested for loops.
Additionally, I had to iterate the toString method of an API return object to retrieve the metadata information, as they were not accessible through the return object's properties.
The problem is the performance of this code. I would like to see if there is a way to optimize this code.
// Read the property or metadata to use in constituting the StoredDocument object
for (QueryResult queryResult : resultSet.getResults()) {
// Create a locally-scoped List<String>
List<String> listOfStoredDocumentProperties = new ArrayList<String>();
Document document = queryResult.getDocument();
String nodeId = document.getPath();
// Populate storedDocument object
storedDocument = new StoredDocument();
storedDocument.setAuthor(document.getAuthor());
storedDocument.setCreated(document.getCreated());
storedDocument.setLastModified(document.getLastModified());
storedDocument.setPath(document.getPath());
storedDocument.setPermissions(document.getPermissions());
storedDocument.setSize(document.getActualVersion().getSize());
storedDocument.setUuid(document.getUuid());
storedDocument.setVersionNumber(document.getActualVersion().getName());
// System.out.println(nodeId);
try {
listOfFormElement = okm.getPropertyGroupProperties(nodeId, documentVo.getGroupId());
int counterForTrackingDocDirectionPos = 0;
for (FormElement formElement : listOfFormElement) {
++counterForTrackingDocDirectionPos;
if (counterForTrackingDocDirectionPos == 4) {
String formElementString = formElement.toString();
// System.out.println("formElementString: " + formElementString);
System.out.println("name: " + formElement.getName());
System.out.println("formElement: " + formElement);
String transformedFormElementString = StringUtils.EMPTY;
try {
transformedFormElementString = formElementString.substring(0, formElementString.indexOf(", selected=true"));
// Read the string from a position that is 3 steps before the last position in the string.
transformedFormElementString = transformedFormElementString
.substring(transformedFormElementString.length() - 3, transformedFormElementString.length()).trim();
transformedFormElementString = transformedFormElementString.startsWith("=")
? transformedFormElementString.substring(1, transformedFormElementString.length()) : transformedFormElementString;
} catch (Exception ex) {
// To catch scenario where formElementString.indexOf(", selected=true") does not find the
// specified string. This happens when document direction is not set and therefore is
// selected=false for both the options IN and OUT.
transformedFormElementString = "NOT SET";
}
listOfStoredDocumentProperties.add(transformedFormElementString);
System.out.println("transformedFormElementString: " + transformedFormElementString);
} else {
String formElementString = formElement.toString();
String transformedFormElementString = formElementString.substring(formElementString.indexOf("value="),
formElementString.indexOf("data="));
// Remove the preceding 'value=' and the last 2 character-constituted string ", "
transformedFormElementString = transformedFormElementString.substring(6, transformedFormElementString.length() - 2).trim();
listOfStoredDocumentProperties.add(transformedFormElementString);
}
}
storedDocument.setCompanyName(listOfStoredDocumentProperties.get(0));
storedDocument.setProductLine(listOfStoredDocumentProperties.get(1));
storedDocument.setSubjectHeading(listOfStoredDocumentProperties.get(2));
storedDocument.setDocumentDirection(listOfStoredDocumentProperties.get(3));
storedDocument.setDocumentType(listOfStoredDocumentProperties.get(4));
storedDocument.setReferenceNumber(listOfStoredDocumentProperties.get(5));
storedDocument.setDate(ISO8601.parseBasic(listOfStoredDocumentProperties.get(6)).getTime().toString());
// Add the storedDocument object to the return list
listOfstoredDocuments.add(storedDocument);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchGroupException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (PathNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (RepositoryException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (DatabaseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnknowException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (WebserviceException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
The solution for it is extending the REST API. In the professional edition, the REST API is extensible with plugins architecture https://docs.openkm.com/kcenter/view/okm-6.4/creating-your-own-rest-plugin-(-extending-rest-api-).html, in the community this option still is not present. The idea is to build a method from server side what provide the exact data what really you need, creating high-level methods.
I have tried to write a code that prints the desired contents from an owl file. Here is my code:
public String execute()
{
OntModel m = ModelFactory.createOntologyModel( OntModelSpec.OWL_MEM );
// get an OntClass reference to one of the classes in the model
// note: ideally, we would delegate this step to Jena's schemagen tool
InputStream in = null;
try {
in = new FileInputStream("C:/OOAD-Softwares/workspace4/SemWeb/build/src/main/resources/semrailwaysv2.owl");
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} // or any windows path
m.read(in, null);
OntClass ontclass = m.getOntClass(SOURCE_URL+"#RailwayStation");
ExtendedIterator iterator = ontclass.listInstances();
while(iterator.hasNext())
{
Object obj = iterator.next();
System.out.println("Object : "+obj.toString());
}
try {
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return SUCCESS;
}
Here I am able to get the number of instances of the desired class from my owl file by directly using the listInstances() method as an iterator without assigning, but I am unable to get the various property values for each instance. How should I proceed to do this? Also if I use the parameterized version of ExtendedIterator,
ExtendedIterator<OntClass> it = ontclass.listInstances();
is giving an error saying
The type ExtendedIterator is not generic; it cannot be parameterized with arguments <OntClass>
How should I proceed?
Edit
I have updated the code, still same problem.
I'm currently using the library JSON-io. I created a desktop application which when a person want to log in in the system send an JSONObject with his username and password. Then the server send back the response if the person is allowed or not (also a JSONObject). Until here everything works fine.
Now i want to make an Android app. I take the same code than before for login but the application crashes.
The code for login is launch from an AsyncTask and i put the permission to access to Internet to the Manifest.
I perform some testing and it occurs that the method write of JSONWriter "delete" my JSON because on the server side he receives this : {}. I tried to hardcode the JSONObject on the server side (the server's code works fine because we can use the desktop app) but this time the readObject on the android App receives also {}.
We tried to send jsonObject.toString() and this time it worked (except that the server isn't configured to handle a string).
Do anyone knows why on android the two methods write and readObject are deleting the JSON ?
Thank you.
EDIT:
Here the code i wrote:
On the android App
protected Boolean doInBackground(Void... params) {
// 3 : create a JSON object and send it to server for verification
JSONObject loginJS = new JSONObject();
try {
loginJS.put("type", Type.LOGIN); // Type is an enum
loginJS.put("username", userName);
loginJS.put("hash", mPassword);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
User user = new User();
System.out
.println("User created and ready to connect to the spu for login");
user.connexionToSPU(); // This method works
System.out.println("LoginJS = "+loginJS.toString()); At this point the print of the JSON is fine we have {"type":"Login", ....}
user.sendToSPU(loginJS); //This is where there's a problem
// 4 : wait response
JSONObject loginResponseJS = user.receiveFromSPU(); // And when i hard code the JSON on the server side receiveFromSPU get a empty JSON
Method connexionToSPU:
public void connexionToSPU() {
jswSPU = null;
jsrSPU = null;
Socket socket = null;
try {
socket = new Socket(prop.readPropertiesXML("IP_adress_server"),
Integer.parseInt(prop.readPropertiesXML("port_server")));
} catch (NumberFormatException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (UnknownHostException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
jswSPU = new JsonWriter(socket.getOutputStream());
jsrSPU = new JsonReader(new BufferedInputStream(socket.getInputStream()));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
sendToSPU method
public void sendToSPU(JSONObject json) {
try {
jswSPU.write(json);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
ReceiveFromSPU method
public JSONObject receiveFromSPU() {
JSONObject json = null;
try {
json = (JSONObject) jsrSPU.readObject();
System.out.println("JSON FROM THE SERVER : "+json.toString());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return json;
}
Hope it will be sufficiently clear.
Thank you
I'm trying to create JSON to Object mapper. Its main idea is that "user" defines a dictionary where keys are JSON attributes and values are Objects property names. So how does it work (so far):
Get value from JSON (var jsonValue)
Get property type from getter (var methodType)
Create setter method and insert value from json
Only problem is that I can't cast jsonValue into object dynamically. I have to check what's the object type (methodType) and then cast it differently for String, Long, Integer and so on. Can I somehow cast it dynamically?
private Cookbook createCookbook(JsonObject jsonCookbook) {
//Cookbook to return
Cookbook cookbook = new Cookbook();
Enumeration<String> e = mappingDictionary.keys();
while (e.hasMoreElements()) {
//get JSON value
String mappingKey = e.nextElement();
JsonElement json = jsonCookbook.get(mappingKey);
String jsonValue = json.getAsString();
//set JSON value to property
String mappingValue = mappingDictionary.get(mappingKey);
//reflection
try {
//get type of the getter
String getMethodName = "get" + mappingValue;
Method getMethod = cookbook.getClass().getMethod(getMethodName, null);
Class<?> methodType = getMethod.getReturnType();
//set methods
String setMethodName = "set" + mappingValue;
Method setMethod = cookbook.getClass().getMethod(setMethodName, methodType);
//set value to property
/* DONT WANT TO DO IT LIKE THIS, THIS IS MY PROBLEM */
if (methodType.equals(String.class))
setMethod.invoke(cookbook, jsonValue);
if (methodType.equals(Long.class))
setMethod.invoke(cookbook, Long.valueOf(jsonValue));
} catch (NoSuchMethodException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IllegalArgumentException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IllegalAccessException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (InvocationTargetException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
return cookbook;
}
You can create non-primitive objects of unknown type in runtime using reflection (as You used) and .newInstance() method.
You can't create primitive types in this way, for example, if You take look in standart JDK serialization implementation (writeObject() of ObjectWriter), You see the switch with 8 cases.