So I have the following object:
public class Foo {
private String firstName = "John";
private String lastName = "Doe";
}
I want to serialize this class to YAML using SnakeYAML (not Jackson or using annotations) and make all properties lowercase like so:
firstname: John
lastname: Doe
I need to do this for a lot of classes, so I am looking for a generic way. Overriding PropertyUtils does not seem to work like in this case for parsing: How to parse field name with dash in snakeyaml?
Not entirely sure if I understood your question correctly, but here is my solution:
Sample sample = new Sample(); // your class
for(Field field : sample.getClass().getDeclaredFields()) {
field.setAccessible(true);
Object value = field.get(sample);
System.out.println(field.getName().toLowerCase() + " " + value.toString() + " " + field.getGenericType().getTypeName());
}
for example, if you have a class like this:
public class Sample {
String name = "John";
String lastName = "Doe";
int six = 6;
}
it will generate the following output:
name John java.lang.String
lastname Doe java.lang.String
six 6 int
you can then plug this into your YAML writer
Hope that answers it
Related
I have a method that can return QRcode data in {'p':1,"x":10,"y":20} this format and it is captured in a variable called qrdata (which is a String data type ).
My question is how can I retrieve value from that key , value pair object ?if .... String qrdata = readQR(image) then how can I retrieve data from qrdata ?
You can use the JSONObject class from javax.json as mentioned in BuildSlayer's answer.
In the example in your question you use simple quotes for 'p'. Assuming it is not a typo and you meant that different charcacters can be used as quotes, you could run into trouble using it though. In that case, you could use plain java to parse your qrData String:
public String[] parseJSON(String qrData){
String[] output = new String[qrData.length()];
int i = 0;
for (String keyValuePair:qrData.split(",")) {
output[i++] = keyValuePair.split(":")[1];
}
return output;
}
}
You can do the following:
JSONObject jsonObject = new JSONObject(qrData);
System.out.println("p: " + jsonObject.getInt("p"));
System.out.println("x: " + jsonObject.getInt("x"));
System.out.println("y: " + jsonObject.getInt("y"));
Output:
p: 1
x: 10
y: 20
I'm a complete beginner to Java and I have been given an exercise where I have to read data from a CSV file and then create an object for each line of the file as the program reads the data from the file.
Here is part of the CSV file:
1,Jay, Walker,91 Boland Drive,BAGOTVILLE,NSW,2477
2,Mel, Lowe,45 Ocean Drive,MILLERS POINT,NSW,2000
3,Hugh, Manatee,32 Edgecliff Road,REDFERN,NSW,2016
4,Elizabeth, Turner,93 Webb Road,MOUNT HUTTON,NSW,2290
and so on ...
Here is my code that reads data from the CSV file:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Client_19918424 {
public static void main(String[] args) throws FileNotFoundException {
File inFile = new File("clients.txt");
Scanner inputFile = new Scanner(inFile);
String str;
String[] tokens;
while (inputFile.hasNext()) {
str = inputFile.nextLine(); // read a line of text from the file
tokens = str.split(","); // split the line using commas as delimiter
System.out.println("Client ID: " + tokens[0]);
System.out.println("Client First Name: " + tokens[1]);
System.out.println("Client Sur Name: " + tokens[2]);
System.out.println("Street Address: " + tokens[3]);
System.out.println("Suburb: " + tokens[4]);
System.out.println("State: " + tokens[5]);
System.out.println("Postcode:" + tokens[6]);
System.out.println( );
} // end while
}
}
this is my Client class (have constructor):
public class Client {
private int clientID;
private String firstName;
private String surName;
private String street;
private String suburb;
private String state;
private int postcode;
// constructor
public Client (int ID, String fName, String sName, String str, String sb, String sta, int pCode) {
clientID = ID;
firstName = fName;
surName = sName;
street = str;
suburb = sb;
state = sta;
postcode = pCode;
}
However I don't know how to create a Client object for each line of text file as the program reads data from file.
like for the first line make something like this:
Client client1 = new Client(1, "Jay", "Walker", "91 Boland Drive", "BAGOTVILLE", "NSW", 2477);
And then add it to array:
Client[0] = client1;
can someone help me to solve this question, im really appreciate.
You are almost there.
All that's left to do is to map each token that is already printed to the corresponding fields in the Client class. Since token[0] doesn't really tell what value it holds you could do it in three ways:
while (inputFile.hasNext()) {
str = inputFile.nextLine();
tokens = str.split(",");
// Because tokens[0] is of type String but clientID is of type int,
// we need to parse it and get the integer representation.
int clientID = Integer.parseInt(tokens[0]);
// Both of type String, no parsing required.
String firstName = tokens[1];
String surName = tokens[2];
String street = tokens[3];
String suburb = tokens[4];
String state = tokens[5];
int postcode = Integer.parseInt(tokens[6]);
// Then all that's left to do is to create a new object of `Client` type
// and pass all the gathered information.
Client client = new Client(clientID, firstName, surName, street, suburb, state, postcode);
System.out.println(client + "\n");
}
At this moment if we try to print the client (last line) we will get something like this: com.example.demo.Client#30a3107a. That's because we didn't tell how we want our object to be displayed. For that toString() method in Client class has to be overriden like so:
#Override
public String toString() {
return "Client ID: " + clientID + "\n" + "Client First Name: " + firstName + "\n"
+ "Client Sur Name: " + surName + "\n" + "Street Address: " + street + "\n"
+ "Suburb: " + suburb + "\n" + "State: " + state + "\n" + "Postcode: " + postcode;
}
It will give the exact output that is in your example.
It is achievable to create the class by passing those tokens directly as well, without the creation of temporary variables:
Client client = new Client(Integer.parseInt(tokens[0]), tokens[1], tokens[2], tokens[3], tokens[4], tokens[5], Integer.parseInt(tokens[6]));
This case brings us to the third solution with setters and getters.
The variables that describe the Client are already defined, it is possible to pass them to assemble the perfect object, but it is not possible to retrieve them. Instead of setting the variables directly in the constructor, we can create a special method that will do the job, for instance:
// Other fields omitted
private int clientID;
// The empty constructor required for later usage,
// since right now, we can't create the object without specifying every property.
public Client() {
}
// This method does exactly the same thing that was done before but
// in the constructor directly
public void setClientID(int clientID) {
this.clientID = clientID;
}
// This method will assist in retrieving the set data from above.
public int getClientID() {
return clientID;
}
And then the while loop would look like this instead:
Client client = new Client();
client.setClientID(Integer.parseInt(tokens[0]));
client.setFirstName(tokens[1]);
client.setSurName(tokens[2]);
client.setStreet(tokens[3]);
client.setSuburb(tokens[4]);
client.setState(tokens[5]);
client.setPostcode(Integer.parseInt(tokens[6]));
And to get those values:
System.out.println("Client ID: " + client.getClientID());
Or you could use the constructor with the fields to create the client, add getters in the class, omit both setters, and the empty constructor if the creation of the client should only be possible with all the fields present.
I have a Json string like below
String jsonRequestString = "{\"access_code\" : \"9bPbN3\" , "
+ "\"merchant_reference\" : \"123\", \"language\" : \"en\",\"id\" : \"149018273\","
+ "\"merchant_identifier\" : \"gKc\", \"signature\" : \"570fd712af47995468550bec2655d9e23cdb451d\", "
+ "\"command\" : \"VOID\"}";
I have a String variable as
String code = "9bPbN3";
Question, how do I plugin the above string instead of hardcoding it at the below place. i.e. instead of 9bPbN3, I want to use the variable code there.
String jsonRequestString = "{\"access_code\" : \"9bPbN3\" , "
Many Thanks in advance.
If you are struggling to arrange the "'s the correct syntax would be
String jsonRequestString = "{\"access_code\" : \""+code+"\" , ";
Instead of formatting Json string manually, which takes alot of effort, consider using a library or util.
For ex (going to use Jackson library) :
Request re = new Request();
re.setCode(code);
...
ObjectMapper mapper = new ObjectMapper();
String jsonStr = mapper.writeValueAsString(re);
String yourVariable = "xyz";
String jsonRequestString = "{\"access_code\" : \"" + yourVariable + "\" , "
+ "\"merchant_reference\" : \"123\", \"language\" : \"en\",\"id\" : \"149018273\","
+ "\"merchant_identifier\" : \"gKc\", \"signature\" : \"570fd712af47995468550bec2655d9e23cdb451d\", "
+ "\"command\" : \"VOID\"}";
General advice is to avoid crafting a json structure out of vanilla strings. Instead use a json parser/writer library for this operations.
Checkout http://stleary.github.io/JSON-java/index.html / http://stleary.github.io/JSON-java/index.html .
There a various other libraries and tutorials available.
If you don't want to go this direction, use a "known value" placeholder and substitute it. So the full json would contain "access_code" : "##ACCESS_CODE##" and you would Substitute the placeholder with the real value. So your json string would be some kind of a string template.
Another option would be to use the format method like so:
String jsonRequestString = "{\"access_code\" : \"%s\" , "
+ "\"merchant_reference\" : \"123\", \"language\" : \"en\",\"id\" : \"149018273\","
+ "\"merchant_identifier\" : \"gKc\", \"signature\" : \"570fd712af47995468550bec2655d9e23cdb451d\", "
+ "\"command\" : \"VOID\"}";
String code = "9bPbN3";
String result = String.format(jsonRequestString, code);
Notice the "%s" I put in the place of where code would go. When you call the format method with code as a parameter, it puts it where the "%s" was.
I´m parsing a plain text and trying to convert into an Object.
The text looks like(and i can´t change the format):
"N001";"2014-08-12-07.11.37.352000";" ";"some#email.com ";4847 ;"street";"NAME SURNAME ";26 ;"CALIFORNIA ";21
and The Object to convert:
String index;
String timestamp;
String mail;
Integer zipCode
...
I´ve tried with:
StringTokenizer st1 = new StringTokenizer(N001\";\"2014-08-12-07.11.37.352000\";\" \";\"some#email.com \";4847 ;\"street\";\"NAME SURNAME \";26 ;\"CALIFORNIA \";21);
while(st2.hasMoreTokens()) {
System.out.println(st2.nextToken(";").replaceAll("\"",""));
}
And the output is the correct one, i´ve thinking to have a counter and hardcoding with a case bucle and set the field deppending the counter, but the problem is that I have 40 fields...
Some idea?
Thanks a lot!
String line = "N001";"2014-08-12-07.11.37.352000";" ";"some#email.com ";4847 ;"street";"NAME SURNAME ";26 ;"CALIFORNIA ";21
StringTokenizer st1 = new StringTokenizer(line, ";");
while(st2.hasMoreTokens()) {
System.out.println(st2.nextToken().replaceAll("\"",""));
}
Or you can use split method and directly get a array of values using the delimiter ;
String []values = line.split(";");
then iterate through the array and get and cast the values they way you want
Regardless of the way you are parsing the file, you somehow need to define the mapping of column-to-field (and how to parse the text).
if this is a CVS file, you could use a library like super-csv. All you need to do is write a mapping definition.
I would first split your input String based on the semi-colon separator, then clean up the values.
For instance:
String input = "\"N001\";\"2014-08-12-07.11.37.352000\";\" " +
"\";\"some#email.com " +
"\";4847 ;\"street\";\"NAME " +
"SURNAME \";26 ;\"CALIFORNIA " +
"\";21 ";
// raw split
String[] split = input.split(";");
System.out.printf("Raw: %n%s%n", Arrays.toString(split));
// cleaning up whitespace and double quotes
ArrayList<String> cleanValues = new ArrayList<String>();
for (String s: split) {
String clean = s.replaceAll("[\\s\"]", "");
if (!clean.isEmpty()) {
cleanValues.add(clean);
}
}
System.out.printf("Clean: %n%s%n", cleanValues);
Output
Raw:
["N001", "2014-08-12-07.11.37.352000", " ", "some#email.com ", 4847 , "street", "NAME SURNAME ", 26 , "CALIFORNIA ", 21 ]
Clean:
[N001, 2014-08-12-07.11.37.352000, some#email.com, 4847, street, NAMESURNAME, 26, CALIFORNIA, 21]
Note
In order to map the values to your variables you will need to know their index in advance, and it will have to be consistent.
Then you can use the get(int i) method to retrieve them from your List - e.g. cleanValues.get(2) will get you the e-mail, etc.
Note (2)
If you do not know the indices in advance or they may vary, then you are in trouble.
You can of course try to get those indices by using regular expressions but I suspect you might end up complicating your life quite a bit.
you can use Java Reflection to automate your process.
Iterate over the fields
Field[] fields = dummyRow.getClass().getFields();
and set your values
SomeClass object = construct.newInstance();
field.set(object , value);
Im going round in circles on this.
I have a class Person, eg
public class Person {
String name = "";
}
Now, I would like to introspect this class instance & figure out what Class is name declared as.
So, name = String or java.lang.String
This is my Code:
'this' is an instance of Person.
try {
String className = this.getClass().getName();
Class cls = Class.forName(className);
Field fieldlist[] = cls.getDeclaredFields();
for (int i = 0; i < fieldlist.length; i++) {
Field fld = fieldlist[i];
int mod = fld.getModifiers();
System.out.println("1. " + fld.toGenericString());
System.out.println("2. " + fld.getName());
System.out.println("3. " + fld.getGenericType() + "]");
Object oj = fld.getType();
// Says that 4: class java.lang.String
System.out.println("4: " + oj.toString());
Class c1 = oj.getClass();
// Should throw Exception
String stype = c1.getDeclaringClass().toString();
System.out.println("5. " + stype);
}
}
catch (Throwable e) {
System.err.println(e);
}
I managed to get to a part that states:
class java.lang.String
but I need it to be "java.lang.String"
Any ideas?
Try.. getType() and then getName()
fld.getType().getName()
Edit:(Aften Green Days' comment) -- Note that
fld.getType().getCanonicalName() will give same output in most cases. The output is different when innerclasses are used. Here is link came from search. Depending what you need to do with classname you may choose one of getName() or getCanonicalName()
System.out.println("3. " + fld.getType().getCanonicalName());
results in:
3. java.lang.String
I guess I solved it,
Should have done this:
String stype = fld.getType().getName();
I got the class name of a field by calling this
f.getDeclaringClass().getSimpleName()