java foreach database List value - java

data is selecte all users in database
it will print out:
[com.test.abc.user.domain.User#b22379c, com.test.abc.user.domain.User#364b96e5, com.test.abc.user.domain.User#1c9fb03c, com.test.abc.user.domain.User#37eb41d2]
I want to know how can I get the value in it .
I want to make it to json string like str so that the front end can get it
Please help me !!
#ResponseBody
public String getList() {
List<User> data = memberObj.getCurrentMembers() ;
System.out.println(data);
//data to string
String str = "{\"data\": [{\"id\": \"1\",\"account\": \"a#gmail.com\",\"name\": \"sky\",\"nick\": \"abc\"}]}";
return str;
}

Use google gson library
List<User> list = new ArrayList<User>();
list.add(new User());
list.add(new User());
String json = new Gson().toJson(list);

You need to give your User class a toString() method.
class User {
String name;
#Override
public String toString() {
return name;
}
}

When you printout data with
System.out.println(data)
you just print out the structure, not the objects in it.
Additionaly, you do the same here:
String str = "{\"data\": [{\"id\": \"1\",\"account\": \"a#gmail.com\",\"name\": \"sky\",\"nick\": \"abc\"}]}";
you just return an object not a value, you have to do this with a for or while loop.

Related

Obtain specific part of a string with JSON Format java

I have a question on how would be the best way to get the information from a string but that has JSON format.
{
"internal_id":"1234",
"moreInformation":"Failed authentication for user."
}
In this case, I want to get the value of "internal_id" and I already did, with subtring, lastIndexOf and indexOf
public static String returnInternalCode(String json){
String internalCode = json.substring(json.lastIndexOf("\"internal_id\":\"") + "\"internal_id\":\"".length(), json.length() - 1);
if (json.lastIndexOf("\"internal_id\":\"") == -1) return null;
return internalCode.substring(0, internalCode.indexOf("\""));
}
I also tried several JSONs with order changes that don't have the data and it also worked. I leave the full class of tests I did:
public class Test {
public static void main(String[] args) {
// Original JSON
String json = "{\"internal_id\":\"999999\",\"moreInformation\":\"Failed authentication for user, 1 authentication attempt remaining.\"}";
// Other JSON order
String json2 = "{\"moreInformation\":\"Failed authentication for user. Invalid response.\", \"moreInformation2\":\"Failed authentication for user. \", \"internal_id\":\"45678\"}";
// JSON without the internal_id
String json3 = "{\"moreInformation\":\"Failed authentication for user. Invalid response.\"}";
// JSON without moreInformation
String json4 = "{\"internal_id\":\"999999\"}";
System.out.println("JSON: ".concat(json4));
System.out.println("internalId: " + returnInternalId(json4));
System.out.println("moreInformation: " + returnMoreInformation(json4));
}
public static String returnInternalId(String json){
String internalCode = json.substring(json.lastIndexOf("\"internal_id\":\"") + "\"internal_id\":\"".length(), json.length());
if (json.lastIndexOf("\"internal_id\":\"") == -1) return null;
return internalCode.substring(0, internalCode.indexOf("\""));
}
public static String returnMoreInformation(String json){
String moreInformation = (json.substring(json.lastIndexOf("\"moreInformation\":\"") + "\"moreInformation\":\"".length(), json.length()));
if (json.lastIndexOf("\"moreInformation\":\"") == -1) return null;
return moreInformation.substring(0, moreInformation.indexOf("\""));
}
}
I would like to know if there are better ways to do what I did, such as with StringBuilder or StringBuffer and also to find out which way uses less memory or is faster to run, how do I know that? How long does it take to execute a method?
Thank you very much!
You can extract the values this way; Using Simple-json library
JSONObject jobj = (JSONObject) parser.parse(yourJsonString); // Pass the Json formatted String
String internal_id = (String) jobj.get("internal_id"); // Extract the value from your key
System.out.println(internal_id); // 1234

Java creating an api to expose a csv instead of json

I am working on a Java api - using Spring Boot - I would like to create a controller that exports data from the db - into a csv that a user can download.
This is an example of what I have making Json responses.
// get chart
#SuppressWarnings("unchecked")
public Object getChart() {
// build clean object
JSONObject contents = new JSONObject();
//inverse bubble chart
JSONObject chart = new JSONObject();
chart.put("label", "250 applicants");
chart.put("value", 120);
contents.put("chart", chart);
contents.put("number", "0202 000 000");
JSONObject json = new JSONObject();
json.put("contents", contents);
return json;
}
I've seen this example -- but its being called from a reactjs framework - so not sure how I would fetch the HttpServletResponse?
Create and Download CSV file Java(Servlet)
would I invoke the api as usual?
//api/getMyCsv
#SuppressWarnings("unchecked")
#RequestMapping(value = {"/api/getMyC"}, method = RequestMethod.GET)
#CrossOrigin(origins = {"*"})
public ResponseEntity<?> getHome(
//HttpServletRequest request
) throws Exception {
JSONObject chart = getChart();
JSONArray data = new JSONArray();
data.add(chart);
//create empty response
JSONObject response = new JSONObject();
//create success response
response.put("data", data);
response.put("status", "success");
response.put("msg", "fetched csv");
return new ResponseEntity<>(response, HttpStatus.OK);
}
so with the react - using axios
export function fetchCsv(data) {
let url = "http://www.example.com/api/getMyC";
return function (dispatch) {
axios.get(url, {
params: data
})
.then(function (response) {
response = response.data.data;
dispatch(alertSuccess(response));
})
.catch(function (error) {
dispatch(alertFail(error));
});
}
}
CSV is just comma separated values right?
So, you can represent a row of data for example, as a class.
Take an address:
30 my street, my town, my country
if I wanted to represent that data as a class, and later as CSV data I'd make a class something like this:
public class AddressCSV{
private String street;
private String town;
private String country;
public AddressCSV(String street, String town, String country){
this.street = street;
this.town = town;
this.country = country;
}
// getters and setters here
// here you could have a method called generateCSV() for example
// or you could override the toString() method like this
#Override
public String toString(){
return street + "," + town + "," + country + "\n"; // Add the '\n' if you need a new line
}
}
Then you use it the same way as your JSONObject, except instead of returning the whole object you do return address.toString();
This is a very simple example of course. Checkout the StringBuilder class if your have a lot of things to build.
Overriding the toString() method means you can do things like pass your object like System.out.printline(address) and it will print the CSV.
The Spring way to help (un)marshaling data is to implement and register an HttpMessageConverter.
You could implement one that specifically handles MediaType text/csv, and supports whatever object types you decide to implement, e.g.
List<List<?>> - Row is a list of values, auto-converted to string.
List<Object[]> - Row is an array of values, auto-converted to string.
List<String[]> - Row is an array of string values.
List<?> - Row is an bean object, field names added as header row.
You may even implement your own field annotations to control column order and header row values.
You could also make it understand JAXB and/or JSON annotations.
With such a converter in place, it's now easy to write Controller methods returning CSV:
#GetMapping(path="/api/getMyC", produces="text/csv")
public List<String[]> getMyCAsCsv() {
List<Object[]> csv = Arrays.asList(
new Object[] { "First Name", "Last Name", "Age" },
new Object[] { "John" , "Doe" , 33 },
new Object[] { "Jane" , "Smith" , 29 }
);
return csv;
}
DO NOT try doing basic String trickery because the address, especially the street is bound to contain characters such as commas, quotes or line endings. This can easily mess up the CSV output. These characters need to be properly escaped in order to generate a parseable CSV output. Use a CSV library for that instead.
Example with univocity-parsers:
ResultSet rs = queryDataFromYourDb();
StringWriter output = new StringWriter(); //writing to a String to make things easy
CsvRoutines csvRoutine = new CsvRoutines();
csvRoutine.write(rs, output);
System.out.println(output.toString());
For performance, can write to an OutputStream directly and add more stuff to it after dumping your ResultSet into CSV. In such case you will want to keep the output open for writing. In this case call:
csvRoutine.setKeepResourcesOpen(true);
Before writing the ResultSet. You'll have to close the resultSet after writing.
Disclaimer: I'm the author of this library. It's open-source and free.

ElasticSearch Multiget issue in Java

I am new to Java programming and need some help here.
I am running below code and getting appropriate response i.e.
{"name1":"Name2","date1":"2016-05-13","message1":"Message2"}
{"name1":"Name0","date1":"2016-05-13","message1":"Message0"}
MultiGetResponse multiGetItemResponses = client.prepareMultiGet()
.add("loc", "message", "AVSoemK55hnvwxeDfgCc", "AVSoemK55hnvwxeDfgCa").get();
for(MultiGetItemResponse itemResponse: multiGetItemResponses){
GetResponse response2 = itemResponse.getResponse();
if(response2.isExists()){
String json2 = response2.getSourceAsString();
System.out.println(json2);
}
}
however, when i am trying to parameterise the search text, its not returning any value. Can anyone please guide what might be going wrong here? I have checked that variable abc is returning correct value i.e. "AVSoemK55hnvwxeDfgCc", "AVSoemK55hnvwxeDfgCa"
public static boolean getData(String ids){
String idAry[] = ids.split(",");
ArrayList<String> idStr = new ArrayList<String>();
for (String id:idAry){
idStr.add('"'+id+'"');
}
String abc = idStr.toString().replace("[", "").replace("]", "");
System.out.println(abc);
MultiGetResponse multiGetItemResponses = client.prepareMultiGet()
.add("loc", "message", abc).get();
// MultiGetResponse multiGetItemResponses = client.prepareMultiGet()
// .add("loc", "message", "AVSoemK55hnvwxeDfgCc", "AVSoemK55hnvwxeDfgCa").get();
//
for(MultiGetItemResponse itemResponse: multiGetItemResponses){
GetResponse response2 = itemResponse.getResponse();
if(response2.isExists()){
String json2 = response2.getSourceAsString();
System.out.println(json2);
}
}
return true;
}
You don't need the abc variable, i.e. you don't need to transform your list to string. You simply need to construct your query like this, by passing idList to your add() call as this call will take the index, the type and an Iterable<String>, so the idList already fits the job.
public static boolean getData(String ids){
String idAry[] = ids.split(",");
List<String> idList = Arrays.asList(idAry);
MultiGetResponse multiGetItemResponses = client.prepareMultiGet()
.add("loc", "message", idList).get();
...

Return records in java

I need to return multiple records in to a variable, in below mention code with in while loop I am getting all the records but while return result I am getting only one record I don't know how to do
public String feed()
{
String projectname=null;
String claintid=null;
String projectstatus=null;
String prjstartdate=null;
String prjenddate=null;
String lastmodified=null;
String prjpinurl=null;
String patientDetails=null;
try
{
Connection conn = getMySqlConnection();
String simpleProc = "{ call Sp_RetPrjvals () }";
CallableStatement cs = conn.prepareCall(simpleProc);
ResultSet rs=(ResultSet) cs.executeQuery();
while(rs.next()){
projectid=rs.getString(1);
projectname=rs.getString(2);
claintid=rs.getString(3);
projectstatus=rs.getString(4);
prjstartdate=rs.getString(5);
prjenddate=rs.getString(6);
lastmodified=rs.getString(7);
prjpinurl=rs.getString(8);
patientDetails=projectid+"|"+projectname+"|"+claintid+"|"+projectstatus+"|"+prjstartdate+"|"+prjenddate+"|"+lastmodified+"|"+prjpinurl;
//here i am getting two values before:::2|Sample project 2|1|WIP|2015-08-01 00:00:00.0|2016-08-01 00:00:00.0|2015-08-24 16:40:10.0|http://hcup-us.ahrq.gov/toolssoftware/ccs/ccs.jsp
before:::1|Sample project 1|1|WIP|null|null|2015-08-24 16:38:39.0|http://hcup-us.ahrq.gov/toolssoftware/ccs/ccs.jsp
}
conn.close();
} catch (Exception e)
{
}
return patientDetails;
// here i am getting only After:::1|Sample project 1|1|WIP|null|null|2015-08-24 16:38:39.0|http://hcup-us.ahrq.gov/toolssoftware/ccs/ccs.jsp
}
The problem is that you override your String. You have to add it to a list or an array.
For example: List<String> al = new ArrayList<String>()
and then you have to add the String you build on every while step into this array and retrun this array:
al.add(patientDetails);
your return statement follows this: return al;
your function header is then:
public List<String> feed(){
patientDetails is a `String` Object.
If you expet to be able to retun a list of striong, then you should use an array of String objects in that case.
Something like:
String[] patientDetails
Then in your code you should add each returned record to your array
Something like:
patientDetails[i] = projectid+"|"+projectname+"|"+claintid+"|"+projectstatus+"|"+prjstartdate+"|"+prjenddate+"|"+lastmodified+"|"+prjpinurl;
i ++; //Initialize this *i* variable outside the while
Also change the signature of your method as:
public String[] feed()
Because you don't know your result size, you need a dynamic structure, like a list:
List<String> pacients = new ArrayList<>();
while(results.next()){
...
String patientDetails = ....;
pacients.add(patientDetails);
}
After this code you will have alist of pacient details. But I would advise you to keep their data in an object, not a String;
class PatientDetails {
String projectname; // you don't have to initialize with null, it's done by default
String claintid;
String projectstatus;
String prjstartdate;
String prjenddate;
String lastmodified;
String prjpinurl;
String patientDetails;
// getters & setters
#Override
public String toString(){
return projectid+"|"+projectname+"|"+claintid+"|"+ ...;
}
}
Now when you will want to print a PatientDetails you will get same result as your string representation.
And you would return a List<PatientDetails> holding your query results.

Java - Parsing JSON Response - Content is either String or JSONObject

I am facing a typical scenario while parsing JSON Response for one of the Service calls.
The content for one of the attributes (from below example, consider "name" as a attribute) coming as either String or JSONObject.
How to handle these kind of scenarios through code. Also, please consider that json content need not be consistent with same set of attributes.
Example:
String Response
{"name":"Adam"}
JSON Response
{"name":{"FirstName":"Adam", "MiddleName":"Don"} }
OR
{"name":{"FirstName":"Adam", "LastName":"Don"} }
OR
{"name":{"MiddleName":"Adam", "LastName":"Don"} }
You can ask the root JSONObject with the method optJSONObject(name) to return a JSONObject for the given name if it exists and is an JsonObject. Otherwise you can also test with optString(name) for a String.
So something like:
JSONObject root = new JSONObject(... data from server ... );
JSONObject obj = root.optJSONObject("name");
if (obj != null) {
// Do something with the object
} else {
String name = root.getString("name");
// Do something with the string
}
Parse your response JSON as a JSONObject, then get another JSONObject for the "name" key, if it throws a JSONException then your object is probably a String in with case you can call get String for the "name" key in your catch block.
String name = "";
JSONObject serverJSON = new JSONObject(YOUR_JSON_RESPONSE_STRING_FROM_SERVER);
try {
JSONObject nameObject = serverJSON.getJSONObject("name");
if (nameObject.has("first_name")) {
name = nameObject.getString("first_name") + " ";
}
if (nameObject.has("middle_name")) {
name += nameObject.getString("middle_name") + " ";
}
if (nameObject.has("last_name")) {
name += nameObject.getString("last_name");
}
name = name.trim();
} catch (JSONException e) {
// Probably a String, try again...
try {
name = serverJSON.getString("name");
catch (JSONException e) {
// Not a String or a JSONObject... figure out what's wrong...
e.printStackTrace();
}
}
I would really recommend though, that if you have any control of the server that you make sure that the name key choose one type and sticks to it; a JSONObject... You would be able to use the has(String key) member function in if statements to properly find all of your data without knowing what existed at runtime...
EDIT: Thought of a different idea... Parse the String to the first colon and see if the next non-whitespace character is a quotation mark, if it is, then your key belongs to a String, if it is a curly brace then it's a JSONObject. (If neither, then you have an error, because you aren't expecting an array or number or null or anything else...)
boolean jsonIsString = true;
String searchString = json.substring(json.indexOf(":")).trim();
if ("{".equals(searchString.charAt(0)) {
jsonIsString = false;
}
Tonity's solution is good. You can also use this solution.
In my solution, there will be no any Exception fired until JSON is wrong. What I am doing is following.
Search for number of ":" in string.
If it returns 1, then we sure that there is "name" value.
Otherwise, we need to check, whether there is "FirstName","MiddleName" or "LastName" exist in string or not.
Just go through this snippet and you will find solution for your problem.
// String str = "{\"name\":\"chintan\"}";
String str = "{\"name\":{\"FirstName\":\"Chintan\",\"LastName\":\"Rathod\"}}";
try {
//we will check how many ":" are there in string, if it is one, then
// we are going to get "name" field.
if ((str.split(":").length - 1) == 1)
{
Log.d("Home", "1");
JSONObject json = new JSONObject(str);
Log.d("Home", "Name : " + json.get("name"));
}
else
{
Log.d("Home", "more then 2");
JSONObject jName = new JSONObject(str);
JSONObject jTemp = jName.getJSONObject("name");
if (jTemp.toString().contains("FirstName"))
Log.d("Home", "FirstName :" + jTemp.getString("FirstName"));
if (jTemp.toString().contains("MiddleName"))
Log.d("Home","MiddleName :" +jTemp.getString("MiddleName"));
if (jTemp.toString().contains("LastName"))
Log.d("Home", "LastName :" + jTemp.getString("LastName"));
}
} catch (JSONException e) {
e.printStackTrace();
}
Output
08-06 11:52:34.060: D/Home(1439): more then 2
08-06 11:52:34.060: D/Home(1439): FirstName :Chintan
08-06 11:52:34.070: D/Home(1439): LastName :Rathod
I faced a problem like this as well. I didn't want to parse the JSON manually. Do this if firstName exists otherwise do that. I didn't want to mess up my structure because I only define java object and my client handles the parsing. So, I came up with following:
#Getter
#Setter
#ToString
class Response {
private Name name;
#Getter
#Setter
#NoArgsConstructor
#ToString
public static class Name {
private String name;
private String firstName;
private String middleName;
private String lastName;
public Name(String name) {
this.name = name;
}
}
}
Then, parse the json;
ObjectMapper objectMapper = new ObjectMapper();
Response response = objectMapper.readValue(json, Response.class);
Now, string response and JSON response can be parsed with the same class.

Categories