Использование request.getSession () в сервлете - лучший способ получить данные для сервлета? - PullRequest
0 голосов
/ 02 марта 2011

Я передавал параметры в сервлет для создания таблицы Excel. Затем я понял, что это может быть опасно в некоторых случаях. Особенно, если пользователь может угадать параметры и узнать информацию из другой компании (в моем случае). Затем я попытался использовать @Inject для инъекции сеанса ViewLines, но это не помогло. Затем я просматривал сообщение от BalusC , используя метод request.getSession (). Это работает отлично, и это просто вытягивает нужные мне объекты из сессии без необходимости передавать их. Это лучший способ сделать это?

Спасибо.

@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();
            }
        }
    }

Ответы [ 3 ]

1 голос
/ 02 марта 2011

Альтернативой является рефакторинг вещи Excel в метод, подобный следующему:

void writeExcelSheet(ViewLines viewLines, OutputStream output) throws IOException

Тогда вы можете просто выполнить работу в методе действия JSF без необходимости перенаправлять его на сервлет:

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();

И при необходимости используйте то же самое в сервлете (я не думаю, что вижу проблему, которая у вас есть сейчас :)):

response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition", "attachment; filename=" + pkgLine.getShortname() + ".xls");
writeExcelSheet(viewLines, response.getOutputStream());
0 голосов
/ 02 марта 2011

Если вам нужны только объекты для области запроса, используйте request.setAttribute (). Если вы помещаете вещи в сеанс, вы рискуете проблемами с памятью.Как правило, сеанс должен поддерживать диалоговое состояние между запросами браузера.Похоже, ваше приложение не нуждается в состоянии.

0 голосов
/ 02 марта 2011

Особенно, если пользователь может угадать параметры и узнать информацию из другой компании (в моем случае).

Если вы ссылаетесь на параметры URL, например /Excel?companyid=1234, то другой подход заключается в проверке вашего сервлета / контроллера, разрешено ли текущему пользователю просматривать объект, который он запрашивает (у вас нет какой-либо аутентификации и авторизация здесь, не так ли?).

...