I want to create a report that pulls in all licenses and insurances, from their separate repositories, into an excel sheet. Is there a way to do it like this:
#RequestMapping(value="/report/expirationReport")
public void getExpirationReport(Model model,HttpServletResponse response){
List<License> licenses;
List<Insurance> insurances;
licenses = licenseRepository.findAll();
insurances = insuranceRepository.findAll();
List<String> headers=Arrays.asList("Legal Name","Principle Name","Type","State","Expiration");
response.addHeader("Content-disposition", "attachment; filename=ExpirationReport.xls");
response.setContentType("application/vnd.ms-excel");
try {
new SimpleExporter().gridExport(headers, licenses, insurances,"client.legalName, client.principleName,type,state,expiration", response.getOutputStream());
response.flushBuffer();
}catch (IOException e) {
e.printStackTrace();
}
}
Both repositories already exist, but I can't just add the Insurances in (like I did above) because the SimpleExporter seems to only be accepting two objects and then the object props. Any idea how to get it to accept all three objects? Or any idea how to best concatenate/save the two repo findAll function results into one data object?
Edit:
I was able to get this to work by going through the Client table, as license and insurances both had foreign keys to client. Here's the code:
#RequestMapping(value="/report/expirationReport")
public void expirationReport(HttpServletResponse response){
List<Client> clients=clientRepository.findAll();
try {
response.addHeader("Content-disposition", "attachment; filename=expirationReport.xlsx");
response.setContentType("application/vnd.ms-excel");
InputStream is= new ClassPathResource("static/reports/expirationReport.xlsx").getInputStream();
Context context= new Context();
context.putVar("clients", clients);
JxlsHelper.getInstance().processTemplate(is,response.getOutputStream(),context);
response.flushBuffer();
} catch (IOException e) {
e.printStackTrace();
}
}
licenses and insurances are two separate lists that have programmatically nothing in common. The could be different in size, so that JXLS won't know at which row it should be used.
Therefore JXLS supports only a single Iterable in gridExport(). Your best bet is to join your lists together. It is up to you to decide whether to join them in the repository or a separate service (or hacked inside the controller), but it must definitely be a single collection.
Related
In fact I am making a Minecraft plugin and I was wondering how some plugins (without using DB) manage to keep information even when the server is off.
For example if we make a grade plugin and we create a different list or we stack the players who constitute each. When the server will shut down and restart afterwards, the lists will become empty again (as I initialized them).
So I wanted to know if anyone had any idea how to keep this information.
If a plugin want to save informations only for itself, and it don't need to make it accessible from another way (a PHP website for example), you can use YAML format.
Create the config file :
File usersFile = new File(plugin.getDataFolder(), "user-data.yml");
if(!usersFile.exists()) { // don't exist
usersFile.createNewFile();
// OR you can copy file, but the plugin should contains a default file
/*try (InputStream in = plugin.getResource("user-data.yml");
OutputStream out = new FileOutputStream(usersFile)) {
ByteStreams.copy(in, out);
} catch (Exception e) {
e.printStackTrace();
}*/
}
Load the file as Yaml content :
YamlConfiguration config = YamlConfiguration.loadConfiguration(usersFile);
Edit content :
config.set(playerUUID, myVar);
Save content :
config.save(usersFile);
Also, I suggest you to make I/O async (read & write) with scheduler.
Bonus:
If you want to make ONE config file per user, and with default config, do like that :
File oneUsersFile = new File(plugin.getDataFolder(), playerUUID + ".yml");
if(!oneUsersFile.exists()) { // don't exist
try (InputStream in = plugin.getResource("my-def-file.yml");
OutputStream out = new FileOutputStream(oneUsersFile)) {
ByteStreams.copy(in, out); // copy default to current
} catch (Exception e) {
e.printStackTrace();
}
}
YamlConfiguration userConfig = YamlConfiguration.loadConfiguration(oneUsersFile);
PS: the variable plugin is the instance of your plugin, i.e. the class which extends "JavaPlugin".
You can use PersistentDataContainers:
To read data from a player, use
PersistentDataContainer p = player.getPersistentDataContainer();
int blocksBroken = p.get(new NamespacedKey(plugin, "blocks_broken"), PersistentDataType.INTEGER); // You can also use DOUBLE, STRING, etc.
The Namespaced key refers to the name or pointer to the data being stored. The PersistentDataType refers to the type of data that is being stored, which can be any Java primitive type or String. To write data to a player, use
p.set(new NamespacedKey(plugin, "blocks_broken"), PersistentDataType.INTEGER, blocksBroken + 1);
After searching for an answer for hours I decided to ask it here, since the solutions I found didn't work.
I have a simple GUI to register a persons first/last name and date of birth. After entering the values, the data is listed in a JList. Now I want to save the data from the JList into a Txt file. But I can't find a way to get the data from the JList.
public void save(){
try(BufferedWriter bw = new BufferedWriter(new FileWriter("jlist.txt")))
{
/* Here should be the part, where I get the data from the JList */
bw.write(person.getNachname() + " ; " + person.getVorname() + " ; " + person.getDate() + "\n");
} catch (Exception speichern) {
speichern.printStackTrace();
}
}
Later I want to take the created Txt file and load it back into the same JList.
Maybe there is even a better way to do this but I haven't found something.
Some tips would be helpful :)
There is no JList method that does this for you.
You need to get the data from the ListModel.
You get the ListModel from the JList using the getModel() method.
You need to write a loop to:
get each element from the ListModel using the getElementAt(...) method.
convert the element to a String and write the data to your file.
Some tips would be helpful
Not related to your question, but typically data like this would be displayed in a JTable. Then you have a separate column for each of the first name, last name and date. Read the section from the Swing tutorial on How to Use Tables for more information.
As camickr point out there is no method implemented for what you a trying to achieve, instead there is a combination of things that you could do for archiving your goal.
You are facing the problem of data persistence. In now-a-days for small|medium|big size industrial applications the recommended approach is to relay on databases. I guess that is out the scope for one person that is starting to code, so using files for storing info is OK but is not straightforward.
In your case, if your application is for non-commercial purposes I would suggest to use the default mechanism for serializing and deserializing objects that comes bundled with the platform. With this you could write an entire object (including its data, a.k.a. its state) to a file on a disk, and later retrieve it with few lines codes. There are details about how the object gets serialize ("translate object to bits") and deserialized ("translate bits to object") that doesn't comes into place right now, but is well to advice to study them in the future if you planning to use this method in a commercial application.
So I suggest that you load and store the information of your application on start-up and shutdown respectively, thus only one load and store per application instance, while the application is active work with the data on memory. THIS is the simplest approach you could have in any application, and for that reason I suggest to start with this ideal scenario.
So, I say a lot of things but let's goes to the code that shows an example of storing (serialize) and loading (deserialize)
import java.io.*;
import java.util.*;
class Person implements Serializable {
String name;
int birthDate;
public Person(String name, int birthDate) {
this.name = name;
this.birthDate = birthDate;
}
}
class Main {
public static void main(String[] args) {
Collection<Person> collection = createExampleCollection();
System.out.println(collection);
storeCollection(collection, "persons.data");
Collection<Person> otherCollection = loadCollection("persons.data");
System.out.println(otherCollection);
}
private static Collection<Person> createExampleCollection() {
Collection<Person> collection = new ArrayList<Person>();
collection.add(new Person("p1",0));
collection.add(new Person("p2",10));
collection.add(new Person("p2",20));
return collection;
}
// here I'm doing two separated things that could gone in separate functions, 1) I'm converting into bytes and object of an specific class, 2) saving those bytes into a file on the disk. The thing is that the platform offers us convenient objects to do this work easily
private static void storeCollection(Collection<Person> collection, String filename) {
try {
FileOutputStream fos = new FileOutputStream(filename);
ObjectOutputStream out = new ObjectOutputStream(fos);
out.writeObject(collection);
out.close();
fos.close();
} catch (IOException i) {
i.printStackTrace();
}
}
// again there two things going on inside, 1) loading bytes from disk 2) converting those bits into a object of a specific class.
private static Collection<Person> loadCollection(String filename) {
try {
FileInputStream fis = new FileInputStream(filename);
ObjectInputStream in = new ObjectInputStream(fis);
Collection<Person> persons = (Collection<Person>) in.readObject();
in.close();
fis.close();
return persons;
} catch (Exception i) {
i.printStackTrace();
return null;
}
}
}
You should try to use the functions of loadCollection and storeCollection on start-up and shutdown respectively.
I made this code with comments for jButton and jList in jFrame, Button saves text Items to File from jList.
private void btnSaveActionPerformed(java.awt.event.ActionEvent evt) { //jButton name: "btnSave"
try { //trying to save file
BufferedWriter bw = new BufferedWriter(new FileWriter("data.txt")); //file where I store the data of jList1 (file will be stored at: C:\Users\%username%\Documents\NetBeansProjects\<ThisProjectName>\data.txt) (if You use NetBeans)
for (int i=0; i<jList1.getModel().getSize(); i++){ //opens a cycle to automatically store data of all items
bw.write(jList1.getModel().getElementAt(i)); //writing a line from jList1
bw.newLine(); //making a new line for the next item (by removing this line, You will write only one line of all items in file)
} //cycle closes
bw.close(); //file writing closes
} catch (IOException ex) { //catching the error when file is not saved
Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex); //showing the error
} //Exception closes
} //Action closes
I am writing a program that uses Serialization to store the program's objects (users, admins, books, etc). I have multiple controllers that control the adding of different objects to different array lists.
Example:
Login controller controls the adding and removing of users to the system
Example:
Book controller which controls adding and removing of books to the system
I would like to know the best way of saving all these different objects from different controllers into my serialized file.
Currently, I have been reading the serialized file in each controller to populate the array lists. this is my reading method in the "Book" controller.
And I have a save to file method as well however I'm not sure how to implement the ArrayList from different controllers.
private void populateArrayLists() {
System.out.print("Im here in ArrayList");
ArrayList<Object> deserialised = new ArrayList<Object>();
try {
FileInputStream file = new FileInputStream("info.ser");
ObjectInputStream inputFile = new ObjectInputStream(file);
deserialised = (ArrayList<Object>) inputFile.readObject();
inputFile.close();
file.close();
} catch (IOException | ClassNotFoundException e) {
JOptionPane.showMessageDialog(null, e.getMessage());
}
books = (ArrayList<Book>) deserialised.get(2);
}
private void saveData() {
ArrayList<Object> allData = new ArrayList<Object>();
books.add(book1);
admins.add(admin1);
users.add(user1);
allData.add(users);
allData.add(admins);
allData.add(books);
try {
FileOutputStream file;
file = new FileOutputStream("info.ser");
ObjectOutputStream outputFile = new ObjectOutputStream(file);
outputFile.writeObject(allData);
outputFile.close();
file.close();
JOptionPane.showMessageDialog(null, "Saved");
} catch (IOException e) {
JOptionPane.showMessageDialog(null, e.getMessage());
}
}
I would like a method of saving all the different objects in different controllers in one place.
Given your question description, I suggest you implement one solution where you make use of the Repository concept in the way described by Domain Driven Design. It allows you to centralize the logic for handling the collection of objects you have so far. Since you decide to use files, I recommend you to have one file per class of objects instead of one file for all your objects collections. Here you can find a basic approach, it can be improved further with generics.
I am creating a program for a small business. This program is meant to have smaller modules that, when developed, will be attatched to the rest of the program. It contains an "Article" and a "Category" class, which is contained in lists in a "ArticleDatabase" class.
This class is serialized and saved to a file to the harddrive.
The Register module is complete, and the "Receipt" class, is likewise contained within lists in a "RegisterDatabase" class, which is serialized and saved to a separate file.
System settings, are saved in the same manner.
However, now i am designing a Invoice module, and found out that i need to add a field to the "Article" class, and to the System data.
The register is now being used, and contains actual data that needs to be saved, and therefore i can't just change the class, since this gives an InvalidClassException when i load.
Since i know that this will be a common problem in the future too, i need some advice on how to tackle this problem.
How can i setup a system i which i can save a file from a class, and load the data into an updated or new version of this class, or should i approach this in an entirely new way?
I have tried loading the data form the old file in to a duplicate class with the needed fields addded, but reconfiguring the program to use the new files instead is a very cumbersome task, and if i have to do this every now and again, a lot of time will be wasted doing this.
The methods used for saving loading are as follows:
public void saveArticleDB() throws IOException {
// Write to disk with FileOutputStream
FileOutputStream f_out = new FileOutputStream("articles.data");
// Write object with ObjectOutputStream
ObjectOutputStream obj_out = new ObjectOutputStream(f_out);
obj_out.writeObject(MyMain.articleDB);
}
public ArticleDB loadArticleDB() throws IOException {
try {
FileInputStream f_in = new FileInputStream("articles.data");
ObjectInputStream obj_in = new ObjectInputStream(f_in);
Object obj = obj_in.readObject();
if (obj instanceof ArticleDB) {
return (ArticleDB) obj;
} else return null;
} catch (FileNotFoundException e) {
new MessageDialog("Article DB - File not found");
return null;
} catch (InvalidClassException e) {
new MessageDialog("Article DB - Class didnt match");
return null;
} catch (ClassNotFoundException e) {
new MessageDialog("Article DB - Class not found");
return null;
}
}
The classes that delivers data to the save file, implements Serializable, and thats the only code used regarding the saving and loading of the class.
This is my first attempt with serializing, saving and loading, which means i am quite new to this, and therefore know/understand very few of the concepts regarding these subjects.
Advice is much appreciated :-)
I have a list of strings in the list assetList.
How can I send the list in the http response in java servlet ?
I am very new to java.
Call this method after converting your list to a string:
private void writeResponse(HttpServletResponse response, String responseString) {
try {
PrintWriter out = response.getWriter();
out.println(responseString);
out.flush();
response.flushBuffer();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
To convert the list of strings to a string, see:
Best way to convert an ArrayList to a string
A list of object is an object. So is the same as adding a object in a response (serialization) and deserializing on the other side.
OutputStream out = response.getOutputStream();
oos = new ObjectOutputStream(out);
oos.writeObject(yourSerializableObject);
More info:
How to get Object from HttpResponse?
If you are free to chose the format of the response, and the response is primarily intended to be processed by a client application, then use JSON. Turn the list of strings into a JSON array (of strings) and send that.
I'd recommend JSON because:
You are best off with a standard format / serializatio scheme than a non-standard (i.e. custom) one.
JSON is easy to generate and parse, in a wide variety of programming languages.
JSON is text based and (relatively) human readable.
There are (of course) lots of alternatives, including language specific ones (Java object serialization), alternatives that are more compact, faster to encode, decode, and so on.
But JSON is a good de-facto choice for typical web-based application protocols.
i would suggest you to read more about servlets, JSP and ManagedBeans.
for the beggining its nice to now how these things works, but later you may upgrade and using JSF for Java Web Applications.
back to your question:
the usual way is using Java "Managed" Beans for that!
lets say you send a request to the servlet, the response should be a list of persons:
you create a Bean named Person.java with id, name, tel, ...etc with getter and setter methods.
then you would make a Controller Class like PersonManager.java
this object may have a method for getting a list of Persons or an emprty list
in your servlet you init these Datas and puting it in the REQUEST Scope for your response
here is an example how to do this in a Servlet:
public class YourServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
{
Person p = new Person();
p.setName("Mohamad ...");
p.set....
ArrayList phones = new ArrayList();
PhoneNumber ph = new PhoneNumber();
ph.set...;
ph.set...;
al.add(ph);
ph = new PhoneNumber();
ph.set...;
ph.set...;
al.add(ph);
a.setPhoneNumbers(al);
req.setAttribute("person", p);
RequestDispatcher rd = req.getRequestDispatcher("yourResult.jsp");
rd.forward(req, res);
}
}
in your JSP you can then retrieve the results and loop over the list or what ever you would like to do with it!