Java library for searching text in JSON file - java

I would like to search after a given keyword in a big JSON file. Does anybody know a java library for this?

Gson could help you to parse the json file easily.
Unlike many other JSON libraries, Gson supports streaming which means you can examine the file in small chunks.

If you're just searching for a keyword, I don't see how the fact that it's JSON requires a special library. This would only help if you were looking for something particular to JSON such as a key or value.
Couldn't you just scan the file line-by-line and search for the substring?
public static boolean find(File f, String searchString) {
boolean result = false;
Scanner in = null;
try {
in = new Scanner(new FileReader(f));
while(in.hasNextLine() && !result) {
if (in.nextLine().contains(searchString))
return true;
}
}
catch(IOException e) {
e.printStackTrace();
}
finally {
try { in.close() ; } catch(Exception e) { /* ignore */ }
}
return false;
}
from http://technojeeves.com/joomla/index.php/free/109-search-for-string-in-text-file-in-java.

You can find json library it here.

Search for JSONArray and JSONObject
http://www.json.org/javadoc/org/json/JSONArray.html
it's pretty easy to work with them.

Related

How to concatenate 2 different types of streams using Smallrye Mutiny Multi?

I would like to concatenate 2 OutputStream of different types using the method Multi.createBy().concatenating().streams. Is there a way to achieve this?
I have 2 streams one is of ByteArrayOutputStream and other is of custom type CustomerEvent and I would like to concatenate them using the SmallRye Mutiny. Is there a way to achieve this?
public class CustomerGenerator {
private ByteArrayOutputStream jsonOutput;
private JsonGenerator jsonGenerator;
private CustomerGenerator() {
try {
jsonOutput = new ByteArrayOutputStream();
jsonGenerator = new JsonFactory().createGenerator(jsonOutput).useDefaultPrettyPrinter();
} catch (IOException ex) {
throw new CustomerGeneratorException("Exception occurred during the generation of customer document : " + ex);
}
}
public Multi < Customer > generateCustomer(final Input input) {
try {
jsonGenerator.writeStartObject();
jsonGenerator.writeStringField("type", "customerDocument");
jsonGenerator.writeStringField("creationDate", Instant.now().toString());
jsonGenerator.writeFieldName("customerBody");
jsonGenerator.writeStartObject();
jsonGenerator.writeFieldName("customerList");
jsonGenerator.writeEndObject(); // End body
jsonGenerator.writeEndObject(); // End whole json file
Multi < ByteArrayOutputStream > jsonWrapper = Multi.createFrom().item(jsonOutput);
return Multi.createBy().concatenating().streams(jsonWrapper, Multi.createFrom().publisher(new CustomerPublisher(input))));
} catch (IOException ex) {
throw new CustomerGeneratorException("Exception occurred during customer document wrapper creation : " + ex);
}
}
}
As you can see from the code sample, I would like to concatenate the generated JSON to my other JSON of type Customer. Is there a way to achieve this?
Multi < ByteArrayOutputStream > jsonWrapper = Multi.createFrom().item(jsonOutput);
return Multi.createBy().concatenating().streams(jsonWrapper, Multi.createFrom().publisher(new CustomerPublisher(input))));
Both Multi have to return a Multi<Customer> if you want to concatenate them.
Looking at your code, it seems that what you need to do is to convert the json into a Customer (or collection of Customer) and then convert it to a Multi. I don't know how you convert the JSON to a Customer, assuming you have a function convertToCustomer, this is how the code should look like:
Multi<Customer> customerMulti = Multi.createFrom().item( convertToCustomer(jsonGenerator))
Multi<Customer> customersPublisher = Multi.createFrom().publisher(new CustomerPublisher(input));
// Now you can concatenate the two
Multi<Customer> result = Multi.createBy().concatenating()
.streams(customerMulti, customersPublisher);
Alternatively, your method could return a Multi<Object>. But I suspect this is not what you need.

Check if file exists from string

This is the code I use when I try to read some specific text in a *.txt file:
public void readFromFile(String filename, JTable table) {
BufferedReader bufferedReader = null;
try {
bufferedReader = new BufferedReader(new FileReader(filename));
String a,b,c,d;
for(int i=0; i<3; i++)
{
a = bufferedReader.readLine();
b = bufferedReader.readLine();
c = bufferedReader.readLine();
d = bufferedReader.readLine();
table.setValueAt(a, i, 0);
table.setValueAt(b, i, 1);
table.setValueAt(c, i, 2);
table.setValueAt(d, i, 3);
}
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
//Close the reader
try {
if (bufferedReader != null) {
bufferedReader.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
And it is called in this way:
readFromFile("C:/data/datafile.txt", table1)
The problem is the following: the 1st time I open the program the *.txt file I'm going to read does not exist, so I thought I could use the function exists(). I have no idea about what to do, but I tried this:
if(("C:/data/datafile.txt").exists()) {
readFromFile("C:/data/datafile.txt", table1)
}
It is not working because NetBeans gives me a lot of errors. How could I fix this?
String has no method named exists() (and even if it did it would not do what you require), which will be the cause of the errors reported by the IDE.
Create an instance of File and invoke exists() on the File instance:
if (new File("C:/data/datafile.txt").exists())
{
}
Note: This answer use classes that aren't available on a version less than Java 7.
The method exists() for the object String doesn't exist. See the String documentation for more information. If you want to check if a file exist base on a path you should use Path with Files to verify the existence of the file.
Path file = Paths.get("C:/data/datafile.txt");
if(Files.exists(file)){
//your code here
}
Some tutorial about the Path class : Oracle tutorial
And a blog post about How to manipulate files in Java 7
Suggestion for your code:
I'll point to you the tutorial about try-with-resources as it could be useful to you. I also want to bring your attention on Files#readAllLines as it could help you reduce the code for the reading operation. Based on this method you could use a for-each loop to add all the lines of the file on your JTable.
you can use this code to check if the file exist
Using java.io.File
File f = new File(filePathString);
if(f.exists()) { /* do something */ }
You need to give it an actual File object. You're on the right track, but NetBeans (and java, for that matter) has no idea what '("C:/data/datafile.txt")' is.
What you probably wanted to do there was create a java.io.File object using that string as the argument, like so:
File file = new File ("C:/data/datafile.txt");
if (file.exists()) {
readFromFile("C:/data/datafile.txt", table1);
}
Also, you were missing a semicolon at the end of the readFromFile call. Im not sure if that is just a typo, but you'll want to check on that as well.
If you know you're only ever using this File object just to check existence, you could also do:
if (new File("C:/data/datafile.txt").exists()) {
readFromFile("C:/data/datafile.txt", table1);
}
If you want to ensure that you can read from the file, it might even be appropriate to use:
if(new File("C:/data/datafile.txt").canRead()){
...
}
as a condition, in order to verify that the file exists and you have sufficient permissions to read from the file.
Link to canRead() javadoc

How to check whether a given string is valid JSON in Java

How do I validate a JSON string in Java? Or could I parse it using regular expressions?
A wild idea, try parsing it and catch the exception:
import org.json.*;
public boolean isJSONValid(String test) {
try {
new JSONObject(test);
} catch (JSONException ex) {
// edited, to include #Arthur's comment
// e.g. in case JSONArray is valid as well...
try {
new JSONArray(test);
} catch (JSONException ex1) {
return false;
}
}
return true;
}
This code uses org.json JSON API implementation that is available on github, in maven and partially on Android.
JACKSON Library
One option would be to use Jackson library. First import the latest version (now is):
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.7.0</version>
</dependency>
Then, you can implement the correct answer as follows:
import com.fasterxml.jackson.databind.ObjectMapper;
public final class JSONUtils {
private JSONUtils(){}
public static boolean isJSONValid(String jsonInString ) {
try {
final ObjectMapper mapper = new ObjectMapper();
mapper.readTree(jsonInString);
return true;
} catch (IOException e) {
return false;
}
}
}
Google GSON option
Another option is to use Google Gson. Import the dependency:
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.5</version>
</dependency>
Again, you can implement the proposed solution as:
import com.google.gson.Gson;
public final class JSONUtils {
private static final Gson gson = new Gson();
private JSONUtils(){}
public static boolean isJSONValid(String jsonInString) {
try {
gson.fromJson(jsonInString, Object.class);
return true;
} catch(com.google.gson.JsonSyntaxException ex) {
return false;
}
}
}
A simple test follows here:
//A valid JSON String to parse.
String validJsonString = "{ \"developers\": [{ \"firstName\":\"Linus\" , \"lastName\":\"Torvalds\" }, " +
"{ \"firstName\":\"John\" , \"lastName\":\"von Neumann\" } ]}";
// Invalid String with a missing parenthesis at the beginning.
String invalidJsonString = "\"developers\": [ \"firstName\":\"Linus\" , \"lastName\":\"Torvalds\" }, " +
"{ \"firstName\":\"John\" , \"lastName\":\"von Neumann\" } ]}";
boolean firstStringValid = JSONUtils.isJSONValid(validJsonString); //true
boolean secondStringValid = JSONUtils.isJSONValid(invalidJsonString); //false
Please, observe that there could be a "minor" issue due to trailing commas that will be fixed in release 3.0.0.
With Google Gson you can use JsonParser:
import com.google.gson.JsonParser;
JsonParser parser = new JsonParser();
parser.parse(json_string); // throws JsonSyntaxException
You could use the .mayBeJSON(String str) available in the JSONUtils library.
It depends on what you are trying to prove with your validation.
Certainly parsing the json as others have suggested is better than using regexes, because the grammar of json is more complicated than can be represented with just regexes.
If the json will only ever be parsed by your java code, then use the same parser to validate it.
But just parsing won't necessarily tell you if it will be accepted in other environments. e.g.
many parsers ignore trailing commas in an object or array, but old versions of IE can fail when they hit a trailing comma.
Other parsers may accept a trailing comma, but add an undefined/null entry after it.
Some parsers may allow unquoted property names.
Some parsers may react differently to non-ASCII characters in strings.
If your validation needs to be very thorough, you could:
try different parsers until you find one that fails on all the corner cases I mentioned above
or you could probably run jsonlint using javax.script.*,
http://npmjs.org/package/jsonlint
or combine using a parser with running jshint using javax.script.*.
https://www.npmjs.org/package/jshint
https://github.com/webjars/jshint
A bit about parsing:
Json, and in fact all languages, use a grammar which is a set of rules that can be used as substitutions. in order to parse json, you need to basically work out those substitutions in reverse
Json is a context free grammar, meaning you can have infinitely nested objects/arrays and the json would still be valid. regex only handles regular grammars (hence the 'reg' in the name), which is a subset of context free grammars that doesn't allow infinite nesting, so it's impossible to use only regex to parse all valid json. you could use a complicated set of regex's and loops with the assumption that nobody will nest past say, 100 levels deep, but it would still be very difficult.
if you ARE up for writing your own parser
you could make a recursive descent parser after you work out the grammar
String jsonInput = "{\"mob no\":\"9846716175\"}";//Read input Here
JSONReader reader = new JSONValidatingReader();
Object result = reader.read(jsonInput);
System.out.println("Validation Success !!");
Please download stringtree-json library
Here is a working example for strict json parsing with gson library:
public static JsonElement parseStrict(String json) {
// throws on almost any non-valid json
return new Gson().getAdapter(JsonElement.class).fromJson(json);
}
See also my other detailed answer in How to check if JSON is valid in Java using GSON with more info and extended test case with various non-valid examples.
The answers are partially correct. I also faced the same problem. Parsing the json and checking for exception seems the usual way but the solution fails for the input json something like
{"outputValueSchemaFormat": "","sortByIndexInRecord": 0,"sortOrder":847874874387209"descending"}kajhfsadkjh
As you can see the json is invalid as there are trailing garbage characters. But if you try to parse the above json using jackson or gson then you will get the parsed map of the valid json and garbage trailing characters are ignored. Which is not the required solution when you are using the parser for checking json validity.
For solution to this problem see here.
PS: This question was asked and answered by me.
Check whether a given string is valid JSON in Kotlin. I Converted answer of MByD Java to Kotlin
fun isJSONValid(test: String): Boolean {
try {
JSONObject(test);
} catch (ex: JSONException) {
try {
JSONArray(test);
} catch (ex1: JSONException) {
return false;
}
}
return true;
}
A solution using the javax.json library:
import javax.json.*;
public boolean isTextJson(String text) {
try {
Json.createReader(new StringReader(text)).readObject();
} catch (JsonException ex) {
try {
Json.createReader(new StringReader(text)).readArray();
} catch (JsonException ex2) {
return false;
}
}
return true;
}
As you can see, there is a lot of solutions, they mainly parse the JSON to check it and at the end you will have to parse it to be sure.
But, depending on the context, you may improve the performances with a pre-check.
What I do when I call APIs, is just checking that the first character is '{' and the last is '}'. If it's not the case, I don't bother creating a parser.
Here you can find a tool that can validate a JSON file, or you could just deserialize your JSON file with any JSON library and if the operation is successful then it should be valid (google-json for example that will throw an exception if the input it is parsing is not valid JSON).
Using Playframework 2.6, the Json library found in the java api can also be used to simply parse the string. The string can either be a json element of json array. Since the returned value is not of importance here we just catch the parse error to determine that the string is a correct json string or not.
import play.libs.Json;
public static Boolean isValidJson(String value) {
try{
Json.parse(value);
return true;
} catch(final Exception e){
return false;
}
}
IMHO, the most elegant way is using the Java API for JSON Processing (JSON-P), one of the JavaEE standards that conforms to the JSR 374.
try(StringReader sr = new StringReader(jsonStrn)) {
Json.createReader(sr).readObject();
} catch(JsonParsingException e) {
System.out.println("The given string is not a valid json");
e.printStackTrace();
}
Using Maven, add the dependency on JSON-P:
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
<version>1.1.4</version>
</dependency>
Visit the JSON-P official page for more informations.
in Gson Version
try {
String errorBody = response.errorBody().string();
MyErrorResponse errorResponse = new Gson().fromJson(errorBody, MyErrorResponse.class);
} catch (JsonSyntaxException e) {
e.printStackTrace();
}
I have found a very simple solution for it.
Please first install this library net.sf.json-lib for it.
import net.sf.json.JSONException;
import net.sf.json.JSONSerializer;
private static boolean isValidJson(String jsonStr) {
boolean isValid = false;
try {
JSONSerializer.toJSON(jsonStr);
isValid = true;
} catch (JSONException je) {
isValid = false;
}
return isValid;
}
public static void testJson() {
String vjson = "{\"employees\": [{ \"firstName\":\"John\" , \"lastName\":\"Doe\" },{ \"firstName\":\"Anna\" , \"lastName\":\"Smith\" },{ \"firstName\":\"Peter\" , \"lastName\":\"Jones\" }]}";
String ivjson = "{\"employees\": [{ \"firstName\":\"John\" ,, \"lastName\":\"Doe\" },{ \"firstName\":\"Anna\" , \"lastName\":\"Smith\" },{ \"firstName\":\"Peter\" , \"lastName\":\"Jones\" }]}";
System.out.println(""+isValidJson(vjson)); // true
System.out.println(""+isValidJson(ivjson)); // false
}
Done. Enjoy
import static net.minidev.json.JSONValue.isValidJson;
and then call this function passing in your JSON String :)
public static boolean isJSONValid(String test) {
try {
isValidJSON(test);
JsonFactory factory = new JsonFactory();
JsonParser parser = factory.createParser(test);
while (!parser.isClosed()) {
parser.nextToken();
}
} catch (Exception e) {
LOGGER.error("exception: ", e);
return false;
}
return true;
}
private static void isValidJSON(String test) {
try {
new JSONObject(test);
} catch (JSONException ex) {
try {
LOGGER.error("exception: ", ex);
new JSONArray(test);
} catch (JSONException ex1) {
LOGGER.error("exception: ", ex1);
throw new Exception("Invalid JSON.");
}
}
}
Above solution covers both the scenarios:
duplicate key
mismatched quotes or missing parentheses etc.
You can try below code, worked for me:
import org.json.JSONObject;
import org.json.JSONTokener;
public static JSONObject parseJsonObject(String substring)
{
return new JSONObject(new JSONTokener(substring));
}

printing HL7 message in console

I'm passing an object to constructor and then adding parameters of this object to HL7.
ORU_R01 is the type of HL7.
When i print HL7 to console, only the last OBX is printed.
What is wrong with my code?
How can i write this HL7 message to socket?
Is there simpler way in java to handel HL7?
public class FlexSMessageHL7 {
private FileWriter writeHL7ToFile;
private PrismaflexSMessage sMessage;
private ORU_R01 message;
private int i = 0;
private OBX obx = null;
public FlexSMessageHL7(FlexSMessage sMessage) {
this.sMessage = sMessage;
this.message = new ORU_R01();
createHL7SMessage();
}
public void createHL7SMessage() {
// Populate the MSH Segment
MSH msh = message.getMSH();
try {
msh.getFieldSeparator().setValue("|");
msh.getEncodingCharacters().setValue("^~\\&");
msh.getDateTimeOfMessage().setValue(sMessage.getTime().toString());
msh.getSendingApplication().getNamespaceID().setValue(String.valueOf(sMessage.getMachID()));
} catch (DataTypeException e) {
e.printStackTrace();
}
// Populate the OBR Segment:time
OBR obr = message.getPATIENT_RESULT().getORDER_OBSERVATION().getOBR();
try {
obr.getObservationDateTime().setValue(String.valueOf(sMessage.getTime()));
} catch (DataTypeException e) {
e.printStackTrace();
}
// Populate the PID Segment:PatientId
PID pid = message.getPATIENT_RESULT().getPATIENT().getPID();
try {
pid.getPatientID().getIDNumber().setValue(sMessage.getPatID());
} catch (HL7Exception e) {
e.printStackTrace();
}
// Populate the OBX Segment:Param_Code, time, Measure_Value
while (i < sMessage.getMsgInfo()) {
for (PrismaflexSRecord sRecord : sMessage.getsRecordCollection()) {
try {
obx = message.getPATIENT_RESULT().getORDER_OBSERVATION().getOBSERVATION(i).getOBX();
obx.getSetIDOBX().setValue(String.valueOf(i));
obx.getObservationIdentifier().getIdentifier().setValue(sRecord.getParamCode());
obx.getDateTimeOfTheObservation().setValue(String.valueOf(sRecord.getTimeStamp()));
obx.getObservationIdentifier().getNameOfCodingSystem().setValue(String.valueOf(sRecord.getMeasureValue()));
i++;
} catch (HL7Exception e) {
e.printStackTrace();
}
}
}
try {
writeHL7ToFile = new FileWriter(File.createTempFile("prismaflexOutputFrom3001HL7", "txt", new File
("c:\\tmp\\prismaflex")));
writeHL7ToFile.write(message.getMSH().toString());
writeHL7ToFile.flush();
} catch (IOException e) {
e.printStackTrace();
}
// Now, Encode the message and look at the output
try {
Parser parser = new PipeParser();
String encodedMessage = parser.encode(message);
System.out.println("Printing HL7 Encoded Message:");
System.out.println(encodedMessage);
} catch (HL7Exception e) {
e.printStackTrace();
}
}
}
As Nicholas Orlowski pointed out, the problem is in the line ending characters, which according to the HL7 standard are CR characters which make a Windows command prompt only reset the cursor to the beggining of the line and overwrite it with next line's content. Therefore for console output You need to replace the line-endings with something else.
For a recent HL7 app using HAPI, which You also seem to be using, I made a little helper method to achieve this function:
private static String replaceNewlines(String input) {
return input.replaceAll("\\r", "\n");
}
The function can be used on all platforms, as it replaces the CR characters with the OS-specific newline character(s).
Then I can use it to output to console as follows:
LOGGER.trace("Generated message contents:\n" + replaceNewlines(outMessage.encode()));
In this case I am using log4j for logging to console, not simple console printout, but the problem was the same for me.
Hope it helps!
Have you considered using the HAPI? It is written for java, it's counter part nHAPI is written for .net as well. Details here:
http://hl7api.sourceforge.net/
I have had a similar problem in my python HL7py library. Many times the console doesn't like printing characters. I had to write a helper that changed CR to LF (line feed) to display the lines correctly. Hope that helps.
It won't display in the console but it will when you write to the file. Try looking at the variable in debug mode and writing it to a file.

Converting LinkedIn XML data to JSON in Java

I am making a LinkedIn app that is primarily written JavaScript and Flash, but all of the data comes from a Java proxy. I need the data to be in JSON, and unfortunately LinkedIn only supports XML. The best solution is to convert XML to JSON on the server before sending it back to the client, but admittedly my Java skills are not strong. I have code that looks like it should work, but I get a JSONObject exception.
I am using the org.json package to manipulate the XML: http://json.org/java/
Here is the Java snippet that tries to convert XML to JSON. It's not pretty, but I'm just trying to make some headway with converting the data:
public static String readResponse(HttpResponse response) {
System.out.println("Reading response...");
try {
BufferedReader br = new BufferedReader(new InputStreamReader(
response.getEntity().getContent()));
String readLine;
String innhold = "";
while (((readLine = br.readLine()) != null)) {
innhold += readLine;
}
try {
JSONObject myJ = new JSONObject();
String ret = myJ.getJSONObject(innhold).toString();
System.out.println(ret);
return ret;
} catch (Exception e) {
System.out.println(e);
}
return innhold;
} catch (IOException e) {
System.out.println(e);
return null;
}
}
Here is data very similar to what I am trying to convert:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<person>
<first-name>First</first-name>
<last-name>Last</last-name>
<headline>My Profile</headline>
<site-standard-profile-request>
<url>http://www.linkedin.com/profile</url>
</site-standard-profile-request>
</person>
And here is the exception I am getting:
org.json.JSONException: JSONObject["<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><person> <first-name>First<\/first-name> <last-name>Last<\/last-name> <headline>My Profile<\/headline> <site-standard-profile-request> <url>http://www.linkedin.com/profile<\/url> <\/site-standard-profile-request><\/person>"] not found.
Any help is appreciated, thanks!
Mads, that did just the trick! Thank you so much, I knew there was a very simple solution that I just wasn't seeing. Here is the magical line that converts an XML string to JSON:
String ret = XML.toJSONObject(aStringOfXml).toString();
It looks like you are using the wrong object and method. JSONObject.getJSONObject() expects you to provide a key to lookup an object, not an arbritrary XML string.
You don't have a key that matches that XML string, so the lookup is failing and you get the exception that the object (with the specified key) was not found.
You are trying to parse XML and serialize as JSON.
I believe that you could use XML.toJSONObject

Categories

Resources