Reputation: 4739
I was passing parameters into a servlet to generate an excel spreadsheet. I then realized this could be dangerous in some cases. Especially if a user could guess parameters and find out information from another company(in my case). I then tried to use @Inject to inject the ViewLines sessionbean but that didn't seem to work. Then I was looking at a post from BalusC using the request.getSession() method. This works fine and this just pulls the objects I need from session without having to pass them. Is this the best way to do this?
Thanks.
@WebServlet(value = "/Excel")
public class ExcelServlet extends HttpServlet {
public static int TIME_STAMP = 1;
public static int OUNCES = 2;
public static int REV = 3;
public static int BENCHMARK = 4;
public static int WORKBOOK = 0;
@EJB
PkgLoadService pkgLoadService;
@EJB
PkgLineService pkgLineService;
private SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmmssZ");
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
OutputStream out = null;
try {
ViewLines viewLines = (ViewLines) request.getSession().getAttribute("viewLines");
/*Date startDate = sdf.parse(request.getParameter("dateStart"));
Date endDate = sdf.parse(request.getParameter("dateEnd"));
PkgLine pkgLine = pkgLineService.find(Integer.parseInt(request.getParameter("pkgLineId")));
*
*/
Date startDate = viewLines.getStartDate();
Date endDate = viewLines.getEndDate();
PkgLine pkgLine = viewLines.getSelectedPkgLine();
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition", "attachment; filename=" + pkgLine.getShortname() + ".xls");
WritableWorkbook workBook = Workbook.createWorkbook(response.getOutputStream());
WritableSheet sheet = workBook.createSheet(pkgLine.getShortname(), WORKBOOK);
WritableCellFormat dateFormat = new WritableCellFormat(DateFormats.FORMAT9);
WritableCellFormat ouncesOverFormat = new WritableCellFormat();
ouncesOverFormat.setBackground(Colour.RED);
setupCellViews(sheet);
setupColumnLables(sheet);
List<PkgLoad> pkgLoadList = pkgLoadService.findBetweenDates(pkgLine, startDate, endDate);
int row = 1;
for (PkgLoad pkgLoad : pkgLoadList) {
sheet.addCell(new Number(0, row, row));
sheet.addCell(new DateTime(TIME_STAMP, row, pkgLoad.getTimeStamp(), dateFormat));
if (pkgLoad.getOunces() > pkgLoad.getWrapSpecId().getBenchmark()) {
sheet.addCell(new Number(OUNCES, row, pkgLoad.getOunces(), ouncesOverFormat));
} else {
sheet.addCell(new Number(OUNCES, row, pkgLoad.getOunces()));
}
sheet.addCell(new Number(REV, row, pkgLoad.getRevolutions()));
sheet.addCell(new Number(BENCHMARK, row, pkgLoad.getWrapSpecId().getBenchmark()));
row++;
}
workBook.write();
workBook.close();
} catch (Exception e) {
throw new ServletException("Exception in Excel Servlet", e);
} finally {
if (out != null) {
out.close();
}
}
}
Upvotes: 0
Views: 3412
Reputation: 1108712
An alternative is to refactor that Excel thing to a method like follows:
void writeExcelSheet(ViewLines viewLines, OutputStream output) throws IOException
Then you can just do the job in a JSF action method without the need to redirect it to the servlet:
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
externalContext.setResponseContentType("application/vnd.ms-excel");
externalContext.setResponseHeader("Content-Disposition", "attachment; filename=" + pkgLine.getShortname() + ".xls");
writeExcelSheet(viewLines, externalContext.getResponseOutputStream());
facesContext.responseComplete();
And reuse the same in the servlet, if necessary (I don't think it is, seeing the problem you have now :) ):
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition", "attachment; filename=" + pkgLine.getShortname() + ".xls");
writeExcelSheet(viewLines, response.getOutputStream());
Upvotes: 1
Reputation: 6286
If you only need objects for the request scope, use the request.setAttribute() If you put things in the session you risk memory problems. Typically, the session is to maintain conversational state between browser requests. Sounds like your app doesn't need state.
Upvotes: 0
Reputation: 139921
Especially if a user could guess parameters and find out information from another company(in my case).
Assuming you are referring to URL parameters, like /Excel?companyid=1234
, then another approach is to check within your Servlet/controller if the current user is allowed to view the object they are requesting (you don't have some sort of authentication and authorization here, don't you?).
Upvotes: 0