2
\$\begingroup\$

I have to show report data for various cases in text-csv format as soon as the user click's on the given URI's.

The given cases are:

  1. End_Customer Data
  2. Incomplete Profiles.
  3. Total Connections

Below are the User and LoginUser models I have:

LoginUser

public class LoginUser { private String contact; private String email; private String address; private Gender gender; @Indexed private String name; private Date dob; @Indexed(unique = true) private String username; 

User

public class User extends LoginUser { public static final String OBJECT_KEY = "APPUSER"; @Id private String id; private String[] imageIds; private String concerns; private String summary; private String likings; private String occupation; private String religion; private String education; private String height; @GeoSpatialIndexed(type = GeoSpatialIndexType.GEO_2DSPHERE) private double[] location; private INTERESTS[] interests; private String fcmId; private List connections; private List declined; private List pending; 
  1. For all the Uri, I have used CSV Writer class to write Header data. The Input's supplied to header Data is through Bean's I have created for respective Uri. For Example for End Customer and Incomplete Profiles I have used User Report bean and for Total Connections I have used Connections Report bean as we have to display data for different fields having different headers.

  2. Then, I have retrieved all the users from the records using findAll method. Then for each user we have done the following task based on the cases:

    • For End_Customer

      For Each User,we have retrieved specific user data and set it in User Report bean and finally set the User Report bean to Csv Writer.

    • For Incomplete Profiles

      For each user,we have checked whether any of the fields is NULL.If this true I have set the user data to User Report Bean and then set finally the User Report Bean to Csv Writer.

    • For TotalConnections

      For each User,I have checked the Connection Id(Connection Id is a Foreign Key that contains a list of user's id). For Each Connection Id,I have retrieved the Connected user specific Details and store them in Connections Report Bean.

UserReport

public class UserReport { @Indexed private String name; @Indexed(unique = true) private String username; private String contact; private String address; private String email; private List connections; private List pending; private INTERESTS[] interests; private String occupation; private Gender gender; private String region; 

ConnectionsReport

public class ConnectionsReport { @Indexed private String name; @Indexed(unique = true) private String username; private List connectionName; private Set mutualInterest; private List locations; private String customerAge; private List connectionAge; private Gender customerGender; private List connectionGender; private String customerAddress; private List connectionAddress; 

Case 1 EndCustomer

@RestController @RequestMapping("/report") public class ReportController { @Autowired private UserService userService; @RequestMapping(value = "/endcustomer", method = RequestMethod.GET, produces = "text/csv") public void endCustomerReport(HttpServletResponse response) { ICsvBeanWriter csvWriter=null; int pageSize=2000; Page<User> users=null; int page=0; String csvFileName = "End-customer.csv"; List<String> headerList=null; Field[] declaredFields=null; UserReport userReport=new UserReport(); try { response.setHeader("Content-Disposition", String.format("attachment; filename=\"%s\"", csvFileName)); headerList = new ArrayList<>(); declaredFields = UserReport.class.getDeclaredFields(); for (Field declaredField : declaredFields) { headerList.add(declaredField.getName()); } String[] header = headerList.toArray(new String[]{}); csvWriter.writeHeader(header); /* CsvPreference.STANDARD_PREFERENCE Ready to use configuration that should cover 99% of all usages.*/ csvWriter = new CsvBeanWriter(response.getWriter(), CsvPreference.STANDARD_PREFERENCE); do { users = userService.getAllUsers(new PageRequest(page,pageSize)); for (User user : users) { userReport.setName(user.getName()); userReport.setUsername(user.getUsername()); userReport.setContact(user.getContact()); userReport.setAddress(user.getAddress()); userReport.setEmail(user.getEmail()); userReport.setConnections(user.getConnections()); userReport.setPending(user.getPending()); userReport.setInterests(user.getInterests()); userReport.setOccupation(user.getOccupation()); userReport.setGender(user.getGender()); csvWriter.write(userReport, header); } page++; }while (users.hasNext()); } catch (IOException e){ e.printStackTrace(); } finally{ if(csvWriter!=null){ try { csvWriter.close(); } catch (IOException e) { e.printStackTrace(); } } } } 

Case 2 Incomplete Profile

@RequestMapping(value = "/incompleteProfiles", method = RequestMethod.GET, produces = "text/csv") public void incompleteProfiles(HttpServletResponse response) { ICsvBeanWriter csvWriter=null; int pageSize=2000; Page<User> users=null; int page=0; String csvFileName = "IncompleteProfiles.csv"; List<String> headerList=null; Field[] declaredFields=null; UserReport userReport=new UserReport(); try { response.setHeader("Content-Disposition", String.format("attachment; filename=\"%s\"", csvFileName)); headerList = new ArrayList<>(); declaredFields = UserReport.class.getDeclaredFields(); for (Field declaredField : declaredFields) { headerList.add(declaredField.getName()); } String[] header = headerList.toArray(new String[]{}); csvWriter.writeHeader(header); /* CsvPreference.STANDARD_PREFERENCE Ready to use configuration that should cover 99% of all usages.*/ csvWriter = new CsvBeanWriter(response.getWriter(), CsvPreference.STANDARD_PREFERENCE); do { users = userService.getAllUsers(new PageRequest(page,pageSize)); for (User user : users) { if(user.getName()==null && user.getGender()==null && user.getInterests()==null && user.getImageIds()==null){ userReport.setName(user.getName()); userReport.setUsername(user.getUsername()); userReport.setContact(user.getContact()); userReport.setAddress(user.getAddress()); userReport.setEmail(user.getEmail()); userReport.setConnections(user.getConnections()); userReport.setPending(user.getPending()); userReport.setInterests(user.getInterests()); userReport.setOccupation(user.getOccupation()); userReport.setGender(user.getGender()); } csvWriter.write(userReport, header); } page++; }while (users.hasNext()); } catch (IOException e){ e.printStackTrace(); } finally{ if(csvWriter!=null){ try { csvWriter.close(); } catch (IOException e) { e.printStackTrace(); } } } } 

Case 3 TotalConnections

 @RequestMapping(value = "/totalConnections", method = RequestMethod.GET, produces = "text/csv") public void totalConnections(HttpServletResponse response) { ICsvBeanWriter csvWriter=null; int pageSize=2000; Page<User> users=null; int page=0; String csvFileName = "totalConnections.csv"; List<String> headerList=null; Field[] declaredFields=null; ConnectionsReport consreport=new ConnectionsReport(); try { response.setHeader("Content-Disposition", String.format("attachment; filename=\"%s\"", csvFileName)); headerList = new ArrayList<>(); declaredFields = ConnectionsReport.class.getDeclaredFields(); for (Field declaredField : declaredFields) { headerList.add(declaredField.getName()); } String[] header = headerList.toArray(new String[]{}); csvWriter.writeHeader(header); /* CsvPreference.STANDARD_PREFERENCE Ready to use configuration that should cover 99% of all usages.*/ csvWriter = new CsvBeanWriter(response.getWriter(), CsvPreference.STANDARD_PREFERENCE); do { users = userService.getAllUsers(new PageRequest(page,pageSize)); for (User user : users) { ArrayList connList=new ArrayList(); Set mutualInterestList=new HashSet(); ArrayList locationList=new ArrayList(); ArrayList ageList=new ArrayList(); ArrayList genderList=new ArrayList(); ArrayList addressList=new ArrayList(); if(user.getConnections()!=null){ consreport.setName(user.getName()); consreport.setUsername(user.getUsername()); List connections=user.getConnections(); Iterator it=connections.iterator(); LocalDate birthdate = new LocalDate(user.getDob()); //Birth date LocalDate now = new LocalDate(); //Today's date Period period = new Period(birthdate, now, PeriodType.yearMonthDay()); consreport.setCustomerAge(period.getYears()+""); while(it.hasNext()) { String connectionId = (String) it.next(); User connectedUser=userService.get(connectionId); connList.add(connectedUser.getName()); mutualInterestList.add(connectedUser.getInterests()); genderList.add(connectedUser.getGender()); addressList.add(connectedUser.getAddress()); locationList.add(connectedUser.getLocation()); addressList.add(connectedUser.getAddress()); LocalDate birthdateconnectedUser = new LocalDate(connectedUser.getDob()); //Birth date Period period1 = new Period(birthdateconnectedUser, now, PeriodType.yearMonthDay()); ageList.add(period1.getYears()); } consreport.setConnectionName(connList); consreport.setMutualInterest(mutualInterestList); consreport.setLocations(locationList); consreport.setConnectionAge(ageList); consreport.setCustomerGender(user.getGender()); consreport.setConnectionGender(genderList); consreport.setCustomerAddress(user.getAddress()); consreport.setConnectionAddress(addressList); } csvWriter.write(consreport, header); } page++; }while (users.hasNext()); } catch (IOException e){ e.printStackTrace(); } finally{ if(csvWriter!=null){ try { csvWriter.close(); } catch (IOException e) { e.printStackTrace(); } } } } } 

Can anyone guide me with how optimizing my code, so that I can make it more efficient and effective in terms of memory and performance?

\$\endgroup\$

    1 Answer 1

    2
    \$\begingroup\$

    Ok, no problem with your POJO classes, fields/getters/setters - its basic so its fine.

    But controller - controller should not have 20 things happening in it. I don't see the import section, so can't tell about csv writer as I don't see what's the library used.

     int pageSize=2000; - this should go into configuration with proper naming some_report_page_size=2000. 

    These three controllers have a same "template" - I would say - refactor it to have reporting service and inject it. Copy/Paste is the nice way to get started and move forward when you're just wanna get things working, but its a maintenance hell later. So move implementations of three controllers into reporting service and then see the common things repeating. Same page size entered, just only file name differs? ok, make a common method and make it as input param. Then there's some different way of handling collection of users you receive? ok, make an interface and few different implementations. Basic approach is "encapsulate what changes". Let me know if you're stuck with this.

    \$\endgroup\$

      Start asking to get answers

      Find the answer to your question by asking.

      Ask question

      Explore related questions

      See similar questions with these tags.